From b562b9154b5bad42e0d651cc1606dafdb377848b Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 7 Jul 2020 22:24:49 -0400 Subject: [PATCH 01/12] DOC: Fix names for GitHub stats pages. --- doc/users/prev_whats_new/github_stats_3.1.2.rst | 6 +++--- doc/users/prev_whats_new/github_stats_3.2.0.rst | 4 ++-- doc/users/prev_whats_new/github_stats_3.2.1.rst | 4 ++-- doc/users/prev_whats_new/github_stats_3.2.2.rst | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/users/prev_whats_new/github_stats_3.1.2.rst b/doc/users/prev_whats_new/github_stats_3.1.2.rst index 9b6356f3a120..9f11f34cb78a 100644 --- a/doc/users/prev_whats_new/github_stats_3.1.2.rst +++ b/doc/users/prev_whats_new/github_stats_3.1.2.rst @@ -1,7 +1,7 @@ -.. _github-stats_3-1-2: +.. _github-stats-3-1-2: -GitHub Stats -============ +GitHub Stats for Matplotlib 3.1.2 +================================= GitHub stats for 2019/05/18 - 2019/06/30 (tag: v3.1.0) diff --git a/doc/users/prev_whats_new/github_stats_3.2.0.rst b/doc/users/prev_whats_new/github_stats_3.2.0.rst index 2c6562a50ba2..f5cee3ad245c 100644 --- a/doc/users/prev_whats_new/github_stats_3.2.0.rst +++ b/doc/users/prev_whats_new/github_stats_3.2.0.rst @@ -1,7 +1,7 @@ .. _github-stats-3-2-0: -GitHub Stats -============ +GitHub Stats for Matplotlib 3.2.0 +================================= GitHub stats for 2019/05/18 - 2020/03/03 (tag: v3.1.0) diff --git a/doc/users/prev_whats_new/github_stats_3.2.1.rst b/doc/users/prev_whats_new/github_stats_3.2.1.rst index 717c4e8f3b04..ec95cf4a7887 100644 --- a/doc/users/prev_whats_new/github_stats_3.2.1.rst +++ b/doc/users/prev_whats_new/github_stats_3.2.1.rst @@ -1,7 +1,7 @@ .. _github-stats-3-2-1: -GitHub Stats -============ +GitHub Stats for Matplotlib 3.2.1 +================================= GitHub stats for 2020/03/03 - 2020/03/17 (tag: v3.2.0) diff --git a/doc/users/prev_whats_new/github_stats_3.2.2.rst b/doc/users/prev_whats_new/github_stats_3.2.2.rst index c1a7a5a307ba..8cd4e4eef1d7 100644 --- a/doc/users/prev_whats_new/github_stats_3.2.2.rst +++ b/doc/users/prev_whats_new/github_stats_3.2.2.rst @@ -1,7 +1,7 @@ -. .. _github-stats-3-2-2: +.. _github-stats-3-2-2: -GitHub Stats -============ +GitHub Stats for Matplotlib 3.2.2 +================================= GitHub stats for 2020/03/18 - 2020/06/17 (tag: v3.2.1) From 1472b3909e002d409538b5d54557a141268d1fb3 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 8 Jul 2020 01:03:22 -0400 Subject: [PATCH 02/12] Add some duplicate names to mailmap. --- .mailmap | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index ad8b7a0c832b..44005da6e2d8 100644 --- a/.mailmap +++ b/.mailmap @@ -149,8 +149,14 @@ Leon Yin Lion Krischer +Manan Kevadiya +Manan Kevadiya <43081866+manan2501@users.noreply.github.com> + Manuel Nuno Melo +Marco Gorelli +Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> + Marek Rudnicki Martin Fitzpatrick @@ -189,7 +195,9 @@ Nicolas P. Rougier OceanWolf -Olivier +Olivier Castany <1868182+ocastany@users.noreply.github.com> +Olivier Castany <1868182+ocastany@users.noreply.github.com> +Olivier Castany <1868182+ocastany@users.noreply.github.com> Om Sitapara From d5eace4c3ea967f03fda42442ba2ac93f0e48fba Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 8 Jul 2020 01:19:23 -0400 Subject: [PATCH 03/12] DOC: Fix some inconsistent heading underlines. --- doc/users/prev_whats_new/whats_new_1.0.rst | 18 +++++++++--------- doc/users/prev_whats_new/whats_new_1.5.rst | 2 +- doc/users/prev_whats_new/whats_new_2.2.rst | 4 ++-- doc/users/prev_whats_new/whats_new_3.0.rst | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/users/prev_whats_new/whats_new_1.0.rst b/doc/users/prev_whats_new/whats_new_1.0.rst index 4f0a6fc47039..cafa8917d518 100644 --- a/doc/users/prev_whats_new/whats_new_1.0.rst +++ b/doc/users/prev_whats_new/whats_new_1.0.rst @@ -1,7 +1,7 @@ .. _whats-new-1-0: New in matplotlib 1.0 -====================== +===================== .. contents:: Table of Contents :depth: 2 @@ -9,7 +9,7 @@ New in matplotlib 1.0 .. _whats-new-html5: HTML5/Canvas backend ---------------------- +-------------------- Simon Ratcliffe and Ludwig Schwardt have released an `HTML5/Canvas `__ backend for matplotlib. The @@ -47,7 +47,7 @@ indexing (starts with 0). e.g.:: See :doc:`/gallery/subplots_axes_and_figures/subplot_demo` for several code examples. Contour fixes and and triplot ---------------------------------- +----------------------------- Ian Thomas has fixed a long-standing bug that has vexed our most talented developers for years. :func:`~matplotlib.pyplot.contourf` @@ -66,7 +66,7 @@ plotting unstructured triangular grids. Triplot Demo multiple calls to show supported ---------------------------------- +-------------------------------- A long standing request is to support multiple calls to :func:`~matplotlib.pyplot.show`. This has been difficult because it @@ -85,7 +85,7 @@ and `bug tracker mplot3d graphs can be embedded in arbitrary axes -------------------------------------------------- +------------------------------------------------ You can now place an mplot3d graph into an arbitrary axes location, supporting mixing of 2D and 3D graphs in the same figure, and/or @@ -100,7 +100,7 @@ argument to add_axes or add_subplot. Thanks Ben Root. What's New 1 Subplot3d tick_params ------------- +----------- Eric Firing wrote tick_params, a convenience method for changing the appearance of ticks and tick labels. See pyplot function @@ -108,7 +108,7 @@ appearance of ticks and tick labels. See pyplot function :meth:`~matplotlib.axes.Axes.tick_params`. Lots of performance and feature enhancements ---------------------------------------------- +-------------------------------------------- * Faster magnification of large images, and the ability to zoom in to @@ -124,7 +124,7 @@ Lots of performance and feature enhancements throughout the API Much improved software carpentry ---------------------------------- +-------------------------------- The matplotlib trunk is probably in as good a shape as it has ever been, thanks to improved `software carpentry @@ -140,7 +140,7 @@ Thanks to Andrew Straw, Michael Droettboom and other matplotlib developers for the heavy lifting. Bugfix marathon ----------------- +--------------- Eric Firing went on a bug fixing and closing marathon, closing over 100 bugs on the (now-closed) SourceForge bug tracker with help from Jae-Joon Lee, Michael diff --git a/doc/users/prev_whats_new/whats_new_1.5.rst b/doc/users/prev_whats_new/whats_new_1.5.rst index 55f52aa5e417..97e4f81fd306 100644 --- a/doc/users/prev_whats_new/whats_new_1.5.rst +++ b/doc/users/prev_whats_new/whats_new_1.5.rst @@ -113,7 +113,7 @@ on two or more property cycles. New Colormaps --------------- +------------- All four of the colormaps proposed as the new default are available as ``'viridis'`` (the new default in 2.0), ``'magma'``, ``'plasma'``, and diff --git a/doc/users/prev_whats_new/whats_new_2.2.rst b/doc/users/prev_whats_new/whats_new_2.2.rst index 41f28ff72b17..05affccc7a6f 100644 --- a/doc/users/prev_whats_new/whats_new_2.2.rst +++ b/doc/users/prev_whats_new/whats_new_2.2.rst @@ -37,14 +37,14 @@ Features include: Note the new API to access this: New ``plt.figure`` and ``plt.subplots`` kwarg: ``constrained_layout`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :meth:`~matplotlib.pyplot.figure` and :meth:`~matplotlib.pyplot.subplots` can now be called with ``constrained_layout=True`` kwarg to enable constrained_layout. New ``ax.set_position`` behaviour -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `.Axes.set_position` now makes the specified axis no longer responsive to ``constrained_layout``, consistent with the idea that the diff --git a/doc/users/prev_whats_new/whats_new_3.0.rst b/doc/users/prev_whats_new/whats_new_3.0.rst index f5f530326322..c92bc9c94f88 100644 --- a/doc/users/prev_whats_new/whats_new_3.0.rst +++ b/doc/users/prev_whats_new/whats_new_3.0.rst @@ -1,7 +1,7 @@ .. _whats-new-3-0-0: New in Matplotlib 3.0 -============================= +===================== Improved default backend selection ---------------------------------- @@ -41,7 +41,7 @@ the order of magnitude depending on the axis values, rather than keeping it fixe Add ``AnchoredDirectionArrows`` feature to mpl_toolkits --------------------------------------------------------- +------------------------------------------------------- A new mpl_toolkits class :class:`~mpl_toolkits.axes_grid1.anchored_artists.AnchoredDirectionArrows` From 8d826733c601efedd4865de4b4264bd26004f3c9 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 8 Jul 2020 01:41:34 -0400 Subject: [PATCH 04/12] DOC: Don't use cross-references in section titles. This totally messed up the page ToC. --- doc/users/prev_whats_new/whats_new_3.3.0.rst | 35 ++++++++++---------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/doc/users/prev_whats_new/whats_new_3.3.0.rst b/doc/users/prev_whats_new/whats_new_3.3.0.rst index 78cb108bba3e..73ed592623f1 100644 --- a/doc/users/prev_whats_new/whats_new_3.3.0.rst +++ b/doc/users/prev_whats_new/whats_new_3.3.0.rst @@ -12,8 +12,8 @@ revision, see the :ref:`github-stats`. :maxdepth: 4 -New `~.axes.Axes.axline` method -------------------------------- +New ``Axes.axline`` method +-------------------------- A new `~.axes.Axes.axline` method has been added to draw infinitely long lines that pass through two points. @@ -114,8 +114,8 @@ For use cases check out the :doc:`Axes box aspect ` example. -`.Axes.sharex`, `.Axes.sharey` ------------------------------- +``Axes.sharex``, ``Axes.sharey`` +-------------------------------- These new methods allow sharing axes *immediately* after creating them. For example, they can be used to selectively link some axes created all together @@ -198,8 +198,8 @@ as an alternative to :: fig.subplots(2, 2, gridspec_kw={"height_ratios": [3, 1]}) -`matplotlib.rc_context` is now a `contextlib.contextmanager` ------------------------------------------------------------- +``matplotlib.rc_context`` is now a ``contextlib.contextmanager`` +---------------------------------------------------------------- `matplotlib.rc_context` can now be used as a decorator (technically, it is now implemented as a `contextlib.contextmanager`), e.g. :: @@ -396,8 +396,8 @@ conversion (using the new epoch) is:: -`~.axes.Axes.set_title` gains a *y* keyword argument to control auto positioning --------------------------------------------------------------------------------- +``Axes.set_title`` gains a *y* keyword argument to control auto positioning +--------------------------------------------------------------------------- `~.axes.Axes.set_title` tries to auto-position the title to avoid any decorators on the top x-axis. This is not always desirable so now @@ -411,8 +411,8 @@ tight_layout now supports suptitle ---------------------------------- -Add :rc:`contour.linewidth` to rcParams ---------------------------------------- +Add ``contour.linewidth`` to rcParams +------------------------------------- The new config option :rc:`contour.linewidth` allows to control the default line width of contours as a float. When set to ``None``, the line widths fall @@ -448,11 +448,12 @@ was only accepted by the PGF backend when saving a multi-page PDF with `.backend_pgf.PdfPages`, but is now allowed when saving a single figure, as well. -`.backend_bases.key_press_handler` and `.backend_bases.button_press_handler` simplifications --------------------------------------------------------------------------------------------- +``backend_bases.key_press_handler`` and ``backend_bases.button_press_handler`` simplifications +---------------------------------------------------------------------------------------------- -These event handlers can now be directly connected to a canvas with -``canvas.mpl_connect("key_press_event", key_press_handler)`` and -``canvas.mpl_connect("button_press_event", button_press_handler)``, rather than -having to write wrapper functions that fill in the (now optional) *canvas* and -*toolbar* parameters. +The `.backend_bases.key_press_handler` and +`.backend_bases.button_press_handler` event handlers can now be directly +connected to a canvas with ``canvas.mpl_connect("key_press_event", +key_press_handler)`` and ``canvas.mpl_connect("button_press_event", +button_press_handler)``, rather than having to write wrapper functions that +fill in the (now optional) *canvas* and *toolbar* parameters. From 20ccea8cc1dbd722cfd98aea24233452235727d0 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 8 Jul 2020 16:12:49 -0400 Subject: [PATCH 05/12] DOC: Re-order 3.3. what's new page. Generally, this is things-with-a-plot, then things-with-an-example, then some random other stuff, and finally groups of things-with-something-in-common (e.g., all rcParams together). --- doc/users/prev_whats_new/whats_new_3.3.0.rst | 405 +++++++++---------- 1 file changed, 200 insertions(+), 205 deletions(-) diff --git a/doc/users/prev_whats_new/whats_new_3.3.0.rst b/doc/users/prev_whats_new/whats_new_3.3.0.rst index 73ed592623f1..0391af789cea 100644 --- a/doc/users/prev_whats_new/whats_new_3.3.0.rst +++ b/doc/users/prev_whats_new/whats_new_3.3.0.rst @@ -12,67 +12,18 @@ revision, see the :ref:`github-stats`. :maxdepth: 4 -New ``Axes.axline`` method --------------------------- - -A new `~.axes.Axes.axline` method has been added to draw infinitely long lines -that pass through two points. - - - -.. plot:: - :include-source: True - - fig, ax = plt.subplots() - - ax.axline((.1, .1), slope=5, color='C0', label='by slope') - ax.axline((.1, .2), (.8, .7), color='C3', label='by points') - - ax.legend() - - -Allow tick formatters to be set with str or function inputs ------------------------------------------------------------ - -`~.Axis.set_major_formatter` and `~.Axis.set_minor_formatter` -now accept `str` or function inputs in addition to `~.ticker.Formatter` -instances. For a `str` a `~.ticker.StrMethodFormatter` is automatically -generated and used. For a function a `~.ticker.FuncFormatter` is automatically -generated and used. - - - -Text color for legend labels ----------------------------- - -The text color of legend labels can now be set by passing a parameter -``labelcolor`` to `~.axes.Axes.legend`. The ``labelcolor`` keyword can be: - -* A single color (either a string or RGBA tuple), which adjusts the text color - of all the labels. -* A list or tuple, allowing the text color of each label to be set - individually. -* ``linecolor``, which sets the text color of each label to match the - corresponding line color. -* ``markerfacecolor``, which sets the text color of each label to match the - corresponding marker face color. -* ``markeredgecolor``, which sets the text color of each label to match the - corresponding marker edge color. - - - Provisional API for composing semantic axes layouts from text or nested lists ----------------------------------------------------------------------------- -The `.Figure` class has a provisional method to generate complex grids -of named `.axes.Axes` based on nested list input or ASCII art: +The `.Figure` class has a provisional method to generate complex grids of named +`.axes.Axes` based on nested list input or ASCII art: .. plot:: :include-source: True axd = plt.figure(constrained_layout=True).subplot_mosaic( - [["Top", "Top", "Edge"], - ["Left", ".", "Edge"]] + [["Top", "Top", "Edge"], + ["Left", ".", "Edge"]] ) for k, ax in axd.items(): ax.text(0.5, 0.5, k, @@ -85,54 +36,47 @@ or as a string (with single-character Axes labels): :include-source: True axd = plt.figure(constrained_layout=True).subplot_mosaic( - """ - TTE - L.E - """) + """ + TTE + L.E + """) for k, ax in axd.items(): ax.text(0.5, 0.5, k, ha='center', va='center', fontsize=36, color='darkgrey') - - See :ref:`sphx_glr_tutorials_provisional_mosaic.py` for more details and examples. -Setting axes box aspect +``GridSpec.subplots()`` ----------------------- -It is now possible to set the aspect of an axes box directly via -`~.Axes.set_box_aspect`. The box aspect is the ratio between axes height -and axes width in physical units, independent of the data limits. -This is useful to e.g. produce a square plot, independent of the data it -contains, or to have a usual plot with the same axes dimensions next to -an image plot with fixed (data-)aspect. +The `.GridSpec` class gained a `~.GridSpecBase.subplots` method, so that one +can write :: -For use cases check out the :doc:`Axes box aspect -` example. + fig.add_gridspec(2, 2, height_ratios=[3, 1]).subplots() +as an alternative to :: -``Axes.sharex``, ``Axes.sharey`` --------------------------------- + fig.subplots(2, 2, gridspec_kw={"height_ratios": [3, 1]}) -These new methods allow sharing axes *immediately* after creating them. For -example, they can be used to selectively link some axes created all together -using `~.Figure.subplots`. -Note that they may *not* be used to share axes after any operation (e.g., -drawing) has occurred on them. +New ``Axes.axline`` method +-------------------------- +A new `~.axes.Axes.axline` method has been added to draw infinitely long lines +that pass through two points. -Align labels to Axes edges --------------------------- +.. plot:: + :include-source: True -`~.axes.Axes.set_xlabel`, `~.axes.Axes.set_ylabel` and `.ColorbarBase.set_label` -support a parameter ``loc`` for simplified positioning. Supported values are -'left', 'center', or 'right'. The default is controlled via -:rc:`xaxis.labelposition` and :rc:`yaxis.labelposition`; the Colorbar label -takes the rcParam based on its orientation. + fig, ax = plt.subplots() + + ax.axline((.1, .1), slope=5, color='C0', label='by slope') + ax.axline((.1, .2), (.8, .7), color='C3', label='by points') + + ax.legend() New "extend" keyword to colors.BoundaryNorm @@ -185,83 +129,113 @@ for out-of-range values with colors that differ from adjacent in-range colors. plt.show() -``GridSpec.subplots()`` ------------------------ +Text color for legend labels +---------------------------- -The `.GridSpec` class gained a `~.GridSpecBase.subplots` method, so that one -can write :: +The text color of legend labels can now be set by passing a parameter +``labelcolor`` to `~.axes.Axes.legend`. The ``labelcolor`` keyword can be: - fig.add_gridspec(2, 2, height_ratios=[3, 1]).subplots() +* A single color (either a string or RGBA tuple), which adjusts the text color + of all the labels. +* A list or tuple, allowing the text color of each label to be set + individually. +* ``linecolor``, which sets the text color of each label to match the + corresponding line color. +* ``markerfacecolor``, which sets the text color of each label to match the + corresponding marker face color. +* ``markeredgecolor``, which sets the text color of each label to match the + corresponding marker edge color. -as an alternative to :: - fig.subplots(2, 2, gridspec_kw={"height_ratios": [3, 1]}) +``Axes.sharex``, ``Axes.sharey`` +-------------------------------- +These new methods allow sharing axes *immediately* after creating them. For +example, they can be used to selectively link some axes created all together +using `~.Figure.subplots`. -``matplotlib.rc_context`` is now a ``contextlib.contextmanager`` ----------------------------------------------------------------- +Note that they may *not* be used to share axes after any operation (e.g., +drawing) has occurred on them. -`matplotlib.rc_context` can now be used as a decorator (technically, it is now -implemented as a `contextlib.contextmanager`), e.g. :: - @rc_context({"lines.linewidth": 2}) - def some_function(...): - ... +Align labels to Axes edges +-------------------------- -rcParams for controlling default "raise window" behavior --------------------------------------------------------- -The new config option :rc:`figure.raise_window` allows to disable -raising the plot window when calling `~.pyplot.show` or `~.pyplot.pause`. -``MacOSX`` backend is currently not supported. +`~.axes.Axes.set_xlabel`, `~.axes.Axes.set_ylabel` and `.ColorbarBase.set_label` +support a parameter ``loc`` for simplified positioning. Supported values are +'left', 'center', or 'right'. The default is controlled via +:rc:`xaxis.labelposition` and :rc:`yaxis.labelposition`; the Colorbar label +takes the rcParam based on its orientation. +Offset text is now set to the top when using ``axis.tick_top()`` +---------------------------------------------------------------- -``imshow`` now coerces 3D arrays with depth 1 to 2D ---------------------------------------------------- +Solves the issue that the power indicator (e.g., 1e4) stayed on the bottom, +even if the ticks were on the top. -Starting from this version arrays of size MxNx1 will be coerced into MxN -for displaying. This means commands like ``plt.imshow(np.random.rand(3, 3, 1))`` -will no longer return an error message that the image shape is invalid. +``Axes.set_title`` gains a *y* keyword argument to control auto positioning +--------------------------------------------------------------------------- -``Axes3D`` no longer distorts the 3D plot to match the 2D aspect ratio ----------------------------------------------------------------------- +`~.axes.Axes.set_title` tries to auto-position the title to avoid any +decorators on the top x-axis. This is not always desirable so now *y* is an +explicit keyword argument of `~.axes.Axes.set_title`. It defaults to *None* +which means to use auto-positioning. If a value is supplied (i.e. the pre-3.0 +default was ``y=1.0``) then auto-positioning is turned off. This can also be +set with the new rcParameter :rc:`axes.titley`. -Plots made with :class:`~mpl_toolkits.mplot3d.axes3d.Axes3D` were previously -stretched to fit a square bounding box. As this stretching was done after -the projection from 3D to 2D, it resulted in distorted images if non-square -bounding boxes were used. As of 3.3, this no longer occurs. -Currently, modes of setting the aspect (via -`~mpl_toolkits.mplot3d.axes3d.Axes3D.set_aspect`) in data space are -not supported for Axes3D but may be in the future. If you want to -simulate having equal aspect in data space, set the ratio of your data -limits to match the value of `~.get_box_aspect`. To control these -ratios use the `~mpl_toolkits.mplot3d.axes3d.Axes3D.set_box_aspect` -method which accepts the ratios as a 3-tuple of X:Y:Z. The default -aspect ratio is 4:4:3. +Dates now use a modern epoch +---------------------------- +Matplotlib converts dates to days since an epoch using `.dates.date2num` (via +`matplotlib.units`). Previously, an epoch of ``0000-12-31T00:00:00`` was used +so that ``0001-01-01`` was converted to 1.0. An epoch so distant in the +past meant that a modern date was not able to preserve microseconds because +2000 years times the 2^(-52) resolution of a 64-bit float gives 14 +microseconds. -3D axes now support minor ticks -------------------------------- +Here we change the default epoch to the more reasonable UNIX default of +``1970-01-01T00:00:00`` which for a modern date has 0.35 microsecond +resolution. (Finer resolution is not possible because we rely on +`datetime.datetime` for the date locators). Access to the epoch is provided +by `~.dates.get_epoch`, and there is a new :rc:`date.epoch` rcParam. The user +may also call `~.dates.set_epoch`, but it must be set *before* any date +conversion or plotting is used. -Home/Forward/Backward buttons now work with 3D axes ---------------------------------------------------- +If you have data stored as ordinal floats in the old epoch, a simple +conversion (using the new epoch) is:: + new_ordinal = old_ordinal + mdates.date2num(np.datetime64('0000-12-31')) -``savefig()`` gained a *backend* keyword argument -------------------------------------------------- +tight_layout now supports suptitle +---------------------------------- -The *backend* keyword argument to ``savefig`` can now be used to pick the -rendering backend without having to globally set the backend; e.g. one can save -PDFs using the pgf backend with ``savefig("file.pdf", backend="pgf")``. +Allow tick formatters to be set with str or function inputs +----------------------------------------------------------- -Offset text is now set to the top when using ``axis.tick_top()`` ----------------------------------------------------------------- +`~.Axis.set_major_formatter` and `~.Axis.set_minor_formatter` +now accept `str` or function inputs in addition to `~.ticker.Formatter` +instances. For a `str` a `~.ticker.StrMethodFormatter` is automatically +generated and used. For a function a `~.ticker.FuncFormatter` is automatically +generated and used. -Solves the issue that the power indicator (e.g. 1e4) stayed on the bottom, even if the ticks were on the top. + +Setting axes box aspect +----------------------- + +It is now possible to set the aspect of an axes box directly via +`~.Axes.set_box_aspect`. The box aspect is the ratio between axes height +and axes width in physical units, independent of the data limits. +This is useful to, e.g., produce a square plot, independent of the data it +contains, or to have a usual plot with the same axes dimensions next to +an image plot with fixed (data-)aspect. + +For use cases check out the :doc:`Axes box aspect +` example. Pcolor and Pcolormesh now accept ``shading='nearest'`` and ``'auto'`` @@ -291,6 +265,22 @@ See :doc:`pcolormesh ` for examples. +Lines now accept ``MarkerStyle`` instances as input +--------------------------------------------------- + +Similar to `~.Axes.scatter`, `~.Axes.plot` and `~.lines.Line2D` now accept +`~.markers.MarkerStyle` instances as input for the *marker* parameter:: + + plt.plot(..., marker=matplotlib.markers.MarkerStyle("D")) + + +``imshow`` now coerces 3D arrays with depth 1 to 2D +--------------------------------------------------- + +Starting from this version arrays of size MxNx1 will be coerced into MxN +for displaying. This means commands like ``plt.imshow(np.random.rand(3, 3, 1))`` +will no longer return an error message that the image shape is invalid. + Set zorder of contour labels ---------------------------- @@ -311,36 +301,93 @@ Fonts can now be selected by passing an absolute `pathlib.Path` to the *font* keyword argument of `.Text`. -Add generalized "mathtext.fallback" rcParam -------------------------------------------- +rcParams improvements +--------------------- + +``matplotlib.rc_context`` is now a ``contextlib.contextmanager`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`matplotlib.rc_context` can now be used as a decorator (technically, it is now +implemented as a `contextlib.contextmanager`), e.g., :: + + @rc_context({"lines.linewidth": 2}) + def some_function(...): + ... + +rcParams for controlling default "raise window" behavior +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The new config option :rc:`figure.raise_window` allows to disable +raising the plot window when calling `~.pyplot.show` or `~.pyplot.pause`. +The ``MacOSX`` backend is currently not supported. + +Add generalized ``mathtext.fallback`` to rcParams +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ New :rc:`mathtext.fallback` rcParam. Takes "cm", "stix", "stixsans" or "none" to turn fallback off. The rcParam *mathtext.fallback_to_cm* is deprecated, but if used, will override new fallback. +Add ``contour.linewidth`` to rcParams +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Lines now accept ``MarkerStyle`` instances as input ---------------------------------------------------- +The new config option :rc:`contour.linewidth` allows to control the default +line width of contours as a float. When set to ``None``, the line widths fall +back to :rc:`lines.linewidth`. The config value is overridden as usual by the +*linewidths* argument passed to `~.axes.Axes.contour` when it is not set to +``None``. -Similar to `~.Axes.scatter`, `~.Axes.plot` and `~.lines.Line2D` now accept -`~.markers.MarkerStyle` instances as input for the *marker* parameter:: - plt.plot(..., marker=matplotlib.markers.MarkerStyle("D")) +3D Axes improvements +-------------------- + +``Axes3D`` no longer distorts the 3D plot to match the 2D aspect ratio +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Plots made with :class:`~mpl_toolkits.mplot3d.axes3d.Axes3D` were previously +stretched to fit a square bounding box. As this stretching was done after the +projection from 3D to 2D, it resulted in distorted images if non-square +bounding boxes were used. As of 3.3, this no longer occurs. + +Currently, modes of setting the aspect (via +`~mpl_toolkits.mplot3d.axes3d.Axes3D.set_aspect`) in data space are not +supported for Axes3D but may be in the future. If you want to simulate having +equal aspect in data space, set the ratio of your data limits to match the +value of `~.get_box_aspect`. To control these ratios use the +`~mpl_toolkits.mplot3d.axes3d.Axes3D.set_box_aspect` method which accepts the +ratios as a 3-tuple of X:Y:Z. The default aspect ratio is 4:4:3. +3D axes now support minor ticks +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Home/Forward/Backward buttons now work with 3D axes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Interactive tool improvements +----------------------------- + Cursor text now uses a number of significant digits matching pointing precision -------------------------------------------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Previously, the x/y position displayed by the cursor text would usually include far more significant digits than the mouse pointing precision (typically one -pixel). This is now fixed for linear scales. - +pixel). This is now fixed for linear scales. Qt zoom rectangle now black and white -------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This makes it visible even over a dark background. +``backend_bases.key_press_handler`` and ``backend_bases.button_press_handler`` simplifications +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The `.backend_bases.key_press_handler` and +`.backend_bases.button_press_handler` event handlers can now be directly +connected to a canvas with ``canvas.mpl_connect("key_press_event", +key_press_handler)`` and ``canvas.mpl_connect("button_press_event", +button_press_handler)``, rather than having to write wrapper functions that +fill in the (now optional) *canvas* and *toolbar* parameters. + Functions to compute a Path's size ---------------------------------- @@ -370,67 +417,25 @@ a correct upper bound for the path's extents, it can differ dramatically from the Path's actual extents for non-linear Bezier curves. -Dates now use a modern epoch ----------------------------- - -Matplotlib converts dates to days since an epoch using `.dates.date2num` (via -`matplotlib.units`). Previously, an epoch of ``0000-12-31T00:00:00`` was used -so that ``0001-01-01`` was converted to 1.0. An epoch so distant in the -past meant that a modern date was not able to preserve microseconds because -2000 years times the 2^(-52) resolution of a 64-bit float gives 14 -microseconds. - -Here we change the default epoch to the more reasonable UNIX default of -``1970-01-01T00:00:00`` which for a modern date has 0.35 microsecond -resolution. (Finer resolution is not possible because we rely on -`datetime.datetime` for the date locators). Access to the epoch is provided -by `~.dates.get_epoch`, and there is a new :rc:`date.epoch` rcParam. The user -may also call `~.dates.set_epoch`, but it must be set *before* any date -conversion or plotting is used. - -If you have data stored as ordinal floats in the old epoch, a simple -conversion (using the new epoch) is:: - - new_ordinal = old_ordinal + mdates.date2num(np.datetime64('0000-12-31')) - - - - -``Axes.set_title`` gains a *y* keyword argument to control auto positioning ---------------------------------------------------------------------------- - -`~.axes.Axes.set_title` tries to auto-position the title to avoid any -decorators on the top x-axis. This is not always desirable so now -*y* is an explicit keyword argument of `~.axes.Axes.set_title`. It -defaults to *None* which means to use auto-positioning. If a value is -supplied (i.e. the pre-3.0 default was ``y=1.0``) then auto-positioning is -turned off. This can also be set with the new rcParameter :rc:`axes.titley`. - - -tight_layout now supports suptitle ----------------------------------- - - -Add ``contour.linewidth`` to rcParams -------------------------------------- +Backend-specific improvements +----------------------------- -The new config option :rc:`contour.linewidth` allows to control the default -line width of contours as a float. When set to ``None``, the line widths fall -back to :rc:`lines.linewidth`. The config value is overridden as usual by the -*linewidths* argument passed to `~.axes.Axes.contour` when it is not set to -``None``. +``savefig()`` gained a *backend* keyword argument +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The *backend* keyword argument to ``savefig`` can now be used to pick the +rendering backend without having to globally set the backend; e.g., one can +save PDFs using the pgf backend with ``savefig("file.pdf", backend="pgf")``. The SVG backend can now render hatches with transparency --------------------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The SVG backend now respects the hatch stroke alpha. Useful applications are, among others, semi-transparent hatches as a subtle way to differentiate columns in bar plots. - Saving SVG now supports adding metadata ---------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When saving SVG files, metadata can now be passed which will be saved in the file using `Dublin Core`_ and `RDF`_. A list of valid metadata can be found in @@ -440,20 +445,10 @@ the documentation for `.FigureCanvasSVG.print_svg`. .. _RDF: https://www.w3.org/1999/.status/PR-rdf-syntax-19990105/status Saving PDF metadata via PGF now consistent with PDF backend ------------------------------------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When saving PDF files using the PGF backend, passed metadata will be interpreted in the same way as with the PDF backend. Previously, this metadata was only accepted by the PGF backend when saving a multi-page PDF with `.backend_pgf.PdfPages`, but is now allowed when saving a single figure, as well. - -``backend_bases.key_press_handler`` and ``backend_bases.button_press_handler`` simplifications ----------------------------------------------------------------------------------------------- - -The `.backend_bases.key_press_handler` and -`.backend_bases.button_press_handler` event handlers can now be directly -connected to a canvas with ``canvas.mpl_connect("key_press_event", -key_press_handler)`` and ``canvas.mpl_connect("button_press_event", -button_press_handler)``, rather than having to write wrapper functions that -fill in the (now optional) *canvas* and *toolbar* parameters. From 176860527bd0c69a8ce07364e325c70118f4374d Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 8 Jul 2020 19:15:46 -0400 Subject: [PATCH 06/12] DOC: Shorten a title. This prevents overflow of the ToC in the sidebar. --- doc/users/prev_whats_new/whats_new_3.3.0.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/users/prev_whats_new/whats_new_3.3.0.rst b/doc/users/prev_whats_new/whats_new_3.3.0.rst index 0391af789cea..41c1f4e6e728 100644 --- a/doc/users/prev_whats_new/whats_new_3.3.0.rst +++ b/doc/users/prev_whats_new/whats_new_3.3.0.rst @@ -378,8 +378,8 @@ Qt zoom rectangle now black and white This makes it visible even over a dark background. -``backend_bases.key_press_handler`` and ``backend_bases.button_press_handler`` simplifications -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Event handler simplifications +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The `.backend_bases.key_press_handler` and `.backend_bases.button_press_handler` event handlers can now be directly From fd7eb1d62544958a38823c11004149d6d769f8bf Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 9 Jul 2020 04:04:33 -0400 Subject: [PATCH 07/12] DOC: Add more plots to 3.3 what's new. --- doc/users/prev_whats_new/whats_new_3.3.0.rst | 141 +++++++++++++++++-- 1 file changed, 129 insertions(+), 12 deletions(-) diff --git a/doc/users/prev_whats_new/whats_new_3.3.0.rst b/doc/users/prev_whats_new/whats_new_3.3.0.rst index 41c1f4e6e728..2f83420368cb 100644 --- a/doc/users/prev_whats_new/whats_new_3.3.0.rst +++ b/doc/users/prev_whats_new/whats_new_3.3.0.rst @@ -146,26 +146,90 @@ The text color of legend labels can now be set by passing a parameter * ``markeredgecolor``, which sets the text color of each label to match the corresponding marker edge color. +.. plot:: + + options = ['C3', 'linecolor', 'markerfacecolor', 'markeredgecolor'] + + fig, axs = plt.subplots(2, 2, constrained_layout=True) + for ax, color in zip(axs.flat, options): + ax.plot([1, 2, 3], marker='o', + color='C0', markerfacecolor='C1', markeredgecolor='C2', + linewidth=3, markersize=10, markeredgewidth=3, + label='a line') + + ax.legend(labelcolor=color) + ax.set_title(f'labelcolor={color!r}') + + ax.margins(0.1) + -``Axes.sharex``, ``Axes.sharey`` --------------------------------- +New ``Axes.sharex``, ``Axes.sharey`` methods +-------------------------------------------- -These new methods allow sharing axes *immediately* after creating them. For -example, they can be used to selectively link some axes created all together -using `~.Figure.subplots`. +These new methods allow sharing axes *immediately* after creating them. Note +that they may *not* be used to share axes after any operation (e.g., drawing) +has occurred on them. + +For example, they can be used to selectively link some axes created all +together using `~.Figure.subplot_mosaic`:: + + fig = plt.figure(constrained_layout=True) + axd = fig.subplot_mosaic([['.', 'histx'], ['histy', 'scat']], + gridspec_kw={'width_ratios': [1, 7], + 'height_ratios': [2, 7]}) + + axd['histx'].sharex(axd['scat']) + axd['histy'].sharey(axd['scat']) + +.. plot:: -Note that they may *not* be used to share axes after any operation (e.g., -drawing) has occurred on them. + np.random.seed(0) + x = np.random.random(100) * 100 + 20 + y = np.random.random(100) * 50 + 25 + c = np.random.random(100) - 0.5 + + fig = plt.figure(constrained_layout=True) + axd = fig.subplot_mosaic([['.', 'histx'], ['histy', 'scat']], + gridspec_kw={'width_ratios': [1, 7], + 'height_ratios': [2, 7]}) + + axd['histy'].invert_xaxis() + axd['histx'].sharex(axd['scat']) + axd['histy'].sharey(axd['scat']) + + im = axd['scat'].scatter(x, y, c=c, cmap='RdBu', picker=True) + fig.colorbar(im, orientation='horizontal', ax=axd['scat'], shrink=0.8) + + axd['histx'].hist(x) + axd['histy'].hist(y, orientation='horizontal') Align labels to Axes edges -------------------------- -`~.axes.Axes.set_xlabel`, `~.axes.Axes.set_ylabel` and `.ColorbarBase.set_label` -support a parameter ``loc`` for simplified positioning. Supported values are -'left', 'center', or 'right'. The default is controlled via -:rc:`xaxis.labelposition` and :rc:`yaxis.labelposition`; the Colorbar label -takes the rcParam based on its orientation. +`~.axes.Axes.set_xlabel`, `~.axes.Axes.set_ylabel` and +`.ColorbarBase.set_label` support a parameter ``loc`` for simplified +positioning. For the xlabel, the supported values are 'left', 'center', or +'right'. For the ylabel, the supported values are 'bottom', 'center', or +'top'. + +The default is controlled via :rc:`xaxis.labelposition` and +:rc:`yaxis.labelposition`; the Colorbar label takes the rcParam based on its +orientation. + +.. plot:: + + options = ['left', 'center', 'right'] + fig, axs = plt.subplots(len(options), 1, constrained_layout=True) + for ax, loc in zip(axs, options): + ax.plot([1, 2, 3]) + ax.set_xlabel(f'xlabel loc={loc!r}', loc=loc) + + options = ['bottom', 'center', 'top'] + fig, axs = plt.subplots(1, len(options), constrained_layout=True) + for ax, loc in zip(axs, options): + ax.plot([1, 2, 3]) + ax.set_ylabel(f'ylabel loc={loc!r}', loc=loc) Offset text is now set to the top when using ``axis.tick_top()`` @@ -185,6 +249,13 @@ which means to use auto-positioning. If a value is supplied (i.e. the pre-3.0 default was ``y=1.0``) then auto-positioning is turned off. This can also be set with the new rcParameter :rc:`axes.titley`. +.. plot:: + + fig, axs = plt.subplots(1, 2, constrained_layout=True, figsize=(5, 2)) + axs[0].set_title('y=0.7\n$\sum_{j_n} x_j$', y=0.7) + axs[1].set_title('y=None\n$\sum_{j_n} x_j$') + plt.show() + Dates now use a modern epoch ---------------------------- @@ -213,6 +284,32 @@ conversion (using the new epoch) is:: tight_layout now supports suptitle ---------------------------------- +Previous versions did not consider `.Figure.suptitle`, and so it may overlap +with other artists after calling `~.Figure.tight_layout`: + +.. plot:: + + fig, axs = plt.subplots(1, 3) + for i, ax in enumerate(axs): + ax.plot([1, 2, 3]) + ax.set_title(f'Axes {i}') + + t = fig.suptitle('suptitle') + t.set_in_layout(False) + fig.tight_layout() + +From now on, the ``suptitle`` will be considered: + +.. plot:: + + fig, axs = plt.subplots(1, 3) + for i, ax in enumerate(axs): + ax.plot([1, 2, 3]) + ax.set_title(f'Axes {i}') + + fig.suptitle('suptitle') + fig.tight_layout() + Allow tick formatters to be set with str or function inputs ----------------------------------------------------------- @@ -360,6 +457,26 @@ ratios as a 3-tuple of X:Y:Z. The default aspect ratio is 4:4:3. 3D axes now support minor ticks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. plot:: + :include-source: True + + ax = plt.figure().add_subplot(projection='3d') + + ax.scatter([0, 1, 2], [1, 3, 5], [30, 50, 70]) + + ax.set_xticks([0.25, 0.75, 1.25, 1.75], minor=True) + ax.set_xticklabels(['a', 'b', 'c', 'd'], minor=True) + + ax.set_yticks([1.5, 2.5, 3.5, 4.5], minor=True) + ax.set_yticklabels(['A', 'B', 'C', 'D'], minor=True) + + ax.set_zticks([35, 45, 55, 65], minor=True) + ax.set_zticklabels([r'$\alpha$', r'$\beta$', r'$\delta$', r'$\gamma$'], + minor=True) + + ax.tick_params(which='major', color='C0', labelcolor='C0', width=5) + ax.tick_params(which='minor', color='C1', labelcolor='C1', width=3) + Home/Forward/Backward buttons now work with 3D axes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 9471870ea4345dcc7ff683fa30081e1302a0abb9 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 9 Jul 2020 18:16:49 -0400 Subject: [PATCH 08/12] DOC: Add more entries to 3.3 what's new. --- doc/users/prev_whats_new/whats_new_3.3.0.rst | 81 +++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/doc/users/prev_whats_new/whats_new_3.3.0.rst b/doc/users/prev_whats_new/whats_new_3.3.0.rst index 2f83420368cb..b96ddf0fd152 100644 --- a/doc/users/prev_whats_new/whats_new_3.3.0.rst +++ b/doc/users/prev_whats_new/whats_new_3.3.0.rst @@ -62,6 +62,30 @@ as an alternative to :: fig.subplots(2, 2, gridspec_kw={"height_ratios": [3, 1]}) +New Turbo colormap +------------------ + +Turbo is an improved rainbow colormap for visualization, created by the Google +AI team for computer visualization and machine learning. Its purpose is to +display depth and disparity data. Please see the `Google AI Blog +`_ +for further details. + +Below shows Turbo and some other rainbow-esque colormaps: + +.. plot:: + + gradient = np.linspace(0, 1, 256) + gradient = np.vstack((gradient, gradient)) + cmaps = ['turbo', 'jet', 'gist_rainbow_r', 'hsv_r'] + + fig, axs = plt.subplots(len(cmaps), constrained_layout=True) + for name, ax in zip(cmaps, axs): + ax.imshow(gradient, aspect='auto', cmap=plt.get_cmap(name)) + ax.set_title(name) + ax.set_axis_off() + + New ``Axes.axline`` method -------------------------- @@ -391,6 +415,18 @@ clabels has been changed to (``2 + zorder`` passed to `~.axes.Axes.contour` / `~.axes.Axes.contourf`). +Better control of ``Axes.pie`` normalization +-------------------------------------------- + +Previously, `.Axes.pie` would normalize its input *x* if ``sum(x) > 1``, but +would do nothing if the sum were less than 1. This can be confusing, so an +explicit keyword argument *normalize* has been added. By default, the old +behavior is preserved. + +By passing *normalize*, one can explicitly control whether any rescaling takes +place and whether partial pies should be created. + + Simple syntax to select fonts by absolute path ---------------------------------------------- @@ -398,6 +434,14 @@ Fonts can now be selected by passing an absolute `pathlib.Path` to the *font* keyword argument of `.Text`. +Improved font weight detection +------------------------------ + +Matplotlib is now better able to determine the weight of fonts from their +metadata, allowing to differentiate between fonts within the same family more +accurately. + + rcParams improvements --------------------- @@ -453,7 +497,6 @@ value of `~.get_box_aspect`. To control these ratios use the `~mpl_toolkits.mplot3d.axes3d.Axes3D.set_box_aspect` method which accepts the ratios as a 3-tuple of X:Y:Z. The default aspect ratio is 4:4:3. - 3D axes now support minor ticks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -483,6 +526,23 @@ Home/Forward/Backward buttons now work with 3D axes Interactive tool improvements ----------------------------- +More consistent toolbar behavior across backends +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Toolbar features are now more consistent across backends. The history buttons +will auto-disable when there is no further action in a direction. The pan and +zoom buttons will be marked active when they are in use. + +In NbAgg and WebAgg, the toolbar buttons are now grouped similarly to other +backends. The WebAgg toolbar now uses the same icons as other backends. + +Toolbar icons are now styled for dark themes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +On dark themes, toolbar icons will now be inverted. When using the GTK3Agg +backend, toolbar icons are now symbolic, and both foreground and background +colors will follow the theme. Tooltips should also behave correctly. + Cursor text now uses a number of significant digits matching pointing precision ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -551,6 +611,19 @@ The SVG backend now respects the hatch stroke alpha. Useful applications are, among others, semi-transparent hatches as a subtle way to differentiate columns in bar plots. +SVG supports URLs on more artists +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +URLs on more artists (i.e., from `.Artist.set_url`) will now be saved in +SVG files, namely, ``Tick``\s and ``Line2D``\s are now supported. + +Images in SVG will no longer be blurred in some viewers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A style is now supplied to images without interpolation (``imshow(..., +interpolation='none'``) so that SVG image viewers will no longer perform +interpolation when rendering themselves. + Saving SVG now supports adding metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -569,3 +642,9 @@ interpreted in the same way as with the PDF backend. Previously, this metadata was only accepted by the PGF backend when saving a multi-page PDF with `.backend_pgf.PdfPages`, but is now allowed when saving a single figure, as well. + +NbAgg and WebAgg no longer use jQuery & jQuery UI +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instead, they are implemented using vanilla JavaScript. Please report any +issues with browsers. From a43d8b3ddbe896bdeed22d98ec19e7c951d06dfd Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 9 Jul 2020 18:17:06 -0400 Subject: [PATCH 09/12] DOC: Fix a typo in Axes.pie docstring. --- lib/matplotlib/axes/_axes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 00ecf9b9b1d2..6717ce746b0c 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2932,7 +2932,7 @@ def pie(self, x, explode=None, labels=None, colors=None, ``sum(x) == 1``. *False* makes a partial pie if ``sum(x) <= 1`` and raises a `ValueError` for ``sum(x) > 1``. - When *None*, defaults to *True* if ``sum(x) > 0`` and *False* if + When *None*, defaults to *True* if ``sum(x) >= 1`` and *False* if ``sum(x) < 1``. Please note that the previous default value of *None* is now @@ -3009,7 +3009,7 @@ def pie(self, x, explode=None, labels=None, colors=None, if sx < 1: cbook.warn_deprecated( "3.3", message="normalize=None does not normalize " - "if the sum is less than 1 but this behavior" + "if the sum is less than 1 but this behavior " "is deprecated since %(since)s until %(removal)s. " "After the deprecation " "period the default value will be normalize=True. " From e6648a73c39249488b7d111ca09c58b24a99a33a Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Fri, 10 Jul 2020 03:12:44 -0400 Subject: [PATCH 10/12] DOC: Edit the 3.3 what's new based on review. --- doc/users/prev_whats_new/whats_new_3.3.0.rst | 86 ++++++++++++++------ 1 file changed, 60 insertions(+), 26 deletions(-) diff --git a/doc/users/prev_whats_new/whats_new_3.3.0.rst b/doc/users/prev_whats_new/whats_new_3.3.0.rst index b96ddf0fd152..8b154f78a96f 100644 --- a/doc/users/prev_whats_new/whats_new_3.3.0.rst +++ b/doc/users/prev_whats_new/whats_new_3.3.0.rst @@ -62,8 +62,8 @@ as an alternative to :: fig.subplots(2, 2, gridspec_kw={"height_ratios": [3, 1]}) -New Turbo colormap ------------------- +Turbo colormap +-------------- Turbo is an improved rainbow colormap for visualization, created by the Google AI team for computer visualization and machine learning. Its purpose is to @@ -71,8 +71,6 @@ display depth and disparity data. Please see the `Google AI Blog `_ for further details. -Below shows Turbo and some other rainbow-esque colormaps: - .. plot:: gradient = np.linspace(0, 1, 256) @@ -103,8 +101,8 @@ that pass through two points. ax.legend() -New "extend" keyword to colors.BoundaryNorm -------------------------------------------- +``colors.BoundaryNorm`` supports *extend* keyword argument +---------------------------------------------------------- `~.colors.BoundaryNorm` now has an *extend* keyword argument, analogous to *extend* in `~.axes.Axes.contourf`. When set to 'both', 'min', or 'max', it @@ -191,8 +189,8 @@ New ``Axes.sharex``, ``Axes.sharey`` methods -------------------------------------------- These new methods allow sharing axes *immediately* after creating them. Note -that they may *not* be used to share axes after any operation (e.g., drawing) -has occurred on them. +that behavior is indeterminate if axes are not shared immediately after +creation. For example, they can be used to selectively link some axes created all together using `~.Figure.subplot_mosaic`:: @@ -281,8 +279,8 @@ set with the new rcParameter :rc:`axes.titley`. plt.show() -Dates now use a modern epoch ----------------------------- +Dates use a modern epoch +------------------------ Matplotlib converts dates to days since an epoch using `.dates.date2num` (via `matplotlib.units`). Previously, an epoch of ``0000-12-31T00:00:00`` was used @@ -299,8 +297,8 @@ by `~.dates.get_epoch`, and there is a new :rc:`date.epoch` rcParam. The user may also call `~.dates.set_epoch`, but it must be set *before* any date conversion or plotting is used. -If you have data stored as ordinal floats in the old epoch, a simple -conversion (using the new epoch) is:: +If you have data stored as ordinal floats in the old epoch, you can convert +them to the new ordinal using the following formula:: new_ordinal = old_ordinal + mdates.date2num(np.datetime64('0000-12-31')) @@ -308,8 +306,8 @@ conversion (using the new epoch) is:: tight_layout now supports suptitle ---------------------------------- -Previous versions did not consider `.Figure.suptitle`, and so it may overlap -with other artists after calling `~.Figure.tight_layout`: +Previous versions did not consider `.Figure.suptitle`, so it may overlap with +other artists after calling `~.Figure.tight_layout`: .. plot:: @@ -342,18 +340,30 @@ Allow tick formatters to be set with str or function inputs now accept `str` or function inputs in addition to `~.ticker.Formatter` instances. For a `str` a `~.ticker.StrMethodFormatter` is automatically generated and used. For a function a `~.ticker.FuncFormatter` is automatically -generated and used. +generated and used. In other words, +:: + + ax.xaxis.set_major_formatter('price: {x:02}') + ax.xaxis.set_minor_formatter(lambda x, pos: 'low' if x < 2 else 'high') + +are shortcuts for:: + + import matplotlib.ticker as mticker + + ax.xaxis.set_major_formatter(mticker.StrMethodFormatter('price: {x:02}')) + ax.xaxis.set_minor_formatter( + mticker.FuncFormatter(lambda x, pos: 'low' if x < 2 else 'high')) Setting axes box aspect ----------------------- It is now possible to set the aspect of an axes box directly via -`~.Axes.set_box_aspect`. The box aspect is the ratio between axes height -and axes width in physical units, independent of the data limits. -This is useful to, e.g., produce a square plot, independent of the data it -contains, or to have a usual plot with the same axes dimensions next to -an image plot with fixed (data-)aspect. +`~.Axes.set_box_aspect`. The box aspect is the ratio between axes height and +axes width in physical units, independent of the data limits. This is useful +to, e.g., produce a square plot, independent of the data it contains, or to +have a non-image plot with the same axes dimensions next to an image plot with +fixed (data-)aspect. For use cases check out the :doc:`Axes box aspect ` example. @@ -424,7 +434,30 @@ explicit keyword argument *normalize* has been added. By default, the old behavior is preserved. By passing *normalize*, one can explicitly control whether any rescaling takes -place and whether partial pies should be created. +place or whether partial pies should be created. If normalization is disabled, +and ``sum(x) > 1``, then an error is raised. + +.. plot:: + + def label(x): + return [str(v) for v in x] + + x = np.array([0.25, 0.3, 0.3]) + fig, ax = plt.subplots(2, 2, constrained_layout=True) + + ax[0, 0].pie(x, autopct='%1.1f%%', labels=label(x), normalize=False) + ax[0, 0].set_title('normalize=False') + ax[0, 1].pie(x, autopct='%1.2f%%', labels=label(x), normalize=True) + ax[0, 1].set_title('normalize=True') + + # For the purposes of keeping the documentation build warning-free, and + # future proof for when the deprecation is made permanent, we pass + # *normalize* here explicitly anyway. + ax[1, 0].pie(x, autopct='%1.2f%%', labels=label(x), normalize=False) + ax[1, 0].set_title('normalize unspecified\nsum(x) < 1') + ax[1, 1].pie(x * 10, autopct='%1.2f%%', labels=label(x * 10), + normalize=True) + ax[1, 1].set_title('normalize unspecified\nsum(x) > 1') Simple syntax to select fonts by absolute path @@ -445,8 +478,8 @@ accurately. rcParams improvements --------------------- -``matplotlib.rc_context`` is now a ``contextlib.contextmanager`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``matplotlib.rc_context`` can be used as a decorator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `matplotlib.rc_context` can now be used as a decorator (technically, it is now implemented as a `contextlib.contextmanager`), e.g., :: @@ -457,9 +490,10 @@ implemented as a `contextlib.contextmanager`), e.g., :: rcParams for controlling default "raise window" behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The new config option :rc:`figure.raise_window` allows to disable -raising the plot window when calling `~.pyplot.show` or `~.pyplot.pause`. -The ``MacOSX`` backend is currently not supported. + +The new config option :rc:`figure.raise_window` allows disabling of the raising +of the plot window when calling `~.pyplot.show` or `~.pyplot.pause`. The +``MacOSX`` backend is currently not supported. Add generalized ``mathtext.fallback`` to rcParams ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 2fb42b1ca3d042201ef313541bf0b97e100fce35 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 14 Jul 2020 02:16:30 -0400 Subject: [PATCH 11/12] DOC: More edits to the 3.3 what's new from review. --- doc/users/prev_whats_new/whats_new_3.3.0.rst | 48 ++++++++++++++++---- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/doc/users/prev_whats_new/whats_new_3.3.0.rst b/doc/users/prev_whats_new/whats_new_3.3.0.rst index 8b154f78a96f..de188035baf1 100644 --- a/doc/users/prev_whats_new/whats_new_3.3.0.rst +++ b/doc/users/prev_whats_new/whats_new_3.3.0.rst @@ -22,8 +22,8 @@ The `.Figure` class has a provisional method to generate complex grids of named :include-source: True axd = plt.figure(constrained_layout=True).subplot_mosaic( - [["Top", "Top", "Edge"], - ["Left", ".", "Edge"]] + [['.', 'histx'], + ['histy', 'scat']] ) for k, ax in axd.items(): ax.text(0.5, 0.5, k, @@ -343,16 +343,45 @@ generated and used. For a function a `~.ticker.FuncFormatter` is automatically generated and used. In other words, :: - ax.xaxis.set_major_formatter('price: {x:02}') - ax.xaxis.set_minor_formatter(lambda x, pos: 'low' if x < 2 else 'high') + ax.xaxis.set_major_formatter('{x} km') + ax.xaxis.set_minor_formatter(lambda x, pos: str(x-5)) are shortcuts for:: import matplotlib.ticker as mticker - ax.xaxis.set_major_formatter(mticker.StrMethodFormatter('price: {x:02}')) + ax.xaxis.set_major_formatter(mticker.StrMethodFormatter('{x} km')) ax.xaxis.set_minor_formatter( - mticker.FuncFormatter(lambda x, pos: 'low' if x < 2 else 'high')) + mticker.FuncFormatter(lambda x, pos: str(x-5)) + +.. plot:: + + from matplotlib import ticker + + titles = ["'{x} km'", "lambda x, pos: str(x-5)"] + formatters = ['{x} km', lambda x, pos: str(x-5)] + + fig, axs = plt.subplots(2, 1, figsize=(8, 2), constrained_layout=True) + + for ax, title, formatter in zip(axs, titles, formatters): + # only show the bottom spine + ax.yaxis.set_major_locator(ticker.NullLocator()) + for spine in ['top', 'left', 'right']: + ax.spines[spine].set_visible(False) + + # define tick positions + ax.xaxis.set_major_locator(ticker.MultipleLocator(1.00)) + ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.25)) + + ax.tick_params(which='major', width=1.00, length=5) + ax.tick_params(which='minor', width=0.75, length=2.5, labelsize=10) + ax.set_xlim(0, 5) + ax.set_ylim(0, 1) + ax.text(0.0, 0.2, f'ax.xaxis.set_major_formatter({title})', + transform=ax.transAxes, fontsize=14, fontname='Monospace', + color='tab:blue') + + ax.xaxis.set_major_formatter(formatter) Setting axes box aspect @@ -450,9 +479,10 @@ and ``sum(x) > 1``, then an error is raised. ax[0, 1].pie(x, autopct='%1.2f%%', labels=label(x), normalize=True) ax[0, 1].set_title('normalize=True') - # For the purposes of keeping the documentation build warning-free, and - # future proof for when the deprecation is made permanent, we pass - # *normalize* here explicitly anyway. + # This is supposed to show the 'old' behavior of not passing *normalize* + # explicitly, but for the purposes of keeping the documentation build + # warning-free, and future proof for when the deprecation is made + # permanent, we pass *normalize* here explicitly anyway. ax[1, 0].pie(x, autopct='%1.2f%%', labels=label(x), normalize=False) ax[1, 0].set_title('normalize unspecified\nsum(x) < 1') ax[1, 1].pie(x * 10, autopct='%1.2f%%', labels=label(x * 10), From 42ce0c72d1be396a0ed11f2c4c8d14d5f924f068 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 14 Jul 2020 02:45:15 -0400 Subject: [PATCH 12/12] DOC: Re-order 3.3 what's new changes. --- doc/users/prev_whats_new/whats_new_3.3.0.rst | 386 +++++++++---------- 1 file changed, 192 insertions(+), 194 deletions(-) diff --git a/doc/users/prev_whats_new/whats_new_3.3.0.rst b/doc/users/prev_whats_new/whats_new_3.3.0.rst index de188035baf1..fe92f6211ce4 100644 --- a/doc/users/prev_whats_new/whats_new_3.3.0.rst +++ b/doc/users/prev_whats_new/whats_new_3.3.0.rst @@ -12,8 +12,11 @@ revision, see the :ref:`github-stats`. :maxdepth: 4 +Figure and Axes creation / management +------------------------------------- + Provisional API for composing semantic axes layouts from text or nested lists ------------------------------------------------------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The `.Figure` class has a provisional method to generate complex grids of named `.axes.Axes` based on nested list input or ASCII art: @@ -48,9 +51,8 @@ or as a string (with single-character Axes labels): See :ref:`sphx_glr_tutorials_provisional_mosaic.py` for more details and examples. - ``GridSpec.subplots()`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ The `.GridSpec` class gained a `~.GridSpecBase.subplots` method, so that one can write :: @@ -61,9 +63,94 @@ as an alternative to :: fig.subplots(2, 2, gridspec_kw={"height_ratios": [3, 1]}) +New ``Axes.sharex``, ``Axes.sharey`` methods +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These new methods allow sharing axes *immediately* after creating them. Note +that behavior is indeterminate if axes are not shared immediately after +creation. + +For example, they can be used to selectively link some axes created all +together using `~.Figure.subplot_mosaic`:: + + fig = plt.figure(constrained_layout=True) + axd = fig.subplot_mosaic([['.', 'histx'], ['histy', 'scat']], + gridspec_kw={'width_ratios': [1, 7], + 'height_ratios': [2, 7]}) + + axd['histx'].sharex(axd['scat']) + axd['histy'].sharey(axd['scat']) + +.. plot:: + + np.random.seed(0) + x = np.random.random(100) * 100 + 20 + y = np.random.random(100) * 50 + 25 + c = np.random.random(100) - 0.5 + + fig = plt.figure(constrained_layout=True) + axd = fig.subplot_mosaic([['.', 'histx'], ['histy', 'scat']], + gridspec_kw={'width_ratios': [1, 7], + 'height_ratios': [2, 7]}) + + axd['histy'].invert_xaxis() + axd['histx'].sharex(axd['scat']) + axd['histy'].sharey(axd['scat']) + + im = axd['scat'].scatter(x, y, c=c, cmap='RdBu', picker=True) + fig.colorbar(im, orientation='horizontal', ax=axd['scat'], shrink=0.8) + + axd['histx'].hist(x) + axd['histy'].hist(y, orientation='horizontal') + +tight_layout now supports suptitle +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Previous versions did not consider `.Figure.suptitle`, so it may overlap with +other artists after calling `~.Figure.tight_layout`: + +.. plot:: + + fig, axs = plt.subplots(1, 3) + for i, ax in enumerate(axs): + ax.plot([1, 2, 3]) + ax.set_title(f'Axes {i}') + + t = fig.suptitle('suptitle') + t.set_in_layout(False) + fig.tight_layout() + +From now on, the ``suptitle`` will be considered: + +.. plot:: + + fig, axs = plt.subplots(1, 3) + for i, ax in enumerate(axs): + ax.plot([1, 2, 3]) + ax.set_title(f'Axes {i}') + + fig.suptitle('suptitle') + fig.tight_layout() + +Setting axes box aspect +~~~~~~~~~~~~~~~~~~~~~~~ + +It is now possible to set the aspect of an axes box directly via +`~.Axes.set_box_aspect`. The box aspect is the ratio between axes height and +axes width in physical units, independent of the data limits. This is useful +to, e.g., produce a square plot, independent of the data it contains, or to +have a non-image plot with the same axes dimensions next to an image plot with +fixed (data-)aspect. + +For use cases check out the :doc:`Axes box aspect +` example. + + +Colors and colormaps +-------------------- Turbo colormap --------------- +~~~~~~~~~~~~~~ Turbo is an improved rainbow colormap for visualization, created by the Google AI team for computer visualization and machine learning. Its purpose is to @@ -83,26 +170,8 @@ for further details. ax.set_title(name) ax.set_axis_off() - -New ``Axes.axline`` method --------------------------- - -A new `~.axes.Axes.axline` method has been added to draw infinitely long lines -that pass through two points. - -.. plot:: - :include-source: True - - fig, ax = plt.subplots() - - ax.axline((.1, .1), slope=5, color='C0', label='by slope') - ax.axline((.1, .2), (.8, .7), color='C3', label='by points') - - ax.legend() - - ``colors.BoundaryNorm`` supports *extend* keyword argument ----------------------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `~.colors.BoundaryNorm` now has an *extend* keyword argument, analogous to *extend* in `~.axes.Axes.contourf`. When set to 'both', 'min', or 'max', it @@ -150,9 +219,8 @@ for out-of-range values with colors that differ from adjacent in-range colors. plt.show() - Text color for legend labels ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The text color of legend labels can now be set by passing a parameter ``labelcolor`` to `~.axes.Axes.legend`. The ``labelcolor`` keyword can be: @@ -184,50 +252,38 @@ The text color of legend labels can now be set by passing a parameter ax.margins(0.1) +Pcolor and Pcolormesh now accept ``shading='nearest'`` and ``'auto'`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -New ``Axes.sharex``, ``Axes.sharey`` methods --------------------------------------------- - -These new methods allow sharing axes *immediately* after creating them. Note -that behavior is indeterminate if axes are not shared immediately after -creation. - -For example, they can be used to selectively link some axes created all -together using `~.Figure.subplot_mosaic`:: - - fig = plt.figure(constrained_layout=True) - axd = fig.subplot_mosaic([['.', 'histx'], ['histy', 'scat']], - gridspec_kw={'width_ratios': [1, 7], - 'height_ratios': [2, 7]}) - - axd['histx'].sharex(axd['scat']) - axd['histy'].sharey(axd['scat']) - -.. plot:: +Previously `.axes.Axes.pcolor` and `.axes.Axes.pcolormesh` handled the +situation where *x* and *y* have the same (respective) size as *C* by dropping +the last row and column of *C*, and *x* and *y* are regarded as the edges of +the remaining rows and columns in *C*. However, many users want *x* and *y* +centered on the rows and columns of *C*. - np.random.seed(0) - x = np.random.random(100) * 100 + 20 - y = np.random.random(100) * 50 + 25 - c = np.random.random(100) - 0.5 +To accommodate this, ``shading='nearest'`` and ``shading='auto'`` are new +allowed strings for the *shading* keyword argument. ``'nearest'`` will center +the color on *x* and *y* if *x* and *y* have the same dimensions as *C* +(otherwise an error will be thrown). ``shading='auto'`` will choose 'flat' or +'nearest' based on the size of *X*, *Y*, *C*. - fig = plt.figure(constrained_layout=True) - axd = fig.subplot_mosaic([['.', 'histx'], ['histy', 'scat']], - gridspec_kw={'width_ratios': [1, 7], - 'height_ratios': [2, 7]}) +If ``shading='flat'`` then *X*, and *Y* should have dimensions one larger than +*C*. If *X* and *Y* have the same dimensions as *C*, then the previous behavior +is used and the last row and column of *C* are dropped, and a +DeprecationWarning is emitted. - axd['histy'].invert_xaxis() - axd['histx'].sharex(axd['scat']) - axd['histy'].sharey(axd['scat']) +Users can also specify this by the new :rc:`pcolor.shading` in their +``.matplotlibrc`` or via `.rcParams`. - im = axd['scat'].scatter(x, y, c=c, cmap='RdBu', picker=True) - fig.colorbar(im, orientation='horizontal', ax=axd['scat'], shrink=0.8) +See :doc:`pcolormesh ` +for examples. - axd['histx'].hist(x) - axd['histy'].hist(y, orientation='horizontal') +Titles, ticks, and labels +------------------------- Align labels to Axes edges --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ `~.axes.Axes.set_xlabel`, `~.axes.Axes.set_ylabel` and `.ColorbarBase.set_label` support a parameter ``loc`` for simplified @@ -253,88 +309,8 @@ orientation. ax.plot([1, 2, 3]) ax.set_ylabel(f'ylabel loc={loc!r}', loc=loc) - -Offset text is now set to the top when using ``axis.tick_top()`` ----------------------------------------------------------------- - -Solves the issue that the power indicator (e.g., 1e4) stayed on the bottom, -even if the ticks were on the top. - - -``Axes.set_title`` gains a *y* keyword argument to control auto positioning ---------------------------------------------------------------------------- - -`~.axes.Axes.set_title` tries to auto-position the title to avoid any -decorators on the top x-axis. This is not always desirable so now *y* is an -explicit keyword argument of `~.axes.Axes.set_title`. It defaults to *None* -which means to use auto-positioning. If a value is supplied (i.e. the pre-3.0 -default was ``y=1.0``) then auto-positioning is turned off. This can also be -set with the new rcParameter :rc:`axes.titley`. - -.. plot:: - - fig, axs = plt.subplots(1, 2, constrained_layout=True, figsize=(5, 2)) - axs[0].set_title('y=0.7\n$\sum_{j_n} x_j$', y=0.7) - axs[1].set_title('y=None\n$\sum_{j_n} x_j$') - plt.show() - - -Dates use a modern epoch ------------------------- - -Matplotlib converts dates to days since an epoch using `.dates.date2num` (via -`matplotlib.units`). Previously, an epoch of ``0000-12-31T00:00:00`` was used -so that ``0001-01-01`` was converted to 1.0. An epoch so distant in the -past meant that a modern date was not able to preserve microseconds because -2000 years times the 2^(-52) resolution of a 64-bit float gives 14 -microseconds. - -Here we change the default epoch to the more reasonable UNIX default of -``1970-01-01T00:00:00`` which for a modern date has 0.35 microsecond -resolution. (Finer resolution is not possible because we rely on -`datetime.datetime` for the date locators). Access to the epoch is provided -by `~.dates.get_epoch`, and there is a new :rc:`date.epoch` rcParam. The user -may also call `~.dates.set_epoch`, but it must be set *before* any date -conversion or plotting is used. - -If you have data stored as ordinal floats in the old epoch, you can convert -them to the new ordinal using the following formula:: - - new_ordinal = old_ordinal + mdates.date2num(np.datetime64('0000-12-31')) - - -tight_layout now supports suptitle ----------------------------------- - -Previous versions did not consider `.Figure.suptitle`, so it may overlap with -other artists after calling `~.Figure.tight_layout`: - -.. plot:: - - fig, axs = plt.subplots(1, 3) - for i, ax in enumerate(axs): - ax.plot([1, 2, 3]) - ax.set_title(f'Axes {i}') - - t = fig.suptitle('suptitle') - t.set_in_layout(False) - fig.tight_layout() - -From now on, the ``suptitle`` will be considered: - -.. plot:: - - fig, axs = plt.subplots(1, 3) - for i, ax in enumerate(axs): - ax.plot([1, 2, 3]) - ax.set_title(f'Axes {i}') - - fig.suptitle('suptitle') - fig.tight_layout() - - Allow tick formatters to be set with str or function inputs ------------------------------------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `~.Axis.set_major_formatter` and `~.Axis.set_minor_formatter` now accept `str` or function inputs in addition to `~.ticker.Formatter` @@ -383,79 +359,69 @@ are shortcuts for:: ax.xaxis.set_major_formatter(formatter) +``Axes.set_title`` gains a *y* keyword argument to control auto positioning +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Setting axes box aspect ------------------------ +`~.axes.Axes.set_title` tries to auto-position the title to avoid any +decorators on the top x-axis. This is not always desirable so now *y* is an +explicit keyword argument of `~.axes.Axes.set_title`. It defaults to *None* +which means to use auto-positioning. If a value is supplied (i.e. the pre-3.0 +default was ``y=1.0``) then auto-positioning is turned off. This can also be +set with the new rcParameter :rc:`axes.titley`. -It is now possible to set the aspect of an axes box directly via -`~.Axes.set_box_aspect`. The box aspect is the ratio between axes height and -axes width in physical units, independent of the data limits. This is useful -to, e.g., produce a square plot, independent of the data it contains, or to -have a non-image plot with the same axes dimensions next to an image plot with -fixed (data-)aspect. +.. plot:: -For use cases check out the :doc:`Axes box aspect -` example. + fig, axs = plt.subplots(1, 2, constrained_layout=True, figsize=(5, 2)) + axs[0].set_title('y=0.7\n$\sum_{j_n} x_j$', y=0.7) + axs[1].set_title('y=None\n$\sum_{j_n} x_j$') + plt.show() +Offset text is now set to the top when using ``axis.tick_top()`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pcolor and Pcolormesh now accept ``shading='nearest'`` and ``'auto'`` ---------------------------------------------------------------------- +Solves the issue that the power indicator (e.g., 1e4) stayed on the bottom, +even if the ticks were on the top. -Previously `.axes.Axes.pcolor` and `.axes.Axes.pcolormesh` handled -the situation where *x* and *y* have the same (respective) size as *C* by -dropping the last row and column of *C*, and *x* and *y* are regarded as the -edges of the remaining rows and columns in *C*. However, many users want -*x* and *y* centered on the rows and columns of *C*. +Set zorder of contour labels +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To accommodate this, ``shading='nearest'`` and ``shading='auto'`` are new -allowed strings for the *shading* keyword argument. ``'nearest'`` will center -the color on *x* and *y* if *x* and *y* have the same dimensions as *C* -(otherwise an error will be thrown). ``shading='auto'`` will choose 'flat' or -'nearest' based on the size of *X*, *Y*, *C*. +`~.axes.Axes.clabel` now accepts a *zorder* keyword argument making it easier +to set the *zorder* of contour labels. If not specified, the default *zorder* +of clabels used to always be 3 (i.e. the default *zorder* of `~.text.Text`) +irrespective of the *zorder* passed to +`~.axes.Axes.contour`/`~.axes.Axes.contourf`. The new default *zorder* for +clabels has been changed to (``2 + zorder`` passed to `~.axes.Axes.contour` / +`~.axes.Axes.contourf`). -If ``shading='flat'`` then *X*, and *Y* should have dimensions one larger -than *C*. If *X* and *Y* have the same dimensions as *C*, then the previous -behavior is used and the last row and column of *C* are dropped, and a -DeprecationWarning is emitted. -Users can also specify this by the new :rc:`pcolor.shading` in their -``.matplotlibrc`` or via `.rcParams`. +Other changes +------------- -See :doc:`pcolormesh ` -for examples. +New ``Axes.axline`` method +~~~~~~~~~~~~~~~~~~~~~~~~~~ +A new `~.axes.Axes.axline` method has been added to draw infinitely long lines +that pass through two points. -Lines now accept ``MarkerStyle`` instances as input ---------------------------------------------------- +.. plot:: + :include-source: True -Similar to `~.Axes.scatter`, `~.Axes.plot` and `~.lines.Line2D` now accept -`~.markers.MarkerStyle` instances as input for the *marker* parameter:: + fig, ax = plt.subplots() - plt.plot(..., marker=matplotlib.markers.MarkerStyle("D")) + ax.axline((.1, .1), slope=5, color='C0', label='by slope') + ax.axline((.1, .2), (.8, .7), color='C3', label='by points') + ax.legend() ``imshow`` now coerces 3D arrays with depth 1 to 2D ---------------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Starting from this version arrays of size MxNx1 will be coerced into MxN for displaying. This means commands like ``plt.imshow(np.random.rand(3, 3, 1))`` will no longer return an error message that the image shape is invalid. - -Set zorder of contour labels ----------------------------- - -`~.axes.Axes.clabel` now accepts a *zorder* keyword argument making it easier -to set the *zorder* of contour labels. If not specified, the default *zorder* -of clabels used to always be 3 (i.e. the default *zorder* of `~.text.Text`) -irrespective of the *zorder* passed to -`~.axes.Axes.contour`/`~.axes.Axes.contourf`. The new default *zorder* for -clabels has been changed to (``2 + zorder`` passed to `~.axes.Axes.contour` / -`~.axes.Axes.contourf`). - - Better control of ``Axes.pie`` normalization --------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Previously, `.Axes.pie` would normalize its input *x* if ``sum(x) > 1``, but would do nothing if the sum were less than 1. This can be confusing, so an @@ -489,16 +455,48 @@ and ``sum(x) > 1``, then an error is raised. normalize=True) ax[1, 1].set_title('normalize unspecified\nsum(x) > 1') +Dates use a modern epoch +~~~~~~~~~~~~~~~~~~~~~~~~ + +Matplotlib converts dates to days since an epoch using `.dates.date2num` (via +`matplotlib.units`). Previously, an epoch of ``0000-12-31T00:00:00`` was used +so that ``0001-01-01`` was converted to 1.0. An epoch so distant in the past +meant that a modern date was not able to preserve microseconds because 2000 +years times the 2^(-52) resolution of a 64-bit float gives 14 microseconds. + +Here we change the default epoch to the more reasonable UNIX default of +``1970-01-01T00:00:00`` which for a modern date has 0.35 microsecond +resolution. (Finer resolution is not possible because we rely on +`datetime.datetime` for the date locators). Access to the epoch is provided by +`~.dates.get_epoch`, and there is a new :rc:`date.epoch` rcParam. The user may +also call `~.dates.set_epoch`, but it must be set *before* any date conversion +or plotting is used. + +If you have data stored as ordinal floats in the old epoch, you can convert +them to the new ordinal using the following formula:: + + new_ordinal = old_ordinal + mdates.date2num(np.datetime64('0000-12-31')) + +Lines now accept ``MarkerStyle`` instances as input +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Similar to `~.Axes.scatter`, `~.Axes.plot` and `~.lines.Line2D` now accept +`~.markers.MarkerStyle` instances as input for the *marker* parameter:: + + plt.plot(..., marker=matplotlib.markers.MarkerStyle("D")) + + +Fonts +----- Simple syntax to select fonts by absolute path ----------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Fonts can now be selected by passing an absolute `pathlib.Path` to the *font* keyword argument of `.Text`. - Improved font weight detection ------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Matplotlib is now better able to determine the weight of fonts from their metadata, allowing to differentiate between fonts within the same family more