API Changes for 3.11.0#
Behavior Changes#
pyplot.subplot and pyplot.subplot_mosaic raise ValueError on existing figures#
Passing a num argument to subplots or subplot_mosaic that refers
to an existing figure or is a Figure instance now raises a ValueError.
These utility functions are intended strictly for the creation of new figures and
subplots. Previously, they accidentally allowed the reuse of existing figures because
they internally called figure. This change ensures that these functions
strictly follow their documented purpose of creating new figures.
To reuse an existing figure, clear it first using clear=True:
fig, axs = plt.subplots(num=1, clear=True)
# or
fig, axd = plt.subplot_mosaic([['A', 'B']], num=1, clear=True)
If you have a Figure instance and want to add subplots to it, use the
object-oriented API:
fig.subplots(nrows=2, ncols=2)
# or
fig.subplot_mosaic([['A', 'B']])
Complex layouts and constrained layout#
Constrained layout now produces smaller spacing between subplots in some circumstances.
This should only affect complex layouts where rows or columns contain different numbers
of subplots, for example a layout created with plt.subplot_mosaic('AC;BC',
layout='constrained').
Bivariate colormaps now fully span the intended range of colors#
Bivariate colormaps generated by SegmentedBivarColormap (e.g., BiOrangeBlue)
from a set of input colors now fully span that range of colors. There had been a bug
with the numerical interpolation such that the colormap did not actually include the
first or last colors.
Rendering of images now more accurate#
There have been several fixes to improve the accuracy of how images are resampled and placed during rendering. Some inaccuracies were up to a pixel off in the output. The most apparent improvement is that the alignment of data pixels with tick marks and grid lines is now reliable. Nearly all image output has changed, but often only at a subtle level that is not obvious qualitatively.
alpha parameter handling on images#
Prior to Matplotlib 3.10.1, when passing an array to imshow(..., alpha=...), the
parameter was silently ignored if the image data was an RGB or RGBA image or if
rcParams["image.interpolation_stage"] (default: 'auto') resolved to "rbga".
Matplotlib 3.10.1 changed this to apply the alpha array as the alpha channel, overwriting any existing transparency information in the image data. Matplotlib 3.11.0 further fixes the handling for RGBA images: the existing alpha channel is now multiplied by the alpha array, consistent with how scalar alpha values are handled.
Legend labels for plot#
Previously if a sequence was passed to the label parameter of plot when
plotting a single dataset, the sequence was automatically cast to string for the legend
label. Now, if the sequence length is not one an error is raised. To keep the old
behavior, cast the sequence to string before passing.
Mixing positional and keyword arguments for legend handles and labels...#
... is no longer valid. If passing handles and labels to legend, they must now
be passed either both positionally or both as keyword arguments.
Axes.add_collection(..., autolim=True) updates view limits#
Axes.add_collection(..., autolim=True) has so far only updated the data limits, and
calling Axes.autoscale_view was also necessary to update the view limits. View limits
are now updated as well if autolim=True, using a lazy internal update mechanism, so
that the costs only apply once also if you add multiple collections.
relim() now accounts for Collection artists#
Previously, relim did not recalculate data limits for Collection
artists (e.g. those created by scatter). Calling ax.relim() followed
by ax.autoscale_view() now correctly includes scatter plots and other collections in
the axes limits.
hist2d no longer forces axes limits#
Previously, Axes.hist2d would force the axes x and y limits to the extents of the
histogrammed data, ignoring any other artists. Axes.hist2d now behaves similarly to
Axes.imshow: axes limits are updated to fit the data, but autoscaling is not
otherwise disabled.
Axes.violinplot and cbook.violin_stats ignore non-finite values#
violinplot and matplotlib.cbook.violin_stats now ignore masked
and non-finite (NaN and inf) values.
Minor log tick labels are set by number of major log ticks, not number of decades spanned#
Previously, by default, on a log-scaled axis, the minor ticks would be unlabeled if the
axis limits spanned more than one decade. The meaning of the minor_thresholds
parameter to LogFormatter has been altered so that the decision of whether to label
the minor ticks is now based on the number of major ticks drawn within the axis limits.
For example, for an axis spanning from 4 to 60 (with thus a single major log tick, at 10), minor ticks are now labeled, even though the axis spans more than one decade.
Setting titles of figures using webagg backend#
Previously when using the webagg backend the title of a figure was set using
figure.set_label. Now it is set using figure.canvas.manager.set_window_title
which is more consistent with other backends.
Default name of ListedColormap#
The default name of ListedColormap has changed from "from_list" to "unnamed".
font_manager.findfont logs if selected font weight does not match requested#
When searching for a font with a weight specified, if the best-matched font differs in weight, then a warning will be logged.
FT2Font no longer sets a default size#
In the interest of handling non-scalable fonts and reducing font initialization, the
FT2Font constructor no longer sets a default size. Non-scalable fonts are sometimes
used for bitmap-backed emoji fonts.
If metrics are important (i.e., if you are loading character glyphs, or setting a text
string), then explicitly call FT2Font.set_size beforehand.
mathtext.VectorParse now includes glyph indices#
For a path-outputting MathTextParser, in the return value of
parse, (a VectorParse), the glyphs field is now a list
containing tuples of:
Specifically, the glyph index was added after the character code.
SVG links open in new tab or window#
Artist.set_url allows to turn the Artist into a link. In SVG output, this has been
implemented without specifying a target attribute. The default target value "_self"
resulted in replacing the SVG document with the linked page when the link was clicked.
The target is now set to "_blank" so that the link opens in a new tab or window.
matplotlib.testing.check_figures_equal defaults to PNG only#
In most cases, checking that figures are equal with check_figures_equal does not
depend on the file format. Consequently, the extensions parameter now defaults to
['png'] instead of ['png', 'pdf', 'svg'], reducing default test requirements.
Default style parameter of image_comparison#
The style parameter of the image_comparison decorator will become 'mpl20' in
Matplotlib 3.13. Not passing it and relying on the previous default will warn until the
change occurs.
Windows configuration directory location#
On Windows, the default configuration and cache directories now use
%LOCALAPPDATA%\matplotlib instead of %USERPROFILE%\.matplotlib. This follows
Windows application data storage conventions.
The MPLCONFIGDIR environment variable can still be used to override this default.
Deprecations#
In-place modification of colormaps#
Colormaps are planned to become immutable in the long term.
As a first step, in-place modifications of colormaps are now pending-deprecated. This
affects the following methods of Colormap:
Colormap.set_bad- usecmap.with_extremes(bad=...)insteadColormap.set_under- usecmap.with_extremes(under=...)insteadColormap.set_over- usecmap.with_extremes(over=...)insteadColormap.set_extremes- usecmap.with_extremes(...)instead
Use the respective Colormap.with_extremes and appropriate keyword arguments instead
which returns a copy of the colormap (available since Matplotlib 3.4). Alternatively, if
you create the colormap yourself, you can also pass the respective arguments to the
constructor (available since Matplotlib 3.11).
Contour labelling on filled contours#
Using clabel to label filled contours created with contourf is
deprecated. clabel() is designed to label contour lines (Axes.contour), and using
it with filled contours can lead to inconsistent plots. If you want to add labels to
filled contours, the recommended approach is to first create the filled contours with
contourf, then overlay contour lines using contour, and finally apply
clabel to those contour lines for labeling. For an example see
Contourf demo.
boxplot and bxp vert parameter, and rcParams["boxplot.vertical"]#
The parameter vert: bool has been deprecated on boxplot and bxp. It
is replaced by orientation: {"vertical", "horizontal"} for API consistency.
rcParams["boxplot.vertical"], which controlled the orientation of boxplot, is
deprecated without replacement.
violinplot and violin vert parameter#
The parameter vert: bool has been deprecated on violinplot and
violin. It will be replaced by orientation: {"vertical", "horizontal"} for
API consistency.
Arbitrary code in axes.prop_cycle rcParam strings#
The axes.prop_cycle rcParam accepts Python expressions that are evaluated in a
limited context. The evaluation context has been further limited and some expressions
that previously worked (list comprehensions, for example) no longer will. This change is
made without a deprecation period to improve security. The previously documented cycler
operations at https://matplotlib.org/cycler/ are still supported.
Capitalization of None in matplotlibrc#
In matplotlibrc config files every capitalization of None was accepted for
denoting the Python constant None. This is now deprecated, and the only accepted
capitalization is None, i.e., starting with a capital letter and all other letters in
lowercase.
Third-party scales no longer need to have an axis parameter#
Since Matplotlib 3.1 PR 12831
scale objects should be reusable and therefore independent of any particular Axis.
Therefore, the use of the axis parameter in the __init__ had been discouraged.
However, having that parameter in the signature was still necessary for API
backwards-compatibility. This is no longer the case.
register_scale now accepts scale classes with or without this parameter.
The axis parameter is pending-deprecated. It will be deprecated in Matplotlib 3.13, and removed in Matplotlib 3.15.
Third-party scales are recommended to remove the axis parameter now if they can afford to restrict compatibility to Matplotlib >= 3.11 already. Otherwise, they may keep the axis parameter and remove it in time for Matplotlib 3.13.
matplotlib.style.core#
The matplotlib.style.core module is deprecated. All APIs intended for public use are
now available in matplotlib.style directly (including USER_LIBRARY_PATHS, which
was previously not reexported).
The following APIs of matplotlib.style.core have been deprecated with no
replacement: BASE_LIBRARY_PATH, STYLE_EXTENSION, STYLE_BLACKLIST,
update_user_library, read_style_directory, update_nested_dict.
Font hinting and kerning factors#
Due to internal changes to support complex text rendering, the hinting factor and
kerning factor on fonts are no longer used. Setting the text.hinting_factor or
text.kerning_factor rcParams (the latter of which existed only for
backwards-compatibility) to any value other than None is deprecated, and they will be
removed in the future.
Likewise, passing the hinting_factor argument to the FT2Font constructor is
deprecated.
FT2Image image buffer#
Use 2D uint8 ndarrays instead. In particular:
The
FT2Imageconstructor tookwidth, heightas separate parameters but the ndarray constructor takes(height, width)as single tuple parameter.FT2Font.draw_glyph_to_bitmapnow (also) takes 2D uint8 arrays as input.FT2Image.draw_rect_filledshould be replaced by directly setting pixel values to black.The
imageattribute of the object returned byMathTextParser("agg").parseis now a 2D uint8 array.
DviFont.widths#
... is deprecated with no replacement.
PdfFile internals#
The PdfFile.dviFontInfo, PdfFile.fontNames, PdfFile.multi_byte_charprocs,
and PdfFile.type1Descriptors attributes are deprecated with no replacement.
The fontfile parameter of PdfFile.createType1Descriptor is deprecated; all
relevant pieces of information are now directly extracted from the t1font argument.
Tfm's internal metrics#
Direct access to Tfm's widths, heights, depths dicts is deprecated;
access a glyph's metrics with Tfm.get_metrics instead.
font_manager.is_opentype_cff_font is deprecated#
There is no replacement.
BezierSegment.point_at_t#
... is deprecated. Instead, it is possible to call the BezierSegment with an argument.
Formatter attributes#
These following attributes are considered internal and users should not have a need to access them:
ScalarFormatter:orderOfMagnitudeandformatConciseDateFormatter:offset_formatFormatter:locs
Parameter ListedColormap(..., N=...)#
Passing the parameter N to ListedColormap is deprecated. Please preprocess the list
colors yourself if needed.
kw, fontproperties, labelcolor, and verts attributes of QuiverKey#
These attributes are deprecated (note that modifying fontproperties, labelcolor,
or verts after the first draw had no effect previously). Directly access the
relevant attributes on the sub-artists QuiverKey.vector and QuiverKey.text,
instead.
apply_theta_transforms option in PolarTransform#
Applying theta transforms in PolarTransform and
InvertedPolarTransform has been removed, and the
apply_theta_transforms keyword argument is deprecated for both classes.
If you need to retain the behaviour where theta values are transformed, chain the
PolarTransform with a Affine2D transform that performs the
theta shift and/or sign shift.
axes parameter of RadialLocator#
... is deprecated. RadialLocator now fetches the relevant information from the
Axis' parent Axes.
Transform helper functions#
The following functions in the transforms module are deprecated, because they are
considerer internal functionality and should not be used by end users:
matplotlib.transforms.nonsingularmatplotlib.transforms.interval_containsmatplotlib.transforms.interval_contains_open
InvertedSymmetricalLogTransform.invlinthresh#
The invlinthresh attribute of InvertedSymmetricalLogTransform is deprecated. Use
the .inverted().transform(linthresh) method instead.
axisartist now uses more standard tick direction controls#
Previously, the position of axisartist ticks (inside or outside the axes) were
set using set_tick_out(bool). They are now set using set_tick_direction("in")
(or "out", or "inout"), and respect rcParams["xtick.direction"] (default: 'out') and rcParams["ytick.direction"] (default: 'out'). In
particular, they default to pointing outwards, consistently with the rest of the
library.
The tick_out parameter of Ticks has been deprecated (use tick_direction instead).
The Ticks.get_tick_out method is deprecated (use Ticks.get_tick_direction
instead).
The unused locs_angles_labels attribute of Ticks and LabelBase has also been
deprecated.
GridFinder.get_grid_info now takes a single bbox as parameter#
Passing x1, y1, x2, y2 as separate parameters is deprecated.
GridFinder.transform_xy and GridFinder.inv_transform_xy#
... are deprecated. Directly use the standard transform returned by
GridFinder.get_transform instead.
axes_grid.Grid.ngrids#
This attribute has been deprecated and renamed n_axes, consistently with the new
name of the Grid constructor parameter that allows setting the actual
number of axes in the grid (the old parameter, ngrids, did not actually work since
Matplotlib 3.3).
The same change has been made in axes_grid.ImageGrid.
canvas parameter to MultiCursor#
... is deprecated. It has been unused for a while already.
Please remove the parameter and change the call from MultiCursor(canvas, axes) to
MultiCursor(axes). Both calls are valid throughout the deprecation period.
CallbackRegistry.disconnect cid parameter renamed to cid_or_func#
The cid parameter of CallbackRegistry.disconnect has been renamed to cid_or_func.
The method now also accepts a callable, which will disconnect that callback from all
signals or from a specific signal if the signal keyword argument is provided.
cbook.normalize_kwargs only supports passing artists and artist classes as second argument#
Support for directly passing an alias mapping or None as second argument to
cbook.normalize_kwargs has been deprecated.
backend_svg.XMLWriter is deprecated#
It is an internal helper not intended for external use.
image.thumbnail#
... is deprecated without replacement. Use Pillow's
thumbnail method instead. See also the Pillow
tutorial.
testing.widgets.mock_event and testing.widgets.do_event#
... are deprecated. Directly construct Event objects (typically MouseEvent or
KeyEvent) and pass them to canvas.callbacks.process() instead.
Removals#
matplotlib.cm.get_cmap#
Colormaps are now available through the ColormapRegistry accessible via
matplotlib.colormaps or matplotlib.pyplot.colormaps.
If you have the name of a colormap as a string, you can use a direct lookup,
matplotlib.colormaps[name] or matplotlib.pyplot.colormaps[name]. Alternatively,
matplotlib.colormaps.get_cmap will maintain the existing behavior of additionally
passing through Colormap instances and converting None to the default colormap.
matplotlib.pyplot.get_cmap will stay as a shortcut to
matplotlib.colormaps.get_cmap.
boxplot tick labels#
The parameter labels has been removed in favour of tick_labels for clarity and
consistency with bar.
plot_date#
Use of plot_date has been discouraged since Matplotlib 3.5 and deprecated since 3.9.
The plot_date function has now been removed.
datetime-like data should directly be plotted usingplot.If you need to plot plain numeric data as Matplotlib date format or need to set a timezone, call
ax.xaxis.axis_date/ax.yaxis.axis_datebeforeplot. SeeAxis.axis_date.
GridHelperCurveLinear.get_tick_iterator#
... is removed with no replacement.
nth_coord parameter to axisartist helpers for fixed axis#
Helper APIs in axisartist for generating a "fixed" axis on rectilinear axes
(FixedAxisArtistHelperRectilinear) no longer take a nth_coord parameter.
That parameter is entirely inferred from the (required) loc parameter.
For curvilinear axes, the nth_coord parameter remains supported (it affects the ticks, not the axis position itself), but it is now keyword-only.
rcsetup.interactive_bk, rcsetup.non_interactive_bk and rcsetup.all_backends#
... are removed and replaced by matplotlib.backends.backend_registry.list_builtin
with the following arguments
matplotlib.backends.BackendFilter.INTERACTIVEmatplotlib.backends.BackendFilter.NON_INTERACTIVENone
interval parameter of TimerBase.start#
The timer interval parameter can no longer be set while starting it. The interval can be specified instead in the timer constructor, or by setting the timer.interval attribute.
TransformNode.is_bbox#
... is removed. Instead check the object using isinstance(..., BboxBase).
BboxTransformToMaxOnly#
... is removed. It can be replaced by BboxTransformTo(LockableBbox(bbox, x0=0, y0=0)).
Image path semantics of toolmanager-based tools#
Previously, MEP22 ("toolmanager-based") Tools would try to load their icon
(tool.image) relative to the current working directory, or, as a fallback, from
Matplotlib's own image directory. Because both approaches are problematic for
third-party tools (the end-user may change the current working directory at any time,
and third-parties cannot add new icons in Matplotlib's image directory), this behavior
has been removed; instead, tool.image is now interpreted relative to the directory
containing the source file where the Tool.image class attribute is defined.
(Defining tool.image as an absolute path also works and is compatible with both the
old and the new semantics.)
Development changes#
Increase to minimum supported versions of dependencies#
For Matplotlib 3.11, the minimum supported versions are being bumped:
Dependency |
min in mpl3.10 |
min in mpl3.11 |
|---|---|---|
Python |
3.10 |
3.11 |
NumPy |
1.23 |
1.25 |
pyparsing |
2.3.1 |
3.0.0 |
This is consistent with our Dependency version policy and SPEC0
pip 25.1 suggested for development#
Dependencies for development (build and testing) are now specified as Dependency Groups instead of individual requirements files.
Consequently, a version of pip that supports Dependency Groups is suggested, namely
version 25.1 or higher. Note that if you install build/testing dependencies manually (by
copying the list from pyproject.toml), then an older version of pip is sufficient.
Glyph indices now typed distinctly from character codes#
Previously, character codes and glyph indices were both typed as int, which means you
could mix and match them erroneously. While the character code can't be made a distinct
type (because it's used for chr/ord), typing glyph indices as a distinct type means
these can't be fully swapped.