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 6 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 (: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
45 changes: 45 additions & 0 deletions pandas/tests/plotting/frame/test_frame_legend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import pytest

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you move other legend tests here? (if we have them)

import pandas.util._test_decorators as td

from pandas import DataFrame

pytestmark = pytest.mark.slow


@td.skip_if_no_mpl
@pytest.mark.xfail(
reason=(
"Open bug in matplotlib "
"https://github.com/matplotlib/matplotlib/issues/11357"
)
)
def test_mixed_yerr():
# https://github.com/pandas-dev/pandas/issues/39522
from matplotlib.collections import LineCollection
from matplotlib.lines import Line2D

df = DataFrame([{"x": 1, "a": 1, "b": 1}, {"x": 2, "a": 2, "b": 3}])

ax = df.plot("x", "a", c="orange", yerr=0.1, label="orange")
df.plot("x", "b", c="blue", yerr=None, ax=ax, label="blue")

legend = ax.get_legend()
result_handles = legend.legendHandles

assert isinstance(result_handles[0], LineCollection)
assert isinstance(result_handles[1], Line2D)


@td.skip_if_no_mpl
def test_legend_false():
# https://github.com/pandas-dev/pandas/issues/40044
df = DataFrame({"a": [1, 1], "b": [2, 3]})
df2 = DataFrame({"d": [2.5, 2.5]})

ax = df.plot(legend=True, color={"a": "blue", "b": "green"}, secondary_y="b")
df2.plot(legend=True, color={"d": "red"}, ax=ax)
legend = ax.get_legend()
result = [handle.get_color() for handle in legend.legendHandles]
expected = ["blue", "green", "red"]
assert result == expected