File: whats_new_3.1.0.rst

package info (click to toggle)
matplotlib 3.3.4-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 78,264 kB
  • sloc: python: 123,969; cpp: 57,655; ansic: 29,431; objc: 2,244; javascript: 757; makefile: 163; sh: 111
file content (375 lines) | stat: -rw-r--r-- 13,785 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

What's new in Matplotlib 3.1
============================

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

New Features
------------

`~.dates.ConciseDateFormatter`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The automatic date formatter used by default can be quite verbose.  A new
formatter can be accessed that tries to make the tick labels appropriately
concise.

  .. plot::

    import datetime
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    import numpy as np

    # make a timeseries...
    base = datetime.datetime(2005, 2, 1)
    dates = np.array([base + datetime.timedelta(hours= 2 * i)
                      for i in range(732)])
    N = len(dates)
    np.random.seed(19680801)
    y = np.cumsum(np.random.randn(N))

    lims = [(np.datetime64('2005-02'), np.datetime64('2005-04')),
            (np.datetime64('2005-02-03'), np.datetime64('2005-02-15')),
            (np.datetime64('2005-02-03 11:00'), np.datetime64('2005-02-04 13:20'))]
    fig, axs = plt.subplots(3, 1, constrained_layout=True)
    for nn, ax in enumerate(axs):
        # activate the formatter here.
        locator = mdates.AutoDateLocator()
        formatter = mdates.ConciseDateFormatter(locator)
        ax.xaxis.set_major_locator(locator)
        ax.xaxis.set_major_formatter(formatter)

        ax.plot(dates, y)
        ax.set_xlim(lims[nn])
    axs[0].set_title('Concise Date Formatter')

    plt.show()

Secondary x/y Axis support
~~~~~~~~~~~~~~~~~~~~~~~~~~

A new method provides the ability to add a second axis to an existing
axes via `.Axes.secondary_xaxis` and `.Axes.secondary_yaxis`.  See
:doc:`/gallery/subplots_axes_and_figures/secondary_axis` for examples.

.. plot::

    import matplotlib.pyplot as plt

    fig, ax = plt.subplots(figsize=(5, 3))
    ax.plot(range(360))
    ax.secondary_xaxis('top', functions=(np.deg2rad, np.rad2deg))


`~.scale.FuncScale` for arbitrary axes scales
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A new `~.scale.FuncScale` class was added (and `~.scale.FuncTransform`)
to allow the user to have arbitrary scale transformations without having to
write a new subclass of `~.scale.ScaleBase`.  This can be accessed by::

  ax.set_yscale('function', functions=(forward, inverse))

where ``forward`` and ``inverse`` are callables that return the scale
transform and its inverse.  See the last example in
:doc:`/gallery/scales/scales`.


Legend for scatter
~~~~~~~~~~~~~~~~~~

A new method for creating legends for scatter plots has been
introduced.  Previously, in order to obtain a legend for a
:meth:`~.axes.Axes.scatter` plot, one could either plot several
scatters, each with an individual label, or create proxy artists to
show in the legend manually.  Now,
:class:`~.collections.PathCollection` provides a method
:meth:`~.collections.PathCollection.legend_elements` to obtain the
handles and labels for a scatter plot in an automated way. This makes
creating a legend for a scatter plot as easy as

.. plot::

    scatter = plt.scatter([1,2,3], [4,5,6], c=[7,2,3])
    plt.legend(*scatter.legend_elements())

An example can be found in :ref:`automatedlegendcreation`.


Matplotlib no longer requires framework app build on MacOSX backend
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previous versions of matplotlib required a Framework build of python to
work. The app type was updated to no longer require this, so the MacOSX
backend should work with non-framework python.


This also adds support for the MacOSX backend for PyPy3.


Figure, FigureCanvas, and Backends
----------------------------------

Figure.frameon is now a direct proxy for the Figure patch visibility state
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Accessing ``Figure.frameon`` (including via ``get_frameon`` and ``set_frameon``
now directly forwards to the visibility of the underlying Rectangle artist
(``Figure.patch.get_frameon``, ``Figure.patch.set_frameon``).


*pil_kwargs* argument added to savefig
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Matplotlib uses Pillow to handle saving to the JPEG and TIFF formats.  The
`~.Figure.savefig()` function gained a *pil_kwargs* keyword argument, which can
be used to forward arguments to Pillow's `pillow.Image.save()`.

The *pil_kwargs* argument can also be used when saving to PNG.  In that case,
Matplotlib also uses Pillow's `pillow.Image.save()` instead of going through its
own builtin PNG support.


Add ``inaxes`` method to `.FigureCanvasBase`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The `.FigureCanvasBase` class has now an `~.FigureCanvasBase.inaxes`
method to check whether a point is in an axes and returns the topmost
axes, else None.

cairo backend defaults to pycairo instead of cairocffi
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This leads to faster import/runtime performance in some cases. The backend
will fall back to cairocffi in case pycairo isn't available.


Axes and Artists
----------------

axes_grid1 and axisartist Axes no longer draw spines twice
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previously, spines of `.axes_grid1` and `.axisartist` Axes would be drawn twice,
leading to a "bold" appearance.  This is no longer the case.


Return type of ArtistInspector.get_aliases changed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`.ArtistInspector.get_aliases` previously returned the set of aliases as
``{fullname: {alias1: None, alias2: None, ...}}``.  The dict-to-None mapping
was used to simulate a set in earlier versions of Python.  It has now been
replaced by a set, i.e. ``{fullname: {alias1, alias2, ...}}``.

This value is also stored in `.ArtistInspector.aliasd`, which has likewise
changed.


`.ConnectionPatch` accepts arbitrary transforms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Alternatively to strings like ``"data"`` or ``"axes fraction"``,
`ConnectionPatch` now accepts any `~matplotlib.transforms.Transform` as input
for the *coordsA* and *coordsB* arguments. This allows to draw lines between
points defined in different user defined coordinate systems. Also see the
:doc:`Connect Simple01 example </gallery/userdemo/connect_simple01>`.


mplot3d Line3D now allows {set,get}_data_3d
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Lines created with the 3d projection in mplot3d can now access the
data using `~.mplot3d.art3d.Line3D.get_data_3d()` which returns a
tuple of array_likes containing the (x, y, z) data. The equivalent
`~.mplot3d.art3d.Line3D.set_data_3d` can be used to modify the data of
an existing Line3D.


``Axes3D.voxels`` now shades the resulting voxels
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The `.Axes3D.voxels` method now takes a
*shade* parameter that defaults to `True`. This shades faces based
on their orientation, behaving just like the matching parameters to
:meth:`~mpl_toolkits.mplot3d.axes3d.Axes3D.plot_trisurf` and
:meth:`~mpl_toolkits.mplot3d.axes3d.Axes3D.bar3d`.  The plot below shows how
this affects the output.

.. plot::

	import matplotlib.pyplot as plt
	import numpy as np

	# prepare some coordinates
	x, y, z = np.indices((8, 8, 8))

	# draw cuboids in the top left and bottom right corners, and a link between them
	cube1 = (x < 3) & (y < 3) & (z < 3)
	cube2 = (x >= 5) & (y >= 5) & (z >= 5)
	link = abs(x - y) + abs(y - z) + abs(z - x) <= 2

	# combine the objects into a single boolean array
	voxels = cube1 | cube2 | link

	# set the colors of each object
	colors = np.empty(voxels.shape, dtype=object)
	colors[link] = 'red'
	colors[cube1] = 'blue'
	colors[cube2] = 'green'

	# and plot everything
	fig = plt.figure(figsize=plt.figaspect(0.5))
	ax, ax_shaded = fig.subplots(1, 2, subplot_kw=dict(projection='3d'))
	ax.voxels(voxels, facecolors=colors, edgecolor='k', shade=False)
	ax.set_title("Unshaded")
	ax_shaded.voxels(voxels, facecolors=colors, edgecolor='k', shade=True)
	ax_shaded.set_title("Shaded (default)")

	plt.show()

Axis and Ticks
--------------

Added `.Axis.get_inverted` and `.Axis.set_inverted`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The `.Axis.get_inverted` and `.Axis.set_inverted` methods query and set whether
the axis uses "inverted" orientation (i.e. increasing to the left for the
x-axis and to the bottom for the y-axis).

They perform tasks similar to `.Axes.xaxis_inverted`, `.Axes.yaxis_inverted`,
`.Axes.invert_xaxis`, and `.Axes.invert_yaxis`, with the specific difference
that `.Axis.set_inverted` makes it easier to set the inversion of an axis
regardless of whether it had previously been inverted before.

Adjust default minor tick spacing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Default minor tick spacing was changed from 0.625 to 0.5 for major ticks spaced
2.5 units apart.


`.EngFormatter` now accepts *usetex*, *useMathText* as keyword only arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A public API has been added to `.EngFormatter` to control how the numbers in
the ticklabels will be rendered. By default, *useMathText* evaluates to
:rc:`axes.formatter.use_mathtext'` and *usetex* evaluates to
:rc:`'text.usetex'`.

If either is `True` then the numbers will be encapsulated by ``$``
signs.  When using ``TeX`` this implies that the numbers will be shown
in TeX's math font. When using mathtext, the ``$`` signs around
numbers will ensure Unicode rendering (as implied by mathtext). This
will make sure that the minus signs in the ticks are rendered as the
Unicode minus (U+2212) when using mathtext (without relying on the
`~.Formatter.fix_minus` method).



Animation and Interactivity
---------------------------

Support for forward/backward mouse buttons
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Figure managers now support a ``button_press`` event for mouse
buttons, similar to the ``key_press`` events. This allows binding
actions to mouse buttons (see `.MouseButton`) The first application of
this mechanism is support of forward/backward mouse buttons in figures
created with the Qt5 backend.


*progress_callback* argument to `~.Animation.save()`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The method `.Animation.save` gained an optional
*progress_callback* argument to notify the saving progress.


Add ``cache_frame_data`` keyword-only argument into `.animation.FuncAnimation`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

`.matplotlib.animation.FuncAnimation` has been caching frame data by
default; however, this caching is not ideal in certain cases e.g. When
`.FuncAnimation` needs to be only drawn(not saved) interactively and
memory required by frame data is quite large. By adding
*cache_frame_data* keyword-only argument, users can now disable this
caching; thereby, this new argument provides a fix for issue
:ghissue:`8528`.


Endless Looping GIFs with PillowWriter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

We acknowledge that most people want to watch a GIF more than
once. Saving an animation as a GIF with PillowWriter now produces an
endless looping GIF.


Adjusted `.matplotlib.widgets.Slider` to have vertical orientation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The :class:`matplotlib.widgets.Slider` widget now takes an optional
argument *orientation* which indicates the direction
(``'horizontal'`` or ``'vertical'``) that the slider should take.

Improved formatting of image values under cursor when a colorbar is present
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When a colorbar is present, its formatter is now used to format the image
values under the mouse cursor in the status bar.  For example, for an image
displaying the values 10,000 and 10,001, the statusbar will now (using default
settings) display the values as ``10000`` and ``10001``), whereas both values
were previously displayed as ``1e+04``.

MouseEvent button attribute is now an IntEnum
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The :attr:`button` attribute of `~.MouseEvent` instances can take the values
None, 1 (left button), 2 (middle button), 3 (right button), "up" (scroll), and
"down" (scroll).  For better legibility, the 1, 2, and 3 values are now
represented using the `enum.IntEnum` class `matplotlib.backend_bases.MouseButton`,
with the values `.MouseButton.LEFT` (``== 1``), `.MouseButton.MIDDLE` (``== 2``),
and `.MouseButton.RIGHT` (``== 3``).


Configuration, Install, and Development
---------------------------------------

The MATPLOTLIBRC environment variable can now point to any "file" path
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This includes device files; in particular, on Unix systems, one can set
``MATPLOTLIBRC`` to ``/dev/null`` to ignore the user's matplotlibrc file and
fall back to Matplotlib's defaults.

As a reminder, if ``MATPLOTLIBRC`` points to a directory, Matplotlib will try
to load the matplotlibrc file from ``$MATPLOTLIBRC/matplotlibrc``.


Allow LaTeX code ``pgf.preamble`` and ``text.latex.preamble`` in MATPLOTLIBRC file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previously, the rc file keys :rc:`pgf.preamble` and
:rc:`text.latex.preamble` were parsed using commas as separators. This
would break valid LaTeX code, such as::

   \usepackage[protrusion=true, expansion=false]{microtype}

The parsing has been modified to pass the complete line to the LaTeX
system, keeping all commas. Passing a list of strings from within a
Python script still works as it used to.



New logging API
~~~~~~~~~~~~~~~

`matplotlib.set_loglevel` / `.pyplot.set_loglevel` can be called to
display more (or less) detailed logging output.