Skip to content

Commit

Permalink
Backport PR #48601 on branch 1.5.x (CI: Fix matplolib release issues) (
Browse files Browse the repository at this point in the history
…#48617)

Backport PR #48601: CI: Fix matplolib release issues

Co-authored-by: Patrick Hoefler <[email protected]>
  • Loading branch information
meeseeksmachine and phofl authored Sep 18, 2022
1 parent aabf659 commit 4fbb055
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 42 deletions.
1 change: 1 addition & 0 deletions doc/source/user_guide/visualization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ To plot multiple column groups in a single axes, repeat ``plot`` method specifyi
It is recommended to specify ``color`` and ``label`` keywords to distinguish each groups.

.. ipython:: python
:okwarning:
ax = df.plot.scatter(x="a", y="b", color="DarkBlue", label="Group 1")
@savefig scatter_plot_repeated.png
Expand Down
2 changes: 1 addition & 1 deletion pandas/plotting/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,7 @@ def __call__(self, *args, **kwargs):
>>> s = pd.Series([1, 3, 2])
>>> s.plot.line()
<AxesSubplot:ylabel='Density'>
<AxesSubplot: ylabel='Density'>
.. plot::
:context: close-figs
Expand Down
1 change: 1 addition & 0 deletions pandas/plotting/_matplotlib/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ def inner():

mpl_ge_3_4_0 = _mpl_version("3.4.0", operator.ge)
mpl_ge_3_5_0 = _mpl_version("3.5.0", operator.ge)
mpl_ge_3_6_0 = _mpl_version("3.6.0", operator.ge)
21 changes: 17 additions & 4 deletions pandas/plotting/_matplotlib/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
)
import warnings

import matplotlib as mpl
from matplotlib.artist import Artist
import numpy as np

Expand Down Expand Up @@ -54,6 +55,7 @@
from pandas.core.frame import DataFrame

from pandas.io.formats.printing import pprint_thing
from pandas.plotting._matplotlib.compat import mpl_ge_3_6_0
from pandas.plotting._matplotlib.converter import register_pandas_matplotlib_converters
from pandas.plotting._matplotlib.groupby import reconstruct_data_with_by
from pandas.plotting._matplotlib.misc import unpack_single_str_list
Expand Down Expand Up @@ -1205,9 +1207,6 @@ def _make_plot(self):

color_by_categorical = c_is_column and is_categorical_dtype(self.data[c])

# pandas uses colormap, matplotlib uses cmap.
cmap = self.colormap or "Greys"
cmap = self.plt.cm.get_cmap(cmap)
color = self.kwds.pop("color", None)
if c is not None and color is not None:
raise TypeError("Specify exactly one of `c` and `color`")
Expand All @@ -1222,6 +1221,17 @@ def _make_plot(self):
else:
c_values = c

# cmap is only used if c_values are integers, otherwise UserWarning
if is_integer_dtype(c_values):
# pandas uses colormap, matplotlib uses cmap.
cmap = self.colormap or "Greys"
if mpl_ge_3_6_0():
cmap = mpl.colormaps[cmap]
else:
cmap = self.plt.cm.get_cmap(cmap)
else:
cmap = None

if color_by_categorical:
from matplotlib import colors

Expand Down Expand Up @@ -1286,7 +1296,10 @@ def _make_plot(self):
ax = self.axes[0]
# pandas uses colormap, matplotlib uses cmap.
cmap = self.colormap or "BuGn"
cmap = self.plt.cm.get_cmap(cmap)
if mpl_ge_3_6_0():
cmap = mpl.colormaps[cmap]
else:
cmap = self.plt.cm.get_cmap(cmap)
cb = self.kwds.pop("colorbar", True)

if C is None:
Expand Down
8 changes: 7 additions & 1 deletion pandas/plotting/_matplotlib/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
)
import warnings

import matplotlib as mpl
import matplotlib.cm as cm
import matplotlib.colors
import numpy as np
Expand All @@ -22,6 +23,8 @@

import pandas.core.common as com

from pandas.plotting._matplotlib.compat import mpl_ge_3_6_0

if TYPE_CHECKING:
from matplotlib.colors import Colormap

Expand Down Expand Up @@ -155,7 +158,10 @@ def _get_cmap_instance(colormap: str | Colormap) -> Colormap:
"""Get instance of matplotlib colormap."""
if isinstance(colormap, str):
cmap = colormap
colormap = cm.get_cmap(colormap)
if mpl_ge_3_6_0():
colormap = mpl.colormaps[colormap]
else:
colormap = cm.get_cmap(colormap)
if colormap is None:
raise ValueError(f"Colormap {cmap} is not recognized")
return colormap
Expand Down
44 changes: 22 additions & 22 deletions pandas/plotting/_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,22 +139,22 @@ def scatter_matrix(
>>> df = pd.DataFrame(np.random.randn(1000, 4), columns=['A','B','C','D'])
>>> pd.plotting.scatter_matrix(df, alpha=0.2)
array([[<AxesSubplot:xlabel='A', ylabel='A'>,
<AxesSubplot:xlabel='B', ylabel='A'>,
<AxesSubplot:xlabel='C', ylabel='A'>,
<AxesSubplot:xlabel='D', ylabel='A'>],
[<AxesSubplot:xlabel='A', ylabel='B'>,
<AxesSubplot:xlabel='B', ylabel='B'>,
<AxesSubplot:xlabel='C', ylabel='B'>,
<AxesSubplot:xlabel='D', ylabel='B'>],
[<AxesSubplot:xlabel='A', ylabel='C'>,
<AxesSubplot:xlabel='B', ylabel='C'>,
<AxesSubplot:xlabel='C', ylabel='C'>,
<AxesSubplot:xlabel='D', ylabel='C'>],
[<AxesSubplot:xlabel='A', ylabel='D'>,
<AxesSubplot:xlabel='B', ylabel='D'>,
<AxesSubplot:xlabel='C', ylabel='D'>,
<AxesSubplot:xlabel='D', ylabel='D'>]], dtype=object)
array([[<AxesSubplot: xlabel='A', ylabel='A'>,
<AxesSubplot: xlabel='B', ylabel='A'>,
<AxesSubplot: xlabel='C', ylabel='A'>,
<AxesSubplot: xlabel='D', ylabel='A'>],
[<AxesSubplot: xlabel='A', ylabel='B'>,
<AxesSubplot: xlabel='B', ylabel='B'>,
<AxesSubplot: xlabel='C', ylabel='B'>,
<AxesSubplot: xlabel='D', ylabel='B'>],
[<AxesSubplot: xlabel='A', ylabel='C'>,
<AxesSubplot: xlabel='B', ylabel='C'>,
<AxesSubplot: xlabel='C', ylabel='C'>,
<AxesSubplot: xlabel='D', ylabel='C'>],
[<AxesSubplot: xlabel='A', ylabel='D'>,
<AxesSubplot: xlabel='B', ylabel='D'>,
<AxesSubplot: xlabel='C', ylabel='D'>,
<AxesSubplot: xlabel='D', ylabel='D'>]], dtype=object)
"""
plot_backend = _get_plot_backend("matplotlib")
return plot_backend.scatter_matrix(
Expand Down Expand Up @@ -247,7 +247,7 @@ def radviz(
... }
... )
>>> pd.plotting.radviz(df, 'Category')
<AxesSubplot:xlabel='y(t)', ylabel='y(t + 1)'>
<AxesSubplot: xlabel='y(t)', ylabel='y(t + 1)'>
"""
plot_backend = _get_plot_backend("matplotlib")
return plot_backend.radviz(
Expand Down Expand Up @@ -311,7 +311,7 @@ def andrews_curves(
... 'pandas/main/pandas/tests/io/data/csv/iris.csv'
... )
>>> pd.plotting.andrews_curves(df, 'Name')
<AxesSubplot:title={'center':'width'}>
<AxesSubplot: title={'center': 'width'}>
"""
plot_backend = _get_plot_backend("matplotlib")
return plot_backend.andrews_curves(
Expand Down Expand Up @@ -445,7 +445,7 @@ def parallel_coordinates(
>>> pd.plotting.parallel_coordinates(
... df, 'Name', color=('#556270', '#4ECDC4', '#C7F464')
... )
<AxesSubplot:xlabel='y(t)', ylabel='y(t + 1)'>
<AxesSubplot: xlabel='y(t)', ylabel='y(t + 1)'>
"""
plot_backend = _get_plot_backend("matplotlib")
return plot_backend.parallel_coordinates(
Expand Down Expand Up @@ -494,15 +494,15 @@ def lag_plot(series: Series, lag: int = 1, ax: Axes | None = None, **kwds) -> Ax
>>> x = np.cumsum(np.random.normal(loc=1, scale=5, size=50))
>>> s = pd.Series(x)
>>> s.plot()
<AxesSubplot:xlabel='Midrange'>
<AxesSubplot: xlabel='Midrange'>
A lag plot with ``lag=1`` returns
.. plot::
:context: close-figs
>>> pd.plotting.lag_plot(s, lag=1)
<AxesSubplot:xlabel='y(t)', ylabel='y(t + 1)'>
<AxesSubplot: xlabel='y(t)', ylabel='y(t + 1)'>
"""
plot_backend = _get_plot_backend("matplotlib")
return plot_backend.lag_plot(series=series, lag=lag, ax=ax, **kwds)
Expand Down Expand Up @@ -536,7 +536,7 @@ def autocorrelation_plot(series: Series, ax: Axes | None = None, **kwargs) -> Ax
>>> spacing = np.linspace(-9 * np.pi, 9 * np.pi, num=1000)
>>> s = pd.Series(0.7 * np.random.rand(1000) + 0.3 * np.sin(spacing))
>>> pd.plotting.autocorrelation_plot(s)
<AxesSubplot:title={'center':'width'}, xlabel='Lag', ylabel='Autocorrelation'>
<AxesSubplot: title={'center': 'width'}, xlabel='Lag', ylabel='Autocorrelation'>
"""
plot_backend = _get_plot_backend("matplotlib")
return plot_backend.autocorrelation_plot(series=series, ax=ax, **kwargs)
Expand Down
26 changes: 18 additions & 8 deletions pandas/tests/plotting/frame/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,15 @@
from pandas.io.formats.printing import pprint_thing
import pandas.plotting as plotting

try:
from pandas.plotting._matplotlib.compat import mpl_ge_3_6_0
except ImportError:
mpl_ge_3_6_0 = lambda: True


@td.skip_if_no_mpl
class TestDataFramePlots(TestPlotBase):
@pytest.mark.xfail(mpl_ge_3_6_0(), reason="Api changed")
@pytest.mark.slow
def test_plot(self):
df = tm.makeTimeDataFrame()
Expand Down Expand Up @@ -733,7 +739,7 @@ def test_plot_scatter_with_c(self):
from pandas.plotting._matplotlib.compat import mpl_ge_3_4_0

df = DataFrame(
np.random.randn(6, 4),
np.random.randint(low=0, high=100, size=(6, 4)),
index=list(string.ascii_letters[:6]),
columns=["x", "y", "z", "four"],
)
Expand Down Expand Up @@ -1533,17 +1539,17 @@ def test_errorbar_plot_iterator(self):

def test_errorbar_with_integer_column_names(self):
# test with integer column names
df = DataFrame(np.random.randn(10, 2))
df_err = DataFrame(np.random.randn(10, 2))
df = DataFrame(np.abs(np.random.randn(10, 2)))
df_err = DataFrame(np.abs(np.random.randn(10, 2)))
ax = _check_plot_works(df.plot, yerr=df_err)
self._check_has_errorbars(ax, xerr=0, yerr=2)
ax = _check_plot_works(df.plot, y=0, yerr=1)
self._check_has_errorbars(ax, xerr=0, yerr=1)

@pytest.mark.slow
def test_errorbar_with_partial_columns(self):
df = DataFrame(np.random.randn(10, 3))
df_err = DataFrame(np.random.randn(10, 2), columns=[0, 2])
df = DataFrame(np.abs(np.random.randn(10, 3)))
df_err = DataFrame(np.abs(np.random.randn(10, 2)), columns=[0, 2])
kinds = ["line", "bar"]
for kind in kinds:
ax = _check_plot_works(df.plot, yerr=df_err, kind=kind)
Expand Down Expand Up @@ -1631,9 +1637,11 @@ def test_table(self):
assert len(ax.tables) == 1

def test_errorbar_scatter(self):
df = DataFrame(np.random.randn(5, 2), index=range(5), columns=["x", "y"])
df = DataFrame(
np.abs(np.random.randn(5, 2)), index=range(5), columns=["x", "y"]
)
df_err = DataFrame(
np.random.randn(5, 2) / 5, index=range(5), columns=["x", "y"]
np.abs(np.random.randn(5, 2)) / 5, index=range(5), columns=["x", "y"]
)

ax = _check_plot_works(df.plot.scatter, x="x", y="y")
Expand All @@ -1660,7 +1668,9 @@ def _check_errorbar_color(containers, expected, has_err="has_xerr"):
)

# GH 8081
df = DataFrame(np.random.randn(10, 5), columns=["a", "b", "c", "d", "e"])
df = DataFrame(
np.abs(np.random.randn(10, 5)), columns=["a", "b", "c", "d", "e"]
)
ax = df.plot.scatter(x="a", y="b", xerr="d", yerr="e", c="red")
self._check_has_errorbars(ax, xerr=1, yerr=1)
_check_errorbar_color(ax.containers, "red", has_err="has_xerr")
Expand Down
4 changes: 2 additions & 2 deletions pandas/tests/plotting/frame/test_frame_color.py
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,6 @@ def test_colors_of_columns_with_same_name(self):

def test_invalid_colormap(self):
df = DataFrame(np.random.randn(3, 2), columns=["A", "B"])
msg = "'invalid_colormap' is not a valid value for name; supported values are "
with pytest.raises(ValueError, match=msg):
msg = "(is not a valid value)|(is not a known colormap)"
with pytest.raises((ValueError, KeyError), match=msg):
df.plot(colormap="invalid_colormap")
7 changes: 7 additions & 0 deletions pandas/tests/plotting/test_datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
from pandas.core.indexes.timedeltas import timedelta_range
from pandas.tests.plotting.common import TestPlotBase

try:
from pandas.plotting._matplotlib.compat import mpl_ge_3_6_0
except ImportError:
mpl_ge_3_6_0 = lambda: True

from pandas.tseries.offsets import WeekOfMonth


Expand Down Expand Up @@ -260,6 +265,7 @@ def test_plot_multiple_inferred_freq(self):
ser = Series(np.random.randn(len(dr)), index=dr)
_check_plot_works(ser.plot)

@pytest.mark.xfail(mpl_ge_3_6_0(), reason="Api changed")
def test_uhf(self):
import pandas.plotting._matplotlib.converter as conv

Expand Down Expand Up @@ -1209,6 +1215,7 @@ def test_secondary_legend(self):
# TODO: color cycle problems
assert len(colors) == 4

@pytest.mark.xfail(mpl_ge_3_6_0(), reason="Api changed")
def test_format_date_axis(self):
rng = date_range("1/1/2012", periods=12, freq="M")
df = DataFrame(np.random.randn(len(rng), 3), rng)
Expand Down
6 changes: 6 additions & 0 deletions pandas/tests/plotting/test_hist_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
_check_plot_works,
)

try:
from pandas.plotting._matplotlib.compat import mpl_ge_3_6_0
except ImportError:
mpl_ge_3_6_0 = lambda: True


@pytest.fixture
def ts():
Expand Down Expand Up @@ -191,6 +196,7 @@ def test_hist_kwargs(self, ts):
ax = ts.plot.hist(align="left", stacked=True, ax=ax)
tm.close()

@pytest.mark.xfail(mpl_ge_3_6_0(), reason="Api changed")
@td.skip_if_no_scipy
def test_hist_kde(self, ts):

Expand Down
16 changes: 12 additions & 4 deletions pandas/tests/plotting/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@

import pandas.plotting as plotting

try:
from pandas.plotting._matplotlib.compat import mpl_ge_3_6_0
except ImportError:
mpl_ge_3_6_0 = lambda: True


@pytest.fixture
def ts():
Expand Down Expand Up @@ -493,6 +498,7 @@ def test_kde_missing_vals(self):
# gh-14821: check if the values have any missing values
assert any(~np.isnan(axes.lines[0].get_xdata()))

@pytest.mark.xfail(mpl_ge_3_6_0(), reason="Api changed")
def test_boxplot_series(self, ts):
_, ax = self.plt.subplots()
ax = ts.plot.box(logy=True, ax=ax)
Expand Down Expand Up @@ -575,8 +581,10 @@ def test_errorbar_asymmetrical(self):
def test_errorbar_plot(self):

s = Series(np.arange(10), name="x")
s_err = np.random.randn(10)
d_err = DataFrame(np.random.randn(10, 2), index=s.index, columns=["x", "y"])
s_err = np.abs(np.random.randn(10))
d_err = DataFrame(
np.abs(np.random.randn(10, 2)), index=s.index, columns=["x", "y"]
)
# test line and bar plots
kinds = ["line", "bar"]
for kind in kinds:
Expand All @@ -597,8 +605,8 @@ def test_errorbar_plot(self):
# test time series plotting
ix = date_range("1/1/2000", "1/1/2001", freq="M")
ts = Series(np.arange(12), index=ix, name="x")
ts_err = Series(np.random.randn(12), index=ix)
td_err = DataFrame(np.random.randn(12, 2), index=ix, columns=["x", "y"])
ts_err = Series(np.abs(np.random.randn(12)), index=ix)
td_err = DataFrame(np.abs(np.random.randn(12, 2)), index=ix, columns=["x", "y"])

ax = _check_plot_works(ts.plot, yerr=ts_err)
self._check_has_errorbars(ax, xerr=0, yerr=1)
Expand Down

0 comments on commit 4fbb055

Please sign in to comment.