Skip to content

Fix legend yerr #40777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion doc/source/whatsnew/v1.3.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,9 @@ Plotting

- Bug in :func:`scatter_matrix` raising when 2d ``ax`` argument passed (:issue:`16253`)
- Prevent warnings when matplotlib's ``constrained_layout`` is enabled (:issue:`25261`)
-
- Bug in :func:`DataFrame.plot` was showing the wrong colors in the legend if the function was called repeatedly and some calls used ``yerr`` while others didn't (partial fix of :issue:`39522`)
- Bug in :func:`DataFrame.plot` was showing the wrong colors in the legend if the function was called repeatedly and some calls used ``secondary_y`` and others use ``legend=False`` (:issue:`40044`)


Groupby/resample/rolling
^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
12 changes: 5 additions & 7 deletions pandas/plotting/_matplotlib/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ def _append_legend_handles_labels(self, handle: Artist, label: str) -> None:
self.legend_labels.append(label)

def _make_legend(self):
ax, leg, handle = self._get_ax_legend_handle(self.axes[0])
ax, leg = self._get_ax_legend(self.axes[0])

handles = []
labels = []
Expand All @@ -609,7 +609,7 @@ def _make_legend(self):
if leg is not None:
title = leg.get_title().get_text()
# Replace leg.LegendHandles because it misses marker info
handles.extend(handle)
handles = leg.legendHandles
labels = [x.get_text() for x in leg.get_texts()]

if self.legend:
Expand Down Expand Up @@ -640,22 +640,20 @@ def _make_legend(self):
if ax.get_visible():
ax.legend(loc="best")

def _get_ax_legend_handle(self, ax: Axes):
def _get_ax_legend(self, ax: Axes):
"""
Take in axes and return ax, legend and handle under different scenarios
Take in axes and return ax and legend under different scenarios
"""
leg = ax.get_legend()

# Get handle from axes
handle, _ = ax.get_legend_handles_labels()
other_ax = getattr(ax, "left_ax", None) or getattr(ax, "right_ax", None)
other_leg = None
if other_ax is not None:
other_leg = other_ax.get_legend()
if leg is None and other_leg is not None:
leg = other_leg
ax = other_ax
return ax, leg, handle
return ax, leg

@cache_readonly
def plt(self):
Expand Down
149 changes: 0 additions & 149 deletions pandas/tests/plotting/frame/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -1163,127 +1163,6 @@ def test_plot_int_columns(self):
df = DataFrame(np.random.randn(100, 4)).cumsum()
_check_plot_works(df.plot, legend=True)

def test_df_legend_labels(self):
kinds = ["line", "bar", "barh", "kde", "area", "hist"]
df = DataFrame(np.random.rand(3, 3), columns=["a", "b", "c"])
df2 = DataFrame(np.random.rand(3, 3), columns=["d", "e", "f"])
df3 = DataFrame(np.random.rand(3, 3), columns=["g", "h", "i"])
df4 = DataFrame(np.random.rand(3, 3), columns=["j", "k", "l"])

for kind in kinds:

ax = df.plot(kind=kind, legend=True)
self._check_legend_labels(ax, labels=df.columns)

ax = df2.plot(kind=kind, legend=False, ax=ax)
self._check_legend_labels(ax, labels=df.columns)

ax = df3.plot(kind=kind, legend=True, ax=ax)
self._check_legend_labels(ax, labels=df.columns.union(df3.columns))

ax = df4.plot(kind=kind, legend="reverse", ax=ax)
expected = list(df.columns.union(df3.columns)) + list(reversed(df4.columns))
self._check_legend_labels(ax, labels=expected)

# Secondary Y
ax = df.plot(legend=True, secondary_y="b")
self._check_legend_labels(ax, labels=["a", "b (right)", "c"])
ax = df2.plot(legend=False, ax=ax)
self._check_legend_labels(ax, labels=["a", "b (right)", "c"])
ax = df3.plot(kind="bar", legend=True, secondary_y="h", ax=ax)
self._check_legend_labels(
ax, labels=["a", "b (right)", "c", "g", "h (right)", "i"]
)

# Time Series
ind = date_range("1/1/2014", periods=3)
df = DataFrame(np.random.randn(3, 3), columns=["a", "b", "c"], index=ind)
df2 = DataFrame(np.random.randn(3, 3), columns=["d", "e", "f"], index=ind)
df3 = DataFrame(np.random.randn(3, 3), columns=["g", "h", "i"], index=ind)
ax = df.plot(legend=True, secondary_y="b")
self._check_legend_labels(ax, labels=["a", "b (right)", "c"])
ax = df2.plot(legend=False, ax=ax)
self._check_legend_labels(ax, labels=["a", "b (right)", "c"])
ax = df3.plot(legend=True, ax=ax)
self._check_legend_labels(ax, labels=["a", "b (right)", "c", "g", "h", "i"])

# scatter
ax = df.plot.scatter(x="a", y="b", label="data1")
self._check_legend_labels(ax, labels=["data1"])
ax = df2.plot.scatter(x="d", y="e", legend=False, label="data2", ax=ax)
self._check_legend_labels(ax, labels=["data1"])
ax = df3.plot.scatter(x="g", y="h", label="data3", ax=ax)
self._check_legend_labels(ax, labels=["data1", "data3"])

# ensure label args pass through and
# index name does not mutate
# column names don't mutate
df5 = df.set_index("a")
ax = df5.plot(y="b")
self._check_legend_labels(ax, labels=["b"])
ax = df5.plot(y="b", label="LABEL_b")
self._check_legend_labels(ax, labels=["LABEL_b"])
self._check_text_labels(ax.xaxis.get_label(), "a")
ax = df5.plot(y="c", label="LABEL_c", ax=ax)
self._check_legend_labels(ax, labels=["LABEL_b", "LABEL_c"])
assert df5.columns.tolist() == ["b", "c"]

def test_missing_marker_multi_plots_on_same_ax(self):
# GH 18222
df = DataFrame(data=[[1, 1, 1, 1], [2, 2, 4, 8]], columns=["x", "r", "g", "b"])
fig, ax = self.plt.subplots(nrows=1, ncols=3)
# Left plot
df.plot(x="x", y="r", linewidth=0, marker="o", color="r", ax=ax[0])
df.plot(x="x", y="g", linewidth=1, marker="x", color="g", ax=ax[0])
df.plot(x="x", y="b", linewidth=1, marker="o", color="b", ax=ax[0])
self._check_legend_labels(ax[0], labels=["r", "g", "b"])
self._check_legend_marker(ax[0], expected_markers=["o", "x", "o"])
# Center plot
df.plot(x="x", y="b", linewidth=1, marker="o", color="b", ax=ax[1])
df.plot(x="x", y="r", linewidth=0, marker="o", color="r", ax=ax[1])
df.plot(x="x", y="g", linewidth=1, marker="x", color="g", ax=ax[1])
self._check_legend_labels(ax[1], labels=["b", "r", "g"])
self._check_legend_marker(ax[1], expected_markers=["o", "o", "x"])
# Right plot
df.plot(x="x", y="g", linewidth=1, marker="x", color="g", ax=ax[2])
df.plot(x="x", y="b", linewidth=1, marker="o", color="b", ax=ax[2])
df.plot(x="x", y="r", linewidth=0, marker="o", color="r", ax=ax[2])
self._check_legend_labels(ax[2], labels=["g", "b", "r"])
self._check_legend_marker(ax[2], expected_markers=["x", "o", "o"])

def test_legend_name(self):
multi = DataFrame(
np.random.randn(4, 4),
columns=[np.array(["a", "a", "b", "b"]), np.array(["x", "y", "x", "y"])],
)
multi.columns.names = ["group", "individual"]

ax = multi.plot()
leg_title = ax.legend_.get_title()
self._check_text_labels(leg_title, "group,individual")

df = DataFrame(np.random.randn(5, 5))
ax = df.plot(legend=True, ax=ax)
leg_title = ax.legend_.get_title()
self._check_text_labels(leg_title, "group,individual")

df.columns.name = "new"
ax = df.plot(legend=False, ax=ax)
leg_title = ax.legend_.get_title()
self._check_text_labels(leg_title, "group,individual")

ax = df.plot(legend=True, ax=ax)
leg_title = ax.legend_.get_title()
self._check_text_labels(leg_title, "new")

def test_no_legend(self):
kinds = ["line", "bar", "barh", "kde", "area", "hist"]
df = DataFrame(np.random.rand(3, 3), columns=["a", "b", "c"])

for kind in kinds:
ax = df.plot(kind=kind, legend=False)
self._check_legend_labels(ax, visible=False)

def test_style_by_column(self):
import matplotlib.pyplot as plt

Expand Down Expand Up @@ -2160,34 +2039,6 @@ def test_plot_no_numeric_data(self):
with pytest.raises(TypeError, match="no numeric data to plot"):
df.plot()

def test_missing_markers_legend(self):
# 14958
df = DataFrame(np.random.randn(8, 3), columns=["A", "B", "C"])
ax = df.plot(y=["A"], marker="x", linestyle="solid")
df.plot(y=["B"], marker="o", linestyle="dotted", ax=ax)
df.plot(y=["C"], marker="<", linestyle="dotted", ax=ax)

self._check_legend_labels(ax, labels=["A", "B", "C"])
self._check_legend_marker(ax, expected_markers=["x", "o", "<"])

def test_missing_markers_legend_using_style(self):
# 14563
df = DataFrame(
{
"A": [1, 2, 3, 4, 5, 6],
"B": [2, 4, 1, 3, 2, 4],
"C": [3, 3, 2, 6, 4, 2],
"X": [1, 2, 3, 4, 5, 6],
}
)

fig, ax = self.plt.subplots()
for kind in "ABC":
df.plot("X", kind, label=kind, ax=ax, style=".")

self._check_legend_labels(ax, labels=["A", "B", "C"])
self._check_legend_marker(ax, expected_markers=[".", ".", "."])

@pytest.mark.parametrize(
"index_name, old_label, new_label",
[
Expand Down
Loading