From 445d425f2f36f4a8a5e4ddee0f1274c82000893c Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 21 May 2026 15:53:23 -0400 Subject: [PATCH 1/2] DOC: Consolidate What's new entries for 3.11 --- doc/release/next_whats_new/3d_scales.rst | 35 - doc/release/next_whats_new/3d_speedups.rst | 6 - doc/release/next_whats_new/axis_inversion.rst | 9 - .../bar_label_padding_update.rst | 4 - .../barcontainer_properties.rst | 7 - .../box_arrow_size_controls.rst | 37 - .../next_whats_new/broken_barh_align.rst | 4 - .../callback_registry_disconnect_func.rst | 19 - .../color_cycle_from_sequence.rst | 9 - .../colormap_bad_under_over.rst | 23 - .../next_whats_new/colormap_with_alpha.rst | 5 - .../cycler_rcparam_security.rst | 14 - .../depthshading_improvement.rst | 39 - doc/release/next_whats_new/figsize_unit.rst | 9 - .../next_whats_new/font_alt_family_names.rst | 25 - doc/release/next_whats_new/font_features.rst | 41 - doc/release/next_whats_new/gif_savefig.rst | 6 - doc/release/next_whats_new/grouped_bar.rst | 26 - doc/release/next_whats_new/hist_color.rst | 5 - .../next_whats_new/ignore_system_fonts.rst | 6 - .../next_whats_new/last_resort_font.rst | 40 - .../next_whats_new/legend_line_width.rst | 21 - doc/release/next_whats_new/libraqm.rst | 42 - .../next_whats_new/log_contour_levels.rst | 4 - doc/release/next_whats_new/logticks.rst | 11 - doc/release/next_whats_new/mathnormal.rst | 10 - .../new_rcparams_grid_options.rst | 33 - .../next_whats_new/okabe_ito_colormap.rst | 29 - .../next_whats_new/partial_figsize_none.rst | 12 - .../next_whats_new/patch_edgegapcolor.rst | 24 - .../next_whats_new/patchcollection_legend.rst | 22 - doc/release/next_whats_new/pdf_fonts.rst | 10 - doc/release/next_whats_new/pie_label.rst | 28 - .../next_whats_new/pyplot-register-figure.rst | 63 - .../next_whats_new/radio_buttons_2d_grid.rst | 54 - doc/release/next_whats_new/scroll_to_zoom.rst | 9 - .../next_whats_new/separated_hatchcolor.rst | 95 -- ...x_and_eight_color_petroff_color_cycles.rst | 21 - .../sliders_callable_valfmt.rst | 6 - doc/release/next_whats_new/snap_rotation.rst | 16 - .../stackplot_style_sequences.rst | 6 - .../streamplot_integration_control.rst | 17 - .../streamplot_multiple_arrows.rst | 22 - .../next_whats_new/subplots_adjust.rst | 7 - doc/release/next_whats_new/tex_phantoms.rst | 11 - doc/release/next_whats_new/text_language.rst | 37 - doc/release/next_whats_new/ttc_fonts.rst | 18 - .../next_whats_new/twin_axes_zorder.rst | 12 - doc/release/next_whats_new/type1_subset.rst | 9 - .../next_whats_new/underline-23616.rst | 12 - .../updated_borderpad_parameter.rst | 18 - doc/release/next_whats_new/violin_stats.rst | 31 - .../next_whats_new/violinplot_colors.rst | 8 - .../next_whats_new/webagg_capture_scroll.rst | 7 - .../xtick_ytick_rotation_modes.rst | 28 - doc/release/next_whats_new/zoom_boxes.rst | 4 - .../prev_whats_new/whats_new_3.10.0.rst | 2 +- .../prev_whats_new/whats_new_3.11.0.rst | 1250 +++++++++++++++++ doc/release/release_notes.rst | 1 + 59 files changed, 1252 insertions(+), 1127 deletions(-) delete mode 100644 doc/release/next_whats_new/3d_scales.rst delete mode 100644 doc/release/next_whats_new/3d_speedups.rst delete mode 100644 doc/release/next_whats_new/axis_inversion.rst delete mode 100644 doc/release/next_whats_new/bar_label_padding_update.rst delete mode 100644 doc/release/next_whats_new/barcontainer_properties.rst delete mode 100644 doc/release/next_whats_new/box_arrow_size_controls.rst delete mode 100644 doc/release/next_whats_new/broken_barh_align.rst delete mode 100644 doc/release/next_whats_new/callback_registry_disconnect_func.rst delete mode 100644 doc/release/next_whats_new/color_cycle_from_sequence.rst delete mode 100644 doc/release/next_whats_new/colormap_bad_under_over.rst delete mode 100644 doc/release/next_whats_new/colormap_with_alpha.rst delete mode 100644 doc/release/next_whats_new/cycler_rcparam_security.rst delete mode 100644 doc/release/next_whats_new/depthshading_improvement.rst delete mode 100644 doc/release/next_whats_new/figsize_unit.rst delete mode 100644 doc/release/next_whats_new/font_alt_family_names.rst delete mode 100644 doc/release/next_whats_new/font_features.rst delete mode 100644 doc/release/next_whats_new/gif_savefig.rst delete mode 100644 doc/release/next_whats_new/grouped_bar.rst delete mode 100644 doc/release/next_whats_new/hist_color.rst delete mode 100644 doc/release/next_whats_new/ignore_system_fonts.rst delete mode 100644 doc/release/next_whats_new/last_resort_font.rst delete mode 100644 doc/release/next_whats_new/legend_line_width.rst delete mode 100644 doc/release/next_whats_new/libraqm.rst delete mode 100644 doc/release/next_whats_new/log_contour_levels.rst delete mode 100644 doc/release/next_whats_new/logticks.rst delete mode 100644 doc/release/next_whats_new/mathnormal.rst delete mode 100644 doc/release/next_whats_new/new_rcparams_grid_options.rst delete mode 100644 doc/release/next_whats_new/okabe_ito_colormap.rst delete mode 100644 doc/release/next_whats_new/partial_figsize_none.rst delete mode 100644 doc/release/next_whats_new/patch_edgegapcolor.rst delete mode 100644 doc/release/next_whats_new/patchcollection_legend.rst delete mode 100644 doc/release/next_whats_new/pdf_fonts.rst delete mode 100644 doc/release/next_whats_new/pie_label.rst delete mode 100644 doc/release/next_whats_new/pyplot-register-figure.rst delete mode 100644 doc/release/next_whats_new/radio_buttons_2d_grid.rst delete mode 100644 doc/release/next_whats_new/scroll_to_zoom.rst delete mode 100644 doc/release/next_whats_new/separated_hatchcolor.rst delete mode 100644 doc/release/next_whats_new/six_and_eight_color_petroff_color_cycles.rst delete mode 100644 doc/release/next_whats_new/sliders_callable_valfmt.rst delete mode 100644 doc/release/next_whats_new/snap_rotation.rst delete mode 100644 doc/release/next_whats_new/stackplot_style_sequences.rst delete mode 100644 doc/release/next_whats_new/streamplot_integration_control.rst delete mode 100644 doc/release/next_whats_new/streamplot_multiple_arrows.rst delete mode 100644 doc/release/next_whats_new/subplots_adjust.rst delete mode 100644 doc/release/next_whats_new/tex_phantoms.rst delete mode 100644 doc/release/next_whats_new/text_language.rst delete mode 100644 doc/release/next_whats_new/ttc_fonts.rst delete mode 100644 doc/release/next_whats_new/twin_axes_zorder.rst delete mode 100644 doc/release/next_whats_new/type1_subset.rst delete mode 100644 doc/release/next_whats_new/underline-23616.rst delete mode 100644 doc/release/next_whats_new/updated_borderpad_parameter.rst delete mode 100644 doc/release/next_whats_new/violin_stats.rst delete mode 100644 doc/release/next_whats_new/violinplot_colors.rst delete mode 100644 doc/release/next_whats_new/webagg_capture_scroll.rst delete mode 100644 doc/release/next_whats_new/xtick_ytick_rotation_modes.rst delete mode 100644 doc/release/next_whats_new/zoom_boxes.rst create mode 100644 doc/release/prev_whats_new/whats_new_3.11.0.rst diff --git a/doc/release/next_whats_new/3d_scales.rst b/doc/release/next_whats_new/3d_scales.rst deleted file mode 100644 index e92b8e0abb61..000000000000 --- a/doc/release/next_whats_new/3d_scales.rst +++ /dev/null @@ -1,35 +0,0 @@ -Non-linear scales on 3D axes ----------------------------- - -Resolving a long-standing issue, 3D axes now support non-linear axis scales -such as 'log', 'symlog', 'logit', 'asinh', and custom 'function' scales, just -like 2D axes. Use `~.Axes3D.set_xscale`, `~.Axes3D.set_yscale`, and -`~.Axes3D.set_zscale` to set the scale for each axis independently. - -.. plot:: - :include-source: true - :alt: A 3D plot with a linear x-axis, logarithmic y-axis, and symlog z-axis. - - import matplotlib.pyplot as plt - import numpy as np - - # A sine chirp with increasing frequency and amplitude - x = np.linspace(0, 1, 400) # time - y = 10 ** (2 * x) # frequency, growing exponentially from 1 to 100 Hz - phase = 2 * np.pi * (10 ** (2 * x) - 1) / (2 * np.log(10)) - z = np.sin(phase) * x ** 2 * 10 # amplitude, growing quadratically - - fig = plt.figure() - ax = fig.add_subplot(projection='3d') - ax.plot(x, y, z) - - ax.set_xlabel('Time (linear)') - ax.set_ylabel('Frequency, Hz (log)') - ax.set_zlabel('Amplitude (symlog)') - - ax.set_yscale('log') - ax.set_zscale('symlog') - - plt.show() - -See `matplotlib.scale` for details on all available scales and their parameters. diff --git a/doc/release/next_whats_new/3d_speedups.rst b/doc/release/next_whats_new/3d_speedups.rst deleted file mode 100644 index 70e80bfbdccb..000000000000 --- a/doc/release/next_whats_new/3d_speedups.rst +++ /dev/null @@ -1,6 +0,0 @@ -3D performance improvements -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Draw time for 3D plots has been improved, especially for surface and wireframe -plots. Users should see up to a 10x speedup in some cases. This should make -interacting with 3D plots much more responsive. diff --git a/doc/release/next_whats_new/axis_inversion.rst b/doc/release/next_whats_new/axis_inversion.rst deleted file mode 100644 index 8d0e161b9ab2..000000000000 --- a/doc/release/next_whats_new/axis_inversion.rst +++ /dev/null @@ -1,9 +0,0 @@ -Standard getters/setters for axis inversion state -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Whether an axis is inverted can now be queried and set using the `.axes.Axes` -getters `~.Axes.get_xinverted`/`~.Axes.get_yinverted` and setters -`~.Axes.set_xinverted`/`~.Axes.set_yinverted`. - -The previously existing methods (`.Axes.xaxis_inverted`, `.Axes.invert_xaxis`) -are now discouraged (but not deprecated) due to their non-standard naming and -behavior. diff --git a/doc/release/next_whats_new/bar_label_padding_update.rst b/doc/release/next_whats_new/bar_label_padding_update.rst deleted file mode 100644 index 7a2ef73c41ca..000000000000 --- a/doc/release/next_whats_new/bar_label_padding_update.rst +++ /dev/null @@ -1,4 +0,0 @@ -``bar_label`` supports individual padding per label ---------------------------------------------------- -``bar_label`` will now accept both a float value or an array-like for -padding. The array-like defines the padding for each label individually. diff --git a/doc/release/next_whats_new/barcontainer_properties.rst b/doc/release/next_whats_new/barcontainer_properties.rst deleted file mode 100644 index 0efe4ee00e4f..000000000000 --- a/doc/release/next_whats_new/barcontainer_properties.rst +++ /dev/null @@ -1,7 +0,0 @@ -``BarContainer`` properties ---------------------------- -`.BarContainer` gained new properties to easily access coordinates of the bars: - -- `~.BarContainer.bottoms` -- `~.BarContainer.tops` -- `~.BarContainer.position_centers` diff --git a/doc/release/next_whats_new/box_arrow_size_controls.rst b/doc/release/next_whats_new/box_arrow_size_controls.rst deleted file mode 100644 index 6fb2b69e49fd..000000000000 --- a/doc/release/next_whats_new/box_arrow_size_controls.rst +++ /dev/null @@ -1,37 +0,0 @@ -Arrow-style sub-classes of ``BoxStyle`` support arrow head resizing -------------------------------------------------------------------- - -The new *head_width* and *head_angle* parameters to -`.BoxStyle.LArrow`, `.BoxStyle.RArrow` and `.BoxStyle.DArrow` allow for adjustment -of the size and aspect ratio of the arrow heads used. - -To give a consistent appearance across all parameter values, the -default head position (where the head starts relative to text) is -slightly changed compared to the previous hard-coded position. - -By using negative angles (or corresponding reflex angles) for *head_angle*, arrows -with 'backwards' heads may be created. - -.. plot:: - :include-source: true - :alt: - Six arrow-shaped text boxes. The arrows on the left have the shaft on - their left; the arrows on the right have the shaft on the right; the - arrows in the middle have shafts on both sides. - - import matplotlib.pyplot as plt - - plt.text(0.2, 0.8, "LArrow", ha='center', size=16, - bbox=dict(boxstyle="larrow, pad=0.3, head_angle=150")) - plt.text(0.2, 0.2, "LArrow", ha='center', size=16, - bbox=dict(boxstyle="larrow, pad=0.3, head_width=0.5")) - plt.text(0.5, 0.8, "DArrow", ha='center', size=16, - bbox=dict(boxstyle="darrow, pad=0.3, head_width=3")) - plt.text(0.5, 0.2, "DArrow", ha='center', size=16, - bbox=dict(boxstyle="darrow, pad=0.3, head_width=1, head_angle=60")) - plt.text(0.8, 0.8, "RArrow", ha='center', size=16, - bbox=dict(boxstyle="rarrow, pad=0.3, head_angle=30")) - plt.text(0.8, 0.2, "RArrow", ha='center', size=16, - bbox=dict(boxstyle="rarrow, pad=0.3, head_width=2, head_angle=-90")) - - plt.show() diff --git a/doc/release/next_whats_new/broken_barh_align.rst b/doc/release/next_whats_new/broken_barh_align.rst deleted file mode 100644 index 5108ac5b0e9a..000000000000 --- a/doc/release/next_whats_new/broken_barh_align.rst +++ /dev/null @@ -1,4 +0,0 @@ -``broken_barh()`` vertical alignment though ``align`` parameter ---------------------------------------------------------------- -`~.Axes.broken_barh` now supports vertical alignment of the bars through the -``align`` parameter. diff --git a/doc/release/next_whats_new/callback_registry_disconnect_func.rst b/doc/release/next_whats_new/callback_registry_disconnect_func.rst deleted file mode 100644 index 05825fe7e774..000000000000 --- a/doc/release/next_whats_new/callback_registry_disconnect_func.rst +++ /dev/null @@ -1,19 +0,0 @@ -``CallbackRegistry.disconnect`` allows directly callbacks by function -------------------------------------------------------------------------- - -`.CallbackRegistry` now allows directly passing a function and optionally signal to -`~.CallbackRegistry.disconnect` instead of needing to track the callback ID -returned by `~.CallbackRegistry.connect`. - -.. code-block:: python - - from matplotlib.cbook import CallbackRegistry - - def my_callback(event): - print(event) - - callbacks = CallbackRegistry() - callbacks.connect('my_signal', my_callback) - - # Disconnect by function reference instead of callback ID - callbacks.disconnect('my_signal', my_callback) diff --git a/doc/release/next_whats_new/color_cycle_from_sequence.rst b/doc/release/next_whats_new/color_cycle_from_sequence.rst deleted file mode 100644 index 0f9214c6fce3..000000000000 --- a/doc/release/next_whats_new/color_cycle_from_sequence.rst +++ /dev/null @@ -1,9 +0,0 @@ -Setting the default color cycle to a named color sequence ---------------------------------------------------------- - -The default color cycle may now be configured in the ``matplotlibrc`` file or -a style file to use any of the :doc:`/gallery/color/color_sequences`. For example - -.. code-block:: none - - axes.prop_cycle : cycler(color='Accent') diff --git a/doc/release/next_whats_new/colormap_bad_under_over.rst b/doc/release/next_whats_new/colormap_bad_under_over.rst deleted file mode 100644 index 772d47e4123d..000000000000 --- a/doc/release/next_whats_new/colormap_bad_under_over.rst +++ /dev/null @@ -1,23 +0,0 @@ -Colormaps support giving colors for bad, under and over values on creation --------------------------------------------------------------------------- - -Colormaps gained keyword arguments ``bad``, ``under``, and ``over`` to -specify these values on creation. Previously, these values would have to -be set afterwards using one of `~.Colormap.set_bad`, `~.Colormap.set_under`, -`~.Colormap.set_bad`, `~.Colormap.set_extremes`, `~.Colormap.with_extremes`. - -It is recommended to use the new functionality, e.g.:: - - cmap = ListedColormap(colors, bad="red", under="darkblue", over="purple") - -instead of:: - - cmap = ListedColormap(colors).with_extremes( - bad="red", under="darkblue", over="purple") - -or:: - - cmap = ListedColormap(colors) - cmap.set_bad("red") - cmap.set_under("darkblue") - cmap.set_over("purple") diff --git a/doc/release/next_whats_new/colormap_with_alpha.rst b/doc/release/next_whats_new/colormap_with_alpha.rst deleted file mode 100644 index 7bc9a84618a2..000000000000 --- a/doc/release/next_whats_new/colormap_with_alpha.rst +++ /dev/null @@ -1,5 +0,0 @@ -Tuning transparency of colormaps --------------------------------- -The new method `.Colormap.with_alpha` allows to create a new colormap with the same -color values but a new uniform alpha value. This is handy if you want to modify only -the transparency of mapped colors for an Artist. diff --git a/doc/release/next_whats_new/cycler_rcparam_security.rst b/doc/release/next_whats_new/cycler_rcparam_security.rst deleted file mode 100644 index e4e2893aa994..000000000000 --- a/doc/release/next_whats_new/cycler_rcparam_security.rst +++ /dev/null @@ -1,14 +0,0 @@ -``axes.prop_cycle`` rcParam security improvements -------------------------------------------------- - -The ``axes.prop_cycle`` rcParam is now parsed in a safer and more restricted -manner. Only literals, ``cycler()`` and ``concat()`` calls, the operators -``+`` and ``*``, and slicing are allowed. All previously valid cycler strings -documented at https://matplotlib.org/cycler/ are still supported, for example: - -.. code-block:: none - - axes.prop_cycle : cycler('color', ['r', 'g', 'b']) + cycler('linewidth', [1, 2, 3]) - axes.prop_cycle : 2 * cycler('color', 'rgb') - axes.prop_cycle : concat(cycler('color', 'rgb'), cycler('color', 'cmk')) - axes.prop_cycle : cycler('color', 'rgbcmk')[:3] diff --git a/doc/release/next_whats_new/depthshading_improvement.rst b/doc/release/next_whats_new/depthshading_improvement.rst deleted file mode 100644 index 8e5c04e84b8c..000000000000 --- a/doc/release/next_whats_new/depthshading_improvement.rst +++ /dev/null @@ -1,39 +0,0 @@ -3D depth-shading fix --------------------- - -Previously, a slightly buggy method of estimating the visual "depth" of 3D -items could lead to sudden and unexpected changes in transparency as the plot -orientation changed. - -Now, the behavior has been made smooth and predictable. A new parameter -``depthshade_minalpha`` has also been added to allow users to set the minimum -transparency level. Depth-shading is an option for Patch3DCollections and -Path3DCollections, including 3D scatter plots. - -The default values for ``depthshade`` and ``depthshade_minalpha`` are now also -controlled via rcParams, with values of ``True`` and ``0.3`` respectively. - -A simple example: - -.. plot:: - :include-source: true - :alt: A 3D scatter plot with depth-shading enabled. - - import matplotlib.pyplot as plt - - fig = plt.figure() - ax = fig.add_subplot(projection="3d") - - X = [i for i in range(10)] - Y = [i for i in range(10)] - Z = [i for i in range(10)] - S = [(i + 1) * 400 for i in range(10)] - - ax.scatter( - xs=X, ys=Y, zs=Z, s=S, - depthshade=True, - depthshade_minalpha=0.3, - ) - ax.view_init(elev=10, azim=-150, roll=0) - - plt.show() diff --git a/doc/release/next_whats_new/figsize_unit.rst b/doc/release/next_whats_new/figsize_unit.rst deleted file mode 100644 index ded95d9930a5..000000000000 --- a/doc/release/next_whats_new/figsize_unit.rst +++ /dev/null @@ -1,9 +0,0 @@ -Figure size units ------------------ - -When creating figures, it is now possible to define figure sizes in cm or pixel. - -Up to now the figure size is specified via ``plt.figure(..., figsize=(6, 4))``, -and the given numbers are interpreted as inches. It is now possible to add a -unit string to the tuple, i.e. ``plt.figure(..., figsize=(600, 400, "px"))``. -Supported unit strings are "in", "cm", "px". diff --git a/doc/release/next_whats_new/font_alt_family_names.rst b/doc/release/next_whats_new/font_alt_family_names.rst deleted file mode 100644 index 11b67bf6d584..000000000000 --- a/doc/release/next_whats_new/font_alt_family_names.rst +++ /dev/null @@ -1,25 +0,0 @@ -Fonts addressable by all their SFNT family names -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Fonts can now be selected by any of the family names they advertise in -the OpenType name table, not just the one FreeType reports as the primary -family name. - -Some fonts store different family names on different platforms or in -different name-table entries. For example, Ubuntu Light stores -``"Ubuntu"`` in the Macintosh-platform Name ID 1 slot (which FreeType -uses as the primary name) and ``"Ubuntu Light"`` in the Microsoft-platform -Name ID 1 slot. Previously only the FreeType-derived name was registered, -requiring an obscure weight-based workaround:: - - # Previously required - matplotlib.rcParams['font.family'] = 'Ubuntu' - matplotlib.rcParams['font.weight'] = 300 - -All name-table entries that describe a family — Name ID 1 on both -platforms, the Typographic Family (Name ID 16), and the WWS Family -(Name ID 21) — are now registered as separate entries in the -`~matplotlib.font_manager.FontManager`, so any of those names can be -used directly:: - - matplotlib.rcParams['font.family'] = 'Ubuntu Light' diff --git a/doc/release/next_whats_new/font_features.rst b/doc/release/next_whats_new/font_features.rst deleted file mode 100644 index 022d36e1e21d..000000000000 --- a/doc/release/next_whats_new/font_features.rst +++ /dev/null @@ -1,41 +0,0 @@ -Specifying font feature tags ----------------------------- - -OpenType fonts may support feature tags that specify alternate glyph shapes or -substitutions to be made optionally. The text API now supports setting a list of feature -tags to be used with the associated font. Feature tags can be set/get with: - -- `matplotlib.text.Text.set_fontfeatures` / `matplotlib.text.Text.get_fontfeatures` -- Any API that creates a `.Text` object by passing the *fontfeatures* argument (e.g., - ``plt.xlabel(..., fontfeatures=...)``) - -Font feature strings are eventually passed to HarfBuzz, and so all `string formats -supported by hb_feature_from_string() -`__ are -supported. Note though that subranges are not explicitly supported and behaviour may -change in the future. - -For example, the default font ``DejaVu Sans`` enables Standard Ligatures (the ``'liga'`` -tag) by default, and also provides optional Discretionary Ligatures (the ``dlig`` tag.) -These may be toggled with ``+`` or ``-``. - -.. plot:: - :include-source: - - fig = plt.figure(figsize=(7, 3)) - - fig.text(0.5, 0.85, 'Ligatures', fontsize=40, horizontalalignment='center') - - # Default has Standard Ligatures (liga). - fig.text(0, 0.6, 'Default: fi ffi fl st', fontsize=40) - - # Disable Standard Ligatures with -liga. - fig.text(0, 0.35, 'Disabled: fi ffi fl st', fontsize=40, - fontfeatures=['-liga']) - - # Enable Discretionary Ligatures with dlig. - fig.text(0, 0.1, 'Discretionary: fi ffi fl st', fontsize=40, - fontfeatures=['dlig']) - -Available font feature tags may be found at -https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist diff --git a/doc/release/next_whats_new/gif_savefig.rst b/doc/release/next_whats_new/gif_savefig.rst deleted file mode 100644 index e6f4732e8b95..000000000000 --- a/doc/release/next_whats_new/gif_savefig.rst +++ /dev/null @@ -1,6 +0,0 @@ -Saving figures as GIF works again -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -According to the figure documentation, the ``savefig`` method supports the -GIF format with the file extension ``.gif``. However, GIF support had been -broken since Matplotlib 2.0.0. It works again. diff --git a/doc/release/next_whats_new/grouped_bar.rst b/doc/release/next_whats_new/grouped_bar.rst deleted file mode 100644 index af57c71b8a3a..000000000000 --- a/doc/release/next_whats_new/grouped_bar.rst +++ /dev/null @@ -1,26 +0,0 @@ -Grouped bar charts ------------------- - -The new method `~.Axes.grouped_bar()` simplifies the creation of grouped bar charts -significantly. It supports different input data types (lists of datasets, dicts of -datasets, data in 2D arrays, pandas DataFrames), and allows for easy customization -of placement via controllable distances between bars and between bar groups. - -Example: - -.. plot:: - :include-source: true - :alt: Diagram of a grouped bar chart of 3 datasets with 2 categories. - - import matplotlib.pyplot as plt - - categories = ['A', 'B'] - datasets = { - 'dataset 0': [1, 11], - 'dataset 1': [3, 13], - 'dataset 2': [5, 15], - } - - fig, ax = plt.subplots() - ax.grouped_bar(datasets, tick_labels=categories) - ax.legend() diff --git a/doc/release/next_whats_new/hist_color.rst b/doc/release/next_whats_new/hist_color.rst deleted file mode 100644 index 2d6a4adb3464..000000000000 --- a/doc/release/next_whats_new/hist_color.rst +++ /dev/null @@ -1,5 +0,0 @@ -``hist()`` supports a single color for multiple datasets --------------------------------------------------------- - -It is now possible to pass a single *color* value to `~.Axes.hist()`. This -value is applied to all datasets. diff --git a/doc/release/next_whats_new/ignore_system_fonts.rst b/doc/release/next_whats_new/ignore_system_fonts.rst deleted file mode 100644 index a04c1d025d90..000000000000 --- a/doc/release/next_whats_new/ignore_system_fonts.rst +++ /dev/null @@ -1,6 +0,0 @@ -New environment variable to ignore system fonts -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -System fonts may be ignored by setting the :envvar:`MPL_IGNORE_SYSTEM_FONTS`; this -suppresses searching for system fonts (in known directories or via some -platform-specific subprocess) as well as limiting the results from `.FontManager.findfont`. diff --git a/doc/release/next_whats_new/last_resort_font.rst b/doc/release/next_whats_new/last_resort_font.rst deleted file mode 100644 index 307d4c2b8558..000000000000 --- a/doc/release/next_whats_new/last_resort_font.rst +++ /dev/null @@ -1,40 +0,0 @@ -Missing glyphs use Last Resort font ------------------------------------ - -Most fonts do not have 100% character coverage, and will fall back to a "not found" -glyph for characters that are not provided. Often, this glyph will be minimal (e.g., the -default DejaVu Sans "not found" glyph is just a rectangle.) Such minimal glyphs provide -no context as to the characters that are missing. - -Now, missing glyphs will fall back to the `Last Resort font -`__ produced by the Unicode Consortium. -This special-purpose font provides glyphs that represent types of Unicode characters. -These glyphs show a representative character from the missing Unicode block, and at -larger sizes, more context to help determine which character and font are needed. - -To disable this fallback behaviour, set :rc:`font.enable_last_resort` to ``False``. - -.. plot:: - :alt: An example of missing glyph behaviour, the first glyph from Bengali script, - second glyph from Hiragana, and the last glyph from the Unicode Private Use - Area. Multiple lines repeat the text with increasing font size from top to - bottom. - - text_raw = r"'\N{Bengali Digit Zero}\N{Hiragana Letter A}\ufdd0'" - text = eval(text_raw) - sizes = [ - (0.85, 8), - (0.80, 10), - (0.75, 12), - (0.70, 16), - (0.63, 20), - (0.55, 24), - (0.45, 32), - (0.30, 48), - (0.10, 64), - ] - - fig = plt.figure() - fig.text(0.01, 0.90, f'Input: {text_raw}') - for y, size in sizes: - fig.text(0.01, y, f'{size}pt:{text}', fontsize=size) diff --git a/doc/release/next_whats_new/legend_line_width.rst b/doc/release/next_whats_new/legend_line_width.rst deleted file mode 100644 index d8cfd57640a8..000000000000 --- a/doc/release/next_whats_new/legend_line_width.rst +++ /dev/null @@ -1,21 +0,0 @@ -``legend.linewidth`` rcParam and parameter -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -A new rcParam ``legend.linewidth`` has been added to control the line width of -the legend's box edges. When set to ``None`` (the default), it inherits the -value from ``patch.linewidth``. This allows for independent control of the -legend frame line width without affecting other elements. - -The `.Legend` constructor also accepts a new *linewidth* parameter to set the -legend frame line width directly, overriding the rcParam value. - -.. plot:: - :include-source: true - :alt: A line plot with a legend showing a thick border around the legend box. - - import matplotlib.pyplot as plt - - fig, ax = plt.subplots() - ax.plot([1, 2, 3], label='data') - ax.legend(linewidth=2.0) # Thick legend box edge - plt.show() diff --git a/doc/release/next_whats_new/libraqm.rst b/doc/release/next_whats_new/libraqm.rst deleted file mode 100644 index 8312f2f9432c..000000000000 --- a/doc/release/next_whats_new/libraqm.rst +++ /dev/null @@ -1,42 +0,0 @@ -Complex text layout with libraqm --------------------------------- - -Text support has been extended to include complex text layout. This support includes: - -1. Languages that require advanced layout, such as Arabic or Hebrew. -2. Text that mixes left-to-right and right-to-left languages. - - .. plot:: - :show-source-link: False - - text = 'Here is some رَقْم in اَلْعَرَبِيَّةُ' - fig = plt.figure(figsize=(6, 1)) - fig.text(0.5, 0.5, text, size=32, ha='center', va='center') - -3. Ligatures that combine several adjacent characters for improved legibility. - - .. plot:: - :show-source-link: False - - text = 'f\N{Hair Space}f\N{Hair Space}i \N{Rightwards Arrow} ffi' - fig = plt.figure(figsize=(3, 1)) - fig.text(0.5, 0.5, text, size=32, ha='center', va='center') - -4. Combining multiple or double-width diacritics. - - .. plot:: - :show-source-link: False - - text = ( - 'a\N{Combining Circumflex Accent}\N{Combining Double Tilde}' - 'c\N{Combining Diaeresis}') - text = ' + '.join( - c if c in 'ac' else f'\N{Dotted Circle}{c}' - for c in text) + f' \N{Rightwards Arrow} {text}' - fig = plt.figure(figsize=(6, 1)) - fig.text(0.5, 0.5, text, size=32, ha='center', va='center', - # Builtin DejaVu Sans doesn't support multiple diacritics. - family=['Noto Sans', 'DejaVu Sans']) - -Note, all advanced features require corresponding font support, and may require -additional fonts over the builtin DejaVu Sans. diff --git a/doc/release/next_whats_new/log_contour_levels.rst b/doc/release/next_whats_new/log_contour_levels.rst deleted file mode 100644 index da5cc2da6070..000000000000 --- a/doc/release/next_whats_new/log_contour_levels.rst +++ /dev/null @@ -1,4 +0,0 @@ -Maximum levels on log-scaled contour plots are now respected -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When plotting contours with a log norm, passing an integer value to the ``levels`` -argument to cap the maximum number of contour levels now works as intended. diff --git a/doc/release/next_whats_new/logticks.rst b/doc/release/next_whats_new/logticks.rst deleted file mode 100644 index b729cd990f91..000000000000 --- a/doc/release/next_whats_new/logticks.rst +++ /dev/null @@ -1,11 +0,0 @@ -Improved selection of log-scale ticks -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The algorithm for selecting log-scale ticks (on powers of ten) has been -improved. In particular, it will now always draw as many ticks as possible -(e.g., it will not draw a single tick if it was possible to fit two ticks); if -subsampling ticks, it will prefer putting ticks on integer multiples of the -subsampling stride (e.g., it prefers putting ticks at 10\ :sup:`0`, 10\ :sup:`3`, -10\ :sup:`6` rather than 10\ :sup:`1`, 10\ :sup:`4`, 10\ :sup:`7`) if this -results in the same number of ticks at the end; and it is now more robust -against floating-point calculation errors. diff --git a/doc/release/next_whats_new/mathnormal.rst b/doc/release/next_whats_new/mathnormal.rst deleted file mode 100644 index 7e4cd5d333fe..000000000000 --- a/doc/release/next_whats_new/mathnormal.rst +++ /dev/null @@ -1,10 +0,0 @@ -Mathtext distinguishes *italic* and *normal* font -------------------------------------------------- - -Matplotlib's lightweight TeX expression parser (``usetex=False``) now distinguishes between *italic* and *normal* math fonts to closer replicate the behaviour of LaTeX. -The normal math font is selected by default in math environment (unless the rcParam ``mathtext.default`` is overwritten) but can be explicitly set with the new ``\mathnormal`` command. Italic font is selected with ``\mathit``. -The main difference is that *italic* produces italic digits, whereas *normal* produces upright digits. Previously, it was not possible to typeset italic digits. -Note that ``normal`` now corresponds to what used to be ``it``, whereas ``it`` now renders all characters italic. -**Important**: In case the default mathematics font is overwritten by setting ``mathtext.default: it`` in ``matplotlibrc``, it must be either commented out or changed to ``mathtext.default: normal`` to preserve its behaviour. Otherwise, all alphanumeric characters, including digits, are rendered italic. - -One difference to traditional LaTeX is that LaTeX further distinguishes between *normal* (``\mathnormal``) and *default math*, where the default uses roman digits and normal uses oldstyle digits. This distinction is no longer present with modern LaTeX engines and unicode-math nor in Matplotlib. diff --git a/doc/release/next_whats_new/new_rcparams_grid_options.rst b/doc/release/next_whats_new/new_rcparams_grid_options.rst deleted file mode 100644 index c2c0455eecbb..000000000000 --- a/doc/release/next_whats_new/new_rcparams_grid_options.rst +++ /dev/null @@ -1,33 +0,0 @@ -Separate styling options for major/minor grid line in rcParams --------------------------------------------------------------- - -Using :rc:`grid.major.*` or :rc:`grid.minor.*` will overwrite the value in -:rc:`grid.*` for the major and minor gridlines, respectively. - -.. plot:: - :include-source: true - :alt: Modifying the gridlines using the new options `rcParams` - - import matplotlib as mpl - import matplotlib.pyplot as plt - - - # Set visibility for major and minor gridlines - mpl.rcParams["axes.grid"] = True - mpl.rcParams["ytick.minor.visible"] = True - mpl.rcParams["xtick.minor.visible"] = True - mpl.rcParams["axes.grid.which"] = "both" - - # Using old values to set both major and minor properties - mpl.rcParams["grid.color"] = "red" - mpl.rcParams["grid.linewidth"] = 1 - - # Overwrite some values for major and minor separately - mpl.rcParams["grid.major.color"] = "black" - mpl.rcParams["grid.major.linewidth"] = 2 - mpl.rcParams["grid.minor.linestyle"] = ":" - mpl.rcParams["grid.minor.alpha"] = 0.6 - - plt.plot([0, 1], [0, 1]) - - plt.show() diff --git a/doc/release/next_whats_new/okabe_ito_colormap.rst b/doc/release/next_whats_new/okabe_ito_colormap.rst deleted file mode 100644 index fad461257932..000000000000 --- a/doc/release/next_whats_new/okabe_ito_colormap.rst +++ /dev/null @@ -1,29 +0,0 @@ -Okabe-Ito accessible color sequence ------------------------------------ - -Matplotlib now includes the `Okabe-Ito color sequence`_. Its colors remain distinguishable for common forms of color-vision deficiency and when printed. - -.. _Okabe-Ito color sequence: https://jfly.uni-koeln.de/color/#pallet - -For example, to set it as the default colormap for your plots and image-like artists, use: - -.. code-block:: python - - import matplotlib.pyplot as plt - from cycler import cycler - - plt.rcParams['axes.prop_cycle'] = cycler('color', plt.colormaps['okabe_ito'].colors) - plt.rcParams['image.cmap'] = 'okabe_ito' - -Or, when creating plots, you can pass it explicitly: - -.. plot:: - - import matplotlib.pyplot as plt - - colors = plt.colormaps['okabe_ito'].colors - x = range(5) - for i, c in enumerate(colors): - plt.plot(x, [v*(i+1) for v in x], color=c, label=f'line {i}') - plt.legend() - plt.show() diff --git a/doc/release/next_whats_new/partial_figsize_none.rst b/doc/release/next_whats_new/partial_figsize_none.rst deleted file mode 100644 index 43bd3e34cc73..000000000000 --- a/doc/release/next_whats_new/partial_figsize_none.rst +++ /dev/null @@ -1,12 +0,0 @@ -Partial ``figsize`` specification at figure creation ----------------------------------------------------- - -Figure creation now accepts a single ``None`` in ``figsize``. -Passing ``(None, h)`` uses the default width from :rc:`figure.figsize`, and -passing ``(w, None)`` uses the default height. -Passing ``(None, None)`` is invalid and raises a `ValueError`. - -For example:: - - import matplotlib.pyplot as plt - fig = plt.figure(figsize=(None, 4)) diff --git a/doc/release/next_whats_new/patch_edgegapcolor.rst b/doc/release/next_whats_new/patch_edgegapcolor.rst deleted file mode 100644 index b981116fbb76..000000000000 --- a/doc/release/next_whats_new/patch_edgegapcolor.rst +++ /dev/null @@ -1,24 +0,0 @@ -``edgegapcolor`` for Patches ----------------------------- - -`~matplotlib.patches.Patch` now supports an *edgegapcolor* parameter, -similar to the existing *gapcolor* in `.Line2D`. This allows patches with -dashed edges to display a secondary color in the gaps, creating a "striped" -edge effect. - -This is useful when drawing unfilled patches on backgrounds of unknown color, -where alternating edge colors ensure the patch boundary remains visible. - -.. plot:: - :include-source: true - :alt: A rectangle with a dashed orange edge and blue gaps, demonstrating the edgegapcolor feature. - - import matplotlib.pyplot as plt - from matplotlib.patches import Rectangle - - fig, ax = plt.subplots() - rect = Rectangle((0.1, 0.1), 0.6, 0.6, fill=False, - edgecolor='orange', edgegapcolor='blue', - linestyle='--', linewidth=3) - ax.add_patch(rect) - plt.show() diff --git a/doc/release/next_whats_new/patchcollection_legend.rst b/doc/release/next_whats_new/patchcollection_legend.rst deleted file mode 100644 index 58574e9e6757..000000000000 --- a/doc/release/next_whats_new/patchcollection_legend.rst +++ /dev/null @@ -1,22 +0,0 @@ -``PatchCollection`` legends now supported ------------------------------------------- -`.PatchCollection` instances now properly display in legends when given a label. -Previously, labels on `~.PatchCollection` objects were ignored by the legend -system, requiring users to create manual legend entries. - -.. plot:: - :include-source: true - :alt: The legend entry displays a rectangle matching the visual properties (colors, line styles, line widths) of the first patch in the collection. - - import matplotlib.pyplot as plt - import matplotlib.patches as mpatches - from matplotlib.collections import PatchCollection - - fig, ax = plt.subplots() - patches = [mpatches.Circle((0, 0), 0.1), mpatches.Rectangle((0.5, 0.5), 0.2, 0.3)] - pc = PatchCollection(patches, facecolor='blue', edgecolor='black', label='My patches') - ax.add_collection(pc) - ax.legend() # Now displays the label "My patches" - plt.show() - -This fix resolves :ghissue:`23998`. diff --git a/doc/release/next_whats_new/pdf_fonts.rst b/doc/release/next_whats_new/pdf_fonts.rst deleted file mode 100644 index 4d8665386a72..000000000000 --- a/doc/release/next_whats_new/pdf_fonts.rst +++ /dev/null @@ -1,10 +0,0 @@ -Improved font embedding in PDF ------------------------------- - -Both Type 3 and Type 42 fonts (see :ref:`fonts` for more details) are now -embedded into PDFs without limitation. Fonts may be split into multiple -embedded subsets in order to satisfy format limits. Additionally, a corrected -Unicode mapping is added for each. - -This means that *all* text should now be selectable and copyable in PDF viewers -that support doing so. diff --git a/doc/release/next_whats_new/pie_label.rst b/doc/release/next_whats_new/pie_label.rst deleted file mode 100644 index 6dc9a3f619c2..000000000000 --- a/doc/release/next_whats_new/pie_label.rst +++ /dev/null @@ -1,28 +0,0 @@ -Adding labels to pie chart wedges ---------------------------------- - -The new `~.Axes.pie_label` method adds a label to each wedge in a pie chart created with -`~.Axes.pie`. It can take - -* a list of strings, similar to the existing *labels* parameter of `~.Axes.pie` -* a format string similar to the existing *autopct* parameter of `~.Axes.pie` except - that it uses the `str.format` method and it can handle absolute values as well as - fractions/percentages - -For more examples, see :doc:`/gallery/pie_and_polar_charts/pie_label`. - -.. plot:: - :include-source: true - :alt: A pie chart with three labels on each wedge, showing a food type, number, and fraction associated with the wedge. - - import matplotlib.pyplot as plt - - data = [36, 24, 8, 12] - labels = ['spam', 'eggs', 'bacon', 'sausage'] - - fig, ax = plt.subplots() - pie = ax.pie(data) - - ax.pie_label(pie, labels, distance=1.1) - ax.pie_label(pie, '{frac:.1%}', distance=0.7) - ax.pie_label(pie, '{absval:d}', distance=0.4) diff --git a/doc/release/next_whats_new/pyplot-register-figure.rst b/doc/release/next_whats_new/pyplot-register-figure.rst deleted file mode 100644 index 86ffcbf2294a..000000000000 --- a/doc/release/next_whats_new/pyplot-register-figure.rst +++ /dev/null @@ -1,63 +0,0 @@ -Figures can be attached to and removed from pyplot -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Figures can now be attached to and removed from management through pyplot, which in -the background also means a less strict coupling to backends. - -In particular, standalone figures (created with the `.Figure` constructor) can now be -registered with the `.pyplot` module by calling ``plt.figure(fig)``. This allows to -show them with ``plt.show()`` as you would do with any figure created with pyplot -factory methods such as ``plt.figure()`` or ``plt.subplots()``. - -When closing a shown figure window, the related figure is reset to the standalone -state, i.e. it's not visible to pyplot anymore, but if you still hold a reference -to it, you can continue to work with it (e.g. do ``fig.savefig()``, or re-add it -to pyplot with ``plt.figure(fig)`` and then show it again). - -The following is now possible - though the example is exaggerated to show what's -possible. In practice, you'll stick with much simpler versions for better -consistency :: - - import matplotlib.pyplot as plt - from matplotlib.figure import Figure - - # Create a standalone figure - fig = Figure() - ax = fig.add_subplot() - ax.plot([1, 2, 3], [4, 5, 6]) - - # Register it with pyplot - plt.figure(fig) - - # Modify the figure through pyplot - plt.xlabel("x label") - - # Show the figure - plt.show() - - # Close the figure window through the GUI - - # Continue to work on the figure - fig.savefig("my_figure.png") - ax.set_ylabel("y label") - - # Re-register the figure and show it again - plt.figure(fig) - plt.show() - -Technical detail: Standalone figures use `.FigureCanvasBase` as canvas. This is -replaced by a backend-dependent subclass when registering with pyplot, and is -reset to `.FigureCanvasBase` when the figure is closed. `.Figure.savefig` uses -the current canvas to save the figure (if possible). Since `.FigureCanvasBase` -can not render the figure, when saving the figure, it will fallback to a suitable -canvas subclass, e.g. `.FigureCanvasAgg` for raster outputs such as png. -Any Agg-based backend will create the same file output. However, there may be -slight differences for non-Agg backends; e.g. if you use "GTK4Cairo" as -interactive backend, ``fig.savefig("file.png")`` may create a slightly different -image depending on whether the figure is registered with pyplot or not. In -general, you should not store a reference to the canvas, but rather always -obtain it from the figure with ``fig.canvas``. This will return the current -canvas, which is either the original `.FigureCanvasBase` or a backend-dependent -subclass, depending on whether the figure is registered with pyplot or not. -Additionally, the swapping of the canvas currently does not play well with -blitting of matplotlib widgets; in such cases either deactivate blitting or do not -continue to use the figure (e.g. saving it after closing the window). diff --git a/doc/release/next_whats_new/radio_buttons_2d_grid.rst b/doc/release/next_whats_new/radio_buttons_2d_grid.rst deleted file mode 100644 index 3840eb69211e..000000000000 --- a/doc/release/next_whats_new/radio_buttons_2d_grid.rst +++ /dev/null @@ -1,54 +0,0 @@ -RadioButtons and CheckButtons widgets support flexible layouts -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The `.widgets.RadioButtons` and `.widgets.CheckButtons` widgets now support -arranging buttons in different layouts via the new *layout* parameter. You can -arrange buttons vertically (default), horizontally, or in a 2D grid by passing -a ``(rows, cols)`` tuple. - -See :doc:`/gallery/widgets/radio_buttons_grid` for a ``(rows, cols)`` example. - -.. plot:: - :include-source: true - :alt: Multiple sine waves with checkboxes to toggle their visibility. - - import matplotlib.pyplot as plt - import numpy as np - from matplotlib.widgets import CheckButtons - - t = np.arange(0.0, 2.0, 0.01) - s0 = np.sin(2*np.pi*t) - s1 = np.sin(4*np.pi*t) - s2 = np.sin(6*np.pi*t) - s3 = np.sin(8*np.pi*t) - - fig, axes = plt.subplot_mosaic( - [['main'], ['buttons']], - height_ratios=[8, 1], - layout="constrained", - ) - - l0, = axes['main'].plot(t, s0, lw=2, color='red', label='2 Hz') - l1, = axes['main'].plot(t, s1, lw=2, color='green', label='4 Hz') - l2, = axes['main'].plot(t, s2, lw=2, color='blue', label='6 Hz') - l3, = axes['main'].plot(t, s3, lw=2, color='purple', label='8 Hz') - axes['main'].set_xlabel('Time (s)') - axes['main'].set_ylabel('Amplitude') - - lines_by_label = {l.get_label(): l for l in [l0, l1, l2, l3]} - - axes['buttons'].set_facecolor('0.9') - check = CheckButtons( - axes['buttons'], - labels=lines_by_label.keys(), - actives=[l.get_visible() for l in lines_by_label.values()], - layout='horizontal' - ) - - def callback(label): - ln = lines_by_label[label] - ln.set_visible(not ln.get_visible()) - fig.canvas.draw_idle() - - check.on_clicked(callback) - plt.show() diff --git a/doc/release/next_whats_new/scroll_to_zoom.rst b/doc/release/next_whats_new/scroll_to_zoom.rst deleted file mode 100644 index 1be522b7a255..000000000000 --- a/doc/release/next_whats_new/scroll_to_zoom.rst +++ /dev/null @@ -1,9 +0,0 @@ -Zooming using mouse wheel -~~~~~~~~~~~~~~~~~~~~~~~~~ - -``Ctrl+MouseWheel`` can be used to zoom in the plot windows. -Additionally, ``x+MouseWheel`` zooms only the x-axis and ``y+MouseWheel`` zooms only the y-axis. - -The zoom focusses on the mouse pointer. With ``Ctrl``, the axes aspect ratio is kept; with ``x`` or ``y``, only the respective axis is scaled. - -Zooming is currently only supported on rectilinear Axes. diff --git a/doc/release/next_whats_new/separated_hatchcolor.rst b/doc/release/next_whats_new/separated_hatchcolor.rst deleted file mode 100644 index a794fba2e515..000000000000 --- a/doc/release/next_whats_new/separated_hatchcolor.rst +++ /dev/null @@ -1,95 +0,0 @@ -Separated ``hatchcolor`` from ``edgecolor`` -------------------------------------------- - -When the *hatchcolor* parameter is specified, it will be used for the hatch. -If it is not specified, it will fall back to using :rc:`hatch.color`. -The special value 'edge' uses the patch edgecolor, with a fallback to -:rc:`patch.edgecolor` if the patch edgecolor is 'none'. -Previously, hatch colors were the same as edge colors, with a fallback to -:rc:`hatch.color` if the patch did not have an edge color. - -.. plot:: - :include-source: true - :alt: Four Rectangle patches, each displaying the color of hatches in different specifications of edgecolor and hatchcolor. Top left has hatchcolor='black' representing the default value when both hatchcolor and edgecolor are not set, top right has edgecolor='blue' and hatchcolor='black' which remains when the edgecolor is set again, bottom left has edgecolor='red' and hatchcolor='orange' on explicit specification and bottom right has edgecolor='green' and hatchcolor='green' when the hatchcolor is not set. - - import matplotlib as mpl - import matplotlib.pyplot as plt - from matplotlib.patches import Rectangle - - fig, ax = plt.subplots() - - # In this case, hatchcolor is orange - patch1 = Rectangle((0.1, 0.1), 0.3, 0.3, edgecolor='red', linewidth=2, - hatch='//', hatchcolor='orange') - ax.add_patch(patch1) - - # When hatchcolor is not specified, it matches edgecolor - # In this case, hatchcolor is green - patch2 = Rectangle((0.6, 0.1), 0.3, 0.3, edgecolor='green', linewidth=2, - hatch='//', facecolor='none') - ax.add_patch(patch2) - - # If both hatchcolor and edgecolor are not specified - # it will default to the 'patch.edgecolor' rcParam, which is black by default - # In this case, hatchcolor is black - patch3 = Rectangle((0.1, 0.6), 0.3, 0.3, hatch='//') - ax.add_patch(patch3) - - # When using `hatch.color` in the `rcParams` - # edgecolor will now not overwrite hatchcolor - # In this case, hatchcolor is black - with plt.rc_context({'hatch.color': 'black'}): - patch4 = Rectangle((0.6, 0.6), 0.3, 0.3, edgecolor='blue', linewidth=2, - hatch='//', facecolor='none') - - # hatchcolor is black (it uses the `hatch.color` rcParam value) - patch4.set_edgecolor('blue') - # hatchcolor is still black (here, it does not update when edgecolor changes) - ax.add_patch(patch4) - - ax.annotate("hatchcolor = 'orange'", - xy=(.5, 1.03), xycoords=patch1, ha='center', va='bottom') - ax.annotate("hatch color unspecified\nedgecolor='green'", - xy=(.5, 1.03), xycoords=patch2, ha='center', va='bottom') - ax.annotate("hatch color unspecified\nusing patch.edgecolor", - xy=(.5, 1.03), xycoords=patch3, ha='center', va='bottom') - ax.annotate("hatch.color='black'", - xy=(.5, 1.03), xycoords=patch4, ha='center', va='bottom') - - plt.show() - -For collections, a sequence of colors can be passed to the *hatchcolor* parameter -which will be cycled through for each hatch, similar to *facecolor* and *edgecolor*. - -Previously, if *edgecolor* was not specified, the hatch color would fall back to -:rc:`patch.edgecolor`, but the alpha value would default to **1.0**, regardless of the -alpha value of the collection. This behavior has been changed such that, if both -*hatchcolor* and *edgecolor* are not specified, the hatch color will fall back -to 'patch.edgecolor' with the alpha value of the collection. - -.. plot:: - :include-source: true - :alt: A random scatter plot with hatches on the markers. The hatches are colored in blue, orange, and green, respectively. After the first three markers, the colors are cycled through again. - - import matplotlib.pyplot as plt - import numpy as np - - np.random.seed(19680801) - - fig, ax = plt.subplots() - - x = [29, 36, 41, 25, 32, 70, 62, 58, 66, 80, 58, 68, 62, 37, 48] - y = [82, 76, 48, 53, 62, 70, 84, 68, 55, 75, 29, 25, 12, 17, 20] - colors = ['tab:blue'] * 5 + ['tab:orange'] * 5 + ['tab:green'] * 5 - - ax.scatter( - x, - y, - s=800, - hatch="xxxx", - hatchcolor=colors, - facecolor="none", - edgecolor="black", - ) - - plt.show() diff --git a/doc/release/next_whats_new/six_and_eight_color_petroff_color_cycles.rst b/doc/release/next_whats_new/six_and_eight_color_petroff_color_cycles.rst deleted file mode 100644 index 3b17b4f68868..000000000000 --- a/doc/release/next_whats_new/six_and_eight_color_petroff_color_cycles.rst +++ /dev/null @@ -1,21 +0,0 @@ -Six and eight color Petroff color cycles ----------------------------------------- - -The six and eight color accessible Petroff color cycles are named 'petroff6' and -'petroff8'. -They compliment the existing 'petroff10' color cycle, added in `Matplotlib 3.10.0`_ - -For more details see -`Petroff, M. A.: "Accessible Color Sequences for Data Visualization" -`_. -To load the 'petroff6' color cycle in place of the default:: - - import matplotlib.pyplot as plt - plt.style.use('petroff6') - -or to load the 'petroff8' color cycle:: - - import matplotlib.pyplot as plt - plt.style.use('petroff8') - -.. _Matplotlib 3.10.0: https://matplotlib.org/stable/users/prev_whats_new/whats_new_3.10.0.html#new-more-accessible-color-cycle diff --git a/doc/release/next_whats_new/sliders_callable_valfmt.rst b/doc/release/next_whats_new/sliders_callable_valfmt.rst deleted file mode 100644 index 1d350dba348a..000000000000 --- a/doc/release/next_whats_new/sliders_callable_valfmt.rst +++ /dev/null @@ -1,6 +0,0 @@ -Callable *valfmt* for ``Slider`` and ``RangeSlider`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In addition to the existing %-format string, the *valfmt* parameter of -`~.matplotlib.widgets.Slider` and `~.matplotlib.widgets.RangeSlider` now -also accepts a callable of the form ``valfmt(val: float) -> str``. diff --git a/doc/release/next_whats_new/snap_rotation.rst b/doc/release/next_whats_new/snap_rotation.rst deleted file mode 100644 index 144a4fa96011..000000000000 --- a/doc/release/next_whats_new/snap_rotation.rst +++ /dev/null @@ -1,16 +0,0 @@ -Snapping 3D rotation angles with Control key -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -3D axes rotation now supports snapping to fixed angular increments -when holding the ``Control`` key during mouse rotation. - -The snap step size is controlled by the new -``axes3d.snap_rotation`` rcParam (default: 5.0 degrees). -Setting it to 0 disables snapping. - -For example:: - - mpl.rcParams["axes3d.snap_rotation"] = 10 - -will snap elevation, azimuth, and roll angles to multiples -of 10 degrees while rotating with the mouse. diff --git a/doc/release/next_whats_new/stackplot_style_sequences.rst b/doc/release/next_whats_new/stackplot_style_sequences.rst deleted file mode 100644 index 209d30a15218..000000000000 --- a/doc/release/next_whats_new/stackplot_style_sequences.rst +++ /dev/null @@ -1,6 +0,0 @@ -Stackplot styling ------------------ - -`~.Axes.stackplot` now accepts sequences for the style parameters *facecolor*, -*edgecolor*, *linestyle*, and *linewidth*, similar to how the *hatch* parameter -is already handled. diff --git a/doc/release/next_whats_new/streamplot_integration_control.rst b/doc/release/next_whats_new/streamplot_integration_control.rst deleted file mode 100644 index 626bb33c8a95..000000000000 --- a/doc/release/next_whats_new/streamplot_integration_control.rst +++ /dev/null @@ -1,17 +0,0 @@ -Streamplot integration control -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Two new options have been added to the `~.axes.Axes.streamplot` function that -give the user better control of the streamline integration. The first is called -``integration_max_step_scale`` and multiplies the default max step computed by the -integrator. The second is called ``integration_max_error_scale`` and multiplies the -default max error set by the integrator. Values for these parameters between -zero and one reduce (tighten) the max step or error to improve streamline -accuracy by performing more computation. Values greater than one increase -(loosen) the max step or error to reduce computation time at the cost of lower -streamline accuracy. - -The integrator defaults are both hand-tuned values and may not be applicable to -all cases, so this allows customizing the behavior to specific use cases. -Modifying only ``integration_max_step_scale`` has proved effective, but it may be useful -to control the error as well. diff --git a/doc/release/next_whats_new/streamplot_multiple_arrows.rst b/doc/release/next_whats_new/streamplot_multiple_arrows.rst deleted file mode 100644 index 25329baa4a87..000000000000 --- a/doc/release/next_whats_new/streamplot_multiple_arrows.rst +++ /dev/null @@ -1,22 +0,0 @@ -Multiple arrows on a streamline -------------------------------- - -A new ``num_arrows`` argument has been added to `~matplotlib.axes.Axes.streamplot` that -allows more than one arrow to be added to each streamline: - -.. plot:: - :include-source: true - :alt: One chart showing a streamplot. Each streamline has three arrows. - - import matplotlib.pyplot as plt - import numpy as np - - w = 3 - Y, X = np.mgrid[-w:w:100j, -w:w:100j] - U = -1 - X**2 + Y - V = 1 + X - Y**2 - - fig, ax = plt.subplots() - ax.streamplot(X, Y, U, V, num_arrows=3) - - plt.show() diff --git a/doc/release/next_whats_new/subplots_adjust.rst b/doc/release/next_whats_new/subplots_adjust.rst deleted file mode 100644 index e0848ec8a3dc..000000000000 --- a/doc/release/next_whats_new/subplots_adjust.rst +++ /dev/null @@ -1,7 +0,0 @@ -Resetting the subplot parameters for figure.clear() ---------------------------------------------------- - -When calling `.Figure.clear()` the settings for `.gridspec.SubplotParams` are restored to the default values. - -`~.SubplotParams.to_dict` is a new method to get the subplot parameters as a dict, -and `~.SubplotParams.reset` resets the parameters to the defaults. diff --git a/doc/release/next_whats_new/tex_phantoms.rst b/doc/release/next_whats_new/tex_phantoms.rst deleted file mode 100644 index 82d39d502fb5..000000000000 --- a/doc/release/next_whats_new/tex_phantoms.rst +++ /dev/null @@ -1,11 +0,0 @@ -mathtext support for ``\phantom``, ``\llap``, ``\rlap`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -mathtext gained support for the TeX macros ``\phantom``, ``\llap``, and -``\rlap``. ``\phantom`` allows to occupy some space on the canvas as if -some text was being rendered, without actually rendering that text, whereas -``\llap`` and ``\rlap`` allows to render some text on the canvas while -pretending that it occupies no space. Altogether these macros allow some finer -control of text alignments. - -See https://www.tug.org/TUGboat/tb22-4/tb72perlS.pdf for a detailed description -of these macros. diff --git a/doc/release/next_whats_new/text_language.rst b/doc/release/next_whats_new/text_language.rst deleted file mode 100644 index 1d4668587b43..000000000000 --- a/doc/release/next_whats_new/text_language.rst +++ /dev/null @@ -1,37 +0,0 @@ -Specifying text language ------------------------- - -OpenType fonts may support language systems which can be used to select different -typographic conventions, e.g., localized variants of letters that share a single Unicode -code point, or different default font features. The text API now supports setting a -language to be used and may be set/get with: - -- `matplotlib.text.Text.set_language` / `matplotlib.text.Text.get_language` -- Any API that creates a `.Text` object by passing the *language* argument (e.g., - ``plt.xlabel(..., language=...)``) - -The language of the text must be in a format accepted by libraqm, namely `a BCP47 -language code `_. If None or -unset, then no particular language will be implied, and default font settings will be -used. - -For example, Matplotlib's default font ``DejaVu Sans`` supports language-specific glyphs -in the Serbian and Macedonian languages in the Cyrillic alphabet (vs Russian), -or the Sámi family of languages in the Latin alphabet (vs English). - -.. plot:: - :include-source: - - fig = plt.figure(figsize=(7, 3)) - - char = '\U00000431' - fig.text(0.5, 0.8, f'\\U{ord(char):08x}', fontsize=40, horizontalalignment='center') - fig.text(0, 0.6, f'Serbian: {char}', fontsize=40, language='sr') - fig.text(1, 0.6, f'Russian: {char}', fontsize=40, language='ru', - horizontalalignment='right') - - char = '\U0000014a' - fig.text(0.5, 0.3, f'\\U{ord(char):08x}', fontsize=40, horizontalalignment='center') - fig.text(0, 0.1, f'Inari Sámi: {char}', fontsize=40, language='smn') - fig.text(1, 0.1, f'English: {char}', fontsize=40, language='en', - horizontalalignment='right') diff --git a/doc/release/next_whats_new/ttc_fonts.rst b/doc/release/next_whats_new/ttc_fonts.rst deleted file mode 100644 index b80b1186707b..000000000000 --- a/doc/release/next_whats_new/ttc_fonts.rst +++ /dev/null @@ -1,18 +0,0 @@ -Support for loading TrueType Collection fonts ---------------------------------------------- - -TrueType Collection fonts (commonly found as files with a ``.ttc`` extension) are now -supported. Namely, Matplotlib will include these file extensions in its scan for system -fonts, and will add all sub-fonts to its list of available fonts (i.e., the list from -`~.font_manager.get_font_names`). - -From most high-level API, this means you should be able to specify the name of any -sub-font in a collection just as you would any other font. Note that at this time, there -is no way to specify the entire collection with any sort of automated selection of the -internal sub-fonts. - -In the low-level API, to ensure backwards-compatibility while facilitating this new -support, a `.FontPath` instance (comprised of a font path and a sub-font index, with -behaviour similar to a `str`) may be passed to the font management API in place of a -simple `os.PathLike` path. Any font management API that previously returned a string path -now returns a `.FontPath` instance instead. diff --git a/doc/release/next_whats_new/twin_axes_zorder.rst b/doc/release/next_whats_new/twin_axes_zorder.rst deleted file mode 100644 index 77ce9419fca0..000000000000 --- a/doc/release/next_whats_new/twin_axes_zorder.rst +++ /dev/null @@ -1,12 +0,0 @@ -Twin Axes ``delta_zorder`` --------------------------- - -`~matplotlib.axes.Axes.twinx` and `~matplotlib.axes.Axes.twiny` now accept a -*delta_zorder* keyword argument, a relative offset added to the original Axes' -zorder, to control whether the twin Axes is drawn in front of, or behind, the -original Axes. For example, pass ``delta_zorder=-1`` to easily draw a twin Axes -behind the main Axes. - -In addition, Matplotlib now automatically manages background patch visibility -for each group of twinned Axes so that only the bottom-most Axes in the group -has a visible background patch (respecting ``frameon``). diff --git a/doc/release/next_whats_new/type1_subset.rst b/doc/release/next_whats_new/type1_subset.rst deleted file mode 100644 index b0ab0a4337e6..000000000000 --- a/doc/release/next_whats_new/type1_subset.rst +++ /dev/null @@ -1,9 +0,0 @@ -PDF files created with usetex now embed subsets of Type 1 fonts ---------------------------------------------------------------- - -When using the PDF backend with the usetex feature, -Matplotlib calls TeX to render the text and formulas in the figure. -The fonts that get used are usually "Type 1" fonts. -They used to be embedded in full -but are now limited to the glyphs that are actually used in the figure. -This reduces the size of the resulting PDF files. diff --git a/doc/release/next_whats_new/underline-23616.rst b/doc/release/next_whats_new/underline-23616.rst deleted file mode 100644 index 184c588b842c..000000000000 --- a/doc/release/next_whats_new/underline-23616.rst +++ /dev/null @@ -1,12 +0,0 @@ -Underlining text while using Mathtext -------------------------------------- - -Mathtext now supports the ``\underline`` command. - -.. code-block:: python - - import matplotlib.pyplot as plt - - plt.text(0.4, 0.7, r'This is $\underline{underlined}$ text.') - plt.text(0.4, 0.3, r'So is $\underline{\mathrm{this}}$.') - plt.show() diff --git a/doc/release/next_whats_new/updated_borderpad_parameter.rst b/doc/release/next_whats_new/updated_borderpad_parameter.rst deleted file mode 100644 index 5acf075f7b51..000000000000 --- a/doc/release/next_whats_new/updated_borderpad_parameter.rst +++ /dev/null @@ -1,18 +0,0 @@ -``borderpad`` accepts a tuple for separate x/y padding -------------------------------------------------------- - -The ``borderpad`` parameter used for placing anchored artists (such as inset axes) now accepts a tuple of ``(x_pad, y_pad)``. - -This allows for specifying separate padding values for the horizontal and -vertical directions, providing finer control over placement. For example, when -placing an inset in a corner, one might want horizontal padding to avoid -overlapping with the main plot's axis labels, but no vertical padding to keep -the inset flush with the plot area edge. - -Example usage with :func:`~mpl_toolkits.axes_grid1.inset_locator.inset_axes`: - -.. code-block:: python - - ax_inset = inset_axes( - ax, width="30%", height="30%", loc='upper left', - borderpad=(4, 0)) diff --git a/doc/release/next_whats_new/violin_stats.rst b/doc/release/next_whats_new/violin_stats.rst deleted file mode 100644 index a764db01da59..000000000000 --- a/doc/release/next_whats_new/violin_stats.rst +++ /dev/null @@ -1,31 +0,0 @@ -``violin_stats`` simpler *method* parameter -------------------------------------------- - -The *method* parameter of `~.cbook.violin_stats` may now be specified as tuple of -strings, and has a new default ``("GaussianKDE", "scott")``. Calling -`~.cbook.violin_stats` followed by `~.Axes.violin` is therefore now equivalent to -calling `~.Axes.violinplot`. - -.. plot:: - :include-source: true - :alt: Example showing violin_stats followed by violin gives the same result as violinplot - - import matplotlib.pyplot as plt - from matplotlib.cbook import violin_stats - import numpy as np - - rng = np.random.default_rng(19680801) - data = rng.normal(size=(10, 3)) - - fig, (ax1, ax2) = plt.subplots(ncols=2, layout='constrained', figsize=(6.4, 3.5)) - - # Create the violin plot in one step - ax1.violinplot(data) - ax1.set_title('One Step') - - # Process the data and then create the violin plot - vstats = violin_stats(data) - ax2.violin(vstats) - ax2.set_title('Two Steps') - - plt.show() diff --git a/doc/release/next_whats_new/violinplot_colors.rst b/doc/release/next_whats_new/violinplot_colors.rst deleted file mode 100644 index 179f868c4288..000000000000 --- a/doc/release/next_whats_new/violinplot_colors.rst +++ /dev/null @@ -1,8 +0,0 @@ -``violinplot`` now accepts color arguments -------------------------------------------- - -`~.Axes.violinplot` and `~.Axes.violin` now accept ``facecolor`` and -``linecolor`` as input arguments. This means that users can set the color of -violinplots as they make them, rather than setting the color of individual -objects afterwards. It is possible to pass a single color to be used for all -violins, or pass a sequence of colors. diff --git a/doc/release/next_whats_new/webagg_capture_scroll.rst b/doc/release/next_whats_new/webagg_capture_scroll.rst deleted file mode 100644 index 106e1ebdf36b..000000000000 --- a/doc/release/next_whats_new/webagg_capture_scroll.rst +++ /dev/null @@ -1,7 +0,0 @@ -WebAgg scroll capture control -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The WebAgg backend now provides the ability to capture scroll events to prevent -page scrolling when interacting with plots. This can be enabled or disabled via -the new `.FigureCanvasWebAggCore.set_capture_scroll` and -`.FigureCanvasWebAggCore.get_capture_scroll` methods. diff --git a/doc/release/next_whats_new/xtick_ytick_rotation_modes.rst b/doc/release/next_whats_new/xtick_ytick_rotation_modes.rst deleted file mode 100644 index 56286824ada5..000000000000 --- a/doc/release/next_whats_new/xtick_ytick_rotation_modes.rst +++ /dev/null @@ -1,28 +0,0 @@ -``xtick`` and ``ytick`` rotation modes --------------------------------------- - -A new feature has been added for handling rotation of xtick and ytick -labels more intuitively. The new `rotation modes ` -"xtick" and "ytick" automatically adjust the alignment of rotated tick labels, -so that the text points towards their anchor point, i.e. ticks. This works for -all four sides of the plot (bottom, top, left, right), reducing the need for -manual adjustments when rotating labels. - -.. plot:: - :include-source: true - :alt: Example of rotated xtick and ytick labels. - - import matplotlib.pyplot as plt - - fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(7, 3.5), layout='constrained') - - pos = range(5) - labels = ['label'] * 5 - ax1.set_xticks(pos, labels, rotation=-45, rotation_mode='xtick') - ax1.set_yticks(pos, labels, rotation=45, rotation_mode='ytick') - ax2.xaxis.tick_top() - ax2.set_xticks(pos, labels, rotation=-45, rotation_mode='xtick') - ax2.yaxis.tick_right() - ax2.set_yticks(pos, labels, rotation=45, rotation_mode='ytick') - - plt.show() diff --git a/doc/release/next_whats_new/zoom_boxes.rst b/doc/release/next_whats_new/zoom_boxes.rst deleted file mode 100644 index 8cc0cc1645a3..000000000000 --- a/doc/release/next_whats_new/zoom_boxes.rst +++ /dev/null @@ -1,4 +0,0 @@ -Consistent zoom boxes ---------------------- - -Zooming now has a consistent dashed box style across all backends. diff --git a/doc/release/prev_whats_new/whats_new_3.10.0.rst b/doc/release/prev_whats_new/whats_new_3.10.0.rst index 232ab6036100..c5f6d0ed9861 100644 --- a/doc/release/prev_whats_new/whats_new_3.10.0.rst +++ b/doc/release/prev_whats_new/whats_new_3.10.0.rst @@ -5,7 +5,7 @@ What's new in Matplotlib 3.10.0 (December 13, 2024) =================================================== For a list of all of the issues and pull requests since the last revision, see the -:ref:`github-stats`. +:ref:`github-stats-3_10_0`. .. contents:: Table of Contents :depth: 4 diff --git a/doc/release/prev_whats_new/whats_new_3.11.0.rst b/doc/release/prev_whats_new/whats_new_3.11.0.rst new file mode 100644 index 000000000000..d48a9854e302 --- /dev/null +++ b/doc/release/prev_whats_new/whats_new_3.11.0.rst @@ -0,0 +1,1250 @@ +============================================== +What's new in Matplotlib 3.11.0 (May 15, 2026) +============================================== + +For a list of all of the issues and pull requests since the last revision, see the +:ref:`github-stats`. + +.. contents:: Table of Contents + :depth: 4 + +.. toctree:: + :maxdepth: 4 + +Figure creation / management +============================ + +Figures can be attached to and removed from pyplot +-------------------------------------------------- + +Figures can now be attached to and removed from management through pyplot, which in the +background also means a less strict coupling to backends. + +In particular, standalone figures (created with the `.Figure` constructor) can now be +registered with the `.pyplot` module by calling ``plt.figure(fig)``. This allows to show +them with ``plt.show()`` as you would do with any figure created with pyplot factory +methods such as ``plt.figure()`` or ``plt.subplots()``. + +When closing a shown figure window, the related figure is reset to the standalone state, +i.e. it's not visible to pyplot anymore, but if you still hold a reference to it, you +can continue to work with it (e.g. do ``fig.savefig()``, or re-add it to pyplot with +``plt.figure(fig)`` and then show it again). + +The following is now possible - though the example is exaggerated to show what's +possible. In practice, you'll stick with much simpler versions for better consistency :: + + import matplotlib.pyplot as plt + from matplotlib.figure import Figure + + # Create a standalone figure + fig = Figure() + ax = fig.add_subplot() + ax.plot([1, 2, 3], [4, 5, 6]) + + # Register it with pyplot + plt.figure(fig) + + # Modify the figure through pyplot + plt.xlabel("x label") + + # Show the figure + plt.show() + + # Close the figure window through the GUI + + # Continue to work on the figure + fig.savefig("my_figure.png") + ax.set_ylabel("y label") + + # Re-register the figure and show it again + plt.figure(fig) + plt.show() + +Technical detail: Standalone figures use `.FigureCanvasBase` as canvas. This is replaced +by a backend-dependent subclass when registering with pyplot, and is reset to +`.FigureCanvasBase` when the figure is closed. `.Figure.savefig` uses the current canvas +to save the figure (if possible). Since `.FigureCanvasBase` can not render the figure, +when saving the figure, it will fallback to a suitable canvas subclass, e.g. +`.FigureCanvasAgg` for raster outputs such as png. Any Agg-based backend will create the +same file output. However, there may be slight differences for non-Agg backends; e.g. if +you use "GTK4Cairo" as interactive backend, ``fig.savefig("file.png")`` may create a +slightly different image depending on whether the figure is registered with pyplot or +not. In general, you should not store a reference to the canvas, but rather always +obtain it from the figure with ``fig.canvas``. This will return the current canvas, +which is either the original `.FigureCanvasBase` or a backend-dependent subclass, +depending on whether the figure is registered with pyplot or not. Additionally, the +swapping of the canvas currently does not play well with blitting of matplotlib widgets; +in such cases either deactivate blitting or do not continue to use the figure (e.g. +saving it after closing the window). + +Figure size units +----------------- + +When creating figures, it is now possible to define figure sizes in cm or pixel. + +Up to now the figure size is specified via ``plt.figure(..., figsize=(6, 4))``, and the +given numbers are interpreted as inches. It is now possible to add a unit string to the +tuple, i.e. ``plt.figure(..., figsize=(600, 400, "px"))``. Supported unit strings are +"in", "cm", "px". + +Partial ``figsize`` specification at figure creation +---------------------------------------------------- + +Figure creation now accepts a single ``None`` in ``figsize``. Passing ``(None, h)`` uses +the default width from :rc:`figure.figsize`, and passing ``(w, None)`` uses the default +height. Passing ``(None, None)`` is invalid and raises a `ValueError`. + +For example:: + + import matplotlib.pyplot as plt + fig = plt.figure(figsize=(None, 4)) + +Resetting the subplot parameters for figure.clear() +--------------------------------------------------- + +When calling `.Figure.clear()` the settings for `.gridspec.SubplotParams` are restored +to the default values. + +`~.SubplotParams.to_dict` is a new method to get the subplot parameters as a dict, and +`~.SubplotParams.reset` resets the parameters to the defaults. + +Plotting methods +================ + +Grouped bar charts +------------------ + +The new method `~.Axes.grouped_bar()` simplifies the creation of grouped bar charts +significantly. It supports different input data types (lists of datasets, dicts of +datasets, data in 2D arrays, pandas DataFrames), and allows for easy customization of +placement via controllable distances between bars and between bar groups. + +Example: + +.. plot:: + :include-source: true + :alt: Diagram of a grouped bar chart of 3 datasets with 2 categories. + + import matplotlib.pyplot as plt + + categories = ['A', 'B'] + datasets = { + 'dataset 0': [1, 11], + 'dataset 1': [3, 13], + 'dataset 2': [5, 15], + } + + fig, ax = plt.subplots() + ax.grouped_bar(datasets, tick_labels=categories) + ax.legend() + +``broken_barh()`` vertical alignment though ``align`` parameter +--------------------------------------------------------------- + +`~.Axes.broken_barh` now supports vertical alignment of the bars through the ``align`` +parameter. + +``hist()`` supports a single color for multiple datasets +-------------------------------------------------------- + +It is now possible to pass a single *color* value to `~.Axes.hist()`. This value is +applied to all datasets. + +Stackplot styling +----------------- + +`~.Axes.stackplot` now accepts sequences for the style parameters *facecolor*, +*edgecolor*, *linestyle*, and *linewidth*, similar to how the *hatch* parameter is +already handled. + +Streamplot integration control +------------------------------ + +Two new options have been added to the `~.axes.Axes.streamplot` function that give the +user better control of the streamline integration. The first is called +``integration_max_step_scale`` and multiplies the default max step computed by the +integrator. The second is called ``integration_max_error_scale`` and multiplies the +default max error set by the integrator. Values for these parameters between zero and +one reduce (tighten) the max step or error to improve streamline accuracy by performing +more computation. Values greater than one increase (loosen) the max step or error to +reduce computation time at the cost of lower streamline accuracy. + +The integrator defaults are both hand-tuned values and may not be applicable to all +cases, so this allows customizing the behavior to specific use cases. Modifying only +``integration_max_step_scale`` has proved effective, but it may be useful to control the +error as well. + +Multiple arrows on a streamline +------------------------------- + +A new ``num_arrows`` argument has been added to `~matplotlib.axes.Axes.streamplot` that +allows more than one arrow to be added to each streamline: + +.. plot:: + :include-source: true + :alt: One chart showing a streamplot. Each streamline has three arrows. + + import matplotlib.pyplot as plt + import numpy as np + + w = 3 + Y, X = np.mgrid[-w:w:100j, -w:w:100j] + U = -1 - X**2 + Y + V = 1 + X - Y**2 + + fig, ax = plt.subplots() + ax.streamplot(X, Y, U, V, num_arrows=3) + + plt.show() + +``violinplot`` now accepts color arguments +------------------------------------------ + +`~.Axes.violinplot` and `~.Axes.violin` now accept ``facecolor`` and ``linecolor`` as +input arguments. This means that users can set the color of violinplots as they make +them, rather than setting the color of individual objects afterwards. It is possible to +pass a single color to be used for all violins, or pass a sequence of colors. + +Annotations +=========== + +``bar_label`` supports individual padding per label +--------------------------------------------------- + +``bar_label`` will now accept both a float value or an array-like for padding. The +array-like defines the padding for each label individually. + +Adding labels to pie chart wedges +--------------------------------- + +The new `~.Axes.pie_label` method adds a label to each wedge in a pie chart created with +`~.Axes.pie`. It can take + +* a list of strings, similar to the existing *labels* parameter of `~.Axes.pie` +* a format string similar to the existing *autopct* parameter of `~.Axes.pie` except + that it uses the `str.format` method and it can handle absolute values as well as + fractions/percentages + +For more examples, see :doc:`/gallery/pie_and_polar_charts/pie_label`. + +.. plot:: + :include-source: true + :alt: + A pie chart with three labels on each wedge, showing a food type, number, and + fraction associated with the wedge. + + import matplotlib.pyplot as plt + + data = [36, 24, 8, 12] + labels = ['spam', 'eggs', 'bacon', 'sausage'] + + fig, ax = plt.subplots() + pie = ax.pie(data) + + ax.pie_label(pie, labels, distance=1.1) + ax.pie_label(pie, '{frac:.1%}', distance=0.7) + ax.pie_label(pie, '{absval:d}', distance=0.4) + +Arrow-style sub-classes of ``BoxStyle`` support arrow head resizing +------------------------------------------------------------------- + +The new *head_width* and *head_angle* parameters to `.BoxStyle.LArrow`, +`.BoxStyle.RArrow` and `.BoxStyle.DArrow` allow for adjustment of the size and aspect +ratio of the arrow heads used. + +To give a consistent appearance across all parameter values, the default head position +(where the head starts relative to text) is slightly changed compared to the previous +hard-coded position. + +By using negative angles (or corresponding reflex angles) for *head_angle*, arrows with +'backwards' heads may be created. + +.. plot:: + :include-source: true + :alt: + Six arrow-shaped text boxes. The arrows on the left have the shaft on their + left; the arrows on the right have the shaft on the right; the arrows in the + middle have shafts on both sides. + + import matplotlib.pyplot as plt + + plt.text(0.2, 0.8, "LArrow", ha='center', size=16, + bbox=dict(boxstyle="larrow, pad=0.3, head_angle=150")) + plt.text(0.2, 0.2, "LArrow", ha='center', size=16, + bbox=dict(boxstyle="larrow, pad=0.3, head_width=0.5")) + plt.text(0.5, 0.8, "DArrow", ha='center', size=16, + bbox=dict(boxstyle="darrow, pad=0.3, head_width=3")) + plt.text(0.5, 0.2, "DArrow", ha='center', size=16, + bbox=dict(boxstyle="darrow, pad=0.3, head_width=1, head_angle=60")) + plt.text(0.8, 0.8, "RArrow", ha='center', size=16, + bbox=dict(boxstyle="rarrow, pad=0.3, head_angle=30")) + plt.text(0.8, 0.2, "RArrow", ha='center', size=16, + bbox=dict(boxstyle="rarrow, pad=0.3, head_width=2, head_angle=-90")) + + plt.show() + +``borderpad`` accepts a tuple for separate x/y padding +------------------------------------------------------- + +The ``borderpad`` parameter used for placing anchored artists (such as inset axes) now +accepts a tuple of ``(x_pad, y_pad)``. + +This allows for specifying separate padding values for the horizontal and vertical +directions, providing finer control over placement. For example, when placing an inset +in a corner, one might want horizontal padding to avoid overlapping with the main plot's +axis labels, but no vertical padding to keep the inset flush with the plot area edge. + +Example usage with :func:`~mpl_toolkits.axes_grid1.inset_locator.inset_axes`: + +.. code-block:: python + + ax_inset = inset_axes( + ax, width="30%", height="30%", loc='upper left', + borderpad=(4, 0)) + +Axes and Artists +================ + +Twin Axes ``delta_zorder`` +-------------------------- + +`~matplotlib.axes.Axes.twinx` and `~matplotlib.axes.Axes.twiny` now accept a +*delta_zorder* keyword argument, a relative offset added to the original Axes' zorder, +to control whether the twin Axes is drawn in front of, or behind, the original Axes. For +example, pass ``delta_zorder=-1`` to easily draw a twin Axes behind the main Axes. + +In addition, Matplotlib now automatically manages background patch visibility for each +group of twinned Axes so that only the bottom-most Axes in the group has a visible +background patch (respecting ``frameon``). + +``BarContainer`` properties +--------------------------- + +`.BarContainer` gained new properties to easily access coordinates of the bars: + +- `~.BarContainer.bottoms` +- `~.BarContainer.tops` +- `~.BarContainer.position_centers` + +Maximum levels on log-scaled contour plots are now respected +------------------------------------------------------------ + +When plotting contours with a log norm, passing an integer value to the ``levels`` +argument to cap the maximum number of contour levels now works as intended. + +``edgegapcolor`` for Patches +---------------------------- + +`~matplotlib.patches.Patch` now supports an *edgegapcolor* parameter, similar to the +existing *gapcolor* in `.Line2D`. This allows patches with dashed edges to display a +secondary color in the gaps, creating a "striped" edge effect. + +This is useful when drawing unfilled patches on backgrounds of unknown color, where +alternating edge colors ensure the patch boundary remains visible. + +.. plot:: + :include-source: true + :alt: + A rectangle with a dashed orange edge and blue gaps, demonstrating the + edgegapcolor feature. + + import matplotlib.pyplot as plt + from matplotlib.patches import Rectangle + + fig, ax = plt.subplots() + rect = Rectangle((0.1, 0.1), 0.6, 0.6, fill=False, + edgecolor='orange', edgegapcolor='blue', + linestyle='--', linewidth=3) + ax.add_patch(rect) + plt.show() + +Separated ``hatchcolor`` from ``edgecolor`` +------------------------------------------- + +When the *hatchcolor* parameter is specified, it will be used for the hatch. If it is +not specified, it will fall back to using :rc:`hatch.color`. The special value 'edge' +uses the patch edgecolor, with a fallback to :rc:`patch.edgecolor` if the patch +edgecolor is 'none'. Previously, hatch colors were the same as edge colors, with a +fallback to :rc:`hatch.color` if the patch did not have an edge color. + +.. plot:: + :include-source: true + :alt: + Four Rectangle patches, each displaying the color of hatches in different + specifications of edgecolor and hatchcolor. Top left has hatchcolor='black' + representing the default value when both hatchcolor and edgecolor are not set, + top right has edgecolor='blue' and hatchcolor='black' which remains when the + edgecolor is set again, bottom left has edgecolor='red' and hatchcolor='orange' + on explicit specification and bottom right has edgecolor='green' and + hatchcolor='green' when the hatchcolor is not set. + + import matplotlib as mpl + import matplotlib.pyplot as plt + from matplotlib.patches import Rectangle + + fig, ax = plt.subplots() + + # In this case, hatchcolor is orange + patch1 = Rectangle((0.1, 0.1), 0.3, 0.3, edgecolor='red', linewidth=2, + hatch='//', hatchcolor='orange') + ax.add_patch(patch1) + + # When hatchcolor is not specified, it matches edgecolor + # In this case, hatchcolor is green + patch2 = Rectangle((0.6, 0.1), 0.3, 0.3, edgecolor='green', linewidth=2, + hatch='//', facecolor='none') + ax.add_patch(patch2) + + # If both hatchcolor and edgecolor are not specified + # it will default to the 'patch.edgecolor' rcParam, which is black by default + # In this case, hatchcolor is black + patch3 = Rectangle((0.1, 0.6), 0.3, 0.3, hatch='//') + ax.add_patch(patch3) + + # When using `hatch.color` in the `rcParams` + # edgecolor will now not overwrite hatchcolor + # In this case, hatchcolor is black + with plt.rc_context({'hatch.color': 'black'}): + patch4 = Rectangle((0.6, 0.6), 0.3, 0.3, edgecolor='blue', linewidth=2, + hatch='//', facecolor='none') + + # hatchcolor is black (it uses the `hatch.color` rcParam value) + patch4.set_edgecolor('blue') + # hatchcolor is still black (here, it does not update when edgecolor changes) + ax.add_patch(patch4) + + ax.annotate("hatchcolor = 'orange'", + xy=(.5, 1.03), xycoords=patch1, ha='center', va='bottom') + ax.annotate("hatch color unspecified\nedgecolor='green'", + xy=(.5, 1.03), xycoords=patch2, ha='center', va='bottom') + ax.annotate("hatch color unspecified\nusing patch.edgecolor", + xy=(.5, 1.03), xycoords=patch3, ha='center', va='bottom') + ax.annotate("hatch.color='black'", + xy=(.5, 1.03), xycoords=patch4, ha='center', va='bottom') + + plt.show() + +For collections, a sequence of colors can be passed to the *hatchcolor* parameter which +will be cycled through for each hatch, similar to *facecolor* and *edgecolor*. + +Previously, if *edgecolor* was not specified, the hatch color would fall back to +:rc:`patch.edgecolor`, but the alpha value would default to **1.0**, regardless of the +alpha value of the collection. This behavior has been changed such that, if both +*hatchcolor* and *edgecolor* are not specified, the hatch color will fall back to +'patch.edgecolor' with the alpha value of the collection. + +.. plot:: + :include-source: true + :alt: + A random scatter plot with hatches on the markers. The hatches are colored in + blue, orange, and green, respectively. After the first three markers, the colors + are cycled through again. + + import matplotlib.pyplot as plt + import numpy as np + + np.random.seed(19680801) + + fig, ax = plt.subplots() + + x = [29, 36, 41, 25, 32, 70, 62, 58, 66, 80, 58, 68, 62, 37, 48] + y = [82, 76, 48, 53, 62, 70, 84, 68, 55, 75, 29, 25, 12, 17, 20] + colors = ['tab:blue'] * 5 + ['tab:orange'] * 5 + ['tab:green'] * 5 + + ax.scatter( + x, + y, + s=800, + hatch="xxxx", + hatchcolor=colors, + facecolor="none", + edgecolor="black", + ) + + plt.show() + +Axis and Ticks +============== + +Standard getters/setters for axis inversion state +------------------------------------------------- + +Whether an axis is inverted can now be queried and set using the `.axes.Axes` getters +`~.Axes.get_xinverted`/`~.Axes.get_yinverted` and setters +`~.Axes.set_xinverted`/`~.Axes.set_yinverted`. + +The previously existing methods (`.Axes.xaxis_inverted`, `.Axes.invert_xaxis`) are now +discouraged (but not deprecated) due to their non-standard naming and behavior. + +``xtick`` and ``ytick`` rotation modes +-------------------------------------- + +A new feature has been added for handling rotation of xtick and ytick labels more +intuitively. The new `rotation modes ` "xtick" +and "ytick" automatically adjust the alignment of rotated tick labels, so that the text +points towards their anchor point, i.e. ticks. This works for all four sides of the plot +(bottom, top, left, right), reducing the need for manual adjustments when rotating +labels. + +.. plot:: + :include-source: true + :alt: Example of rotated xtick and ytick labels. + + import matplotlib.pyplot as plt + + fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(7, 3.5), layout='constrained') + + pos = range(5) + labels = ['label'] * 5 + ax1.set_xticks(pos, labels, rotation=-45, rotation_mode='xtick') + ax1.set_yticks(pos, labels, rotation=45, rotation_mode='ytick') + ax2.xaxis.tick_top() + ax2.set_xticks(pos, labels, rotation=-45, rotation_mode='xtick') + ax2.yaxis.tick_right() + ax2.set_yticks(pos, labels, rotation=45, rotation_mode='ytick') + + plt.show() + +Improved selection of log-scale ticks +------------------------------------- + +The algorithm for selecting log-scale ticks (on powers of ten) has been improved. In +particular, it will now always draw as many ticks as possible (e.g., it will not draw a +single tick if it was possible to fit two ticks); if subsampling ticks, it will prefer +putting ticks on integer multiples of the subsampling stride (e.g., it prefers putting +ticks at 10\ :sup:`0`, 10\ :sup:`3`, 10\ :sup:`6` rather than 10\ :sup:`1`, 10\ +:sup:`4`, 10\ :sup:`7`) if this results in the same number of ticks at the end; and it +is now more robust against floating-point calculation errors. + +Colors and colormaps +==================== + +Okabe-Ito accessible color sequence +----------------------------------- + +Matplotlib now includes the `Okabe-Ito color sequence`_. Its colors remain +distinguishable for common forms of color-vision deficiency and when printed. + +.. _Okabe-Ito color sequence: https://jfly.uni-koeln.de/color/#pallet + +For example, to set it as the default colormap for your plots and image-like artists, +use: + +.. code-block:: python + + import matplotlib.pyplot as plt + from cycler import cycler + + plt.rcParams['axes.prop_cycle'] = cycler('color', plt.colormaps['okabe_ito'].colors) + plt.rcParams['image.cmap'] = 'okabe_ito' + +Or, when creating plots, you can pass it explicitly: + +.. plot:: + + import matplotlib.pyplot as plt + + colors = plt.colormaps['okabe_ito'].colors + x = range(5) + for i, c in enumerate(colors): + plt.plot(x, [v*(i+1) for v in x], color=c, label=f'line {i}') + plt.legend() + plt.show() + +Six and eight color Petroff color cycles +---------------------------------------- + +The six and eight color accessible Petroff color cycles are named 'petroff6' and +'petroff8'. They compliment the existing 'petroff10' color cycle, added in `Matplotlib +3.10.0`_ + +For more details see `Petroff, M. A.: "Accessible Color Sequences for Data +Visualization" `_. To load the 'petroff6' color cycle +in place of the default:: + + import matplotlib.pyplot as plt + plt.style.use('petroff6') + +or to load the 'petroff8' color cycle:: + + import matplotlib.pyplot as plt + plt.style.use('petroff8') + +.. _Matplotlib 3.10.0: https://matplotlib.org/stable/users/prev_whats_new/whats_new_3.10.0.html#new-more-accessible-color-cycle + +Setting the default color cycle to a named color sequence +--------------------------------------------------------- + +The default color cycle may now be configured in the ``matplotlibrc`` file or a style +file to use any of the :doc:`/gallery/color/color_sequences`. For example + +.. code-block:: none + + axes.prop_cycle : cycler(color='Accent') + +Colormaps support giving colors for bad, under and over values on creation +-------------------------------------------------------------------------- + +Colormaps gained keyword arguments ``bad``, ``under``, and ``over`` to specify these +values on creation. Previously, these values would have to be set afterwards using one +of `~.Colormap.set_bad`, `~.Colormap.set_under`, `~.Colormap.set_bad`, +`~.Colormap.set_extremes`, `~.Colormap.with_extremes`. + +It is recommended to use the new functionality, e.g.:: + + cmap = ListedColormap(colors, bad="red", under="darkblue", over="purple") + +instead of:: + + cmap = ListedColormap(colors).with_extremes( + bad="red", under="darkblue", over="purple") + +or:: + + cmap = ListedColormap(colors) + cmap.set_bad("red") + cmap.set_under("darkblue") + cmap.set_over("purple") + +Tuning transparency of colormaps +-------------------------------- + +The new method `.Colormap.with_alpha` allows to create a new colormap with the same +color values but a new uniform alpha value. This is handy if you want to modify only the +transparency of mapped colors for an Artist. + +Fonts and Text +============== + +Complex text layout with libraqm +-------------------------------- + +Text support has been extended to include complex text layout. This support includes: + +1. Languages that require advanced layout, such as Arabic or Hebrew. +2. Text that mixes left-to-right and right-to-left languages. + + .. plot:: + :show-source-link: False + + text = 'Here is some رَقْم in اَلْعَرَبِيَّةُ' + fig = plt.figure(figsize=(6, 1)) + fig.text(0.5, 0.5, text, size=32, ha='center', va='center') + +3. Ligatures that combine several adjacent characters for improved legibility. + + .. plot:: + :show-source-link: False + + text = 'f\N{Hair Space}f\N{Hair Space}i \N{Rightwards Arrow} ffi' + fig = plt.figure(figsize=(3, 1)) + fig.text(0.5, 0.5, text, size=32, ha='center', va='center') + +4. Combining multiple or double-width diacritics. + + .. plot:: + :show-source-link: False + + text = ( + 'a\N{Combining Circumflex Accent}\N{Combining Double Tilde}' + 'c\N{Combining Diaeresis}') + text = ' + '.join( + c if c in 'ac' else f'\N{Dotted Circle}{c}' + for c in text) + f' \N{Rightwards Arrow} {text}' + fig = plt.figure(figsize=(6, 1)) + fig.text(0.5, 0.5, text, size=32, ha='center', va='center', + # Builtin DejaVu Sans doesn't support multiple diacritics. + family=['Noto Sans', 'DejaVu Sans']) + +Note, all advanced features require corresponding font support, and may require +additional fonts over the builtin DejaVu Sans. + +Specifying font feature tags +---------------------------- + +OpenType fonts may support feature tags that specify alternate glyph shapes or +substitutions to be made optionally. The text API now supports setting a list of feature +tags to be used with the associated font. Feature tags can be set/get with: + +- `matplotlib.text.Text.set_fontfeatures` / `matplotlib.text.Text.get_fontfeatures` +- Any API that creates a `.Text` object by passing the *fontfeatures* argument (e.g., + ``plt.xlabel(..., fontfeatures=...)``) + +Font feature strings are eventually passed to HarfBuzz, and so all `string formats +supported by hb_feature_from_string() +`__ are +supported. Note though that subranges are not explicitly supported and behaviour may +change in the future. + +For example, the default font ``DejaVu Sans`` enables Standard Ligatures (the ``'liga'`` +tag) by default, and also provides optional Discretionary Ligatures (the ``dlig`` tag.) +These may be toggled with ``+`` or ``-``. + +.. plot:: + :include-source: + + fig = plt.figure(figsize=(7, 3)) + + fig.text(0.5, 0.85, 'Ligatures', fontsize=40, horizontalalignment='center') + + # Default has Standard Ligatures (liga). + fig.text(0, 0.6, 'Default: fi ffi fl st', fontsize=40) + + # Disable Standard Ligatures with -liga. + fig.text(0, 0.35, 'Disabled: fi ffi fl st', fontsize=40, + fontfeatures=['-liga']) + + # Enable Discretionary Ligatures with dlig. + fig.text(0, 0.1, 'Discretionary: fi ffi fl st', fontsize=40, + fontfeatures=['dlig']) + +Available font feature tags may be found at +https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist + +Specifying text language +------------------------ + +OpenType fonts may support language systems which can be used to select different +typographic conventions, e.g., localized variants of letters that share a single Unicode +code point, or different default font features. The text API now supports setting a +language to be used and may be set/get with: + +- `matplotlib.text.Text.set_language` / `matplotlib.text.Text.get_language` +- Any API that creates a `.Text` object by passing the *language* argument (e.g., + ``plt.xlabel(..., language=...)``) + +The language of the text must be in a format accepted by libraqm, namely `a BCP47 +language code `_. If None or +unset, then no particular language will be implied, and default font settings will be +used. + +For example, Matplotlib's default font ``DejaVu Sans`` supports language-specific glyphs +in the Serbian and Macedonian languages in the Cyrillic alphabet (vs Russian), or the +Sámi family of languages in the Latin alphabet (vs English). + +.. plot:: + :include-source: + + fig = plt.figure(figsize=(7, 3)) + + char = '\U00000431' + fig.text(0.5, 0.8, f'\\U{ord(char):08x}', fontsize=40, horizontalalignment='center') + fig.text(0, 0.6, f'Serbian: {char}', fontsize=40, language='sr') + fig.text(1, 0.6, f'Russian: {char}', fontsize=40, language='ru', + horizontalalignment='right') + + char = '\U0000014a' + fig.text(0.5, 0.3, f'\\U{ord(char):08x}', fontsize=40, horizontalalignment='center') + fig.text(0, 0.1, f'Inari Sámi: {char}', fontsize=40, language='smn') + fig.text(1, 0.1, f'English: {char}', fontsize=40, language='en', + horizontalalignment='right') + +Missing glyphs use Last Resort font +----------------------------------- + +Most fonts do not have 100% character coverage, and will fall back to a "not found" +glyph for characters that are not provided. Often, this glyph will be minimal (e.g., the +default DejaVu Sans "not found" glyph is just a rectangle.) Such minimal glyphs provide +no context as to the characters that are missing. + +Now, missing glyphs will fall back to the `Last Resort font +`__ produced by the Unicode Consortium. +This special-purpose font provides glyphs that represent types of Unicode characters. +These glyphs show a representative character from the missing Unicode block, and at +larger sizes, more context to help determine which character and font are needed. + +To disable this fallback behaviour, set :rc:`font.enable_last_resort` to ``False``. + +.. plot:: + :alt: + An example of missing glyph behaviour, the first glyph from Bengali script, + second glyph from Hiragana, and the last glyph from the Unicode Private Use + Area. Multiple lines repeat the text with increasing font size from top to + bottom. + + text_raw = r"'\N{Bengali Digit Zero}\N{Hiragana Letter A}\ufdd0'" + text = eval(text_raw) + sizes = [ + (0.85, 8), + (0.80, 10), + (0.75, 12), + (0.70, 16), + (0.63, 20), + (0.55, 24), + (0.45, 32), + (0.30, 48), + (0.10, 64), + ] + + fig = plt.figure() + fig.text(0.01, 0.90, f'Input: {text_raw}') + for y, size in sizes: + fig.text(0.01, y, f'{size}pt:{text}', fontsize=size) + +Fonts addressable by all their SFNT family names +------------------------------------------------ + +Fonts can now be selected by any of the family names they advertise in the OpenType name +table, not just the one FreeType reports as the primary family name. + +Some fonts store different family names on different platforms or in different +name-table entries. For example, Ubuntu Light stores ``"Ubuntu"`` in the +Macintosh-platform Name ID 1 slot (which FreeType uses as the primary name) and +``"Ubuntu Light"`` in the Microsoft-platform Name ID 1 slot. Previously only the +FreeType-derived name was registered, requiring an obscure weight-based workaround:: + + # Previously required + matplotlib.rcParams['font.family'] = 'Ubuntu' + matplotlib.rcParams['font.weight'] = 300 + +All name-table entries that describe a family — Name ID 1 on both platforms, the +Typographic Family (Name ID 16), and the WWS Family (Name ID 21) — are now registered as +separate entries in the `~matplotlib.font_manager.FontManager`, so any of those names +can be used directly:: + + matplotlib.rcParams['font.family'] = 'Ubuntu Light' + +Support for loading TrueType Collection fonts +--------------------------------------------- + +TrueType Collection fonts (commonly found as files with a ``.ttc`` extension) are now +supported. Namely, Matplotlib will include these file extensions in its scan for system +fonts, and will add all sub-fonts to its list of available fonts (i.e., the list from +`~.font_manager.get_font_names`). + +From most high-level API, this means you should be able to specify the name of any +sub-font in a collection just as you would any other font. Note that at this time, there +is no way to specify the entire collection with any sort of automated selection of the +internal sub-fonts. + +In the low-level API, to ensure backwards-compatibility while facilitating this new +support, a `.FontPath` instance (comprised of a font path and a sub-font index, with +behaviour similar to a `str`) may be passed to the font management API in place of a +simple `os.PathLike` path. Any font management API that previously returned a string +path now returns a `.FontPath` instance instead. + +New environment variable to ignore system fonts +----------------------------------------------- + +System fonts may be ignored by setting the :envvar:`MPL_IGNORE_SYSTEM_FONTS`; this +suppresses searching for system fonts (in known directories or via some +platform-specific subprocess) as well as limiting the results from +`.FontManager.findfont`. + +Mathtext distinguishes *italic* and *normal* font +------------------------------------------------- + +Matplotlib's lightweight TeX expression parser (``usetex=False``) now distinguishes +between *italic* and *normal* math fonts to closer replicate the behaviour of LaTeX. The +normal math font is selected by default in math environment (unless the rcParam +``mathtext.default`` is overwritten) but can be explicitly set with the new +``\mathnormal`` command. Italic font is selected with ``\mathit``. The main difference +is that *italic* produces italic digits, whereas *normal* produces upright digits. +Previously, it was not possible to typeset italic digits. Note that ``normal`` now +corresponds to what used to be ``it``, whereas ``it`` now renders all characters italic. +**Important**: In case the default mathematics font is overwritten by setting +``mathtext.default: it`` in ``matplotlibrc``, it must be either commented out or changed +to ``mathtext.default: normal`` to preserve its behaviour. Otherwise, all alphanumeric +characters, including digits, are rendered italic. + +One difference to traditional LaTeX is that LaTeX further distinguishes between *normal* +(``\mathnormal``) and *default math*, where the default uses roman digits and normal +uses oldstyle digits. This distinction is no longer present with modern LaTeX engines +and unicode-math nor in Matplotlib. + +mathtext support for ``\phantom``, ``\llap``, ``\rlap`` +------------------------------------------------------- + +mathtext gained support for the TeX macros ``\phantom``, ``\llap``, and ``\rlap``. +``\phantom`` allows to occupy some space on the canvas as if some text was being +rendered, without actually rendering that text, whereas ``\llap`` and ``\rlap`` allows +to render some text on the canvas while pretending that it occupies no space. +Altogether these macros allow some finer control of text alignments. + +See https://www.tug.org/TUGboat/tb22-4/tb72perlS.pdf for a detailed description of these +macros. + +Underlining text while using Mathtext +------------------------------------- + +Mathtext now supports the ``\underline`` command. + +.. code-block:: python + + import matplotlib.pyplot as plt + + plt.text(0.4, 0.7, r'This is $\underline{underlined}$ text.') + plt.text(0.4, 0.3, r'So is $\underline{\mathrm{this}}$.') + plt.show() + +Improved font embedding in PDF +------------------------------ + +Both Type 3 and Type 42 fonts (see :ref:`fonts` for more details) are now embedded into +PDFs without limitation. Fonts may be split into multiple embedded subsets in order to +satisfy format limits. Additionally, a corrected Unicode mapping is added for each. + +This means that *all* text should now be selectable and copyable in PDF viewers that +support doing so. + +PDF files created with usetex now embed subsets of Type 1 fonts +--------------------------------------------------------------- + +When using the PDF backend with the usetex feature, Matplotlib calls TeX to render the +text and formulas in the figure. The fonts that get used are usually "Type 1" fonts. +They used to be embedded in full but are now limited to the glyphs that are actually +used in the figure. This reduces the size of the resulting PDF files. + +rcParams improvements +===================== + +Separate styling options for major/minor grid line in rcParams +-------------------------------------------------------------- + +Using :rc:`grid.major.*` or :rc:`grid.minor.*` will overwrite the value in :rc:`grid.*` +for the major and minor gridlines, respectively. + +.. plot:: + :include-source: true + :alt: Modifying the gridlines using the new options `rcParams` + + import matplotlib as mpl + import matplotlib.pyplot as plt + + + # Set visibility for major and minor gridlines + mpl.rcParams["axes.grid"] = True + mpl.rcParams["ytick.minor.visible"] = True + mpl.rcParams["xtick.minor.visible"] = True + mpl.rcParams["axes.grid.which"] = "both" + + # Using old values to set both major and minor properties + mpl.rcParams["grid.color"] = "red" + mpl.rcParams["grid.linewidth"] = 1 + + # Overwrite some values for major and minor separately + mpl.rcParams["grid.major.color"] = "black" + mpl.rcParams["grid.major.linewidth"] = 2 + mpl.rcParams["grid.minor.linestyle"] = ":" + mpl.rcParams["grid.minor.alpha"] = 0.6 + + plt.plot([0, 1], [0, 1]) + + plt.show() + +``axes.prop_cycle`` rcParam security improvements +------------------------------------------------- + +The ``axes.prop_cycle`` rcParam is now parsed in a safer and more restricted manner. +Only literals, ``cycler()`` and ``concat()`` calls, the operators ``+`` and ``*``, and +slicing are allowed. All previously valid cycler strings documented at +https://matplotlib.org/cycler/ are still supported, for example: + +.. code-block:: none + + axes.prop_cycle : cycler('color', ['r', 'g', 'b']) + cycler('linewidth', [1, 2, 3]) + axes.prop_cycle : 2 * cycler('color', 'rgb') + axes.prop_cycle : concat(cycler('color', 'rgb'), cycler('color', 'cmk')) + axes.prop_cycle : cycler('color', 'rgbcmk')[:3] + +Legends +======= + +``legend.linewidth`` rcParam and parameter +------------------------------------------ + +A new rcParam ``legend.linewidth`` has been added to control the line width of the +legend's box edges. When set to ``None`` (the default), it inherits the value from +``patch.linewidth``. This allows for independent control of the legend frame line width +without affecting other elements. + +The `.Legend` constructor also accepts a new *linewidth* parameter to set the legend +frame line width directly, overriding the rcParam value. + +.. plot:: + :include-source: true + :alt: A line plot with a legend showing a thick border around the legend box. + + import matplotlib.pyplot as plt + + fig, ax = plt.subplots() + ax.plot([1, 2, 3], label='data') + ax.legend(linewidth=2.0) # Thick legend box edge + plt.show() + +``PatchCollection`` legends now supported +----------------------------------------- + +`.PatchCollection` instances now properly display in legends when given a label. +Previously, labels on `~.PatchCollection` objects were ignored by the legend system, +requiring users to create manual legend entries. + +.. plot:: + :include-source: true + :alt: + The legend entry displays a rectangle matching the visual properties (colors, + line styles, line widths) of the first patch in the collection. + + import matplotlib.pyplot as plt + import matplotlib.patches as mpatches + from matplotlib.collections import PatchCollection + + fig, ax = plt.subplots() + patches = [mpatches.Circle((0, 0), 0.1), mpatches.Rectangle((0.5, 0.5), 0.2, 0.3)] + pc = PatchCollection(patches, facecolor='blue', edgecolor='black', label='My patches') + ax.add_collection(pc) + ax.legend() # Now displays the label "My patches" + plt.show() + +Widgets and Interactivity +========================= + +Zooming using mouse wheel +------------------------- + +``Ctrl+MouseWheel`` can be used to zoom in the plot windows. Additionally, +``x+MouseWheel`` zooms only the x-axis and ``y+MouseWheel`` zooms only the y-axis. + +The zoom focusses on the mouse pointer. With ``Ctrl``, the axes aspect ratio is kept; +with ``x`` or ``y``, only the respective axis is scaled. + +Zooming is currently only supported on rectilinear Axes. + +Consistent zoom boxes +--------------------- + +Zooming now has a consistent dashed box style across all backends. + +RadioButtons and CheckButtons widgets support flexible layouts +-------------------------------------------------------------- + +The `.widgets.RadioButtons` and `.widgets.CheckButtons` widgets now support arranging +buttons in different layouts via the new *layout* parameter. You can arrange buttons +vertically (default), horizontally, or in a 2D grid by passing a ``(rows, cols)`` tuple. + +See :doc:`/gallery/widgets/radio_buttons_grid` for a ``(rows, cols)`` example. + +.. plot:: + :include-source: true + :alt: Multiple sine waves with checkboxes to toggle their visibility. + + import matplotlib.pyplot as plt + import numpy as np + from matplotlib.widgets import CheckButtons + + t = np.arange(0.0, 2.0, 0.01) + s0 = np.sin(2*np.pi*t) + s1 = np.sin(4*np.pi*t) + s2 = np.sin(6*np.pi*t) + s3 = np.sin(8*np.pi*t) + + fig, axes = plt.subplot_mosaic( + [['main'], ['buttons']], + height_ratios=[8, 1], + layout="constrained", + ) + + l0, = axes['main'].plot(t, s0, lw=2, color='red', label='2 Hz') + l1, = axes['main'].plot(t, s1, lw=2, color='green', label='4 Hz') + l2, = axes['main'].plot(t, s2, lw=2, color='blue', label='6 Hz') + l3, = axes['main'].plot(t, s3, lw=2, color='purple', label='8 Hz') + axes['main'].set_xlabel('Time (s)') + axes['main'].set_ylabel('Amplitude') + + lines_by_label = {l.get_label(): l for l in [l0, l1, l2, l3]} + + axes['buttons'].set_facecolor('0.9') + check = CheckButtons( + axes['buttons'], + labels=lines_by_label.keys(), + actives=[l.get_visible() for l in lines_by_label.values()], + layout='horizontal' + ) + + def callback(label): + ln = lines_by_label[label] + ln.set_visible(not ln.get_visible()) + fig.canvas.draw_idle() + + check.on_clicked(callback) + plt.show() + +Callable *valfmt* for ``Slider`` and ``RangeSlider`` +---------------------------------------------------- + +In addition to the existing %-format string, the *valfmt* parameter of +`~.matplotlib.widgets.Slider` and `~.matplotlib.widgets.RangeSlider` now also accepts a +callable of the form ``valfmt(val: float) -> str``. + +WebAgg scroll capture control +------------------------------ + +The WebAgg backend now provides the ability to capture scroll events to prevent page +scrolling when interacting with plots. This can be enabled or disabled via the new +`.FigureCanvasWebAggCore.set_capture_scroll` and +`.FigureCanvasWebAggCore.get_capture_scroll` methods. + +3D plotting improvements +======================== + +Non-linear scales on 3D axes +---------------------------- + +Resolving a long-standing issue, 3D axes now support non-linear axis scales such as +'log', 'symlog', 'logit', 'asinh', and custom 'function' scales, just like 2D axes. Use +`~.Axes3D.set_xscale`, `~.Axes3D.set_yscale`, and `~.Axes3D.set_zscale` to set the scale +for each axis independently. + +.. plot:: + :include-source: true + :alt: A 3D plot with a linear x-axis, logarithmic y-axis, and symlog z-axis. + + import matplotlib.pyplot as plt + import numpy as np + + # A sine chirp with increasing frequency and amplitude + x = np.linspace(0, 1, 400) # time + y = 10 ** (2 * x) # frequency, growing exponentially from 1 to 100 Hz + phase = 2 * np.pi * (10 ** (2 * x) - 1) / (2 * np.log(10)) + z = np.sin(phase) * x ** 2 * 10 # amplitude, growing quadratically + + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.plot(x, y, z) + + ax.set_xlabel('Time (linear)') + ax.set_ylabel('Frequency, Hz (log)') + ax.set_zlabel('Amplitude (symlog)') + + ax.set_yscale('log') + ax.set_zscale('symlog') + + plt.show() + +See `matplotlib.scale` for details on all available scales and their parameters. + +Snapping 3D rotation angles with Control key +-------------------------------------------- + +3D axes rotation now supports snapping to fixed angular increments when holding the +``Control`` key during mouse rotation. + +The snap step size is controlled by the new ``axes3d.snap_rotation`` rcParam (default: +5.0 degrees). Setting it to 0 disables snapping. + +For example:: + + mpl.rcParams["axes3d.snap_rotation"] = 10 + +will snap elevation, azimuth, and roll angles to multiples of 10 degrees while rotating +with the mouse. + +3D depth-shading fix +-------------------- + +Previously, a slightly buggy method of estimating the visual "depth" of 3D items could +lead to sudden and unexpected changes in transparency as the plot orientation changed. + +Now, the behavior has been made smooth and predictable. A new parameter +``depthshade_minalpha`` has also been added to allow users to set the minimum +transparency level. Depth-shading is an option for Patch3DCollections and +Path3DCollections, including 3D scatter plots. + +The default values for ``depthshade`` and ``depthshade_minalpha`` are now also controlled +via rcParams, with values of ``True`` and ``0.3`` respectively. + +A simple example: + +.. plot:: + :include-source: true + :alt: A 3D scatter plot with depth-shading enabled. + + import matplotlib.pyplot as plt + + fig = plt.figure() + ax = fig.add_subplot(projection="3d") + + X = [i for i in range(10)] + Y = [i for i in range(10)] + Z = [i for i in range(10)] + S = [(i + 1) * 400 for i in range(10)] + + ax.scatter( + xs=X, ys=Y, zs=Z, s=S, + depthshade=True, + depthshade_minalpha=0.3, + ) + ax.view_init(elev=10, azim=-150, roll=0) + + plt.show() + +3D performance improvements +--------------------------- + +Draw time for 3D plots has been improved, especially for surface and wireframe plots. +Users should see up to a 10x speedup in some cases. This should make interacting with 3D +plots much more responsive. + +Other improvements +================== + +Saving figures as GIF works again +--------------------------------- + +According to the figure documentation, the ``savefig`` method supports the GIF format +with the file extension ``.gif``. However, GIF support had been broken since Matplotlib +2.0.0. It works again. + +``CallbackRegistry.disconnect`` allows directly callbacks by function +------------------------------------------------------------------------- + +`.CallbackRegistry` now allows directly passing a function and optionally signal to +`~.CallbackRegistry.disconnect` instead of needing to track the callback ID returned by +`~.CallbackRegistry.connect`. + +.. code-block:: python + + from matplotlib.cbook import CallbackRegistry + + def my_callback(event): + print(event) + + callbacks = CallbackRegistry() + callbacks.connect('my_signal', my_callback) + + # Disconnect by function reference instead of callback ID + callbacks.disconnect('my_signal', my_callback) + +``violin_stats`` simpler *method* parameter +------------------------------------------- + +The *method* parameter of `~.cbook.violin_stats` may now be specified as tuple of +strings, and has a new default ``("GaussianKDE", "scott")``. Calling +`~.cbook.violin_stats` followed by `~.Axes.violin` is therefore now equivalent to +calling `~.Axes.violinplot`. + +.. plot:: + :include-source: true + :alt: + Example showing violin_stats followed by violin gives the same result as + violinplot. + + import matplotlib.pyplot as plt + from matplotlib.cbook import violin_stats + import numpy as np + + rng = np.random.default_rng(19680801) + data = rng.normal(size=(10, 3)) + + fig, (ax1, ax2) = plt.subplots(ncols=2, layout='constrained', figsize=(6.4, 3.5)) + + # Create the violin plot in one step + ax1.violinplot(data) + ax1.set_title('One Step') + + # Process the data and then create the violin plot + vstats = violin_stats(data) + ax2.violin(vstats) + ax2.set_title('Two Steps') + + plt.show() diff --git a/doc/release/release_notes.rst b/doc/release/release_notes.rst index cbceb4978121..399329c95acf 100644 --- a/doc/release/release_notes.rst +++ b/doc/release/release_notes.rst @@ -18,6 +18,7 @@ Version 3.11 .. toctree:: :maxdepth: 1 + prev_whats_new/whats_new_3.11.0.rst ../api/prev_api_changes/api_changes_3.11.0.rst github_stats.rst From cbc4f93fa165d2d0d4e33ace869839be12003953 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Fri, 22 May 2026 04:31:33 -0400 Subject: [PATCH 2/2] DOC: Clean up 3.11 What's New notes --- .../prev_whats_new/whats_new_3.10.0.rst | 2 + .../prev_whats_new/whats_new_3.11.0.rst | 205 +++++++++--------- 2 files changed, 104 insertions(+), 103 deletions(-) diff --git a/doc/release/prev_whats_new/whats_new_3.10.0.rst b/doc/release/prev_whats_new/whats_new_3.10.0.rst index c5f6d0ed9861..99889319da87 100644 --- a/doc/release/prev_whats_new/whats_new_3.10.0.rst +++ b/doc/release/prev_whats_new/whats_new_3.10.0.rst @@ -16,6 +16,8 @@ For a list of all of the issues and pull requests since the last revision, see t Accessible Colors ================= +.. _whats-new-3-10-0-petroff10: + New more-accessible color cycle ------------------------------- diff --git a/doc/release/prev_whats_new/whats_new_3.11.0.rst b/doc/release/prev_whats_new/whats_new_3.11.0.rst index d48a9854e302..973eedcda928 100644 --- a/doc/release/prev_whats_new/whats_new_3.11.0.rst +++ b/doc/release/prev_whats_new/whats_new_3.11.0.rst @@ -21,12 +21,12 @@ Figures can now be attached to and removed from management through pyplot, which background also means a less strict coupling to backends. In particular, standalone figures (created with the `.Figure` constructor) can now be -registered with the `.pyplot` module by calling ``plt.figure(fig)``. This allows to show +registered with the `.pyplot` module by calling ``plt.figure(fig)``. This allows showing them with ``plt.show()`` as you would do with any figure created with pyplot factory -methods such as ``plt.figure()`` or ``plt.subplots()``. +functions such as ``plt.figure()`` or ``plt.subplots()``. When closing a shown figure window, the related figure is reset to the standalone state, -i.e. it's not visible to pyplot anymore, but if you still hold a reference to it, you +i.e., it's not visible to pyplot anymore, but if you still hold a reference to it, you can continue to work with it (e.g. do ``fig.savefig()``, or re-add it to pyplot with ``plt.figure(fig)`` and then show it again). @@ -60,32 +60,37 @@ possible. In practice, you'll stick with much simpler versions for better consis plt.figure(fig) plt.show() -Technical detail: Standalone figures use `.FigureCanvasBase` as canvas. This is replaced -by a backend-dependent subclass when registering with pyplot, and is reset to -`.FigureCanvasBase` when the figure is closed. `.Figure.savefig` uses the current canvas -to save the figure (if possible). Since `.FigureCanvasBase` can not render the figure, -when saving the figure, it will fallback to a suitable canvas subclass, e.g. -`.FigureCanvasAgg` for raster outputs such as png. Any Agg-based backend will create the -same file output. However, there may be slight differences for non-Agg backends; e.g. if -you use "GTK4Cairo" as interactive backend, ``fig.savefig("file.png")`` may create a -slightly different image depending on whether the figure is registered with pyplot or -not. In general, you should not store a reference to the canvas, but rather always -obtain it from the figure with ``fig.canvas``. This will return the current canvas, -which is either the original `.FigureCanvasBase` or a backend-dependent subclass, -depending on whether the figure is registered with pyplot or not. Additionally, the -swapping of the canvas currently does not play well with blitting of matplotlib widgets; -in such cases either deactivate blitting or do not continue to use the figure (e.g. -saving it after closing the window). +.. dropdown:: Technical detail + :color: info + :icon: info + + Standalone figures use `.FigureCanvasBase` as canvas. This is replaced by a + backend-dependent subclass when registering with pyplot, and is reset to + `.FigureCanvasBase` when the figure is closed. `.Figure.savefig` uses the current + canvas to save the figure (if possible). Since `.FigureCanvasBase` can not render + the figure, when saving the figure, it will fallback to a suitable canvas subclass, + e.g., `.FigureCanvasAgg` for raster outputs such as PNG. + + Any Agg-based backend will create the same file output. However, there may be slight + differences for non-Agg backends; e.g. if you use "GTK4Cairo" as interactive + backend, ``fig.savefig("file.png")`` may create a slightly different image depending + on whether the figure is registered with pyplot or not. + + In general, you should not store a reference to the canvas, but rather always obtain + it from the figure with ``fig.canvas``. This will return the current canvas, which + is either the original `.FigureCanvasBase` or a backend-dependent subclass, + depending on whether the figure is registered with pyplot or not. Figure size units ----------------- -When creating figures, it is now possible to define figure sizes in cm or pixel. +When creating figures, it is now possible to define figure sizes in centimetres or +pixels. Up to now the figure size is specified via ``plt.figure(..., figsize=(6, 4))``, and the given numbers are interpreted as inches. It is now possible to add a unit string to the tuple, i.e. ``plt.figure(..., figsize=(600, 400, "px"))``. Supported unit strings are -"in", "cm", "px". +``"in"``, ``"cm"``, or ``"px"``. Partial ``figsize`` specification at figure creation ---------------------------------------------------- @@ -96,11 +101,11 @@ height. Passing ``(None, None)`` is invalid and raises a `ValueError`. For example:: - import matplotlib.pyplot as plt - fig = plt.figure(figsize=(None, 4)) + plt.rcParams['figure.figsize'] = (14, 11) + fig = plt.figure(figsize=(None, 4)) # Size will be (14, 4) -Resetting the subplot parameters for figure.clear() ---------------------------------------------------- +Subplot parameters are reset in ``Figure.clear`` +------------------------------------------------ When calling `.Figure.clear()` the settings for `.gridspec.SubplotParams` are restored to the default values. @@ -119,14 +124,10 @@ significantly. It supports different input data types (lists of datasets, dicts datasets, data in 2D arrays, pandas DataFrames), and allows for easy customization of placement via controllable distances between bars and between bar groups. -Example: - .. plot:: - :include-source: true + :include-source: :alt: Diagram of a grouped bar chart of 3 datasets with 2 categories. - import matplotlib.pyplot as plt - categories = ['A', 'B'] datasets = { 'dataset 0': [1, 11], @@ -138,10 +139,10 @@ Example: ax.grouped_bar(datasets, tick_labels=categories) ax.legend() -``broken_barh()`` vertical alignment though ``align`` parameter ---------------------------------------------------------------- +``broken_barh()`` vertical alignment through *align* parameter +-------------------------------------------------------------- -`~.Axes.broken_barh` now supports vertical alignment of the bars through the ``align`` +`~.Axes.broken_barh` now supports vertical alignment of the bars through the *align* parameter. ``hist()`` supports a single color for multiple datasets @@ -160,14 +161,18 @@ already handled. Streamplot integration control ------------------------------ -Two new options have been added to the `~.axes.Axes.streamplot` function that give the -user better control of the streamline integration. The first is called -``integration_max_step_scale`` and multiplies the default max step computed by the -integrator. The second is called ``integration_max_error_scale`` and multiplies the -default max error set by the integrator. Values for these parameters between zero and -one reduce (tighten) the max step or error to improve streamline accuracy by performing -more computation. Values greater than one increase (loosen) the max step or error to -reduce computation time at the cost of lower streamline accuracy. +Two new options have been added to the `~.axes.Axes.streamplot` method that give better +control of the streamline integration: + +``integration_max_step_scale`` + Multiplies the default max step computed by the integrator. +``integration_max_error_scale`` + Multiplies the default max error set by the integrator. + +Values for these parameters between zero and one reduce (tighten) the max step or error +to improve streamline accuracy by performing more computation. Values greater than one +increase (loosen) the max step or error to reduce computation time at the cost of lower +streamline accuracy. The integrator defaults are both hand-tuned values and may not be applicable to all cases, so this allows customizing the behavior to specific use cases. Modifying only @@ -177,11 +182,11 @@ error as well. Multiple arrows on a streamline ------------------------------- -A new ``num_arrows`` argument has been added to `~matplotlib.axes.Axes.streamplot` that +A new *num_arrows* argument has been added to `~matplotlib.axes.Axes.streamplot` that allows more than one arrow to be added to each streamline: .. plot:: - :include-source: true + :include-source: :alt: One chart showing a streamplot. Each streamline has three arrows. import matplotlib.pyplot as plt @@ -201,9 +206,9 @@ allows more than one arrow to be added to each streamline: ------------------------------------------ `~.Axes.violinplot` and `~.Axes.violin` now accept ``facecolor`` and ``linecolor`` as -input arguments. This means that users can set the color of violinplots as they make -them, rather than setting the color of individual objects afterwards. It is possible to -pass a single color to be used for all violins, or pass a sequence of colors. +input arguments. This means that the color of violinplots can be set as they are made, +rather than setting the color of individual objects afterwards. It is possible to pass a +single color to be used for all violins, or pass a sequence of colors. Annotations =========== @@ -211,7 +216,7 @@ Annotations ``bar_label`` supports individual padding per label --------------------------------------------------- -``bar_label`` will now accept both a float value or an array-like for padding. The +`~.Axes.bar_label` will now accept both a float value or an array-like for padding. The array-like defines the padding for each label individually. Adding labels to pie chart wedges @@ -228,7 +233,7 @@ The new `~.Axes.pie_label` method adds a label to each wedge in a pie chart crea For more examples, see :doc:`/gallery/pie_and_polar_charts/pie_label`. .. plot:: - :include-source: true + :include-source: :alt: A pie chart with three labels on each wedge, showing a food type, number, and fraction associated with the wedge. @@ -260,7 +265,7 @@ By using negative angles (or corresponding reflex angles) for *head_angle*, arro 'backwards' heads may be created. .. plot:: - :include-source: true + :include-source: :alt: Six arrow-shaped text boxes. The arrows on the left have the shaft on their left; the arrows on the right have the shaft on the right; the arrows in the @@ -283,10 +288,10 @@ By using negative angles (or corresponding reflex angles) for *head_angle*, arro plt.show() -``borderpad`` accepts a tuple for separate x/y padding -------------------------------------------------------- +*borderpad* accepts a tuple for separate x/y padding +---------------------------------------------------- -The ``borderpad`` parameter used for placing anchored artists (such as inset axes) now +The *borderpad* parameter used for placing anchored artists (such as inset axes) now accepts a tuple of ``(x_pad, y_pad)``. This allows for specifying separate padding values for the horizontal and vertical @@ -311,7 +316,7 @@ Twin Axes ``delta_zorder`` `~matplotlib.axes.Axes.twinx` and `~matplotlib.axes.Axes.twiny` now accept a *delta_zorder* keyword argument, a relative offset added to the original Axes' zorder, to control whether the twin Axes is drawn in front of, or behind, the original Axes. For -example, pass ``delta_zorder=-1`` to easily draw a twin Axes behind the main Axes. +example, pass ``delta_zorder=-1`` to draw a twin Axes behind the main Axes. In addition, Matplotlib now automatically manages background patch visibility for each group of twinned Axes so that only the bottom-most Axes in the group has a visible @@ -343,7 +348,7 @@ This is useful when drawing unfilled patches on backgrounds of unknown color, wh alternating edge colors ensure the patch boundary remains visible. .. plot:: - :include-source: true + :include-source: :alt: A rectangle with a dashed orange edge and blue gaps, demonstrating the edgegapcolor feature. @@ -368,7 +373,7 @@ edgecolor is 'none'. Previously, hatch colors were the same as edge colors, with fallback to :rc:`hatch.color` if the patch did not have an edge color. .. plot:: - :include-source: true + :include-source: :alt: Four Rectangle patches, each displaying the color of hatches in different specifications of edgecolor and hatchcolor. Top left has hatchcolor='black' @@ -434,7 +439,7 @@ alpha value of the collection. This behavior has been changed such that, if both 'patch.edgecolor' with the alpha value of the collection. .. plot:: - :include-source: true + :include-source: :alt: A random scatter plot with hatches on the markers. The hatches are colored in blue, orange, and green, respectively. After the first three markers, the colors @@ -469,8 +474,8 @@ Axis and Ticks Standard getters/setters for axis inversion state ------------------------------------------------- -Whether an axis is inverted can now be queried and set using the `.axes.Axes` getters -`~.Axes.get_xinverted`/`~.Axes.get_yinverted` and setters +Whether an axis is inverted can now be queried using the `.axes.Axes` getters +`~.Axes.get_xinverted`/`~.Axes.get_yinverted` and set using `~.Axes.set_xinverted`/`~.Axes.set_yinverted`. The previously existing methods (`.Axes.xaxis_inverted`, `.Axes.invert_xaxis`) are now @@ -487,7 +492,7 @@ points towards their anchor point, i.e. ticks. This works for all four sides of labels. .. plot:: - :include-source: true + :include-source: :alt: Example of rotated xtick and ytick labels. import matplotlib.pyplot as plt @@ -522,10 +527,9 @@ Colors and colormaps Okabe-Ito accessible color sequence ----------------------------------- -Matplotlib now includes the `Okabe-Ito color sequence`_. Its colors remain -distinguishable for common forms of color-vision deficiency and when printed. - -.. _Okabe-Ito color sequence: https://jfly.uni-koeln.de/color/#pallet +Matplotlib now includes the `Okabe-Ito color sequence +`_. Its colors remain distinguishable for +common forms of color-vision deficiency and when printed. For example, to set it as the default colormap for your plots and image-like artists, use: @@ -535,7 +539,7 @@ use: import matplotlib.pyplot as plt from cycler import cycler - plt.rcParams['axes.prop_cycle'] = cycler('color', plt.colormaps['okabe_ito'].colors) + plt.rcParams['axes.prop_cycle'] = cycler(color='okabe_ito') plt.rcParams['image.cmap'] = 'okabe_ito' Or, when creating plots, you can pass it explicitly: @@ -554,24 +558,22 @@ Or, when creating plots, you can pass it explicitly: Six and eight color Petroff color cycles ---------------------------------------- -The six and eight color accessible Petroff color cycles are named 'petroff6' and -'petroff8'. They compliment the existing 'petroff10' color cycle, added in `Matplotlib -3.10.0`_ +The six and eight color accessible Petroff color cycles are named ``'petroff6'`` and +``'petroff8'``. They complement the existing ``'petroff10'`` color cycle, added in +:ref:`Matplotlib 3.10.0 `. For more details see `Petroff, M. A.: "Accessible Color Sequences for Data -Visualization" `_. To load the 'petroff6' color cycle -in place of the default:: +Visualization" `_. To load the ``'petroff6'`` color +cycle in place of the default:: import matplotlib.pyplot as plt plt.style.use('petroff6') -or to load the 'petroff8' color cycle:: +or to load the ``'petroff8'`` color cycle:: import matplotlib.pyplot as plt plt.style.use('petroff8') -.. _Matplotlib 3.10.0: https://matplotlib.org/stable/users/prev_whats_new/whats_new_3.10.0.html#new-more-accessible-color-cycle - Setting the default color cycle to a named color sequence --------------------------------------------------------- @@ -887,13 +889,10 @@ satisfy format limits. Additionally, a corrected Unicode mapping is added for ea This means that *all* text should now be selectable and copyable in PDF viewers that support doing so. -PDF files created with usetex now embed subsets of Type 1 fonts ---------------------------------------------------------------- - -When using the PDF backend with the usetex feature, Matplotlib calls TeX to render the -text and formulas in the figure. The fonts that get used are usually "Type 1" fonts. -They used to be embedded in full but are now limited to the glyphs that are actually -used in the figure. This reduces the size of the resulting PDF files. +When using the ``usetex`` feature, Matplotlib calls TeX to render the text and formulas +in the figure. The fonts that get used are usually "Type 1" fonts. They used to be +embedded in full but are now limited to the glyphs that are actually used in the figure. +This reduces the size of the resulting PDF files. rcParams improvements ===================== @@ -905,7 +904,7 @@ Using :rc:`grid.major.*` or :rc:`grid.minor.*` will overwrite the value in :rc:` for the major and minor gridlines, respectively. .. plot:: - :include-source: true + :include-source: :alt: Modifying the gridlines using the new options `rcParams` import matplotlib as mpl @@ -962,7 +961,7 @@ The `.Legend` constructor also accepts a new *linewidth* parameter to set the le frame line width directly, overriding the rcParam value. .. plot:: - :include-source: true + :include-source: :alt: A line plot with a legend showing a thick border around the legend box. import matplotlib.pyplot as plt @@ -980,7 +979,7 @@ Previously, labels on `~.PatchCollection` objects were ignored by the legend sys requiring users to create manual legend entries. .. plot:: - :include-source: true + :include-source: :alt: The legend entry displays a rectangle matching the visual properties (colors, line styles, line widths) of the first patch in the collection. @@ -1002,11 +1001,11 @@ Widgets and Interactivity Zooming using mouse wheel ------------------------- -``Ctrl+MouseWheel`` can be used to zoom in the plot windows. Additionally, -``x+MouseWheel`` zooms only the x-axis and ``y+MouseWheel`` zooms only the y-axis. +:kbd:`Control+MouseWheel` can be used to zoom in the plot windows. Additionally, +:kbd:`x+MouseWheel` zooms only the x-axis and :kbd:`y+MouseWheel` zooms only the y-axis. -The zoom focusses on the mouse pointer. With ``Ctrl``, the axes aspect ratio is kept; -with ``x`` or ``y``, only the respective axis is scaled. +The zoom focusses on the mouse pointer. With :kbd:`Control`, the axes aspect ratio is +kept; with :kbd:`x` or :kbd:`y`, only the respective axis is scaled. Zooming is currently only supported on rectilinear Axes. @@ -1025,7 +1024,7 @@ vertically (default), horizontally, or in a 2D grid by passing a ``(rows, cols)` See :doc:`/gallery/widgets/radio_buttons_grid` for a ``(rows, cols)`` example. .. plot:: - :include-source: true + :include-source: :alt: Multiple sine waves with checkboxes to toggle their visibility. import matplotlib.pyplot as plt @@ -1091,12 +1090,12 @@ Non-linear scales on 3D axes ---------------------------- Resolving a long-standing issue, 3D axes now support non-linear axis scales such as -'log', 'symlog', 'logit', 'asinh', and custom 'function' scales, just like 2D axes. Use -`~.Axes3D.set_xscale`, `~.Axes3D.set_yscale`, and `~.Axes3D.set_zscale` to set the scale -for each axis independently. +``'log'``, ``'symlog'``, ``'logit'``, ``'asinh'``, and custom ``'function'`` scales, +just like 2D axes. Use `~.Axes3D.set_xscale`, `~.Axes3D.set_yscale`, and +`~.Axes3D.set_zscale` to set the scale for each axis independently. .. plot:: - :include-source: true + :include-source: :alt: A 3D plot with a linear x-axis, logarithmic y-axis, and symlog z-axis. import matplotlib.pyplot as plt @@ -1126,11 +1125,11 @@ See `matplotlib.scale` for details on all available scales and their parameters. Snapping 3D rotation angles with Control key -------------------------------------------- -3D axes rotation now supports snapping to fixed angular increments when holding the -``Control`` key during mouse rotation. +Rotation of 3D axes now supports snapping to fixed angular increments when holding the +:kbd:`Control` key during mouse rotation. -The snap step size is controlled by the new ``axes3d.snap_rotation`` rcParam (default: -5.0 degrees). Setting it to 0 disables snapping. +The snap step size is controlled by the new :rc:`axes3d.snap_rotation` rcParam. Setting +it to 0 disables snapping. For example:: @@ -1146,17 +1145,17 @@ Previously, a slightly buggy method of estimating the visual "depth" of 3D items lead to sudden and unexpected changes in transparency as the plot orientation changed. Now, the behavior has been made smooth and predictable. A new parameter -``depthshade_minalpha`` has also been added to allow users to set the minimum -transparency level. Depth-shading is an option for Patch3DCollections and -Path3DCollections, including 3D scatter plots. +*depthshade_minalpha* has also been added to allow users to set the minimum transparency +level. Depth-shading is an option for `.Patch3DCollection` and `.Path3DCollection`, +including 3D scatter plots. -The default values for ``depthshade`` and ``depthshade_minalpha`` are now also controlled -via rcParams, with values of ``True`` and ``0.3`` respectively. +The default values for ``depthshade`` and ``depthshade_minalpha`` are now controlled by +:rc:`axes3d.depthshade` and :rc:`axes3d.depthshade_minalpha`, respectively. A simple example: .. plot:: - :include-source: true + :include-source: :alt: A 3D scatter plot with depth-shading enabled. import matplotlib.pyplot as plt @@ -1182,7 +1181,7 @@ A simple example: --------------------------- Draw time for 3D plots has been improved, especially for surface and wireframe plots. -Users should see up to a 10x speedup in some cases. This should make interacting with 3D +Users should see up to a 10× speedup in some cases. This should make interacting with 3D plots much more responsive. Other improvements @@ -1224,7 +1223,7 @@ strings, and has a new default ``("GaussianKDE", "scott")``. Calling calling `~.Axes.violinplot`. .. plot:: - :include-source: true + :include-source: :alt: Example showing violin_stats followed by violin gives the same result as violinplot.