Skip to content

Commit

Permalink
MAINT: remove obsolete matplotlib version compatibility (#3577)
Browse files Browse the repository at this point in the history
* Remove code related to unsupported mpl versions

* Remove unused imports

* Remove unnecesarry code blocks

* Update matplotlib dependency version
  • Loading branch information
MaozGelbart authored Nov 30, 2023
1 parent 9a2196d commit 7e3da70
Show file tree
Hide file tree
Showing 10 changed files with 16 additions and 123 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ requires-python = ">=3.8"
dependencies = [
"numpy>=1.20,!=1.24.0",
"pandas>=1.2",
"matplotlib>=3.3,!=3.6.1",
"matplotlib>=3.4,!=3.6.1",
]

[project.optional-dependencies]
Expand Down
60 changes: 0 additions & 60 deletions seaborn/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,66 +67,6 @@ def __call__(self, value, clip=None):
return new_norm


def scale_factory(scale, axis, **kwargs):
"""
Backwards compatability for creation of independent scales.
Matplotlib scales require an Axis object for instantiation on < 3.4.
But the axis is not used, aside from extraction of the axis_name in LogScale.
"""
modify_transform = False
if _version_predates(mpl, "3.4"):
if axis[0] in "xy":
modify_transform = True
axis = axis[0]
base = kwargs.pop("base", None)
if base is not None:
kwargs[f"base{axis}"] = base
nonpos = kwargs.pop("nonpositive", None)
if nonpos is not None:
kwargs[f"nonpos{axis}"] = nonpos

if isinstance(scale, str):
class Axis:
axis_name = axis
axis = Axis()

scale = mpl.scale.scale_factory(scale, axis, **kwargs)

if modify_transform:
transform = scale.get_transform()
transform.base = kwargs.get("base", 10)
if kwargs.get("nonpositive") == "mask":
# Setting a private attribute, but we only get here
# on an old matplotlib, so this won't break going forwards
transform._clip = False

return scale


def set_scale_obj(ax, axis, scale):
"""Handle backwards compatability with setting matplotlib scale."""
if _version_predates(mpl, "3.4"):
# The ability to pass a BaseScale instance to Axes.set_{}scale was added
# to matplotlib in version 3.4.0: GH: matplotlib/matplotlib/pull/19089
# Workaround: use the scale name, which is restrictive only if the user
# wants to define a custom scale; they'll need to update the registry too.
if scale.name is None:
# Hack to support our custom Formatter-less CatScale
return
method = getattr(ax, f"set_{axis}scale")
kws = {}
if scale.name == "function":
trans = scale.get_transform()
kws["functions"] = (trans._forward, trans._inverse)
method(scale.name, **kws)
axis_obj = getattr(ax, f"{axis}axis")
scale.set_default_locators_and_formatters(axis_obj)
else:
ax.set(**{f"{axis}scale": scale})


def get_colormap(name):
"""Handle changes to matplotlib colormap interface in 3.6."""
try:
Expand Down
36 changes: 9 additions & 27 deletions seaborn/_core/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from seaborn._stats.base import Stat
from seaborn._core.data import PlotData
from seaborn._core.moves import Move
from seaborn._core.scales import Scale, Nominal
from seaborn._core.scales import Scale
from seaborn._core.subplots import Subplots
from seaborn._core.groupby import GroupBy
from seaborn._core.properties import PROPERTIES, Property
Expand All @@ -40,10 +40,9 @@
)
from seaborn._core.exceptions import PlotSpecError
from seaborn._core.rules import categorical_order
from seaborn._compat import set_scale_obj, set_layout_engine
from seaborn._compat import set_layout_engine
from seaborn.rcmod import axes_style, plotting_context
from seaborn.palettes import color_palette
from seaborn.utils import _version_predates

from typing import TYPE_CHECKING, TypedDict
if TYPE_CHECKING:
Expand Down Expand Up @@ -462,16 +461,12 @@ def on(self, target: Axes | SubFigure | Figure) -> Plot:
"""
accepted_types: tuple # Allow tuple of various length
if hasattr(mpl.figure, "SubFigure"): # Added in mpl 3.4
accepted_types = (
mpl.axes.Axes, mpl.figure.SubFigure, mpl.figure.Figure
)
accepted_types_str = (
f"{mpl.axes.Axes}, {mpl.figure.SubFigure}, or {mpl.figure.Figure}"
)
else:
accepted_types = mpl.axes.Axes, mpl.figure.Figure
accepted_types_str = f"{mpl.axes.Axes} or {mpl.figure.Figure}"
accepted_types = (
mpl.axes.Axes, mpl.figure.SubFigure, mpl.figure.Figure
)
accepted_types_str = (
f"{mpl.axes.Axes}, {mpl.figure.SubFigure}, or {mpl.figure.Figure}"
)

if not isinstance(target, accepted_types):
err = (
Expand Down Expand Up @@ -1369,19 +1364,6 @@ def _setup_scales(
share_state = self._subplots.subplot_spec[f"share{axis}"]
subplots = [view for view in self._subplots if view[axis] == coord]

# Shared categorical axes are broken on matplotlib<3.4.0.
# https://github.com/matplotlib/matplotlib/pull/18308
# This only affects us when sharing *paired* axes. This is a novel/niche
# behavior, so we will raise rather than hack together a workaround.
if axis is not None and _version_predates(mpl, "3.4"):
paired_axis = axis in p._pair_spec.get("structure", {})
cat_scale = isinstance(scale, Nominal)
ok_dim = {"x": "col", "y": "row"}[axis]
shared_axes = share_state not in [False, "none", ok_dim]
if paired_axis and cat_scale and shared_axes:
err = "Sharing paired categorical axes requires matplotlib>=3.4.0"
raise RuntimeError(err)

if scale is None:
self._scales[var] = Scale._identity()
else:
Expand All @@ -1407,7 +1389,7 @@ def _setup_scales(
axis_obj = getattr(view["ax"], f"{axis}axis")
seed_values = self._get_subplot_data(var_df, var, view, share_state)
view_scale = scale._setup(seed_values, prop, axis=axis_obj)
set_scale_obj(view["ax"], axis, view_scale._matplotlib_scale)
view["ax"].set(**{f"{axis}scale": view_scale._matplotlib_scale})

for layer, new_series in zip(layers, transformed_data):
layer_df = layer["data"].frame
Expand Down
2 changes: 0 additions & 2 deletions seaborn/_core/scales.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,6 @@ def _setup(
# major_formatter = new._get_formatter(major_locator, **new._label_params)

class CatScale(mpl.scale.LinearScale):
name = None # To work around mpl<3.4 compat issues

def set_default_locators_and_formatters(self, axis):
...
# axis.set_major_locator(major_locator)
Expand Down
10 changes: 2 additions & 8 deletions seaborn/_core/subplots.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,8 @@ def init_figure(
err = " ".join([
"Cannot create multiple subplots after calling `Plot.on` with",
f"a {mpl.axes.Axes} object.",
f" You may want to use a {mpl.figure.SubFigure} instead.",
])
try:
err += f" You may want to use a {mpl.figure.SubFigure} instead."
except AttributeError: # SubFigure added in mpl 3.4
pass
raise RuntimeError(err)

self._subplot_list = [{
Expand All @@ -179,10 +176,7 @@ def init_figure(
self._figure = target.figure
return self._figure

elif (
hasattr(mpl.figure, "SubFigure") # Added in mpl 3.4
and isinstance(target, mpl.figure.SubFigure)
):
elif isinstance(target, mpl.figure.SubFigure):
figure = target.figure
elif isinstance(target, mpl.figure.Figure):
figure = target
Expand Down
8 changes: 2 additions & 6 deletions seaborn/_marks/bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
resolve_color,
document_properties
)
from seaborn.utils import _version_predates

from typing import TYPE_CHECKING
if TYPE_CHECKING:
Expand Down Expand Up @@ -170,11 +169,8 @@ def _plot(self, split_gen, scales, orient):
ax.add_patch(bar)

# Add a container which is useful for, e.g. Axes.bar_label
if _version_predates(mpl, "3.4"):
container_kws = {}
else:
orientation = {"x": "vertical", "y": "horizontal"}[orient]
container_kws = dict(datavalues=vals, orientation=orientation)
orientation = {"x": "vertical", "y": "horizontal"}[orient]
container_kws = dict(datavalues=vals, orientation=orientation)
container = mpl.container.BarContainer(bars, **container_kws)
ax.add_container(container)

Expand Down
8 changes: 0 additions & 8 deletions tests/_core/test_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,10 +579,6 @@ def test_pair_categories(self):
assert_vector_equal(m.passed_data[0]["x"], pd.Series([0., 1.], [0, 1]))
assert_vector_equal(m.passed_data[1]["x"], pd.Series([0., 1.], [0, 1]))

@pytest.mark.xfail(
_version_predates(mpl, "3.4.0"),
reason="Sharing paired categorical axes requires matplotlib>3.4.0"
)
def test_pair_categories_shared(self):

data = [("a", "a"), ("b", "c")]
Expand Down Expand Up @@ -1115,10 +1111,6 @@ def test_on_figure(self, facet):
assert m.passed_axes == f.axes
assert p._figure is f

@pytest.mark.skipif(
_version_predates(mpl, "3.4"),
reason="mpl<3.4 does not have SubFigure",
)
@pytest.mark.parametrize("facet", [True, False])
def test_on_subfigure(self, facet):

Expand Down
6 changes: 2 additions & 4 deletions tests/_core/test_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import pytest
from numpy.testing import assert_array_equal

from seaborn.utils import _version_predates
from seaborn._core.rules import categorical_order
from seaborn._core.scales import Nominal, Continuous, Boolean
from seaborn._core.properties import (
Expand Down Expand Up @@ -250,9 +249,8 @@ def test_standardization(self):
assert f("#123456") == to_rgb("#123456")
assert f("#12345678") == to_rgba("#12345678")

if not _version_predates(mpl, "3.4.0"):
assert f("#123") == to_rgb("#123")
assert f("#1234") == to_rgba("#1234")
assert f("#123") == to_rgb("#123")
assert f("#1234") == to_rgba("#1234")


class ObjectPropertyBase(DataFixtures):
Expand Down
4 changes: 0 additions & 4 deletions tests/_core/test_scales.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,10 +571,6 @@ def test_empty_data(self):
s = Nominal()._setup(x, Coordinate())
assert_array_equal(s(x), [])

@pytest.mark.skipif(
_version_predates(mpl, "3.4.0"),
reason="Test failing on older matplotlib for unclear reasons",
)
def test_finalize(self, x):

ax = mpl.figure.Figure().subplots()
Expand Down
3 changes: 0 additions & 3 deletions tests/test_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
_no_statsmodels = True

from seaborn import regression as lm
from seaborn.utils import _version_predates
from seaborn.palettes import color_palette

rs = np.random.RandomState(0)
Expand Down Expand Up @@ -611,8 +610,6 @@ def test_lmplot_scatter_kws(self):
npt.assert_array_equal(red, red_scatter.get_facecolors()[0, :3])
npt.assert_array_equal(blue, blue_scatter.get_facecolors()[0, :3])

@pytest.mark.skipif(_version_predates(mpl, "3.4"),
reason="MPL bug #15967")
@pytest.mark.parametrize("sharex", [True, False])
def test_lmplot_facet_truncate(self, sharex):

Expand Down

0 comments on commit 7e3da70

Please sign in to comment.