|
| 1 | +.. _whats-new-2-2-0: |
| 2 | + |
| 3 | +New in Matplotlib 2.2 |
| 4 | +===================== |
| 5 | + |
| 6 | +Constrained Layout Manager |
| 7 | +-------------------------- |
| 8 | + |
| 9 | +.. warning:: |
| 10 | + |
| 11 | + Constrained Layout is **experimental**. The |
| 12 | + behaviour and API are subject to change, or the whole functionality |
| 13 | + may be removed without a deprecation period. |
| 14 | + |
| 15 | + |
| 16 | +A new method to automatically decide spacing between subplots and their |
| 17 | +organizing ``GridSpec`` instances has been added. It is meant to |
| 18 | +replace the venerable ``tight_layout`` method. It is invoked via |
| 19 | +a new ``constrained_layout=True`` kwarg to |
| 20 | +`~.figure.Figure` or `~.figure.subplots`. |
| 21 | + |
| 22 | +There are new ``rcParams`` for this package, and spacing can be |
| 23 | +more finely tuned with the new `~.set_constrained_layout_pads`. |
| 24 | + |
| 25 | +Features include: |
| 26 | + |
| 27 | + - Automatic spacing for subplots with a fixed-size padding in inches around |
| 28 | + subplots and all their decorators, and space between as a fraction |
| 29 | + of subplot size between subplots. |
| 30 | + - Spacing for `~.figure.suptitle`, and colorbars that are attached to |
| 31 | + more than one axes. |
| 32 | + - Nested `~.GridSpec` layouts using `~.GridSpecFromSubplotSpec`. |
| 33 | + |
| 34 | + For more details and capabilities please see the new tutorial: |
| 35 | + :doc:`/tutorials/intermediate/constrainedlayout_guide` |
| 36 | + |
| 37 | +Note the new API to access this: |
| 38 | + |
| 39 | +New ``plt.figure`` and ``plt.subplots`` kwarg: ``constrained_layout`` |
| 40 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 41 | + |
| 42 | +:meth:`~matplotlib.pyplot.figure` and :meth:`~matplotlib.pyplot.subplots` |
| 43 | +can now be called with ``constrained_layout=True`` kwarg to enable |
| 44 | +constrained_layout. |
| 45 | + |
| 46 | +New ``ax.set_position`` behaviour |
| 47 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 48 | + |
| 49 | +:meth:`~matplotlib.axes.set_position` now makes the specified axis no |
| 50 | +longer responsive to ``constrained_layout``, consistent with the idea that the |
| 51 | +user wants to place an axis manually. |
| 52 | + |
| 53 | +Internally, this means that old ``ax.set_position`` calls *inside* the library |
| 54 | +are changed to private ``ax._set_position`` calls so that |
| 55 | +``constrained_layout`` will still work with these axes. |
| 56 | + |
| 57 | +New ``figure`` kwarg for ``GridSpec`` |
| 58 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 59 | + |
| 60 | +In order to facilitate ``constrained_layout``, ``GridSpec`` now accepts a |
| 61 | +``figure`` keyword. This is backwards compatible, in that not supplying this |
| 62 | +will simply cause ``constrained_layout`` to not operate on the subplots |
| 63 | +orgainzed by this ``GridSpec`` instance. Routines that use ``GridSpec`` (e.g. |
| 64 | +``fig.subplots``) have been modified to pass the figure to ``GridSpec``. |
| 65 | + |
| 66 | + |
| 67 | +xlabels and ylabels can now be automatically aligned |
| 68 | +---------------------------------------------------- |
| 69 | + |
| 70 | +Subplot axes ``ylabels`` can be misaligned horizontally if the tick labels |
| 71 | +are very different widths. The same can happen to ``xlabels`` if the |
| 72 | +ticklabels are rotated on one subplot (for instance). The new methods |
| 73 | +on the `Figure` class: `Figure.align_xlabels` and `Figure.align_ylabels` |
| 74 | +will now align these labels horizontally or vertically. If the user only |
| 75 | +wants to align some axes, a list of axes can be passed. If no list is |
| 76 | +passed, the algorithm looks at all the labels on the figure. |
| 77 | + |
| 78 | +Only labels that have the same subplot locations are aligned. i.e. the |
| 79 | +ylabels are aligned only if the subplots are in the same column of the |
| 80 | +subplot layout. |
| 81 | + |
| 82 | +Alignemnt is persistent and automatic after these are called. |
| 83 | + |
| 84 | +A convenience wrapper `Figure.align_labels` calls both functions at once. |
| 85 | + |
| 86 | +.. plot:: |
| 87 | + |
| 88 | + import matplotlib.gridspec as gridspec |
| 89 | + |
| 90 | + fig = plt.figure(figsize=(5, 3), tight_layout=True) |
| 91 | + gs = gridspec.GridSpec(2, 2) |
| 92 | + |
| 93 | + ax = fig.add_subplot(gs[0,:]) |
| 94 | + ax.plot(np.arange(0, 1e6, 1000)) |
| 95 | + ax.set_ylabel('Test') |
| 96 | + for i in range(2): |
| 97 | + ax = fig.add_subplot(gs[1, i]) |
| 98 | + ax.set_ylabel('Booooo') |
| 99 | + ax.set_xlabel('Hello') |
| 100 | + if i == 0: |
| 101 | + for tick in ax.get_xticklabels(): |
| 102 | + tick.set_rotation(45) |
| 103 | + fig.align_labels() |
| 104 | + |
| 105 | + |
| 106 | +Axes legends now included in tight_bbox |
| 107 | +--------------------------------------- |
| 108 | + |
| 109 | +Legends created via ``ax.legend`` can sometimes overspill the limits of |
| 110 | +the axis. Tools like ``fig.tight_layout()`` and |
| 111 | +``fig.savefig(bbox_inches='tight')`` would clip these legends. A change |
| 112 | +was made to include them in the ``tight`` calculations. |
| 113 | + |
| 114 | + |
| 115 | +Cividis colormap |
| 116 | +---------------- |
| 117 | + |
| 118 | +A new dark blue/yellow colormap named 'cividis' was added. Like |
| 119 | +viridis, cividis is perceptually uniform and colorblind |
| 120 | +friendly. However, cividis also goes a step further: not only is it |
| 121 | +usable by colorblind users, it should actually look effectively |
| 122 | +identical to colorblind and non-colorblind users. For more details, |
| 123 | +see Nunez J, Anderton C, and Renslow R. (submitted). Optimizing |
| 124 | +colormaps with consideration for color vision deficiency to enable |
| 125 | +accurate interpretation of scientific data." |
| 126 | + |
| 127 | +.. plot:: |
| 128 | + |
| 129 | + import matplotlib.pyplot as plt |
| 130 | + import numpy as np |
| 131 | + |
| 132 | + fig, ax = plt.subplots() |
| 133 | + pcm = ax.pcolormesh(np.random.rand(32,32), cmap='cividis') |
| 134 | + fig.colorbar(pcm) |
| 135 | + |
| 136 | + |
| 137 | +New style colorblind-friendly color cycle |
| 138 | +----------------------------------------- |
| 139 | + |
| 140 | +A new style defining a color cycle has been added, |
| 141 | +tableau-colorblind10, to provide another option for |
| 142 | +colorblind-friendly plots. A demonstration of this new |
| 143 | +style can be found in the reference_ of style sheets. To |
| 144 | +load this color cycle in place of the default one:: |
| 145 | + |
| 146 | + import matplotlib.pyplot as plt |
| 147 | + plt.style.use('tableau-colorblind10') |
| 148 | + |
| 149 | +.. _reference: https://matplotlib.org/gallery/style_sheets/style_sheets_reference.html |
| 150 | + |
| 151 | + |
| 152 | +Support for numpy.datetime64 |
| 153 | +---------------------------- |
| 154 | + |
| 155 | +Matplotlib has supported `datetime.datetime` dates for a long time in |
| 156 | +`matplotlib.dates`. We |
| 157 | +now support `numpy.datetime64` dates as well. Anywhere that |
| 158 | +`dateime.datetime` could be used, `numpy.datetime64` can be used. eg:: |
| 159 | + |
| 160 | + time = np.arange('2005-02-01', '2005-02-02', dtype='datetime64[h]') |
| 161 | + plt.plot(time) |
| 162 | + |
| 163 | + |
| 164 | + |
| 165 | +Writing animations with Pillow |
| 166 | +------------------------------ |
| 167 | +It is now possible to use Pillow as an animation writer. Supported output |
| 168 | +formats are currently gif (Pillow>=3.4) and webp (Pillow>=5.0). Use e.g. as :: |
| 169 | + |
| 170 | + from __future__ import division |
| 171 | + |
| 172 | + from matplotlib import pyplot as plt |
| 173 | + from matplotlib.animation import FuncAnimation, PillowWriter |
| 174 | + |
| 175 | + fig, ax = plt.subplots() |
| 176 | + line, = plt.plot([0, 1]) |
| 177 | + |
| 178 | + def animate(i): |
| 179 | + line.set_ydata([0, i / 20]) |
| 180 | + return [line] |
| 181 | + |
| 182 | + anim = FuncAnimation(fig, animate, 20, blit=True) |
| 183 | + anim.save("movie.gif", writer=PillowWriter(fps=24)) |
| 184 | + plt.show() |
| 185 | + |
| 186 | + |
| 187 | +Slider UI widget can snap to discrete values |
| 188 | +-------------------------------------------- |
| 189 | + |
| 190 | +The slider UI widget can take the optional argument *valstep*. Doing so |
| 191 | +forces the slider to take on only discrete values, starting from *valmin* and |
| 192 | +counting up to *valmax* with steps of size *valstep*. |
| 193 | + |
| 194 | +If *closedmax==True*, then the slider will snap to *valmax* as well. |
| 195 | + |
| 196 | + |
| 197 | + |
| 198 | +``capstyle`` and ``joinstyle`` attributes added to `Collection` |
| 199 | +--------------------------------------------------------------- |
| 200 | + |
| 201 | +The `Collection` class now has customizable ``capstyle`` and ``joinstyle`` |
| 202 | +attributes. This allows the user for example to set the ``capstyle`` of |
| 203 | +errorbars. |
| 204 | + |
| 205 | + |
| 206 | +*pad* kwarg added to ax.set_title |
| 207 | +--------------------------------- |
| 208 | + |
| 209 | +The method `axes.set_title` now has a *pad* kwarg, that specifies the |
| 210 | +distance from the top of an axes to where the title is drawn. The units |
| 211 | +of *pad* is points, and the default is the value of the (already-existing) |
| 212 | +``rcParams['axes.titlepad']``. |
| 213 | + |
| 214 | + |
| 215 | +Comparison of 2 colors in Matplotlib |
| 216 | +------------------------------------ |
| 217 | + |
| 218 | +As the colors in Matplotlib can be specified with a wide variety of ways, the |
| 219 | +`matplotlib.colors.same_color` method has been added which checks if |
| 220 | +two `~matplotlib.colors` are the same. |
| 221 | + |
| 222 | + |
| 223 | +Autoscaling a polar plot snaps to the origin |
| 224 | +-------------------------------------------- |
| 225 | + |
| 226 | +Setting the limits automatically in a polar plot now snaps the radial limit |
| 227 | +to zero if the automatic limit is nearby. This means plotting from zero doesn't |
| 228 | +automatically scale to include small negative values on the radial axis. |
| 229 | + |
| 230 | +The limits can still be set manually in the usual way using `set_ylim`. |
| 231 | + |
| 232 | + |
| 233 | +PathLike support |
| 234 | +---------------- |
| 235 | + |
| 236 | +On Python 3.6+, `~matplotlib.pyplot.savefig`, `~matplotlib.pyplot.imsave`, |
| 237 | +`~matplotlib.pyplot.imread`, and animation writers now accept `os.PathLike`\s |
| 238 | +as input. |
| 239 | + |
| 240 | + |
| 241 | +`Axes.tick_params` can set gridline properties |
| 242 | +---------------------------------------------- |
| 243 | + |
| 244 | +`Tick` objects hold gridlines as well as the tick mark and its label. |
| 245 | +`Axis.set_tick_params`, `Axes.tick_params` and `pyplot.tick_params` |
| 246 | +now have keyword arguments 'grid_color', 'grid_alpha', 'grid_linewidth', |
| 247 | +and 'grid_linestyle' for overriding the defaults in `rcParams`: |
| 248 | +'grid.color', etc. |
| 249 | + |
| 250 | + |
| 251 | +`Axes.imshow` clips RGB values to the valid range |
| 252 | +------------------------------------------------- |
| 253 | + |
| 254 | +When `Axes.imshow` is passed an RGB or RGBA value with out-of-range |
| 255 | +values, it now logs a warning and clips them to the valid range. |
| 256 | +The old behaviour, wrapping back in to the range, often hid outliers |
| 257 | +and made interpreting RGB images unreliable. |
| 258 | + |
| 259 | + |
| 260 | +Properties in `matplotlibrc` to place xaxis and yaxis tick labels |
| 261 | +----------------------------------------------------------------- |
| 262 | + |
| 263 | +Introducing four new boolean properties in `.matplotlibrc` for default |
| 264 | +positions of xaxis and yaxis tick labels, namely, |
| 265 | +`xtick.labeltop`, `xtick.labelbottom`, `ytick.labelright` and |
| 266 | +`ytick.labelleft`. These can also be changed in rcParams. |
| 267 | + |
| 268 | + |
| 269 | +PGI bindings for gtk3 |
| 270 | +--------------------- |
| 271 | + |
| 272 | +The GTK3 backends can now use PGI_ instead of PyGObject_. PGI is a fairly |
| 273 | +incomplete binding for GObject, thus its use is not recommended; its main |
| 274 | +benefit is its availability on Travis (thus allowing CI testing for the gtk3agg |
| 275 | +and gtk3cairo backends). |
| 276 | + |
| 277 | +The binding selection rules are as follows: |
| 278 | +- if ``gi`` has already been imported, use it; else |
| 279 | +- if ``pgi`` has already been imported, use it; else |
| 280 | +- if ``gi`` can be imported, use it; else |
| 281 | +- if ``pgi`` can be imported, use it; else |
| 282 | +- error out. |
| 283 | + |
| 284 | +Thus, to force usage of PGI when both bindings are installed, import it first. |
| 285 | + |
| 286 | +.. _PGI: https://pgi.readthedocs.io/en/latest/ |
| 287 | +.. _PyGObject: http://pygobject.readthedocs.io/en/latest/# |
| 288 | + |
| 289 | + |
| 290 | + |
| 291 | +Cairo rendering for Qt, WX, and Tk canvases |
| 292 | +------------------------------------------- |
| 293 | + |
| 294 | +The new ``Qt4Cairo``, ``Qt5Cairo``, ``WXCairo``, and ``TkCairo`` |
| 295 | +backends allow Qt, Wx, and Tk canvases to use Cairo rendering instead of |
| 296 | +Agg. |
| 297 | + |
| 298 | + |
| 299 | +Added support for QT in new ToolManager |
| 300 | +--------------------------------------- |
| 301 | + |
| 302 | +Now it is possible to use the ToolManager with Qt5 |
| 303 | +For example |
| 304 | + |
| 305 | + import matplotlib |
| 306 | + |
| 307 | + matplotlib.use('QT5AGG') |
| 308 | + matplotlib.rcParams['toolbar'] = 'toolmanager' |
| 309 | + import matplotlib.pyplot as plt |
| 310 | + |
| 311 | + plt.plot([1,2,3]) |
| 312 | + plt.show() |
| 313 | + |
| 314 | + |
| 315 | +Treat the new Tool classes experimental for now, the API will likely change and perhaps the rcParam as well |
| 316 | + |
| 317 | +The main example `examples/user_interfaces/toolmanager_sgskip.py` shows more |
| 318 | +details, just adjust the header to use QT instead of GTK3 |
| 319 | + |
| 320 | + |
| 321 | + |
| 322 | +TkAgg backend reworked to support PyPy |
| 323 | +-------------------------------------- |
| 324 | + |
| 325 | +PyPy_ can now plot using the TkAgg backend, supported on PyPy 5.9 |
| 326 | +and greater (both PyPy for python 2.7 and PyPy for python 3.5). |
| 327 | + |
| 328 | +.. _PyPy: https:/www.pypy.org |
| 329 | + |
| 330 | + |
| 331 | + |
| 332 | +Python logging library used for debug output |
| 333 | +-------------------------------------------- |
| 334 | + |
| 335 | +Matplotlib has in the past (sporadically) used an internal |
| 336 | +verbose-output reporter. This version converts those calls to using the |
| 337 | +standard python `logging` library. |
| 338 | + |
| 339 | +Support for the old ``rcParams`` ``verbose.level`` and ``verbose.fileo`` is |
| 340 | +dropped. |
| 341 | + |
| 342 | +The command-line options ``--verbose-helpful`` and ``--verbose-debug`` are |
| 343 | +still accepted, but deprecated. They are now equivalent to setting |
| 344 | +``logging.INFO`` and ``logging.DEBUG``. |
| 345 | + |
| 346 | +The logger's root name is ``matplotlib`` and can be accessed from programs |
| 347 | +as:: |
| 348 | + |
| 349 | + import logging |
| 350 | + mlog = logging.getLogger('matplotlib') |
| 351 | + |
| 352 | +Instructions for basic usage are in :ref:`troubleshooting-faq` and for |
| 353 | +developers in :ref:`contributing`. |
| 354 | + |
| 355 | +.. _logging: https://docs.python.org/3/library/logging.html |
| 356 | + |
| 357 | +Improved `repr` for `Transform`\s |
| 358 | +--------------------------------- |
| 359 | + |
| 360 | +`Transform`\s now indent their `repr`\s in a more legible manner: |
| 361 | + |
| 362 | +.. code-block:: ipython |
| 363 | +
|
| 364 | + In [1]: l, = plt.plot([]); l.get_transform() |
| 365 | + Out[1]: |
| 366 | + CompositeGenericTransform( |
| 367 | + TransformWrapper( |
| 368 | + BlendedAffine2D( |
| 369 | + IdentityTransform(), |
| 370 | + IdentityTransform())), |
| 371 | + CompositeGenericTransform( |
| 372 | + BboxTransformFrom( |
| 373 | + TransformedBbox( |
| 374 | + Bbox(x0=-0.05500000000000001, y0=-0.05500000000000001, x1=0.05500000000000001, y1=0.05500000000000001), |
| 375 | + TransformWrapper( |
| 376 | + BlendedAffine2D( |
| 377 | + IdentityTransform(), |
| 378 | + IdentityTransform())))), |
| 379 | + BboxTransformTo( |
| 380 | + TransformedBbox( |
| 381 | + Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88), |
| 382 | + BboxTransformTo( |
| 383 | + TransformedBbox( |
| 384 | + Bbox(x0=0.0, y0=0.0, x1=6.4, y1=4.8), |
| 385 | + Affine2D( |
| 386 | + [[ 100. 0. 0.] |
| 387 | + [ 0. 100. 0.] |
| 388 | + [ 0. 0. 1.]]))))))) |
0 commit comments