diff --git a/doc/_static/gif_attachment_example.png b/doc/_static/gif_attachment_example.png new file mode 100644 index 000000000000..93bcf44e91f9 Binary files /dev/null and b/doc/_static/gif_attachment_example.png differ diff --git a/doc/missing-references.json b/doc/missing-references.json index 29dd9a62affe..a2f3e2738f5e 100644 --- a/doc/missing-references.json +++ b/doc/missing-references.json @@ -23,6 +23,10 @@ "button": [ "doc/users/prev_whats_new/whats_new_3.1.0.rst:338" ], + "cbar_axes": [ + "lib/mpl_toolkits/axes_grid1/axes_grid.py:docstring of mpl_toolkits.axes_grid1.axes_grid.ImageGrid:48", + "lib/mpl_toolkits/axisartist/axes_grid.py:docstring of mpl_toolkits.axisartist.axes_grid.ImageGrid:48" + ], "dividers": [ "lib/mpl_toolkits/axes_grid1/colorbar.py:docstring of mpl_toolkits.axes_grid1.colorbar.ColorbarBase:29" ], @@ -792,8 +796,8 @@ "doc/api/prev_api_changes/api_changes_1.5.0.rst:44" ], "Size.from_any": [ - "lib/mpl_toolkits/axes_grid1/axes_grid.py:docstring of mpl_toolkits.axes_grid1.axes_grid.ImageGrid:73", - "lib/mpl_toolkits/axisartist/axes_grid.py:docstring of mpl_toolkits.axisartist.axes_grid.ImageGrid:48" + "lib/mpl_toolkits/axes_grid1/axes_grid.py:docstring of mpl_toolkits.axes_grid1.axes_grid.ImageGrid:60", + "lib/mpl_toolkits/axisartist/axes_grid.py:docstring of mpl_toolkits.axisartist.axes_grid.ImageGrid:60" ], "Style": [ "doc/devel/MEP/MEP26.rst:68" @@ -892,13 +896,13 @@ "doc/api/prev_api_changes/api_changes_3.1.0.rst:933" ], "axes_grid1": [ - "doc/index.rst:184" + "doc/index.rst:154" ], "axis.Axis.get_ticks_position": [ "doc/api/prev_api_changes/api_changes_3.1.0.rst:821" ], "axisartist": [ - "doc/index.rst:184" + "doc/index.rst:154" ], "backend_bases.RendererBase": [ "lib/matplotlib/backends/backend_template.py:docstring of matplotlib.backends.backend_template.RendererTemplate:4" @@ -1506,7 +1510,7 @@ "lib/mpl_toolkits/axisartist/axis_artist.py:docstring of mpl_toolkits.axisartist.axis_artist:26" ], "mplot3d": [ - "doc/index.rst:184" + "doc/index.rst:154" ], "new_figure_manager": [ "doc/devel/MEP/MEP23.rst:75" @@ -1689,4 +1693,4 @@ "lib/mpl_toolkits/mplot3d/axes3d.py:docstring of mpl_toolkits.mplot3d.axes3d.Axes3D.get_ylim3d:24" ] } -} +} \ No newline at end of file diff --git a/doc/thirdpartypackages/index.rst b/doc/thirdpartypackages/index.rst index 68c8685ec7a2..a8208059e40b 100644 --- a/doc/thirdpartypackages/index.rst +++ b/doc/thirdpartypackages/index.rst @@ -194,6 +194,36 @@ Yellowbrick .. image:: /_static/yellowbrick.png :height: 400px +Animations +********** + +animatplot +========== +`animatplot `_ is a library for +producing interactive animated plots with the goal of making production of +animated plots almost as easy as static ones. + +.. image:: /_static/animatplot.png + +For an animated version of the above picture and more examples, see the +`animatplot gallery. `_ + +gif +=== +`gif `_ is an ultra lightweight animated gif API. + +.. image:: /_static/gif_attachment_example.png + +numpngw +======= + +`numpngw `_ provides functions for writing +NumPy arrays to PNG and animated PNG files. It also includes the class +``AnimatedPNGWriter`` that can be used to save a Matplotlib animation as an +animated PNG file. See the example on the PyPI page or at the ``numpngw`` +`github repository `_. + +.. image:: /_static/numpngw_animated_example.png Interactivity ************* @@ -209,17 +239,6 @@ MplDataCursor written by Joe Kington to provide interactive "data cursors" (clickable annotation boxes) for Matplotlib. -animatplot -========== -`animatplot `_ is a library for -producing interactive animated plots with the goal of making production of -animated plots almost as easy as static ones. - -.. image:: /_static/animatplot.png - -For an animated version of the above picture and more examples, see the -`animatplot gallery. `_ - Rendering backends ****************** @@ -263,17 +282,6 @@ border, and logo. .. image:: /_static/mpl_template_example.png :height: 330px -numpngw -======= - -`numpngw `_ provides functions for writing -NumPy arrays to PNG and animated PNG files. It also includes the class -``AnimatedPNGWriter`` that can be used to save a Matplotlib animation as an -animated PNG file. See the example on the PyPI page or at the ``numpngw`` -`github repository `_. - -.. image:: /_static/numpngw_animated_example.png - blume ===== diff --git a/lib/matplotlib/cbook/__init__.py b/lib/matplotlib/cbook/__init__.py index 7ea6fec67920..e04ef4b3aa7a 100644 --- a/lib/matplotlib/cbook/__init__.py +++ b/lib/matplotlib/cbook/__init__.py @@ -1382,9 +1382,10 @@ def _check_1d(x): # This code should correctly identify and coerce to a # numpy array all pandas versions. with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings("always", - category=DeprecationWarning, - module='pandas[.*]') + warnings.filterwarnings( + "always", + category=DeprecationWarning, + message='Support for multi-dimensional indexing') ndim = x[:, None].ndim # we have definitely hit a pandas index or series object diff --git a/lib/matplotlib/colorbar.py b/lib/matplotlib/colorbar.py index 72f30723ae64..1e2fc9c201a6 100644 --- a/lib/matplotlib/colorbar.py +++ b/lib/matplotlib/colorbar.py @@ -452,6 +452,7 @@ def __init__(self, ax, cmap=None, self.locator = None self.formatter = None self._manual_tick_data_values = None + self._scale = None # linear, log10 for now. Hopefully more? if ticklocation == 'auto': ticklocation = 'bottom' if orientation == 'horizontal' else 'right' @@ -585,8 +586,8 @@ def _use_auto_colorbar_locator(self): one. (check is used twice so factored out here...) """ contouring = self.boundaries is not None and self.spacing == 'uniform' - return (type(self.norm) in [colors.Normalize, colors.LogNorm] - and not contouring) + return (type(self.norm) in [colors.Normalize, colors.LogNorm] and + not contouring) def _reset_locator_formatter_scale(self): """ @@ -602,9 +603,16 @@ def _reset_locator_formatter_scale(self): self.ax.set_xscale('log') self.ax.set_yscale('log') self.minorticks_on() + self._scale = 'log' else: self.ax.set_xscale('linear') self.ax.set_yscale('linear') + if (isintance(self.norm, colors.Normalize) and + not issubclass(type(self.norm), colors.Normalize): + self._scale = 'linear' + else: + self._scale = 'manual' + def update_ticks(self): """ @@ -1119,13 +1127,13 @@ def _mesh(self): else: y = self._proportional_y() xmid = np.array([0.5]) - try: + if not self._scale == 'manual' y = norm.inverse(y) x = norm.inverse(x) xmid = norm.inverse(xmid) - except ValueError: - # occurs for norms that don't have an inverse, in - # which case manually scale: + else: + # if a norm doesn't have a named scale, or + # we are not using a norm dv = self.vmax - self.vmin x = x * dv + self.vmin y = y * dv + self.vmin diff --git a/lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_norms.png b/lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_norms.png new file mode 100644 index 000000000000..922ecc0519f6 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_norms.png differ diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index 3932177565c5..7c6a9100843f 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -373,7 +373,6 @@ def test_colorbar_get_ticks(): data = np.arange(1200).reshape(30, 40) levels = [0, 200, 400, 600, 800, 1000, 1200] - plt.subplot() plt.contourf(data, levels=levels) # testing getter for user set ticks @@ -581,3 +580,18 @@ def test_colorbar_int(clim): im = ax.imshow([[*map(np.int16, clim)]]) fig.colorbar(im) assert (im.norm.vmin, im.norm.vmax) == clim + + +@image_comparison( + baseline_images=['colorbar_norms'], extensions=['png']) +def test_cbar_norms(): + # Test colormaps with different norms + norms = [mcolors.Normalize(vmin=-1, vmax=2), + mcolors.BoundaryNorm(boundaries=[-1, 0, 1], ncolors=4), + mcolors.LogNorm(vmin=1, vmax=1e4), + mcolors.PowerNorm(gamma=0.2, vmin=0.1, vmax=0.6), + mcolors.SymLogNorm(1, vmin=-10, vmax=10), + mcolors.TwoSlopeNorm(1, vmin=0, vmax=2)] + fig, axs = plt.subplots(ncols=len(norms), constrained_layout=True) + for ax, norm in zip(axs, norms): + fig.colorbar(cm.ScalarMappable(norm=norm, cmap='viridis'), cax=ax, extend='both') diff --git a/lib/mpl_toolkits/axes_grid1/axes_grid.py b/lib/mpl_toolkits/axes_grid1/axes_grid.py index 44fe15f1f4d3..2f22d39ba3f8 100644 --- a/lib/mpl_toolkits/axes_grid1/axes_grid.py +++ b/lib/mpl_toolkits/axes_grid1/axes_grid.py @@ -82,12 +82,13 @@ def cla(self): class Grid: """ - A class that creates a grid of Axes. In matplotlib, the axes - location (and size) is specified in the normalized figure - coordinates. This may not be ideal for images that needs to be - displayed with a given aspect ratio. For example, displaying - images of a same size with some fixed padding between them cannot - be easily done in matplotlib. AxesGrid is used in such case. + A grid of Axes. + + In Matplotlib, the axes location (and size) is specified in normalized + figure coordinates. This may not be ideal for images that needs to be + displayed with a given aspect ratio; for example, it is difficult to + display multiple images of a same size with some fixed padding between + them. AxesGrid can be used in such case. """ _defaultAxesClass = Axes @@ -115,14 +116,25 @@ def __init__(self, fig, rect : (float, float, float, float) or int The axes position, as a ``(left, bottom, width, height)`` tuple or as a three-digit subplot position code (e.g., "121"). + nrows_ncols : (int, int) + Number of rows and columns in the grid. + ngrids : int or None, default: None + If not None, only the first *ngrids* axes in the grid are created. direction : {"row", "column"}, default: "row" + Whether axes are created in row-major ("row by row") or + column-major order ("column by column"). axes_pad : float or (float, float), default: 0.02 Padding or (horizontal padding, vertical padding) between axes, in inches. add_all : bool, default: True + Whether to add the axes to the figure using `.Figure.add_axes`. share_all : bool, default: False + Whether all axes share their x- and y-axis. Overrides *share_x* + and *share_y*. share_x : bool, default: True + Whether all axes of a column share their x-axis. share_y : bool, default: True + Whether all axes of a row share their y-axis. label_mode : {"L", "1", "all"}, default: "L" Determines which axes will get tick labels: @@ -133,6 +145,8 @@ def __init__(self, fig, axes_class : subclass of `matplotlib.axes.Axes`, default: None aspect : bool, default: False + Whether the axes aspect ratio follows the aspect ratio of the data + limits. """ self._nrows, self._ncols = nrows_ncols @@ -332,14 +346,7 @@ def get_vsize_hsize(self): class ImageGrid(Grid): - """ - A class that creates a grid of Axes. In matplotlib, the axes - location (and size) is specified in the normalized figure - coordinates. This may not be ideal for images that needs to be - displayed with a given aspect ratio. For example, displaying - images of a same size with some fixed padding between them cannot - be easily done in matplotlib. ImageGrid is used in such case. - """ + # docstring inherited _defaultCbarAxesClass = CbarAxes @@ -368,13 +375,24 @@ def __init__(self, fig, rect : (float, float, float, float) or int The axes position, as a ``(left, bottom, width, height)`` tuple or as a three-digit subplot position code (e.g., "121"). + nrows_ncols : (int, int) + Number of rows and columns in the grid. + ngrids : int or None, default: None + If not None, only the first *ngrids* axes in the grid are created. direction : {"row", "column"}, default: "row" - axes_pad : float or (float, float), default: 0.02 + Whether axes are created in row-major ("row by row") or + column-major order ("column by column"). This also affects the + order in which axes are accessed using indexing (``grid[index]``). + axes_pad : float or (float, float), default: 0.02in Padding or (horizontal padding, vertical padding) between axes, in inches. add_all : bool, default: True + Whether to add the axes to the figure using `.Figure.add_axes`. share_all : bool, default: False + Whether all axes share their x- and y-axis. aspect : bool, default: True + Whether the axes aspect ratio follows the aspect ratio of the data + limits. label_mode : {"L", "1", "all"}, default: "L" Determines which axes will get tick labels: @@ -383,10 +401,16 @@ def __init__(self, fig, - "1": Only the bottom left axes is labelled. - "all": all axes are labelled. - cbar_mode : {"each", "single", "edge", None }, default: None + cbar_mode : {"each", "single", "edge", None}, default: None + Whether to create a colorbar for "each" axes, a "single" colorbar + for the entire grid, colorbars only for axes on the "edge" + determined by *cbar_location*, or no colorbars. The colorbars are + stored in the :attr:`cbar_axes` attribute. cbar_location : {"left", "right", "bottom", "top"}, default: "right" cbar_pad : float, default: None + Padding between the image axes and the colorbar axes. cbar_size : size specification (see `.Size.from_any`), default: "5%" + Colorbar size. cbar_set_cax : bool, default: True If True, each axes in the grid has a *cax* attribute that is bound to associated *cbar_axes*. diff --git a/tutorials/toolkits/axes_grid.py b/tutorials/toolkits/axes_grid.py index 75e7766f0303..41cccc0f1829 100644 --- a/tutorials/toolkits/axes_grid.py +++ b/tutorials/toolkits/axes_grid.py @@ -40,12 +40,14 @@ ImageGrid --------- -A class that creates a grid of Axes. In matplotlib, the axes location -(and size) is specified in the normalized figure coordinates. This may -not be ideal for images that needs to be displayed with a given aspect -ratio. For example, displaying images of a same size with some fixed -padding between them cannot be easily done in matplotlib. ImageGrid is -used in such case. +A grid of Axes. + +In Matplotlib, the axes location (and size) is specified in normalized +figure coordinates. This may not be ideal for images that needs to be +displayed with a given aspect ratio; for example, it is difficult to +display multiple images of a same size with some fixed padding between +them. `~.axes_grid1.axes_grid.ImageGrid` can be used in such a case; see its +docs for a detailed list of the parameters it accepts. .. figure:: ../../gallery/axes_grid1/images/sphx_glr_simple_axesgrid_001.png :target: ../../gallery/axes_grid1/simple_axesgrid.html @@ -78,76 +80,6 @@ your mouse in interactive backends) of one axes will affect all other shared axes. -When initialized, ImageGrid creates given number (*ngrids* or *ncols* * -*nrows* if *ngrids* is None) of Axes instances. A sequence-like -interface is provided to access the individual Axes instances (e.g., -grid[0] is the first Axes in the grid. See below for the order of -axes). - -ImageGrid takes following arguments, - - ============= ======== ================================================ - Name Default Description - ============= ======== ================================================ - fig - rect - nrows_ncols number of rows and cols. e.g., (2, 2) - ngrids None number of grids. nrows x ncols if None - direction "row" increasing direction of axes number. [row|column] - axes_pad 0.02 pad between axes in inches - add_all True Add axes to figures if True - share_all False xaxis & yaxis of all axes are shared if True - aspect True aspect of axes - label_mode "L" location of tick labels thaw will be displayed. - "1" (only the lower left axes), - "L" (left most and bottom most axes), - or "all". - cbar_mode None [None|single|each] - cbar_location "right" [right|top] - cbar_pad None pad between image axes and colorbar axes - cbar_size "5%" size of the colorbar - axes_class None - ============= ======== ================================================ - - *rect* - specifies the location of the grid. You can either specify - coordinates of the rectangle to be used (e.g., (0.1, 0.1, 0.8, 0.8) - as in the Axes), or the subplot-like position (e.g., "121"). - - *direction* - means the increasing direction of the axes number. - - *aspect* - By default (False), widths and heights of axes in the grid are - scaled independently. If True, they are scaled according to their - data limits (similar to aspect parameter in Matplotlib). - - *share_all* - if True, xaxis and yaxis of all axes are shared. - - *direction* - direction of increasing axes number. For "row", - - +---------+---------+ - | grid[0] | grid[1] | - +---------+---------+ - | grid[2] | grid[3] | - +---------+---------+ - - For "column", - - +---------+---------+ - | grid[0] | grid[2] | - +---------+---------+ - | grid[1] | grid[3] | - +---------+---------+ - -You can also create a colorbar (or colorbars). You can have colorbar -for each axes (cbar_mode="each"), or you can have a single colorbar -for the grid (cbar_mode="single"). The colorbar can be placed on your -right, or top. The axes for each colorbar is stored as a *cbar_axes* -attribute. - The examples below show what you can do with ImageGrid. .. figure:: ../../gallery/axes_grid1/images/sphx_glr_demo_axes_grid_001.png