From ca487996e37165648432f2e9f76094021fe0f752 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 11 Jan 2023 15:35:18 -0500 Subject: [PATCH 1/6] Remove remaining deprecations from 3.5 --- .../api_changes_3.5.0/deprecations.rst | 2 +- .../api_changes_3.5.0/removals.rst | 2 +- doc/api/testing_api.rst | 5 -- lib/matplotlib/__init__.py | 52 ----------- lib/matplotlib/axes/_axes.py | 14 --- lib/matplotlib/axes/_base.py | 88 +++---------------- lib/matplotlib/backend_bases.py | 15 +--- lib/matplotlib/category.py | 6 -- lib/matplotlib/legend_handler.py | 26 +----- lib/matplotlib/pyplot.py | 11 --- lib/matplotlib/rcsetup.py | 7 +- lib/matplotlib/scale.py | 5 -- lib/matplotlib/testing/conftest.py | 40 +-------- lib/matplotlib/tests/test_axes.py | 71 ++------------- lib/matplotlib/units.py | 19 +--- lib/mpl_toolkits/axes_grid1/axes_divider.py | 36 ++------ lib/mpl_toolkits/axes_grid1/axes_grid.py | 1 - 17 files changed, 39 insertions(+), 361 deletions(-) diff --git a/doc/api/prev_api_changes/api_changes_3.5.0/deprecations.rst b/doc/api/prev_api_changes/api_changes_3.5.0/deprecations.rst index 7ce5132bc7fa..7bb9009fbe77 100644 --- a/doc/api/prev_api_changes/api_changes_3.5.0/deprecations.rst +++ b/doc/api/prev_api_changes/api_changes_3.5.0/deprecations.rst @@ -162,7 +162,7 @@ implement a ``convert`` method that not only accepted instances of the unit, but also unitless values (which are passed through as is). This is no longer the case (``convert`` is never called with a unitless value), and such support in `.StrCategoryConverter` is deprecated. Likewise, the -`.ConversionInterface.is_numlike` helper is deprecated. +``.ConversionInterface.is_numlike`` helper is deprecated. Consider calling `.Axis.convert_units` instead, which still supports unitless values. diff --git a/doc/api/prev_api_changes/api_changes_3.5.0/removals.rst b/doc/api/prev_api_changes/api_changes_3.5.0/removals.rst index ce9ddef5ba5f..45b574e04cf5 100644 --- a/doc/api/prev_api_changes/api_changes_3.5.0/removals.rst +++ b/doc/api/prev_api_changes/api_changes_3.5.0/removals.rst @@ -282,7 +282,7 @@ Arguments - The *dummy* parameter of `.RendererPgf` has been removed. - The *props* parameter of `.Shadow` has been removed; use keyword arguments instead. -- The *recursionlimit* parameter of `matplotlib.test` has been removed. +- The *recursionlimit* parameter of ``matplotlib.test`` has been removed. - The *label* parameter of `.Tick` has no effect and has been removed. - `~.ticker.MaxNLocator` no longer accepts a positional parameter and the keyword argument *nbins* simultaneously because they specify the same diff --git a/doc/api/testing_api.rst b/doc/api/testing_api.rst index 808d2b870109..7731d4510b27 100644 --- a/doc/api/testing_api.rst +++ b/doc/api/testing_api.rst @@ -3,11 +3,6 @@ ********************** -:func:`matplotlib.test` -======================= - -.. autofunction:: matplotlib.test - :mod:`matplotlib.testing` ========================= diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 4289eb1702eb..d4e335bb108e 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -1302,58 +1302,6 @@ def _init_tests(): "" if ft2font.__freetype_build_type__ == 'local' else "not ")) -@_api.deprecated("3.5", alternative='pytest') -def test(verbosity=None, coverage=False, **kwargs): - """Run the matplotlib test suite.""" - - try: - import pytest - except ImportError: - print("matplotlib.test requires pytest to run.") - return -1 - - if not os.path.isdir(os.path.join(os.path.dirname(__file__), 'tests')): - print("Matplotlib test data is not installed") - return -1 - - old_backend = get_backend() - try: - use('agg') - - args = kwargs.pop('argv', []) - provide_default_modules = True - use_pyargs = True - for arg in args: - if any(arg.startswith(module_path) - for module_path in default_test_modules): - provide_default_modules = False - break - if os.path.exists(arg): - provide_default_modules = False - use_pyargs = False - break - if use_pyargs: - args += ['--pyargs'] - if provide_default_modules: - args += default_test_modules - - if coverage: - args += ['--cov'] - - if verbosity: - args += ['-' + 'v' * verbosity] - - retcode = pytest.main(args, **kwargs) - finally: - if old_backend.lower() != 'agg': - use(old_backend) - - return retcode - - -test.__test__ = False # pytest: this function is not a test - - def _replacer(data, value): """ Either returns ``data[value]`` or passes ``data`` back, converts either to diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index a6fecd374fba..a3ec2914a777 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -5792,18 +5792,6 @@ def _interp_grid(X): C = cbook.safe_masked_invalid(C) return X, Y, C, shading - def _pcolor_grid_deprecation_helper(self): - grid_active = any(axis._major_tick_kw["gridOn"] - for axis in self._axis_map.values()) - # explicit is-True check because get_axisbelow() can also be 'line' - grid_hidden_by_pcolor = self.get_axisbelow() is True - if grid_active and not grid_hidden_by_pcolor: - _api.warn_deprecated( - "3.5", message="Auto-removal of grids by pcolor() and " - "pcolormesh() is deprecated since %(since)s and will be " - "removed %(removal)s; please call grid(False) first.") - self.grid(False) - @_preprocess_data() @_docstring.dedent_interpd def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None, @@ -6008,7 +5996,6 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None, collection = mcoll.PolyCollection( verts, array=C, cmap=cmap, norm=norm, alpha=alpha, **kwargs) collection._scale_norm(norm, vmin, vmax) - self._pcolor_grid_deprecation_helper() x = X.compressed() y = Y.compressed() @@ -6242,7 +6229,6 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None, coords, antialiased=antialiased, shading=shading, array=C, cmap=cmap, norm=norm, alpha=alpha, **kwargs) collection._scale_norm(norm, vmin, vmax) - self._pcolor_grid_deprecation_helper() coords = coords.reshape(-1, 2) # flatten the grid structure; keep x, y diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 53f5607f41d1..0f12b6c6c4c1 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -1,4 +1,4 @@ -from collections.abc import Iterable, MutableSequence +from collections.abc import Iterable, Sequence from contextlib import ExitStack import functools import inspect @@ -1403,7 +1403,7 @@ def cla(self): else: self.clear() - class ArtistList(MutableSequence): + class ArtistList(Sequence): """ A sublist of Axes children based on their type. @@ -1414,7 +1414,7 @@ class ArtistList(MutableSequence): This class exists only for the transition period to warn on the deprecated modification of artist lists. """ - def __init__(self, axes, prop_name, add_name, + def __init__(self, axes, prop_name, valid_types=None, invalid_types=None): """ Parameters @@ -1425,9 +1425,6 @@ def __init__(self, axes, prop_name, add_name, prop_name : str The property name used to access this sublist from the Axes; used to generate deprecation warnings. - add_name : str - The method name used to add Artists of this sublist's type to - the Axes; used to generate deprecation warnings. valid_types : list of type, optional A list of types that determine which children will be returned by this sublist. If specified, then the Artists in the sublist @@ -1442,7 +1439,6 @@ def __init__(self, axes, prop_name, add_name, """ self._axes = axes self._prop_name = prop_name - self._add_name = add_name self._type_check = lambda artist: ( (not valid_types or isinstance(artist, valid_types)) and (not invalid_types or not isinstance(artist, invalid_types)) @@ -1468,103 +1464,47 @@ def __getitem__(self, key): def __add__(self, other): if isinstance(other, (list, _AxesBase.ArtistList)): return [*self, *other] + if isinstance(other, (tuple, _AxesBase.ArtistList)): + return (*self, *other) return NotImplemented def __radd__(self, other): if isinstance(other, list): return other + list(self) + if isinstance(other, tuple): + return other + tuple(self) return NotImplemented - def insert(self, index, item): - _api.warn_deprecated( - '3.5', - name=f'modification of the Axes.{self._prop_name}', - obj_type='property', - alternative=f'Axes.{self._add_name}') - try: - index = self._axes._children.index(self[index]) - except IndexError: - index = None - getattr(self._axes, self._add_name)(item) - if index is not None: - # Move new item to the specified index, if there's something to - # put it before. - self._axes._children[index:index] = self._axes._children[-1:] - del self._axes._children[-1] - - def __setitem__(self, key, item): - _api.warn_deprecated( - '3.5', - name=f'modification of the Axes.{self._prop_name}', - obj_type='property', - alternative=f'Artist.remove() and Axes.f{self._add_name}') - del self[key] - if isinstance(key, slice): - key = key.start - if not np.iterable(item): - self.insert(key, item) - return - - try: - index = self._axes._children.index(self[key]) - except IndexError: - index = None - for i, artist in enumerate(item): - getattr(self._axes, self._add_name)(artist) - if index is not None: - # Move new items to the specified index, if there's something - # to put it before. - i = -(i + 1) - self._axes._children[index:index] = self._axes._children[i:] - del self._axes._children[i:] - - def __delitem__(self, key): - _api.warn_deprecated( - '3.5', - name=f'modification of the Axes.{self._prop_name}', - obj_type='property', - alternative='Artist.remove()') - if isinstance(key, slice): - for artist in self[key]: - artist.remove() - else: - self[key].remove() - @property def artists(self): - return self.ArtistList(self, 'artists', 'add_artist', invalid_types=( + return self.ArtistList(self, 'artists', invalid_types=( mcoll.Collection, mimage.AxesImage, mlines.Line2D, mpatches.Patch, mtable.Table, mtext.Text)) @property def collections(self): - return self.ArtistList(self, 'collections', 'add_collection', + return self.ArtistList(self, 'collections', valid_types=mcoll.Collection) @property def images(self): - return self.ArtistList(self, 'images', 'add_image', - valid_types=mimage.AxesImage) + return self.ArtistList(self, 'images', valid_types=mimage.AxesImage) @property def lines(self): - return self.ArtistList(self, 'lines', 'add_line', - valid_types=mlines.Line2D) + return self.ArtistList(self, 'lines', valid_types=mlines.Line2D) @property def patches(self): - return self.ArtistList(self, 'patches', 'add_patch', - valid_types=mpatches.Patch) + return self.ArtistList(self, 'patches', valid_types=mpatches.Patch) @property def tables(self): - return self.ArtistList(self, 'tables', 'add_table', - valid_types=mtable.Table) + return self.ArtistList(self, 'tables', valid_types=mtable.Table) @property def texts(self): - return self.ArtistList(self, 'texts', 'add_artist', - valid_types=mtext.Text) + return self.ArtistList(self, 'texts', valid_types=mtext.Text) def get_facecolor(self): """Get the facecolor of the Axes.""" diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 16ce51cd600e..c573c369e9e3 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -1969,7 +1969,7 @@ def leave_notify_event(self, guiEvent=None): @_api.deprecated("3.6", alternative=( "callbacks.process('enter_notify_event', LocationEvent(...))")) - def enter_notify_event(self, guiEvent=None, xy=None): + def enter_notify_event(self, guiEvent=None, *, xy): """ Callback processing for the mouse cursor entering the canvas. @@ -1983,18 +1983,7 @@ def enter_notify_event(self, guiEvent=None, xy=None): xy : (float, float) The coordinate location of the pointer when the canvas is entered. """ - if xy is not None: - x, y = xy - self._lastx, self._lasty = x, y - else: - x = None - y = None - _api.warn_deprecated( - '3.0', removal='3.5', name='enter_notify_event', - message='Since %(since)s, %(name)s expects a location but ' - 'your backend did not pass one. This will become an error ' - '%(removal)s.') - + self._lastx, self._lasty = x, y = xy event = LocationEvent('figure_enter_event', self, x, y, guiEvent) self.callbacks.process('figure_enter_event', event) diff --git a/lib/matplotlib/category.py b/lib/matplotlib/category.py index 280a9802f2fb..e3c386f9d576 100644 --- a/lib/matplotlib/category.py +++ b/lib/matplotlib/category.py @@ -58,12 +58,6 @@ def convert(value, unit, axis): is_numlike = all(units.ConversionInterface.is_numlike(v) and not isinstance(v, (str, bytes)) for v in values) - if values.size and is_numlike: - _api.warn_deprecated( - "3.5", message="Support for passing numbers through unit " - "converters is deprecated since %(since)s and support will be " - "removed %(removal)s; use Axis.convert_units instead.") - return np.asarray(values, dtype=float) # force an update so it also does type checking unit.update(values) return np.vectorize(unit._mapping.__getitem__, otypes=[float])(values) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index cc39cd39cd6d..849644145856 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -27,7 +27,6 @@ def legend_artist(self, legend, orig_handle, fontsize, handlebox) """ -from collections.abc import Sequence from itertools import cycle import numpy as np @@ -132,9 +131,6 @@ def legend_artist(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, handlebox.get_transform()) - if isinstance(artists, _Line2DHandleList): - artists = [artists[0]] - # create_artists will return a list of artists. for a in artists: handlebox.add_artist(a) @@ -277,24 +273,6 @@ def create_artists(self, legend, orig_handle, return [legline, legline_marker] -class _Line2DHandleList(Sequence): - def __init__(self, legline): - self._legline = legline - - def __len__(self): - return 2 - - def __getitem__(self, index): - if index != 0: - # Make HandlerLine2D return [self._legline] directly after - # deprecation elapses. - _api.warn_deprecated( - "3.5", message="Access to the second element returned by " - "HandlerLine2D is deprecated since %(since)s; it will be " - "removed %(removal)s.") - return [self._legline, self._legline][index] - - class HandlerLine2D(HandlerNpoints): """ Handler for `.Line2D` instances. @@ -331,7 +309,7 @@ def create_artists(self, legend, orig_handle, legline.set_transform(trans) - return _Line2DHandleList(legline) + return [legline] class HandlerPatch(HandlerBase): @@ -790,8 +768,6 @@ def create_artists(self, legend, orig_handle, _a_list = handler.create_artists( legend, handle1, next(xds_cycle), ydescent, width, height, fontsize, trans) - if isinstance(_a_list, _Line2DHandleList): - _a_list = [_a_list[0]] a_list.extend(_a_list) return a_list diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index acd187d5d1c9..04b9bdb79ab2 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -1070,17 +1070,6 @@ def axes(arg=None, **kwargs): %(Axes:kwdoc)s - Notes - ----- - If the figure already has an Axes with key (*args*, - *kwargs*) then it will simply make that axes current and - return it. This behavior is deprecated. Meanwhile, if you do - not want this behavior (i.e., you want to force the creation of a - new axes), you must use a unique set of args and kwargs. The Axes - *label* attribute has been exposed for this purpose: if you want - two Axes that are otherwise identical to be added to the figure, - make sure you give them unique labels. - See Also -------- .Figure.add_axes diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index 7d0425196d78..22b11f44e8b5 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -182,10 +182,7 @@ def validator(s): (s is None or isinstance(s, str) and s.lower() == "none")): return None if cls is str and not isinstance(s, str): - _api.warn_deprecated( - "3.5", message="Support for setting an rcParam that expects a " - "str value to a non-str value is deprecated since %(since)s " - "and support will be removed %(removal)s.") + raise ValueError(f'Could not convert {s!r} to str') try: return cls(s) except (TypeError, ValueError) as e: @@ -218,7 +215,7 @@ def _validate_pathlike(s): # between "" (cwd) and "." (cwd, but gets updated by user selections). return os.fsdecode(s) else: - return validate_string(s) # Emit deprecation warning. + return validate_string(s) def validate_fonttype(s): diff --git a/lib/matplotlib/scale.py b/lib/matplotlib/scale.py index 534165cc72e5..01e09f11b444 100644 --- a/lib/matplotlib/scale.py +++ b/lib/matplotlib/scale.py @@ -710,11 +710,6 @@ def scale_factory(scale, axis, **kwargs): scale : {%(names)s} axis : `matplotlib.axis.Axis` """ - if scale != scale.lower(): - _api.warn_deprecated( - "3.5", message="Support for case-insensitive scales is deprecated " - "since %(since)s and support will be removed %(removal)s.") - scale = scale.lower() scale_cls = _api.check_getitem(_scale_mapping, scale=scale) return scale_cls(axis, **kwargs) diff --git a/lib/matplotlib/testing/conftest.py b/lib/matplotlib/testing/conftest.py index 21f6c707ecf8..41ed522b72d9 100644 --- a/lib/matplotlib/testing/conftest.py +++ b/lib/matplotlib/testing/conftest.py @@ -1,7 +1,7 @@ import pytest import sys import matplotlib -from matplotlib import _api, cbook +from matplotlib import _api def pytest_configure(config): @@ -13,8 +13,6 @@ def pytest_configure(config): ("markers", "flaky: (Provided by pytest-rerunfailures.)"), ("markers", "timeout: (Provided by pytest-timeout.)"), ("markers", "backend: Set alternate Matplotlib backend temporarily."), - ("markers", - "style: Set alternate Matplotlib style temporarily (deprecated)."), ("markers", "baseline_images: Compare output against references."), ("markers", "pytz: Tests that require pytz to be installed."), ("filterwarnings", "error"), @@ -56,16 +54,6 @@ def mpl_test_settings(request): if any(sys.modules.get(k) for k in ('PyQt4', 'PySide')): pytest.skip('Qt4 binding already imported') - # Default of cleanup and image_comparison too. - style = ["classic", "_classic_test_patch"] - style_marker = request.node.get_closest_marker('style') - if style_marker is not None: - assert len(style_marker.args) == 1, \ - "Marker 'style' must specify 1 style." - _api.warn_deprecated("3.5", name="style", obj_type="pytest marker", - alternative="@mpl.style.context(...)") - style, = style_marker.args - matplotlib.testing.setup() with _api.suppress_matplotlib_deprecation_warning(): if backend is not None: @@ -82,36 +70,14 @@ def mpl_test_settings(request): .format(backend, exc)) else: raise - matplotlib.style.use(style) + # Default of cleanup and image_comparison too. + matplotlib.style.use(["classic", "_classic_test_patch"]) try: yield finally: matplotlib.use(prev_backend) -@pytest.fixture -@_api.deprecated("3.5", alternative="none") -def mpl_image_comparison_parameters(request, extension): - # This fixture is applied automatically by the image_comparison decorator. - # - # The sole purpose of this fixture is to provide an indirect method of - # obtaining parameters *without* modifying the decorated function - # signature. In this way, the function signature can stay the same and - # pytest won't get confused. - # We annotate the decorated function with any parameters captured by this - # fixture so that they can be used by the wrapper in image_comparison. - baseline_images, = request.node.get_closest_marker('baseline_images').args - if baseline_images is None: - # Allow baseline image list to be produced on the fly based on current - # parametrization. - baseline_images = request.getfixturevalue('baseline_images') - - func = request.function - with cbook._setattr_cm(func.__wrapped__, - parameters=(baseline_images, extension)): - yield - - @pytest.fixture def pd(): """Fixture to import and configure pandas.""" diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 642316e4c000..bcbee036ce2b 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -8115,19 +8115,13 @@ def test_artist_sublists(): with pytest.raises(IndexError, match='out of range'): ax.lines[len(lines) + 1] - # Deleting items (multiple or single) should warn. - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.lines property'): - del ax.lines[-1] - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.lines property'): - del ax.lines[-1:] - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.lines property'): - del ax.lines[1:] - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.lines property'): - del ax.lines[0] + # Adding to other lists should produce a regular list. + assert ax.lines + [1, 2, 3] == [*lines, 1, 2, 3] + assert [1, 2, 3] + ax.lines == [1, 2, 3, *lines] + + # Adding to other tuples should produce a regular tuples. + assert ax.lines + (1, 2, 3) == (*lines, 1, 2, 3) + assert (1, 2, 3) + ax.lines == (1, 2, 3, *lines) # Lists should be empty after removing items. col.remove() @@ -8136,59 +8130,10 @@ def test_artist_sublists(): assert not ax.images patch.remove() assert not ax.patches + assert not ax.tables text.remove() assert not ax.texts - # Everything else should remain empty. - assert not ax.lines - assert not ax.tables - - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.texts property'): - ax.texts.append(text) - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.collections property'): - ax.collections.append(col) - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.images property'): - ax.images.append(im) - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.patches property'): - ax.patches.append(patch) - # verify things are back - assert list(ax.collections) == [col] - assert list(ax.images) == [im] - assert list(ax.patches) == [patch] - assert list(ax.texts) == [text] - - # Adding items should warn. - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.lines property'): - ax.lines.append(lines[-2]) - assert list(ax.lines) == [lines[-2]] - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.lines property'): - ax.lines.append(lines[-1]) - assert list(ax.lines) == lines[-2:] - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.lines property'): - ax.lines.insert(-2, lines[0]) - assert list(ax.lines) == [lines[0], lines[-2], lines[-1]] - - # Modifying items should warn. - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.lines property'): - ax.lines[0] = lines[0] - assert list(ax.lines) == [lines[0], lines[-2], lines[-1]] - with pytest.warns(MatplotlibDeprecationWarning, - match='modification of the Axes.lines property'): - ax.lines[1:1] = lines[1:-2] - assert list(ax.lines) == lines - - # Adding to other lists should produce a regular list. - assert ax.lines + [1, 2, 3] == [*lines, 1, 2, 3] - assert [1, 2, 3] + ax.lines == [1, 2, 3, *lines] - for ln in ax.lines: ln.remove() assert len(ax.lines) == 0 diff --git a/lib/matplotlib/units.py b/lib/matplotlib/units.py index 2bcfcaf2eb12..e3480f228bb4 100644 --- a/lib/matplotlib/units.py +++ b/lib/matplotlib/units.py @@ -46,7 +46,7 @@ def default_units(x, axis): import numpy as np from numpy import ma -from matplotlib import _api, cbook +from matplotlib import cbook class ConversionError(TypeError): @@ -131,23 +131,6 @@ def convert(obj, unit, axis): """ return obj - @staticmethod - @_api.deprecated("3.5") - def is_numlike(x): - """ - The Matplotlib datalim, autoscaling, locators etc work with scalars - which are the units converted to floats given the current unit. The - converter may be passed these floats, or arrays of them, even when - units are set. - """ - if np.iterable(x): - for thisx in x: - if thisx is ma.masked: - continue - return isinstance(thisx, Number) - else: - return isinstance(x, Number) - class DecimalConverter(ConversionInterface): """Converter for decimal.Decimal data to float.""" diff --git a/lib/mpl_toolkits/axes_grid1/axes_divider.py b/lib/mpl_toolkits/axes_grid1/axes_divider.py index 143a2f35cb19..2a6bd0d5da08 100644 --- a/lib/mpl_toolkits/axes_grid1/axes_divider.py +++ b/lib/mpl_toolkits/axes_grid1/axes_divider.py @@ -202,17 +202,9 @@ def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None): x0, y0 = x, y if nx1 is None: - _api.warn_deprecated( - "3.5", message="Support for passing nx1=None to mean nx+1 is " - "deprecated since %(since)s; in a future version, nx1=None " - "will mean 'up to the last cell'.") - nx1 = nx + 1 + nx1 = -1 if ny1 is None: - _api.warn_deprecated( - "3.5", message="Support for passing ny1=None to mean ny+1 is " - "deprecated since %(since)s; in a future version, ny1=None " - "will mean 'up to the last cell'.") - ny1 = ny + 1 + ny1 = -1 x1, w1 = x0 + ox[nx] / fig_w, (ox[nx1] - ox[nx]) / fig_w y1, h1 = y0 + oy[ny] / fig_h, (oy[ny1] - oy[ny]) / fig_h @@ -299,17 +291,9 @@ def __init__(self, axes_divider, nx, ny, nx1=None, ny1=None): self._nx, self._ny = nx - _xrefindex, ny - _yrefindex if nx1 is None: - _api.warn_deprecated( - "3.5", message="Support for passing nx1=None to mean nx+1 is " - "deprecated since %(since)s; in a future version, nx1=None " - "will mean 'up to the last cell'.") - nx1 = nx + 1 + nx1 = len(self._axes_divider) if ny1 is None: - _api.warn_deprecated( - "3.5", message="Support for passing ny1=None to mean ny+1 is " - "deprecated since %(since)s; in a future version, ny1=None " - "will mean 'up to the last cell'.") - ny1 = ny + 1 + ny1 = len(self._axes_divider[0]) self._nx1 = nx1 - _xrefindex self._ny1 = ny1 - _yrefindex @@ -600,11 +584,7 @@ def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None): x0, y0, ox, hh = _locate( x, y, w, h, summed_ws, equal_hs, fig_w, fig_h, self.get_anchor()) if nx1 is None: - _api.warn_deprecated( - "3.5", message="Support for passing nx1=None to mean nx+1 is " - "deprecated since %(since)s; in a future version, nx1=None " - "will mean 'up to the last cell'.") - nx1 = nx + 1 + nx1 = -1 x1, w1 = x0 + ox[nx] / fig_w, (ox[nx1] - ox[nx]) / fig_w y1, h1 = y0, hh return mtransforms.Bbox.from_bounds(x1, y1, w1, h1) @@ -639,11 +619,7 @@ def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None): y0, x0, oy, ww = _locate( y, x, h, w, summed_hs, equal_ws, fig_h, fig_w, self.get_anchor()) if ny1 is None: - _api.warn_deprecated( - "3.5", message="Support for passing ny1=None to mean ny+1 is " - "deprecated since %(since)s; in a future version, ny1=None " - "will mean 'up to the last cell'.") - ny1 = ny + 1 + ny1 = -1 x1, w1 = x0, ww y1, h1 = y0 + oy[ny] / fig_h, (oy[ny1] - oy[ny]) / fig_h return mtransforms.Bbox.from_bounds(x1, y1, w1, h1) diff --git a/lib/mpl_toolkits/axes_grid1/axes_grid.py b/lib/mpl_toolkits/axes_grid1/axes_grid.py index 51925bfde5e3..1d6d6265e86f 100644 --- a/lib/mpl_toolkits/axes_grid1/axes_grid.py +++ b/lib/mpl_toolkits/axes_grid1/axes_grid.py @@ -20,7 +20,6 @@ def _tick_only(ax, bottom_on, left_on): class CbarAxesBase: def __init__(self, *args, orientation, **kwargs): self.orientation = orientation - self._locator = None # deprecated. super().__init__(*args, **kwargs) def colorbar(self, mappable, *, ticks=None, **kwargs): From 8482fc291deda7d707999a9810db89900f44a59b Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 11 Jan 2023 15:50:36 -0500 Subject: [PATCH 2/6] MNT: remove check that exists only for removed deprecation --- lib/matplotlib/category.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/matplotlib/category.py b/lib/matplotlib/category.py index e3c386f9d576..4ac2379ea5f5 100644 --- a/lib/matplotlib/category.py +++ b/lib/matplotlib/category.py @@ -53,11 +53,6 @@ def convert(value, unit, axis): StrCategoryConverter._validate_unit(unit) # dtype = object preserves numerical pass throughs values = np.atleast_1d(np.array(value, dtype=object)) - # pass through sequence of non binary numbers - with _api.suppress_matplotlib_deprecation_warning(): - is_numlike = all(units.ConversionInterface.is_numlike(v) - and not isinstance(v, (str, bytes)) - for v in values) # force an update so it also does type checking unit.update(values) return np.vectorize(unit._mapping.__getitem__, otypes=[float])(values) From 90dfdbc3350fd4f3f7bffc1ab05610a1403a791b Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 11 Jan 2023 15:51:18 -0500 Subject: [PATCH 3/6] TST: remove tests of (now expired) deprecation warnings --- lib/matplotlib/tests/test_category.py | 12 ------------ lib/matplotlib/tests/test_rcparams.py | 2 -- 2 files changed, 14 deletions(-) diff --git a/lib/matplotlib/tests/test_category.py b/lib/matplotlib/tests/test_category.py index 6eb590d6e82d..87dece6346f7 100644 --- a/lib/matplotlib/tests/test_category.py +++ b/lib/matplotlib/tests/test_category.py @@ -3,7 +3,6 @@ import numpy as np import matplotlib as mpl -from matplotlib._api import MatplotlibDeprecationWarning from matplotlib.axes import Axes import matplotlib.pyplot as plt import matplotlib.category as cat @@ -101,17 +100,6 @@ def test_convert(self, vals): def test_convert_one_string(self, value): assert self.cc.convert(value, self.unit, self.ax) == 0 - def test_convert_one_number(self): - with pytest.warns(MatplotlibDeprecationWarning): - actual = self.cc.convert(0.0, self.unit, self.ax) - np.testing.assert_allclose(actual, np.array([0.])) - - def test_convert_float_array(self): - data = np.array([1, 2, 3], dtype=float) - with pytest.warns(MatplotlibDeprecationWarning): - actual = self.cc.convert(data, self.unit, self.ax) - np.testing.assert_allclose(actual, np.array([1., 2., 3.])) - @pytest.mark.parametrize("fvals", fvalues, ids=fids) def test_convert_fail(self, fvals): with pytest.raises(TypeError): diff --git a/lib/matplotlib/tests/test_rcparams.py b/lib/matplotlib/tests/test_rcparams.py index 8a7c1028574b..c17e88aee1ac 100644 --- a/lib/matplotlib/tests/test_rcparams.py +++ b/lib/matplotlib/tests/test_rcparams.py @@ -230,8 +230,6 @@ def generate_validator_testcases(valid): ), 'fail': ((set(), ValueError), (1, ValueError), - ((1, 2), _api.MatplotlibDeprecationWarning), - (np.array([1, 2]), _api.MatplotlibDeprecationWarning), ) }, {'validator': _listify_validator(validate_int, n=2), From dfbaaa88fbb7ebc6e6e61d86171cd32b005056e5 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 11 Jan 2023 15:58:21 -0500 Subject: [PATCH 4/6] MNT: remove orphaned module attribute --- lib/matplotlib/__init__.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index d4e335bb108e..b279c465163e 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -1278,12 +1278,6 @@ def is_interactive(): return rcParams['interactive'] -default_test_modules = [ - 'matplotlib.tests', - 'mpl_toolkits.tests', -] - - def _init_tests(): # The version of FreeType to install locally for running the # tests. This must match the value in `setupext.py` From 6f9c155a531571c8529868d51577041f1fdb3933 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 11 Jan 2023 16:57:12 -0500 Subject: [PATCH 5/6] DOC: tweak wording on ArtistList class docstring --- lib/matplotlib/axes/_base.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 0f12b6c6c4c1..0bf5b71860a0 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -1407,12 +1407,9 @@ class ArtistList(Sequence): """ A sublist of Axes children based on their type. - The type-specific children sublists will become immutable in - Matplotlib 3.7. Then, these artist lists will likely be replaced by - tuples. Use as if this is a tuple already. - - This class exists only for the transition period to warn on the - deprecated modification of artist lists. + The type-specific children sublists were made immutable in Matplotlib + 3.7. In the future these artist lists may be replaced by tuples. Use + as if this is a tuple already. """ def __init__(self, axes, prop_name, valid_types=None, invalid_types=None): From a5d95fe78ced54c728296b13626077ff1d3b8fd2 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 11 Jan 2023 17:02:35 -0500 Subject: [PATCH 6/6] DOC: add notes for removals --- .../next_api_changes/removals/24948-ES.rst | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 doc/api/next_api_changes/removals/24948-ES.rst diff --git a/doc/api/next_api_changes/removals/24948-ES.rst b/doc/api/next_api_changes/removals/24948-ES.rst new file mode 100644 index 000000000000..23ca84dd3202 --- /dev/null +++ b/doc/api/next_api_changes/removals/24948-ES.rst @@ -0,0 +1,104 @@ + +Testing support +~~~~~~~~~~~~~~~ + +``matplotlib.test()`` has been removed +...................................... + +Run tests using ``pytest`` from the commandline instead. The variable +``matplotlib.default_test_modules`` was only used for ``matplotlib.test()`` and +is thus removed as well. + +To test an installed copy, be sure to specify both ``matplotlib`` and +``mpl_toolkits`` with ``--pyargs``:: + + python -m pytest --pyargs matplotlib.tests mpl_toolkits.tests + +See :ref:`testing` for more details. + + + +Auto-removal of grids by `~.Axes.pcolor` and `~.Axes.pcolormesh` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`~.Axes.pcolor` and `~.Axes.pcolormesh` previously remove any visible axes +major grid. This behavior is removed; please explicitly call ``ax.grid(False)`` +to remove the grid. + + + +Modification of ``Axes`` children sublists +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +See :ref:`Behavioural API Changes 3.5 - Axes children combined` for more +information; modification of the following sublists is no longer supported: + +* ``Axes.artists`` +* ``Axes.collections`` +* ``Axes.images`` +* ``Axes.lines`` +* ``Axes.patches`` +* ``Axes.tables`` +* ``Axes.texts`` + +To remove an Artist, use its `.Artist.remove` method. To add an Artist, use the +corresponding ``Axes.add_*`` method. + + + +``ConversionInterface.convert`` no longer accepts unitless values +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Previously, custom subclasses of `.units.ConversionInterface` needed to +implement a ``convert`` method that not only accepted instances of the unit, +but also unitless values (which are passed through as is). This is no longer +the case (``convert`` is never called with a unitless value), and such support +in ``.StrCategoryConverter`` is removed. Likewise, the +``.ConversionInterface.is_numlike`` helper is removed. + +Consider calling `.Axis.convert_units` instead, which still supports unitless +values. + + +Normal list of `.Artist` objects now returned by `.HandlerLine2D.create_artists` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For Matplotlib 3.5 and 3.6 a proxy list was returned that simulated the return +of `.HandlerLine2DCompound.create_artists`. Now a list containing only the +single artist is return. + + +rcParams will no longer cast inputs to str +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +rcParams that expect a (non-pathlike) str no longer cast non-str inputs using +`str`. This will avoid confusing errors in subsequent code if e.g. a list input +gets implicitly cast to a str. + + + +Case-insensitive scales +~~~~~~~~~~~~~~~~~~~~~~~ + +Previously, scales could be set case-insensitively (e.g., +``set_xscale("LoG")``). Now all builtin scales use lowercase names. + + + +Support for ``nx1 = None`` or ``ny1 = None`` in ``AxesLocator`` and ``Divider.locate`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In `.axes_grid1.axes_divider`, various internal APIs no longer supports +passing ``nx1 = None`` or ``ny1 = None`` to mean ``nx + 1`` or ``ny + 1``, in +preparation for a possible future API which allows indexing and slicing of +dividers (possibly ``divider[a:b] == divider.new_locator(a, b)``, but also +``divider[a:] == divider.new_locator(a, )``). The user-facing +`.Divider.new_locator` API is unaffected -- it correctly normalizes ``nx1 = +None`` and ``ny1 = None`` as needed. + + +change signature of ``.FigureCanvasBase.enter_notify_event`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The *xy* parameter is now required and keyword only. This was deprecated in +3.0 and originally slated to be removed in 3.5. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy