Skip to content

Remove remaining 3.8 deprecations #28874

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 4 commits into from
Oct 8, 2024
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
180 changes: 180 additions & 0 deletions doc/api/next_api_changes/removals/28874-ES.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
Passing extra positional arguments to ``Figure.add_axes``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Positional arguments passed to `.Figure.add_axes` other than a rect or an existing
``Axes`` were previously ignored, and is now an error.


Artists explicitly passed in will no longer be filtered by legend() based on their label
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previously, artists explicitly passed to ``legend(handles=[...])`` are filtered out if
their label starts with an underscore. This filter is no longer applied; explicitly
filter out such artists (``[art for art in artists if not
art.get_label().startswith('_')]``) if necessary.

Note that if no handles are specified at all, then the default still filters out labels
starting with an underscore.


The parameter of ``Annotation.contains`` and ``Legend.contains`` is renamed to *mouseevent*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

... consistently with `.Artist.contains`.


Support for passing the "frac" key in ``annotate(..., arrowprops={"frac": ...})``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

... has been removed. This key has had no effect since Matplotlib 1.5.


Passing non-int or sequence of non-int to ``Table.auto_set_column_width``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Column numbers are ints, and formerly passing any other type was effectively ignored.
This has now become an error.


Widgets
~~~~~~~

The *visible* attribute getter of ``*Selector`` widgets has been removed; use
``get_visible`` instead.


Auto-closing of figures when switching backend
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Allowable backend switches (i.e. those that do not swap a GUI event loop with another
one) will not close existing figures. If necessary, call ``plt.close("all")`` before
switching.


``FigureCanvasBase.switch_backends``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

... has been removed with no replacement.


Accessing ``event.guiEvent`` after event handlers return
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

... is no longer supported, and ``event.guiEvent`` will be set to None once the event
handlers return. For some GUI toolkits, it is unsafe to use the event, though you may
separately stash the object at your own risk.


``PdfPages(keep_empty=True)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A zero-page PDF is not valid, thus passing ``keep_empty=True`` to `.backend_pdf.PdfPages`
and `.backend_pgf.PdfPages`, and the ``keep_empty`` attribute of these classes, is no
longer allowed, and empty PDF files will not be created.

Furthermore, `.backend_pdf.PdfPages` no longer immediately creates the target file upon
instantiation, but only when the first figure is saved. To fully control file creation,
directly pass an opened file object as argument (``with open(path, "wb") as file,
PdfPages(file) as pdf: ...``).


``backend_ps.psDefs``
~~~~~~~~~~~~~~~~~~~~~

The ``psDefs`` module-level variable in ``backend_ps`` has been removed with no
replacement.


Automatic papersize selection in PostScript
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Setting :rc:`ps.papersize` to ``'auto'`` or passing ``papersize='auto'`` to
`.Figure.savefig` is no longer supported. Either pass an explicit paper type name, or
omit this parameter to use the default from the rcParam.


``RendererAgg.tostring_rgb`` and ``FigureCanvasAgg.tostring_rgb``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

... have been remove with no direct replacement. Consider using ``buffer_rgba`` instead,
which should cover most use cases.


``NavigationToolbar2QT.message`` has been removed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

... with no replacement.


``TexManager.texcache``
~~~~~~~~~~~~~~~~~~~~~~~

... is considered private and has been removed. The location of the cache directory is
clarified in the doc-string.


``cbook`` API changes
~~~~~~~~~~~~~~~~~~~~~

``cbook.Stack`` has been removed with no replacement.

``Grouper.clean()`` has been removed with no replacement. The Grouper class now cleans
itself up automatically.

The *np_load* parameter of ``cbook.get_sample_data`` has been removed; `.get_sample_data`
now auto-loads numpy arrays. Use ``get_sample_data(..., asfileobj=False)`` instead to get
the filename of the data file, which can then be passed to `open`, if desired.


Calling ``paths.get_path_collection_extents`` with empty *offsets*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Calling `~.get_path_collection_extents` with an empty *offsets* parameter has an
ambiguous interpretation and is no longer allowed.


``bbox.anchored()`` with no explicit container
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Not passing a *container* argument to `.BboxBase.anchored` is no longer supported.


``INVALID_NON_AFFINE``, ``INVALID_AFFINE``, ``INVALID`` attributes of ``TransformNode``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

These attributes have been removed.


``axes_grid1`` API changes
~~~~~~~~~~~~~~~~~~~~~~~~~~

``anchored_artists.AnchoredEllipse`` has been removed. Instead, directly construct an
`.AnchoredOffsetbox`, an `.AuxTransformBox`, and an `~.patches.Ellipse`, as demonstrated
in :doc:`/gallery/misc/anchored_artists`.

The ``axes_divider.AxesLocator`` class has been removed. The ``new_locator`` method of
divider instances now instead returns an opaque callable (which can still be passed to
``ax.set_axes_locator``).

``axes_divider.Divider.locate`` has been removed; use ``Divider.new_locator(...)(ax,
renderer)`` instead.

``axes_grid.CbarAxesBase.toggle_label`` has been removed. Instead, use standard methods
for manipulating colorbar labels (`.Colorbar.set_label`) and tick labels
(`.Axes.tick_params`).

``inset_location.InsetPosition`` has been removed; use `~.Axes.inset_axes` instead.


``axisartist`` API changes
~~~~~~~~~~~~~~~~~~~~~~~~~~

The ``axisartist.axes_grid`` and ``axisartist.axes_rgb`` modules, which provide wrappers
combining the functionality of `.axes_grid1` and `.axisartist`, have been removed;
directly use e.g. ``AxesGrid(..., axes_class=axislines.Axes)`` instead.

Calling an axisartist Axes to mean `~matplotlib.pyplot.axis` has been removed; explicitly
call the method instead.

``floating_axes.GridHelperCurveLinear.get_data_boundary`` has been removed. Use
``grid_finder.extreme_finder(*[None] * 5)`` to get the extremes of the grid.
2 changes: 1 addition & 1 deletion doc/api/prev_api_changes/api_changes_3.6.0/behaviour.rst
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ Specified exception types in ``Grid``

In a few cases an `Exception` was thrown when an incorrect argument value was
set in the `mpl_toolkits.axes_grid1.axes_grid.Grid` (=
`mpl_toolkits.axisartist.axes_grid.Grid`) constructor. These are replaced as
``mpl_toolkits.axisartist.axes_grid.Grid``) constructor. These are replaced as
follows:

* Providing an incorrect value for *ngrids* now raises a `ValueError`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Passing undefined *label_mode* to ``Grid``
... is deprecated. This includes `mpl_toolkits.axes_grid1.axes_grid.Grid`,
`mpl_toolkits.axes_grid1.axes_grid.AxesGrid`, and
`mpl_toolkits.axes_grid1.axes_grid.ImageGrid` as well as the corresponding
classes imported from `mpl_toolkits.axisartist.axes_grid`.
classes imported from ``mpl_toolkits.axisartist.axes_grid``.

Pass ``label_mode='keep'`` instead to get the previous behavior of not modifying labels.

Expand Down
2 changes: 1 addition & 1 deletion doc/api/prev_api_changes/api_changes_3.9.0/removals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Passing undefined *label_mode* to ``Grid``
... is no longer allowed. This includes `mpl_toolkits.axes_grid1.axes_grid.Grid`,
`mpl_toolkits.axes_grid1.axes_grid.AxesGrid`, and
`mpl_toolkits.axes_grid1.axes_grid.ImageGrid` as well as the corresponding classes
imported from `mpl_toolkits.axisartist.axes_grid`.
imported from ``mpl_toolkits.axisartist.axes_grid``.

Pass ``label_mode='keep'`` instead to get the previous behavior of not modifying labels.

Expand Down
2 changes: 0 additions & 2 deletions doc/api/toolkits/axisartist.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ You can find a tutorial describing usage of axisartist at the

axisartist.angle_helper
axisartist.axes_divider
axisartist.axes_grid
axisartist.axes_rgb
axisartist.axis_artist
axisartist.axisline_style
axisartist.axislines
Expand Down
38 changes: 2 additions & 36 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -1178,26 +1178,12 @@ class Event:
def __init__(self, name, canvas, guiEvent=None):
self.name = name
self.canvas = canvas
self._guiEvent = guiEvent
self._guiEvent_deleted = False
self.guiEvent = guiEvent

def _process(self):
"""Process this event on ``self.canvas``, then unset ``guiEvent``."""
self.canvas.callbacks.process(self.name, self)
self._guiEvent_deleted = True

@property
def guiEvent(self):
# After deprecation elapses: remove _guiEvent_deleted; make guiEvent a plain
# attribute set to None by _process.
if self._guiEvent_deleted:
_api.warn_deprecated(
"3.8", message="Accessing guiEvent outside of the original GUI event "
"handler is unsafe and deprecated since %(since)s; in the future, the "
"attribute will be set to None after quitting the event handler. You "
"may separately record the value of the guiEvent attribute at your own "
"risk.")
return self._guiEvent
self.guiEvent = None


class DrawEvent(Event):
Expand Down Expand Up @@ -2097,12 +2083,6 @@ def print_figure(
if dpi == 'figure':
dpi = getattr(self.figure, '_original_dpi', self.figure.dpi)

if kwargs.get("papertype") == 'auto':
# When deprecation elapses, remove backend_ps._get_papertype & its callers.
_api.warn_deprecated(
"3.8", name="papertype='auto'", addendum="Pass an explicit paper type, "
"'figure', or omit the *papertype* argument entirely.")

# Remove the figure manager, if any, to avoid resizing the GUI widget.
with (cbook._setattr_cm(self, manager=None),
self._switch_canvas_and_return_print_method(format, backend)
Expand Down Expand Up @@ -2207,20 +2187,6 @@ def get_default_filename(self):
default_filetype = self.get_default_filetype()
return f'{default_basename}.{default_filetype}'

@_api.deprecated("3.8")
def switch_backends(self, FigureCanvasClass):
"""
Instantiate an instance of FigureCanvasClass

This is used for backend switching, e.g., to instantiate a
FigureCanvasPS from a FigureCanvasGTK. Note, deep copying is
not done, so any changes to one of the instances (e.g., setting
figure size or line props), will be reflected in the other
"""
newCanvas = FigureCanvasClass(self.figure)
newCanvas._is_saving = self._is_saving
return newCanvas

def mpl_connect(self, s, func):
"""
Bind function *func* to event *s*.
Expand Down
5 changes: 1 addition & 4 deletions lib/matplotlib/backend_bases.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,11 @@ class TimerBase:
class Event:
name: str
canvas: FigureCanvasBase
guiEvent: Any
def __init__(
self, name: str, canvas: FigureCanvasBase, guiEvent: Any | None = ...
) -> None: ...

@property
def guiEvent(self) -> Any: ...

class DrawEvent(Event):
renderer: RendererBase
def __init__(
Expand Down Expand Up @@ -348,7 +346,6 @@ class FigureCanvasBase:
def get_default_filetype(cls) -> str: ...
def get_default_filename(self) -> str: ...
_T = TypeVar("_T", bound=FigureCanvasBase)
def switch_backends(self, FigureCanvasClass: type[_T]) -> _T: ...
def mpl_connect(self, s: str, func: Callable[[Event], Any]) -> int: ...
def mpl_disconnect(self, cid: int) -> None: ...
def new_timer(
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/backend_tools.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ class ToolXScale(AxisScaleBase):
def set_scale(self, ax, scale: str | ScaleBase) -> None: ...

class ToolViewsPositions(ToolBase):
views: dict[Figure | Axes, cbook.Stack]
positions: dict[Figure | Axes, cbook.Stack]
views: dict[Figure | Axes, cbook._Stack]
positions: dict[Figure | Axes, cbook._Stack]
Comment on lines +78 to +79
Copy link
Member Author

Choose a reason for hiding this comment

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

So this is a bit weird to have here in the public API when the cbook.Stack is going away. mypy doesn't like this since it's not in cbook.pyi. Is this really something that should be public?

Copy link
Member Author

@QuLogic QuLogic Sep 26, 2024

Choose a reason for hiding this comment

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

We discussed on the call today and decided to keep cbook._Stack in the type stubs to keep this working. If we want, then probably could also deprecate access to these attributes as they are probably internal.

home_views: dict[Figure, dict[Axes, tuple[float, float, float, float]]]
def add_figure(self, figure: Figure) -> None: ...
def clear(self, figure: Figure) -> None: ...
Expand Down
14 changes: 0 additions & 14 deletions lib/matplotlib/backends/backend_agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,6 @@ def buffer_rgba(self):
def tostring_argb(self):
return np.asarray(self._renderer).take([3, 0, 1, 2], axis=2).tobytes()

@_api.deprecated("3.8", alternative="buffer_rgba")
def tostring_rgb(self):
return np.asarray(self._renderer).take([0, 1, 2], axis=2).tobytes()

def clear(self):
self._renderer.clear()

Expand Down Expand Up @@ -398,16 +394,6 @@ def get_renderer(self):
self._lastKey = key
return self.renderer

@_api.deprecated("3.8", alternative="buffer_rgba")
def tostring_rgb(self):
"""
Get the image as RGB `bytes`.

`draw` must be called at least once before this function will work and
to update the renderer for any subsequent changes to the Figure.
"""
return self.renderer.tostring_rgb()

def tostring_argb(self):
"""
Get the image as ARGB `bytes`.
Expand Down
22 changes: 3 additions & 19 deletions lib/matplotlib/backends/backend_pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2663,9 +2663,9 @@ class PdfPages:
confusion when using `~.pyplot.savefig` and forgetting the format argument.
"""

_UNSET = object()

def __init__(self, filename, keep_empty=_UNSET, metadata=None):
@_api.delete_parameter("3.10", "keep_empty",
addendum="This parameter does nothing.")
def __init__(self, filename, keep_empty=None, metadata=None):
"""
Create a new PdfPages object.

Expand All @@ -2676,10 +2676,6 @@ def __init__(self, filename, keep_empty=_UNSET, metadata=None):
The file is opened when a figure is saved for the first time (overwriting
any older file with the same name).

keep_empty : bool, optional
If set to False, then empty pdf files will be deleted automatically
when closed.

metadata : dict, optional
Information dictionary object (see PDF reference section 10.2.1
'Document Information Dictionary'), e.g.:
Expand All @@ -2693,13 +2689,6 @@ def __init__(self, filename, keep_empty=_UNSET, metadata=None):
self._filename = filename
self._metadata = metadata
self._file = None
if keep_empty and keep_empty is not self._UNSET:
_api.warn_deprecated("3.8", message=(
"Keeping empty pdf files is deprecated since %(since)s and support "
"will be removed %(removal)s."))
self._keep_empty = keep_empty

keep_empty = _api.deprecate_privatize_attribute("3.8")

def __enter__(self):
return self
Expand All @@ -2721,11 +2710,6 @@ def close(self):
self._file.finalize()
self._file.close()
self._file = None
elif self._keep_empty: # True *or* UNSET.
_api.warn_deprecated("3.8", message=(
"Keeping empty pdf files is deprecated since %(since)s and support "
"will be removed %(removal)s."))
PdfFile(self._filename, metadata=self._metadata).close() # touch the file.

def infodict(self):
"""
Expand Down
Loading
Loading