File: whats_new_3.8.0.rst

package info (click to toggle)
matplotlib 3.10.1%2Bdfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 78,352 kB
  • sloc: python: 147,118; cpp: 62,988; objc: 1,679; ansic: 1,426; javascript: 786; makefile: 104; sh: 53
file content (529 lines) | stat: -rw-r--r-- 17,458 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
==============================================
What's new in Matplotlib 3.8.0 (Sept 13, 2023)
==============================================

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

Type Hints
==========

Matplotlib now provides first-party PEP484 style type hints files for most public APIs.

While still considered provisional and subject to change (and sometimes we are not
quite able to fully specify what we would like to), they should provide a reasonable
basis to type check many common usage patterns, as well as integrating with many
editors/IDEs.

Plotting and Annotation improvements
====================================

Support customizing antialiasing for text and annotation
--------------------------------------------------------
``matplotlib.pyplot.annotate()`` and ``matplotlib.pyplot.text()`` now support parameter *antialiased*.
When *antialiased* is set to ``True``, antialiasing will be applied to the text.
When *antialiased* is set to ``False``, antialiasing will not be applied to the text.
When *antialiased* is not specified, antialiasing will be set by :rc:`text.antialiased` at the creation time of ``Text`` and ``Annotation`` object.
Examples:

.. code-block:: python

    mpl.text.Text(.5, .5, "foo\nbar", antialiased=True)
    plt.text(0.5, 0.5, '6 inches x 2 inches', antialiased=True)
    ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5), antialiased=False)

If the text contains math expression, *antialiased* applies to the whole text.
Examples:

.. code-block:: python

    # no part will be antialiased for the text below
    plt.text(0.5, 0.25, r"$I'm \sqrt{x}$", antialiased=False)

Also note that antialiasing for tick labels will be set with :rc:`text.antialiased` when they are created (usually when a ``Figure`` is created) and cannot be changed afterwards.

Furthermore, with this new feature, you may want to make sure that you are creating and saving/showing the figure under the same context::

    # previously this was a no-op, now it is what works
    with rccontext(text.antialiased=False):
        fig, ax = plt.subplots()
        ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5))
        fig.savefig('/tmp/test.png')


    # previously this had an effect, now this is a no-op
    fig, ax = plt.subplots()
    ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5))
    with rccontext(text.antialiased=False):
        fig.savefig('/tmp/test.png')

rcParams for ``AutoMinorLocator`` divisions
-------------------------------------------
The rcParams :rc:`xtick.minor.ndivs` and :rc:`ytick.minor.ndivs` have been
added to enable setting the default number of divisions; if set to ``auto``,
the number of divisions will be chosen by the distance between major ticks.

Axline setters and getters
--------------------------

The returned object from `.axes.Axes.axline` now supports getter and setter
methods for its *xy1*, *xy2* and *slope* attributes:

.. code-block:: python

    line1.get_xy1()
    line1.get_slope()
    line2.get_xy2()

.. code-block:: python

    line1.set_xy1(.2, .3)
    line1.set_slope(2.4)
    line2.set_xy2(.1, .6)

Clipping for contour plots
--------------------------

`~.Axes.contour` and `~.Axes.contourf` now accept the *clip_path* parameter.

.. plot::
    :include-source: true

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.patches as mpatches

    x = y = np.arange(-3.0, 3.01, 0.025)
    X, Y = np.meshgrid(x, y)
    Z1 = np.exp(-X**2 - Y**2)
    Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
    Z = (Z1 - Z2) * 2

    fig, ax = plt.subplots()
    patch = mpatches.RegularPolygon((0, 0), 5, radius=2,
                                    transform=ax.transData)
    ax.contourf(X, Y, Z, clip_path=patch)

    plt.show()

``Axes.ecdf``
-------------
A new Axes method, `~.Axes.ecdf`, allows plotting empirical cumulative
distribution functions without any binning.

.. plot::
   :include-source:

   import matplotlib.pyplot as plt
   import numpy as np

   fig, ax = plt.subplots()
   ax.ecdf(np.random.randn(100))

``Figure.get_suptitle()``, ``Figure.get_supxlabel()``, ``Figure.get_supylabel()``
---------------------------------------------------------------------------------
These methods return the strings set by ``Figure.suptitle()``, ``Figure.supxlabel()``
and ``Figure.supylabel()`` respectively.

``Ellipse.get_vertices()``, ``Ellipse.get_co_vertices()``
---------------------------------------------------------------------------------
These methods return the coordinates of ellipse vertices of
major and minor axis. Additionally, an example gallery demo is added which
shows how to add an arrow to an ellipse showing a clockwise or counter-clockwise
rotation of the ellipse. To place the arrow exactly on the ellipse,
the coordinates of the vertices are used.

Remove inner ticks in ``label_outer()``
---------------------------------------
Up to now, ``label_outer()`` has only removed the ticklabels. The ticks lines
were left visible. This is now configurable through a new parameter
``label_outer(remove_inner_ticks=True)``.


.. plot::
   :include-source: true

    import numpy as np
    import matplotlib.pyplot as plt

    x = np.linspace(0, 2 * np.pi, 100)

    fig, axs = plt.subplots(2, 2, sharex=True, sharey=True,
                            gridspec_kw=dict(hspace=0, wspace=0))

    axs[0, 0].plot(x, np.sin(x))
    axs[0, 1].plot(x, np.cos(x))
    axs[1, 0].plot(x, -np.cos(x))
    axs[1, 1].plot(x, -np.sin(x))

    for ax in axs.flat:
        ax.grid(color='0.9')
        ax.label_outer(remove_inner_ticks=True)

Configurable legend shadows
---------------------------
The *shadow* parameter of legends now accepts dicts in addition to booleans.
Dictionaries can contain any keywords for `.patches.Patch`.
For example, this allows one to set the color and/or the transparency of a legend shadow:

.. code-block:: python

   ax.legend(loc='center left', shadow={'color': 'red', 'alpha': 0.5})

and to control the shadow location:

.. code-block:: python

   ax.legend(loc='center left', shadow={"ox":20, "oy":-20})

Configuration is currently not supported via :rc:`legend.shadow`.


``offset`` parameter for MultipleLocator
----------------------------------------

An *offset* may now be specified to shift all the ticks by the given value.

.. plot::
    :include-source: true

    import matplotlib.pyplot as plt
    import matplotlib.ticker as mticker

    _, ax = plt.subplots()
    ax.plot(range(10))
    locator = mticker.MultipleLocator(base=3, offset=0.3)
    ax.xaxis.set_major_locator(locator)

    plt.show()

Add a new valid color format ``(matplotlib_color, alpha)``
----------------------------------------------------------


.. plot::
    :include-source: true

    import matplotlib.pyplot as plt
    from matplotlib.patches import Rectangle

    fig, ax = plt.subplots()

    rectangle = Rectangle((.2, .2), .6, .6,
                          facecolor=('blue', 0.2),
                          edgecolor=('green', 0.5))
    ax.add_patch(rectangle)


Users can define a color using the new color specification, *(matplotlib_color, alpha)*.
Note that an explicit alpha keyword argument will override an alpha value from
*(matplotlib_color, alpha)*.

The pie chart shadow can be controlled
--------------------------------------

The *shadow* argument to `~.Axes.pie` can now be a dict, allowing more control
of the `.Shadow`-patch used.


``PolyQuadMesh`` is a new class for drawing quadrilateral meshes
----------------------------------------------------------------

`~.Axes.pcolor` previously returned a flattened `.PolyCollection` with only
the valid polygons (unmasked) contained within it. Now, we return a `.PolyQuadMesh`,
which is a mixin incorporating the usefulness of 2D array and mesh coordinates
handling, but still inheriting the draw methods of `.PolyCollection`, which enables
more control over the rendering properties than a normal `.QuadMesh` that is
returned from `~.Axes.pcolormesh`. The new class subclasses `.PolyCollection` and thus
should still behave the same as before. This new class keeps track of the mask for
the user and updates the Polygons that are sent to the renderer appropriately.

.. plot::

    arr = np.arange(12).reshape((3, 4))

    fig, ax = plt.subplots()
    pc = ax.pcolor(arr)

    # Mask one element and show that the hatch is also not drawn
    # over that region
    pc.set_array(np.ma.masked_equal(arr, 5))
    pc.set_hatch('//')

    plt.show()

Shadow shade can be controlled
------------------------------

The `.Shadow` patch now has a *shade* argument to control the shadow darkness.
If 1, the shadow is black, if 0, the shadow has the same color as the patch that
is shadowed. The default value, which earlier was fixed, is 0.7.

``SpinesProxy`` now supports calling the ``set()`` method
---------------------------------------------------------
One can now call e.g. ``ax.spines[:].set(visible=False)``.

Allow setting the tick label fonts with a keyword argument
----------------------------------------------------------
``Axes.tick_params`` now accepts a *labelfontfamily* keyword that changes the tick
label font separately from the rest of the text objects:

.. code-block:: python

    Axis.tick_params(labelfontfamily='monospace')


Figure, Axes, and Legend Layout
===============================

pad_inches="layout" for savefig
-------------------------------

When using constrained or compressed layout,

.. code-block:: python

    savefig(filename, bbox_inches="tight", pad_inches="layout")

will now use the padding sizes defined on the layout engine.

Add a public method to modify the location of ``Legend``
--------------------------------------------------------

`~matplotlib.legend.Legend` locations now can be tweaked after they've been defined.

.. plot::
    :include-source: true

    from matplotlib import pyplot as plt

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)

    x = list(range(-100, 101))
    y = [i**2 for i in x]

    ax.plot(x, y, label="f(x)")
    ax.legend()
    ax.get_legend().set_loc("right")
    # Or
    # ax.get_legend().set(loc="right")

    plt.show()


``rcParams['legend.loc']`` now accepts float-tuple inputs
---------------------------------------------------------

The :rc:`legend.loc` rcParams now accepts float-tuple inputs, same as the *loc* keyword argument to `.Legend`.
This allows users to set the location of the legend in a more flexible and consistent way.

Mathtext improvements
=====================

Improvements are to Mathtext, Matplotlib's native TeX-like mathematics parser
(see :ref:`mathtext`, not to be confused with Matplotlib using LaTeX directly:
:ref:`usetex`).

Boldsymbol mathtext command ``\boldsymbol``
-------------------------------------------

Supports using the ``\boldsymbol{}`` command in mathtext:

To change symbols to bold enclose the text in a font command as
shown:

.. code-block:: none

    r'$\boldsymbol{a+2+\alpha}$'

.. math::
   \boldsymbol{a+2+\alpha}

``mathtext`` has more sizable delimiters
----------------------------------------

The ``\lgroup`` and ``\rgroup`` sizable delimiters have been added.

The following delimiter names have been supported earlier, but can now be sized with
``\left`` and ``\right``:

* ``\lbrace``, ``\rbrace``, ``\leftbrace``, and ``\rightbrace``
* ``\lbrack`` and ``\rbrack``
* ``\leftparen`` and ``\rightparen``

There are really no obvious advantages in using these.
Instead, they are are added for completeness.

``mathtext`` documentation improvements
---------------------------------------

The documentation is updated to take information directly from the parser. This
means that (almost) all supported symbols, operators etc are shown at :ref:`mathtext`.

``mathtext`` now supports ``\substack``
---------------------------------------

``\substack`` can be used to create multi-line subscripts or superscripts within an equation.

To use it to enclose the math in a substack command as shown:

.. code-block:: none

    r'$\sum_{\substack{1\leq i\leq 3\\ 1\leq j\leq 5}}$'

.. mathmpl::

    \sum_{\substack{1\leq i\leq 3\\ 1\leq j\leq 5}}



``mathtext`` now supports ``\middle`` delimiter
-----------------------------------------------

The ``\middle`` delimiter has been added, and can now be used with the
``\left`` and ``\right`` delimiters:

To use the middle command enclose it in between the ``\left`` and
``\right`` delimiter command as shown:

.. code-block:: none

    r'$\left( \frac{a}{b} \middle| q \right)$'

.. mathmpl::

    \left( \frac{a}{b} \middle| q \right)

``mathtext`` operators
----------------------

There has been a number of operators added and corrected when a Unicode font is used.
In addition, correct spacing has been added to a number of the previous operators.
Especially, the characters used for ``\gnapprox``, ``\lnapprox``, ``\leftangle``, and
``\rightangle`` have been corrected.

``mathtext`` spacing corrections
--------------------------------

As consequence of the updated documentation, the spacing on a number of relational and
operator symbols were classified like that and therefore will be spaced properly.

``mathtext`` now supports ``\text``
-----------------------------------

``\text`` can be used to obtain upright text within an equation and to get a plain dash
(-).

.. plot::
    :include-source: true
    :alt: Illustration of the newly added \text command, showing that it renders as normal text, including spaces, despite being part of an equation. Also show that a dash is not rendered as a minus when part of a \text command.

    import matplotlib.pyplot as plt
    plt.text(0.1, 0.5, r"$a = \sin(\phi) \text{ such that } \phi = \frac{x}{y}$")
    plt.text(0.1, 0.3, r"$\text{dashes (-) are retained}$")


Bold-italic mathtext command ``\mathbfit``
------------------------------------------

Supports use of bold-italic font style in mathtext using the ``\mathbfit{}`` command:

To change font to bold and italic enclose the text in a font command as
shown:

.. code-block:: none

    r'$\mathbfit{\eta \leq C(\delta(\eta))}$

.. math::
   \mathbfit{\eta \leq C(\delta(\eta))}


3D plotting improvements
========================

Specify ticks and axis label positions for 3D plots
---------------------------------------------------

You can now specify the positions of ticks and axis labels for 3D plots.

.. plot::
   :include-source:

   import matplotlib.pyplot as plt

   positions = ['lower', 'upper', 'default', 'both', 'none']
   fig, axs = plt.subplots(2, 3, figsize=(12, 8),
                           subplot_kw={'projection': '3d'})
   for ax, pos in zip(axs.flatten(), positions):
       for axis in ax.xaxis, ax.yaxis, ax.zaxis:
           axis.set_label_position(pos)
           axis.set_ticks_position(pos)
       title = f'position="{pos}"'
       ax.set(xlabel='x', ylabel='y', zlabel='z', title=title)
   axs[1, 2].axis('off')

3D hover coordinates
--------------------

The x, y, z coordinates displayed in 3D plots were previously showing
nonsensical values. This has been fixed to report the coordinate on the view
pane directly beneath the mouse cursor. This is likely to be most useful when
viewing 3D plots along a primary axis direction when using an orthographic
projection, or when a 2D plot has been projected onto one of the 3D axis panes.
Note that there is still no way to directly display the coordinates of plotted
data points.

3D plots can share view angles
------------------------------

3D plots can now share the same view angles, so that when you rotate one plot
the other plots also rotate. This can be done with the *shareview* keyword
argument when adding an axes, or by using the *ax1.shareview(ax2)* method of
existing 3D axes.


Other improvements
==================

macosx: New figures can be opened in either windows or tabs
-----------------------------------------------------------

There is a new :rc:`macosx.window_mode` rcParam to control how
new figures are opened with the macosx backend. The default is
**system** which uses the system settings, or one can specify either
**tab** or **window** to explicitly choose the mode used to open new figures.

``matplotlib.mpl_toolkits`` is now an implicit namespace package
----------------------------------------------------------------

Following the deprecation of ``pkg_resources.declare_namespace`` in ``setuptools`` 67.3.0,
``matplotlib.mpl_toolkits`` is now implemented as an implicit namespace, following
`PEP 420 <https://peps.python.org/pep-0420/>`_.

Plot Directive now can make responsive images with "srcset"
-----------------------------------------------------------

The plot sphinx directive (``matplotlib.sphinxext.plot_directive``, invoked in
rst as ``.. plot::``) can be configured to automatically make higher res
figures and add these to the the built html docs.  In ``conf.py``::

    extensions = [
    ...
        'matplotlib.sphinxext.plot_directive',
        'matplotlib.sphinxext.figmpl_directive',
    ...]

    plot_srcset = ['2x']

will make png files with double the resolution for hiDPI displays.  Resulting
html files will have image entries like::

    <img src="../_images/nestedpage-index-2.png" style="" srcset="../_images/nestedpage-index-2.png, ../_images/nestedpage-index-2.2x.png 2.00x" alt="" class="plot-directive "/>