diff --git a/doc/_templates/automodule.rst b/doc/_templates/automodule.rst index 7fa0780eb266..e9f2a755d413 100644 --- a/doc/_templates/automodule.rst +++ b/doc/_templates/automodule.rst @@ -1,5 +1,12 @@ {{ fullname | escape | underline}} +{% if fullname in ['mpl_toolkits.axes_grid1.colorbar'] %} +.. To prevent problems with the autosummary for the colorbar doc + treat this separately (sphinx-doc/sphinx/issues/4874) +.. automodule:: {{ fullname }} + :members: + +{% else %} .. automodule:: {{ fullname }} :no-members: @@ -33,3 +40,4 @@ Functions {{ item }}{% endif %}{% endfor %} {% endif %} {% endblock %} +{% endif %} diff --git a/doc/_templates/autosummary.rst b/doc/_templates/autosummary.rst index cf000cc16de0..8991f3c9ebc4 100644 --- a/doc/_templates/autosummary.rst +++ b/doc/_templates/autosummary.rst @@ -6,11 +6,17 @@ .. auto{{ objtype }}:: {{ objname }} {% if objtype in ['class', 'method', 'function'] %} - +{% if objname in ['AxesGrid', 'Scalable', 'HostAxes', 'FloatingAxes', + 'ParasiteAxesAuxTrans', 'ParasiteAxes'] %} +.. Filter out the above aliases to other classes, as sphinx gallery + creates no example file for those (sphinx-gallery/sphinx-gallery#365) + +{% else %} .. include:: {{module}}.{{objname}}.examples .. raw:: html
+{% endif %} {% endif %} \ No newline at end of file diff --git a/doc/api/api_changes.rst b/doc/api/api_changes.rst index dacb95c6660b..fa9ccddf786d 100644 --- a/doc/api/api_changes.rst +++ b/doc/api/api_changes.rst @@ -62,7 +62,7 @@ Changed function signatures kwarg ``fig`` to `.GridSpec.get_subplot_params` is deprecated, use ``figure`` instead. -Using `.pyplot.axes` with an `.Axes` as argument is deprecated. This sets +Using `.pyplot.axes` with an `~matplotlib.axes.Axes` as argument is deprecated. This sets the current axes, i.e. it has the same effect as `.pyplot.sca`. For clarity ``plt.sca(ax)`` should be preferred over ``plt.axes(ax)``. @@ -864,7 +864,7 @@ Deprecation and removal Color of Axes ~~~~~~~~~~~~~ -The ``axisbg`` and ``axis_bgcolor`` properties on ``Axes`` have been +The ``axisbg`` and ``axis_bgcolor`` properties on *Axes* have been deprecated in favor of ``facecolor``. GTK and GDK backends deprecated @@ -1297,8 +1297,8 @@ algorithm that was not necessarily applicable to custom Axes. Three new private methods, :meth:`~matplotlib.axes._base._AxesBase._get_view`, :meth:`~matplotlib.axes._base._AxesBase._set_view`, and :meth:`~matplotlib.axes._base._AxesBase._set_view_from_bbox`, allow for custom -``Axes`` classes to override the pan and zoom algorithms. Implementors of -custom ``Axes`` who override these methods may provide suitable behaviour for +*Axes* classes to override the pan and zoom algorithms. Implementors of +custom *Axes* who override these methods may provide suitable behaviour for both pan and zoom as well as the view navigation buttons on the interactive toolbars. diff --git a/doc/api/index.rst b/doc/api/index.rst index 3cc26c8beb06..78669f992177 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -74,5 +74,8 @@ Toolkits .. toctree:: :maxdepth: 1 - toolkits/axes_grid.rst + toolkits/mplot3d.rst + toolkits/axes_grid1.rst + toolkits/axisartist.rst + toolkits/axes_grid.rst diff --git a/doc/api/toolkits/axes_grid.rst b/doc/api/toolkits/axes_grid.rst index ed8692fcc016..991b0ff6813a 100644 --- a/doc/api/toolkits/axes_grid.rst +++ b/doc/api/toolkits/axes_grid.rst @@ -1,28 +1,26 @@ .. _axes_grid-api-index: -#################################### -The Matplotlib axes_grid Toolkit API -#################################### - -:Release: |version| -:Date: |today| +Matplotlib axes_grid Toolkit +============================ .. currentmodule:: mpl_toolkits -Axes Grid ---------- + .. note:: - - There is an older version of the AxesGrid toolkit, ``axes_grid`` (instead of - ``axes_grid1``). The old version had a single namespace for all axes_grid - objects, and in the new version this toolkit was broken - into the two modules below. For the documentation on ``axes_grid``, + AxesGrid toolkit has been a part of matplotlib since v + 0.99. Originally, the toolkit had a single namespace of + *axes_grid*. In more recent version, the toolkit + has divided into two separate namespace (*axes_grid1* and *axisartist*). + While *axes_grid* namespace is maintained for the backward compatibility, + use of *axes_grid1* and *axisartist* is recommended. + For the documentation on ``axes_grid``, see the `previous version of the docs `_. -.. autosummary:: - :toctree: ../_as_gen - :template: automodule.rst +.. toctree:: + :maxdepth: 1 + + axes_grid1 + axisartist + - axes_grid1 - axisartist diff --git a/doc/api/toolkits/axes_grid1.rst b/doc/api/toolkits/axes_grid1.rst new file mode 100644 index 000000000000..52363877e285 --- /dev/null +++ b/doc/api/toolkits/axes_grid1.rst @@ -0,0 +1,39 @@ +.. _toolkit_axesgrid1-index: + +Matplotlib axes_grid1 Toolkit +============================= + +The matplotlib :class:`mpl_toolkits.axes_grid1` toolkit is a collection of +helper classes to ease displaying multiple images in matplotlib. While the +aspect parameter in matplotlib adjust the position of the single axes, +axes_grid1 toolkit provides a framework to adjust the position of +multiple axes according to their aspects. + +See :ref:`axes_grid1_users-guide-index` for a guide on the usage of axes_grid1. + +.. figure:: ../../gallery/axes_grid1/images/sphx_glr_demo_axes_grid_001.png + :target: ../../gallery/axes_grid1/demo_axes_grid.html + :align: center + :scale: 50 + + + +.. currentmodule:: mpl_toolkits + +**The submodules of the axes_grid1 API are:** + +.. autosummary:: + :toctree: ../_as_gen + :template: automodule.rst + + axes_grid1.anchored_artists + axes_grid1.axes_divider + axes_grid1.axes_grid + axes_grid1.axes_rgb + axes_grid1.axes_size + axes_grid1.colorbar + axes_grid1.inset_locator + axes_grid1.mpl_axes + axes_grid1.parasite_axes + + diff --git a/doc/api/toolkits/axisartist.rst b/doc/api/toolkits/axisartist.rst new file mode 100644 index 000000000000..a08113f71396 --- /dev/null +++ b/doc/api/toolkits/axisartist.rst @@ -0,0 +1,40 @@ +.. _toolkit_axisartist-index: + +Matplotlib axisartist Toolkit +============================= + +The *axisartist* namespace includes a derived Axes implementation ( +:class:`mpl_toolkits.axisartist.Axes`). The +biggest difference is that the artists that are responsible for drawing +axis lines, ticks, ticklabels, and axis labels are separated out from the +mpl's Axis class. This change was strongly motivated to support curvilinear grid. + +You can find a tutorial describing usage of axisartist at the +:ref:`axisartist_users-guide-index` user guide. + +.. figure:: ../../gallery/axisartist/images/sphx_glr_demo_curvelinear_grid_001.png + :target: ../../gallery/axisartist/demo_curvelinear_grid.html + :align: center + :scale: 50 + +.. currentmodule:: mpl_toolkits + +**The submodules of the axisartist API are:** + +.. autosummary:: + :toctree: ../_as_gen + :template: automodule.rst + + axisartist.angle_helper + axisartist.axes_divider + axisartist.axes_grid + axisartist.axes_rgb + axisartist.axis_artist + axisartist.axisline_style + axisartist.axislines + axisartist.clip_path + axisartist.floating_axes + axisartist.grid_finder + axisartist.grid_helper_curvelinear + axisartist.parasite_axes + diff --git a/doc/mpl_toolkits/index.rst b/doc/api/toolkits/index.rst similarity index 51% rename from doc/mpl_toolkits/index.rst rename to doc/api/toolkits/index.rst index b4322f578def..2089156a1d21 100644 --- a/doc/mpl_toolkits/index.rst +++ b/doc/api/toolkits/index.rst @@ -24,8 +24,8 @@ lighter weight solution for some use cases. Check out the :doc:`mplot3d tutorial ` for more information. -.. figure:: ../gallery/mplot3d/images/sphx_glr_contourf3d_2_001.png - :target: ../gallery/mplot3d/contourf3d_2.html +.. figure:: ../../gallery/mplot3d/images/sphx_glr_contourf3d_2_001.png + :target: ../../gallery/mplot3d/contourf3d_2.html :align: center :scale: 50 @@ -41,37 +41,20 @@ Links ----- * mpl3d API: :ref:`toolkit_mplot3d-api` -.. _toolkit_axes_grid1: +.. _toolkit_axes_grid1_incl: -axes_grid1 -========== +.. include:: axes_grid1.rst + :start-line: 1 -The :mod:`mpl_toolkits.axes_grid1` toolkit is a -collection of helper classes for displaying multiple axes in Matplotlib. +.. _toolkit_axisartist_incl: + +.. include:: axisartist.rst + :start-line: 1 -.. image:: /_static/demo_axes_grid.png - -.. toctree:: - :maxdepth: 2 - - axes_grid1/index.rst - - -.. _toolkit_axisartist: - -axisartist -========== - -The :mod:`mpl_toolkits.axisartist` toolkit contains -a custom Axes class that is meant to support curvilinear grids. - -.. toctree:: - :maxdepth: 2 - - axisartist/index.rst +.. _toolkit_axes_grid_incl: + +.. include:: axes_grid.rst + :start-line: 1 -API ---- -* Axes Grid and Axis Artist API: :ref:`axes_grid-api-index` diff --git a/doc/mpl_toolkits/mplot3d/faq.rst b/doc/api/toolkits/mplot3d/faq.rst similarity index 100% rename from doc/mpl_toolkits/mplot3d/faq.rst rename to doc/api/toolkits/mplot3d/faq.rst diff --git a/doc/mpl_toolkits/mplot3d/index.rst b/doc/api/toolkits/mplot3d/index.rst similarity index 95% rename from doc/mpl_toolkits/mplot3d/index.rst rename to doc/api/toolkits/mplot3d/index.rst index b53d0fc153c9..8b153c06903f 100644 --- a/doc/mpl_toolkits/mplot3d/index.rst +++ b/doc/api/toolkits/mplot3d/index.rst @@ -14,7 +14,7 @@ The resulting graph will have the same look and feel as regular 2D plots. See the :doc:`mplot3d tutorial ` for more information on how to use this toolkit. -.. image:: ../../_static/demo_mplot3d.png +.. image:: /_static/demo_mplot3d.png The interactive backends also provide the ability to rotate and zoom the 3D scene. One can rotate the 3D scene by simply clicking-and-dragging diff --git a/doc/contents.rst b/doc/contents.rst index 72612f7b7694..104e143a07c2 100644 --- a/doc/contents.rst +++ b/doc/contents.rst @@ -16,7 +16,7 @@ Overview users/index.rst faq/index.rst - mpl_toolkits/index.rst + api/toolkits/index.rst resources/index.rst thirdpartypackages/index.rst api/index.rst diff --git a/doc/index.rst b/doc/index.rst index b5eb92d8534f..fa9c101ab2c2 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -142,7 +142,7 @@ require changes to your existing code is logged in the :doc:`API changes Toolkits ======== -Matplotlib ships with several add-on :doc:`toolkits `, +Matplotlib ships with several add-on :doc:`toolkits `, including 3d plotting with `mplot3d`, axes helpers in `axes_grid1` and axis helpers in `axisartist`. diff --git a/doc/mpl_toolkits/axes_grid1/index.rst b/doc/mpl_toolkits/axes_grid1/index.rst deleted file mode 100644 index aacb1cc5b872..000000000000 --- a/doc/mpl_toolkits/axes_grid1/index.rst +++ /dev/null @@ -1,24 +0,0 @@ - -.. _toolkit_axesgrid1-index: - -Matplotlib axes_grid1 Toolkit -============================= - -The matplotlib :class:`mpl_toolkits.axes_grid1` toolkit is a collection of -helper classes to ease displaying multiple images in matplotlib. While the -aspect parameter in matplotlib adjust the position of the single axes, -axesgrid1 toolkit provides a framework to adjust the position of -multiple axes according to their aspects. - -See :ref:`axes_grid1_users-guide-index` for a guide on the usage of axes_grid1. - - -.. image:: ../../_static/demo_axes_grid.png - -.. note:: - AxesGrid toolkit has been a part of matplotlib since v - 0.99. Originally, the toolkit had a single namespace of - *axes_grid*. In more recent version, the toolkit - has divided into two separate namespace (*axes_grid1* and *axisartist*). - While *axes_grid* namespace is maintained for the backward compatibility, - use of *axes_grid1* and *axisartist* is recommended. diff --git a/doc/mpl_toolkits/axisartist/index.rst b/doc/mpl_toolkits/axisartist/index.rst deleted file mode 100644 index 2a46936f1381..000000000000 --- a/doc/mpl_toolkits/axisartist/index.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. _toolkit_axisartist-index: - -Matplotlib axisartist Toolkit -============================= - -The *axisartist* namespace includes a derived Axes implementation ( -:class:`mpl_toolkits.axisartist.Axes`). The -biggest difference is that the artists that are responsible for drawing -axis lines, ticks, ticklabels, and axis labels are separated out from the -mpl's Axis class. This change was strongly motivated to support curvilinear grid. - -You can find a tutorial describing usage of axisartist at -:ref:`axisartist_users-guide-index`. diff --git a/examples/axes_grid1/inset_locator_demo.py b/examples/axes_grid1/inset_locator_demo.py index ee3f54acdffd..878d3a5b1b04 100644 --- a/examples/axes_grid1/inset_locator_demo.py +++ b/examples/axes_grid1/inset_locator_demo.py @@ -4,49 +4,141 @@ ================== """ + +############################################################################### +# The `.inset_locator`'s `~.inset_axes` allows to easily place insets in the +# corners of the axes by specifying a width and height and optionally +# a location (loc) which accepts locations as codes, similar to +# `~matplotlib.axes.Axes.legend`. +# By default, the inset is offset by some points from the axes - this is +# controlled via the `borderpad` parameter. + import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1.inset_locator import inset_axes + + +fig, (ax, ax2) = plt.subplots(1, 2, figsize=[5.5, 2.8]) + +# Create inset of width 1.3 inches and height 0.9 inches +# at the default upper right location +axins = inset_axes(ax, width=1.3, height=0.9) + +# Create inset of width 30% and height 40% of the parent axes' bounding box +# at the lower left corner (loc=3) +axins2 = inset_axes(ax, width="30%", height="40%", loc=3) + +# Create inset of mixed specifications in the second subplot; +# width is 30% of parent axes' bounding box and +# height is 1 inch at the upper left corner (loc=2) +axins3 = inset_axes(ax2, width="30%", height=1., loc=2) + +# Create an inset in the lower right corner (loc=4) with borderpad=1, i.e. +# 10 points padding (as 10pt is the default fontsize) to the parent axes +axins4 = inset_axes(ax2, width="20%", height="20%", loc=4, borderpad=1) + +# Turn ticklabels of insets off +for axi in [axins, axins2, axins3, axins4]: + axi.tick_params(labelleft=False, labelbottom=False) + +plt.show() -from mpl_toolkits.axes_grid1.inset_locator import inset_axes, zoomed_inset_axes -from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar +############################################################################### +# The arguments `bbox_to_anchor` and `bbox_transfrom` can be used for a more +# fine grained control over the inset position and size or even to position +# the inset at completely arbitrary positions. +# The `bbox_to_anchor` sets the bounding box in coordinates according to the +# `bbox_transform`. +# -def add_sizebar(ax, size): - asb = AnchoredSizeBar(ax.transData, - size, - str(size), - loc=8, - pad=0.1, borderpad=0.5, sep=5, - frameon=False) - ax.add_artist(asb) +fig = plt.figure(figsize=[5.5, 2.8]) +ax = fig.add_subplot(121) +# We use the axes transform as bbox_transform. Therefore the bounding box +# needs to be specified in axes coordinates ((0,0) is the lower left corner +# of the axes, (1,1) is the upper right corner). +# The bounding box (.2, .4, .6, .5) starts at (.2,.4) and ranges to (.8,.9) +# in those coordinates. +# Inside of this bounding box an inset of half the bounding box' width and +# three quarters of the bounding box' height is created. The lower left corner +# of the inset is aligned to the lower left corner of the bounding box (loc=3). +# The inset is then offset by the default 0.5 in units of the font size. + +axins = inset_axes(ax, width="50%", height="75%", + bbox_to_anchor=(.2, .4, .6, .5), + bbox_transform=ax.transAxes, loc=3) + +# For visualization purposes we mark the bounding box by a rectangle +ax.add_patch(plt.Rectangle((.2, .4), .6, .5, ls="--", ec="c", fc="None", + transform=ax.transAxes)) + +# We set the axis limits to something other than the default, in order to not +# distract from the fact that axes coodinates are used here. +ax.axis([0, 10, 0, 10]) + + +# Note how the two following insets are created at the same positions, one by +# use of the default parent axes' bbox and the other via a bbox in axes +# coordinates and the respective transform. +ax2 = fig.add_subplot(222) +axins2 = inset_axes(ax2, width="30%", height="50%") + +ax3 = fig.add_subplot(224) +axins3 = inset_axes(ax3, width="100%", height="100%", + bbox_to_anchor=(.7, .5, .3, .5), + bbox_transform=ax3.transAxes) + +# For visualization purposes we mark the bounding box by a rectangle +ax2.add_patch(plt.Rectangle((0, 0), 1, 1, ls="--", lw=2, ec="c", fc="None")) +ax3.add_patch(plt.Rectangle((.7, .5), .3, .5, ls="--", lw=2, + ec="c", fc="None")) + +# Turn ticklabels off +for axi in [axins2, axins3, ax2, ax3]: + axi.tick_params(labelleft=False, labelbottom=False) + +plt.show() -fig, (ax, ax2) = plt.subplots(1, 2, figsize=[5.5, 3]) -# first subplot -ax.set_aspect(1) +############################################################################### +# In the above the axes transform together with 4-tuple bounding boxes has been +# used as it mostly is useful to specify an inset relative to the axes it is +# an inset to. However other use cases are equally possible. The following +# example examines some of those. +# -axins = inset_axes(ax, - width="30%", # width = 30% of parent_bbox - height=1., # height : 1 inch - loc=3) +fig = plt.figure(figsize=[5.5, 2.8]) +ax = fig.add_subplot(131) -plt.xticks(visible=False) -plt.yticks(visible=False) +# Create an inset outside the axes +axins = inset_axes(ax, width="100%", height="100%", + bbox_to_anchor=(1.05, .6, .5, .4), + bbox_transform=ax.transAxes, loc=2, borderpad=0) +axins.tick_params(left=False, right=True, labelleft=False, labelright=True) +# Create an inset with a 2-tuple bounding box. Note that this creates a +# bbox without extent. This hence only makes sense when specifying +# width and height in absolute units (inches). +axins2 = inset_axes(ax, width=0.5, height=0.4, + bbox_to_anchor=(0.33, 0.25), + bbox_transform=ax.transAxes, loc=3, borderpad=0) -# second subplot -ax2.set_aspect(1) -axins = zoomed_inset_axes(ax2, zoom=0.5, loc='upper right') -# fix the number of ticks on the inset axes -axins.yaxis.get_major_locator().set_params(nbins=7) -axins.xaxis.get_major_locator().set_params(nbins=7) +ax2 = fig.add_subplot(133) +ax2.set_xscale("log") +ax2.axis([1e-6, 1e6, -2, 6]) -plt.xticks(visible=False) -plt.yticks(visible=False) +# Create inset in data coordinates using ax.transData as transform +axins3 = inset_axes(ax2, width="100%", height="100%", + bbox_to_anchor=(1e-2, 2, 1e3, 3), + bbox_transform=ax2.transData, loc=2, borderpad=0) -add_sizebar(ax2, 0.5) -add_sizebar(axins, 0.5) +# Create an inset horizontally centered in figure coordinates and vertically +# bound to line up with the axes. +from matplotlib.transforms import blended_transform_factory +transform = blended_transform_factory(fig.transFigure, ax2.transAxes) +axins4 = inset_axes(ax2, width="16%", height="34%", + bbox_to_anchor=(0, 0, 1, 1), + bbox_transform=transform, loc=8, borderpad=0) -plt.draw() plt.show() diff --git a/examples/axes_grid1/inset_locator_demo2.py b/examples/axes_grid1/inset_locator_demo2.py index a70cbb926e64..509413d3bf83 100644 --- a/examples/axes_grid1/inset_locator_demo2.py +++ b/examples/axes_grid1/inset_locator_demo2.py @@ -3,11 +3,16 @@ Inset Locator Demo2 =================== +This Demo shows how to create a zoomed inset via `~.zoomed_inset_axes`. +In the first subplot an `~.AnchoredSizeBar` shows the zoom effect. +In the second subplot a connection to the region of interest is +created via `~.mark_inset`. """ + import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes -from mpl_toolkits.axes_grid1.inset_locator import mark_inset +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes, mark_inset +from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar import numpy as np @@ -20,36 +25,63 @@ def get_demo_image(): # z is a numpy array of 15x15 return z, (-3, 4, -4, 3) -fig, ax = plt.subplots(figsize=[5, 4]) +fig, (ax, ax2) = plt.subplots(ncols=2, figsize=[6, 3]) + + +# First subplot, showing an inset with a size bar. +ax.set_aspect(1) + +axins = zoomed_inset_axes(ax, zoom=0.5, loc='upper right') +# fix the number of ticks on the inset axes +axins.yaxis.get_major_locator().set_params(nbins=7) +axins.xaxis.get_major_locator().set_params(nbins=7) + +plt.setp(axins.get_xticklabels(), visible=False) +plt.setp(axins.get_yticklabels(), visible=False) -# prepare the demo image + +def add_sizebar(ax, size): + asb = AnchoredSizeBar(ax.transData, + size, + str(size), + loc=8, + pad=0.1, borderpad=0.5, sep=5, + frameon=False) + ax.add_artist(asb) + +add_sizebar(ax, 0.5) +add_sizebar(axins, 0.5) + + +# Second subplot, showing an image with an inset zoom +# and a marked inset Z, extent = get_demo_image() Z2 = np.zeros([150, 150], dtype="d") ny, nx = Z.shape Z2[30:30 + ny, 30:30 + nx] = Z # extent = [-3, 4, -4, 3] -ax.imshow(Z2, extent=extent, interpolation="nearest", +ax2.imshow(Z2, extent=extent, interpolation="nearest", origin="lower") -axins = zoomed_inset_axes(ax, 6, loc=1) # zoom = 6 -axins.imshow(Z2, extent=extent, interpolation="nearest", - origin="lower") + +axins2 = zoomed_inset_axes(ax2, 6, loc=1) # zoom = 6 +axins2.imshow(Z2, extent=extent, interpolation="nearest", + origin="lower") # sub region of the original image x1, x2, y1, y2 = -1.5, -0.9, -2.5, -1.9 -axins.set_xlim(x1, x2) -axins.set_ylim(y1, y2) +axins2.set_xlim(x1, x2) +axins2.set_ylim(y1, y2) # fix the number of ticks on the inset axes -axins.yaxis.get_major_locator().set_params(nbins=7) -axins.xaxis.get_major_locator().set_params(nbins=7) +axins2.yaxis.get_major_locator().set_params(nbins=7) +axins2.xaxis.get_major_locator().set_params(nbins=7) -plt.xticks(visible=False) -plt.yticks(visible=False) +plt.setp(axins2.get_xticklabels(), visible=False) +plt.setp(axins2.get_yticklabels(), visible=False) # draw a bbox of the region of the inset axes in the parent axes and # connecting lines between the bbox and the inset axes area -mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5") +mark_inset(ax2, axins2, loc1=2, loc2=4, fc="none", ec="0.5") -plt.draw() plt.show() diff --git a/examples/ticks_and_spines/date_index_formatter.py b/examples/ticks_and_spines/date_index_formatter2.py similarity index 100% rename from examples/ticks_and_spines/date_index_formatter.py rename to examples/ticks_and_spines/date_index_formatter2.py diff --git a/lib/matplotlib/colorbar.py b/lib/matplotlib/colorbar.py index 8f780e25dff3..80664a99f939 100644 --- a/lib/matplotlib/colorbar.py +++ b/lib/matplotlib/colorbar.py @@ -152,7 +152,7 @@ default to the current image. cax : :class:`~matplotlib.axes.Axes` object, optional - Axis into which the colorbar will be drawn + Axes into which the colorbar will be drawn. ax : :class:`~matplotlib.axes.Axes`, list of Axes, optional Parent axes from which space for a new colorbar axes will be stolen. diff --git a/lib/matplotlib/contour.py b/lib/matplotlib/contour.py index 096787e8f54f..f6fdfd61c268 100644 --- a/lib/matplotlib/contour.py +++ b/lib/matplotlib/contour.py @@ -52,7 +52,7 @@ def get_rotation(self): class ContourLabeler(object): - """Mixin to provide labelling capability to ContourSet""" + """Mixin to provide labelling capability to `.ContourSet`.""" def clabel(self, *args, **kwargs): """ @@ -312,14 +312,14 @@ def get_real_label_width(self, lev, fmt, fsize): return lw def set_label_props(self, label, text, color): - "set the label properties - color, fontsize, text" + """Set the label properties - color, fontsize, text.""" label.set_text(text) label.set_color(color) label.set_fontproperties(self.labelFontProps) label.set_clip_box(self.ax.bbox) def get_text(self, lev, fmt): - "get the text of the label" + """Get the text of the label.""" if isinstance(lev, six.string_types): return lev else: @@ -520,15 +520,18 @@ def add_label_near(self, x, y, inline=True, inline_spacing=5, specified transform will be used to translate (x, y) into display coordinates. - *inline*: - controls whether the underlying contour is removed or - not. Default is *True*. + Parameters + ---------- + x, y : float + The approximate location of the label. - *inline_spacing*: - space in pixels to leave on each side of label when - placing inline. Defaults to 5. This spacing will be - exact for labels at locations where the contour is - straight, less so for labels on curved contours. + inline : bool, optional, default: True + If *True* remove the segment of the contour beneath the label. + + inline_spacing : int, optional, default: 5 + Space in pixels to leave on each side of label when placing + inline. This spacing will be exact for labels at locations where + the contour is straight, less so for labels on curved contours. """ if transform is None: @@ -665,7 +668,7 @@ def labels(self, inline, inline_spacing): def _find_closest_point_on_leg(p1, p2, p0): - """find closest point to p0 on line segment connecting p1 and p2""" + """Find the closest point to p0 on line segment connecting p1 and p2.""" # handle degenerate case if np.all(p2 == p1): @@ -691,7 +694,7 @@ def _find_closest_point_on_leg(p1, p2, p0): def _is_closed_polygon(X): """ - Tests whether first and last object in a sequence are the same. These are + Return whether first and last object in a sequence are the same. These are presumably coordinates on a polygonal curve, in which case this function tests if that curve is closed. """ @@ -735,7 +738,42 @@ class ContourSet(cm.ScalarMappable, ContourLabeler): """ Store a set of contour lines or filled regions. - User-callable method: clabel + User-callable method: `~.axes.Axes.clabel` + + Parameters + ---------- + ax : `~.axes.Axes` + + levels : [level0, level1, ..., leveln] + A list of floating point numbers indicating the contour + levels. + + allsegs : [level0segs, level1segs, ...] + List of all the polygon segments for all the *levels*. + For contour lines ``len(allsegs) == len(levels)``, and for + filled contour regions ``len(allsegs) = len(levels)-1``. The lists + should look like:: + + level0segs = [polygon0, polygon1, ...] + polygon0 = array_like [[x0,y0], [x1,y1], ...] + + allkinds : ``None`` or [level0kinds, level1kinds, ...] + Optional list of all the polygon vertex kinds (code types), as + described and used in Path. This is used to allow multiply- + connected paths such as holes within filled polygons. + If not ``None``, ``len(allkinds) == len(allsegs)``. The lists + should look like:: + + level0kinds = [polygon0kinds, ...] + polygon0kinds = [vertexcode0, vertexcode1, ...] + + If *allkinds* is not ``None``, usually all polygons for a + particular contour level are grouped together so that + ``level0segs = [polygon0]`` and ``level0kinds = [polygon0kinds]``. + + kwargs : + Keyword arguments are as described in the docstring of + `~.axes.Axes.contour`. Attributes ---------- @@ -758,15 +796,20 @@ def __init__(self, ax, *args, **kwargs): Draw contour lines or filled regions, depending on whether keyword arg *filled* is ``False`` (default) or ``True``. - The first three arguments must be: + Call signature:: + + ContourSet(ax, levels, allsegs, [allkinds], **kwargs) - *ax*: axes object. + Parameters + ---------- + ax : + The `~.axes.Axes` object to draw on. - *levels*: [level0, level1, ..., leveln] + levels : [level0, level1, ..., leveln] A list of floating point numbers indicating the contour levels. - *allsegs*: [level0segs, level1segs, ...] + allsegs : [level0segs, level1segs, ...] List of all the polygon segments for all the *levels*. For contour lines ``len(allsegs) == len(levels)``, and for filled contour regions ``len(allsegs) = len(levels)-1``. The lists @@ -775,7 +818,7 @@ def __init__(self, ax, *args, **kwargs): level0segs = [polygon0, polygon1, ...] polygon0 = array_like [[x0,y0], [x1,y1], ...] - *allkinds*: *None* or [level0kinds, level1kinds, ...] + allkinds : [level0kinds, level1kinds, ...], optional Optional list of all the polygon vertex kinds (code types), as described and used in Path. This is used to allow multiply- connected paths such as holes within filled polygons. @@ -789,8 +832,9 @@ def __init__(self, ax, *args, **kwargs): particular contour level are grouped together so that ``level0segs = [polygon0]`` and ``level0kinds = [polygon0kinds]``. - Keyword arguments are as described in the docstring of - `~.Axes.contour`. + **kwargs + Keyword arguments are as described in the docstring of + `~axes.Axes.contour`. """ self.ax = ax self.levels = kwargs.pop('levels', None) @@ -981,15 +1025,28 @@ def __getstate__(self): def legend_elements(self, variable_name='x', str_format=str): """ - Return a list of artist and labels suitable for passing through + Return a list of artists and labels suitable for passing through to :func:`plt.legend` which represent this ContourSet. - Args: + The labels have the form "0 < x <= 1" stating the data ranges which + the artists represent. + + Parameters + ---------- + variable_name : str + The string used inside the inequality used on the labels. + + str_format : function: float -> str + Function used to format the numbers in the labels. - *variable_name*: the string used inside the inequality used - on the labels + Returns + ------- + artists : List[`.Artist`] + A list of the artists. + + labels : List[str] + A list of the labels. - *str_format*: function used to format the numbers in the labels """ artists = [] labels = [] @@ -1305,7 +1362,10 @@ def get_alpha(self): return self.alpha def set_alpha(self, alpha): - """sets alpha for all ContourSet artists""" + """ + Set the alpha blending value for all ContourSet artists. + *alpha* must be between 0 (transparent) and 1 (opaque). + """ self.alpha = alpha self.changed() @@ -1377,7 +1437,7 @@ class QuadContourSet(ContourSet): """ Create and store a set of contour lines or filled regions. - User-callable method: :meth:`clabel` + User-callable method: `~axes.Axes.clabel` Attributes ---------- @@ -1584,70 +1644,48 @@ def _initialize_x_y(self, z): _contour_doc = """ Plot contours. + Call signature:: + + contour([X, Y,] Z, [levels], **kwargs) + :func:`~matplotlib.pyplot.contour` and :func:`~matplotlib.pyplot.contourf` draw contour lines and filled contours, respectively. Except as noted, function signatures and return values are the same for both versions. - :func:`~matplotlib.pyplot.contourf` differs from the MATLAB - version in that it does not draw the polygon edges. - To draw edges, add line contours with - calls to :func:`~matplotlib.pyplot.contour`. - - - Call signatures:: - - contour(Z) - - make a contour plot of an array *Z*. The level values are chosen - automatically. - - :: - - contour(X,Y,Z) - - *X*, *Y* specify the (x, y) coordinates of the surface - - :: - - contour(Z,N) - contour(X,Y,Z,N) - - contour up to *N+1* automatically chosen contour levels - (*N* intervals). - - :: - - contour(Z,V) - contour(X,Y,Z,V) - draw contour lines at the values specified in sequence *V*, - which must be in increasing order. - - :: - - contourf(..., V) + Parameters + ---------- + X, Y : array-like, optional + The coordinates of the values in *Z*. - fill the ``len(V)-1`` regions between the values in *V*, - which must be in increasing order. + *X* and *Y* must both be 2-D with the same shape as *Z* (e.g. + created via :func:`numpy.meshgrid`), or they must both be 1-D such + that ``len(X) == M`` is the number of columns in *Z* and + ``len(Y) == N`` is the number of rows in *Z*. - :: + If not given, they are assumed to be integer indices, i.e. + ``X = range(M)``, ``Y = range(N)``. - contour(Z, **kwargs) + Z : array-like(N, M) + The height values over which the contour is drawn. - Use keyword args to control colors, linewidth, origin, cmap ... see - below for more details. + levels : int or array-like, optional + Determines the number and positions of the contour lines / regions. - *X* and *Y* must both be 2-D with the same shape as *Z*, or they - must both be 1-D such that ``len(X)`` is the number of columns in - *Z* and ``len(Y)`` is the number of rows in *Z*. + If an int *n*, use *n* data intervals; i.e. draw *n+1* contour + lines. The level heights are automatically chosen. - ``C = contour(...)`` returns a - :class:`~matplotlib.contour.QuadContourSet` object. + If array-like, draw contour lines at the specified levels. + The values must be in increasing order. - Optional keyword arguments: + Returns + ------- + :class:`~matplotlib.contour.QuadContourSet` - *corner_mask*: bool, optional + Other Parameters + ---------------- + corner_mask : bool, optional Enable/disable corner masking, which only has an effect if *Z* is a masked array. If ``False``, any quad touching a masked point is masked out. If ``True``, only the triangular corners of quads @@ -1657,50 +1695,54 @@ def _initialize_x_y(self, z): Defaults to ``rcParams['contour.corner_mask']``, which defaults to ``True``. - *colors*: [ *None* | string | (mpl_colors) ] - If *None*, the colormap specified by cmap will be used. + colors : color string or sequence of colors, optional + The colors of the levels, i.e. the lines for `.contour` and the + areas for `.contourf`. - If a string, like 'r' or 'red', all levels will be plotted in this - color. + The sequence is cycled for the levels in ascending order. If the + sequence is shorter than the number of levels, it's repeated. - If a tuple of matplotlib color args (string, float, rgb, etc), - different levels will be plotted in different colors in the order - specified. + As a shortcut, single color strings may be used in place of + one-element lists, i.e. ``'red'`` instead of ``['red']`` to color + all levels with the same color. This shortcut does only work for + color strings, not for other ways of specifying colors. - *alpha*: float - The alpha blending value + By default (value *None*), the colormap specified by *cmap* + will be used. - *cmap*: [ *None* | Colormap ] - A cm :class:`~matplotlib.colors.Colormap` instance or - *None*. If *cmap* is *None* and *colors* is *None*, a - default Colormap is used. + alpha : float, optional + The alpha blending value, between 0 (transparent) and 1 (opaque). - *norm*: [ *None* | Normalize ] - A :class:`matplotlib.colors.Normalize` instance for - scaling data values to colors. If *norm* is *None* and - *colors* is *None*, the default linear scaling is used. + cmap : str or `.Colormap`, optional + A `.Colormap` instance or registered colormap name. The colormap + maps the level values to colors. + Defaults to :rc:`image.cmap`. - *vmin*, *vmax*: [ *None* | scalar ] - If not *None*, either or both of these values will be - supplied to the :class:`matplotlib.colors.Normalize` - instance, overriding the default color scaling based on - *levels*. + If given, *colors* take precedence over *cmap*. - *levels*: [level0, level1, ..., leveln] - A list of floating point numbers indicating the level - curves to draw, in increasing order; e.g., to draw just - the zero contour pass ``levels=[0]`` + norm : `~matplotlib.colors.Normalize`, optional + If a colormap is used, the `.Normalize` instance scales the level + values to the canonical colormap range [0, 1] for mapping to + colors. If not given, the default linear scaling is used. - *origin*: [ *None* | 'upper' | 'lower' | 'image' ] - If *None*, the first value of *Z* will correspond to the - lower left corner, location (0,0). If 'image', the rc - value for ``image.origin`` will be used. + vmin, vmax : float, optional + If not *None*, either or both of these values will be supplied to + the `.Normalize` instance, overriding the default color scaling + based on *levels*. - This keyword is not active if *X* and *Y* are specified in - the call to contour. + origin : {*None*, 'upper', 'lower', 'image'}, optional + Determines the orientation and exact position of *Z* by specifying + the position of ``Z[0, 0]``. This is only relevant, if *X*, *Y* + are not given. - *extent*: [ *None* | (x0,x1,y0,y1) ] + - *None*: ``Z[0, 0]`` is at X=0, Y=0 in the lower left corner. + - 'lower': ``Z[0, 0]`` is at X=0.5, Y=0.5 in the lower left corner. + - 'upper': ``Z[0, 0]`` is at X=N+0.5, Y=0.5 in the upper left + corner. + - 'image': Use the value from :rc:`image.origin`. Note: The value + *None* in the rcParam is currently handled as 'lower'. + extent : (x0, x1, y0, y1), optional If *origin* is not *None*, then *extent* is interpreted as in :func:`matplotlib.pyplot.imshow`: it gives the outer pixel boundaries. In this case, the position of Z[0,0] @@ -1711,13 +1753,12 @@ def _initialize_x_y(self, z): This keyword is not active if *X* and *Y* are specified in the call to contour. - *locator*: [ *None* | ticker.Locator subclass ] - If *locator* is *None*, the default - :class:`~matplotlib.ticker.MaxNLocator` is used. The - locator is used to determine the contour levels if they - are not given explicitly via the *V* argument. + locator : ticker.Locator subclass, optional + The locator is used to determine the contour levels if they + are not given explicitly via *levels*. + Defaults to `~.ticker.MaxNLocator`. - *extend*: [ 'neither' | 'both' | 'min' | 'max' ] + extend : {'neither', 'both', 'min', 'max'}, optional Unless this is 'neither', contour levels are automatically added to one or both ends of the range so that all data are included. These added ranges are then mapped to the @@ -1726,16 +1767,16 @@ def _initialize_x_y(self, z): :meth:`matplotlib.colors.Colormap.set_under` and :meth:`matplotlib.colors.Colormap.set_over` methods. - *xunits*, *yunits*: [ *None* | registered units ] + xunits, yunits : registered units, optional Override axis units by specifying an instance of a :class:`matplotlib.units.ConversionInterface`. - *antialiased*: bool - enable antialiasing, overriding the defaults. For + antialiased : bool, optinal + Enable antialiasing, overriding the defaults. For filled contours, the default is *True*. For line contours, - it is taken from rcParams['lines.antialiased']. + it is taken from :rc:`lines.antialiased`. - *nchunk*: [ 0 | integer ] + Nchunk : int >= 0, optional If 0, no subdivision of the domain. Specify a positive integer to divide the domain into subdomains of *nchunk* by *nchunk* quads. Chunking reduces the maximum length of polygons generated by the @@ -1744,43 +1785,52 @@ def _initialize_x_y(self, z): however introduce rendering artifacts at chunk boundaries depending on the backend, the *antialiased* flag and value of *alpha*. - contour-only keyword arguments: + linewidths : float or sequence of float, optional + *Only applies to* `.contour`. - *linewidths*: [ *None* | number | tuple of numbers ] - If *linewidths* is *None*, the default width in - ``lines.linewidth`` in ``matplotlibrc`` is used. + The line width of the contour lines. If a number, all levels will be plotted with this linewidth. - If a tuple, different levels will be plotted with different - linewidths in the order specified. + If a sequence, the levels in ascending order will be plotted with + the linewidths in the order specified. - *linestyles*: [ *None* | 'solid' | 'dashed' | 'dashdot' | 'dotted' ] - If *linestyles* is *None*, the default is 'solid' unless - the lines are monochrome. In that case, negative - contours will take their linestyle from the ``matplotlibrc`` - ``contour.negative_linestyle`` setting. + Defaults to :rc:`lines.linewidth`. + + linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, optional + *Only applies to* `.contour`. + + If *linestyles* is *None*, the default is 'solid' unless the lines + are monochrome. In that case, negative contours will take their + linestyle from :rc:`contour.negative_linestyle` setting. *linestyles* can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary. - contourf-only keyword arguments: + hatches : List[str], optional + *Only applies to* `.contourf`. - *hatches*: A list of cross hatch patterns to use on the filled areas. If None, no hatching will be added to the contour. Hatching is supported in the PostScript, PDF, SVG and Agg backends only. - Note: contourf fills intervals that are closed at the top; that - is, for boundaries *z1* and *z2*, the filled region is:: + Notes + ----- + 1. :func:`~matplotlib.pyplot.contourf` differs from the MATLAB + version in that it does not draw the polygon edges. + To draw edges, add line contours with + calls to :func:`~matplotlib.pyplot.contour`. + + 2. contourf fills intervals that are closed at the top; that + is, for boundaries *z1* and *z2*, the filled region is:: - z1 < z <= z2 + z1 < Z <= z2 - There is one exception: if the lowest boundary coincides with - the minimum value of the *z* array, then that minimum value - will be included in the lowest interval. + There is one exception: if the lowest boundary coincides with + the minimum value of the *Z* array, then that minimum value + will be included in the lowest interval. """ diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 55feb32a1139..d80b16d55ab3 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -7,7 +7,7 @@ control the default spacing of the subplots :class:`Figure` - top level container for all plot elements + Top level container for all plot elements. """ @@ -62,7 +62,8 @@ def _stale_figure_callback(self, val): class AxesStack(Stack): """ - Specialization of the Stack to handle all tracking of Axes in a Figure. + Specialization of the `.Stack` to handle all tracking of + `~matplotlib.axes.Axes` in a `.Figure`. This stack stores ``key, (ind, axes)`` pairs, where: * **key** should be a hash of the args and kwargs @@ -154,7 +155,6 @@ def current_key_axes(self): Return a tuple of ``(key, axes)`` for the active axes. If no axes exists on the stack, then returns ``(None, None)``. - """ if not len(self._elements): return self._default, self._default @@ -171,48 +171,44 @@ def __contains__(self, a): class SubplotParams(object): """ - A class to hold the parameters for a subplot + A class to hold the parameters for a subplot. """ def __init__(self, left=None, bottom=None, right=None, top=None, wspace=None, hspace=None): """ - All dimensions are fraction of the figure width or height. - All values default to their rc params - - The following attributes are available + All dimensions are fractions of the figure width or height. + Defaults are given by :rc:`figure.subplot.[name]`. - left : 0.125 - The left side of the subplots of the figure + Parameters + ---------- + left : float + The left side of the subplots of the figure. - right : 0.9 - The right side of the subplots of the figure + right : float + The right side of the subplots of the figure. - bottom : 0.1 - The bottom of the subplots of the figure + bottom : float + The bottom of the subplots of the figure. - top : 0.9 - The top of the subplots of the figure + top : float + The top of the subplots of the figure. - wspace : 0.2 + wspace : float The amount of width reserved for space between subplots, - expressed as a fraction of the average axis width + expressed as a fraction of the average axis width. - hspace : 0.2 + hspace : float The amount of height reserved for space between subplots, - expressed as a fraction of the average axis height + expressed as a fraction of the average axis height. """ - self.validate = True self.update(left, bottom, right, top, wspace, hspace) def update(self, left=None, bottom=None, right=None, top=None, wspace=None, hspace=None): """ - Update the current values. If any kwarg is None, default to - the current value, if set, otherwise to rc - + Update the dimensions of the passed parameters. *None* means unchanged. """ - thisleft = getattr(self, 'left', None) thisright = getattr(self, 'right', None) thistop = getattr(self, 'top', None) @@ -255,8 +251,9 @@ def _update_this(self, s, val): class Figure(Artist): - """ + The top level container for all the plot elements. + The Figure instance supports callbacks through a *callbacks* attribute which is a `.CallbackRegistry` instance. The events you can connect to are 'dpi_changed', and the callback will be called with ``func(fig)`` where @@ -284,12 +281,12 @@ def __repr__(self): ) def __init__(self, - figsize=None, # defaults to rc figure.figsize - dpi=None, # defaults to rc figure.dpi - facecolor=None, # defaults to rc figure.facecolor - edgecolor=None, # defaults to rc figure.edgecolor - linewidth=0.0, # the default linewidth of the frame - frameon=None, # whether or not to draw the figure frame + figsize=None, + dpi=None, + facecolor=None, + edgecolor=None, + linewidth=0.0, + frameon=None, subplotpars=None, # default to rc tight_layout=None, # default to rc figure.autolayout constrained_layout=None, # default to rc @@ -298,34 +295,35 @@ def __init__(self, """ Parameters ---------- - figsize : 2-tuple of floats - ``(width, height)`` tuple in inches + figsize : 2-tuple of floats, default: :rc:`figure.figsize` + Figure dimension ``(width, height)`` in inches. - dpi : float - Dots per inch + dpi : float, default: :rc:`figure.dpi` + Dots per inch. - facecolor - The figure patch facecolor; defaults to rc ``figure.facecolor`` + facecolor : default: :rc:`figure.facecolor` + The figure patch facecolor. - edgecolor - The figure patch edge color; defaults to rc ``figure.edgecolor`` + edgecolor : default: :rc:`figure.edgecolor` + The figure patch edge color. linewidth : float - The figure patch edge linewidth; the default linewidth of the frame + The linewidth of the frame (i.e. the edge linewidth of the figure + patch). - frameon : bool - If ``False``, suppress drawing the figure frame + frameon : bool, default: :rc:`figure.frameon` + If ``False``, suppress drawing the figure frame. subplotpars : :class:`SubplotParams` - Subplot parameters, defaults to rc + Subplot parameters. If not given, the default subplot + parameters :rc:`figure.subplot.*` are used. - tight_layout : bool - If ``False`` use *subplotpars*; if ``True`` adjust subplot + tight_layout : bool or dict, default: :rc:`figure.autolayout` + If ``False`` use *subplotpars*. If ``True`` adjust subplot parameters using `.tight_layout` with default padding. - When providing a dict containing the keys - ``pad``, ``w_pad``, ``h_pad``, and ``rect``, the default - `.tight_layout` paddings will be overridden. - Defaults to rc ``figure.autolayout``. + When providing a dict containing the keys ``pad``, ``w_pad``, + ``h_pad``, and ``rect``, the default `.tight_layout` paddings + will be overridden. constrained_layout : bool If ``True`` use constrained layout to adjust positioning of plot @@ -334,7 +332,7 @@ def __init__(self, :doc:`/tutorials/intermediate/constrainedlayout_guide` for examples. (Note: does not work with :meth:`.subplot` or :meth:`.subplot2grid`.) - Defaults to rc ``figure.constrained_layout.use``. + Defaults to :rc:`figure.constrained_layout.use`. """ Artist.__init__(self) # remove the non-figure artist _axes property @@ -404,7 +402,7 @@ def __init__(self, self._align_ylabel_grp = cbook.Grouper() @property - @cbook.deprecated("2.1", alternative="Figure.patch") + @cbook.deprecated("2.1", alternative="`.Figure.patch`") def figurePatch(self): return self.patch @@ -462,7 +460,12 @@ def show(self, warn=True): def _get_axes(self): return self._axstack.as_list() - axes = property(fget=_get_axes, doc="Read-only: list of axes in Figure") + axes = property(fget=_get_axes, + doc="List of axes in the Figure. You can access the " + "axes in the Figure through this list. " + "Do not modify the list itself. Instead, use " + "`~Figure.add_axes`, `~.Figure.subplot` or " + "`~.Figure.delaxes` to add or remove an axes.") def _get_dpi(self): return self._dpi @@ -482,12 +485,10 @@ def _set_dpi(self, dpi, forward=True): self.set_size_inches(w, h, forward=forward) self.callbacks.process('dpi_changed', self) - dpi = property(_get_dpi, _set_dpi) + dpi = property(_get_dpi, _set_dpi, doc="The resolution in dots per inch.") def get_tight_layout(self): - """ - Return whether and how `.tight_layout` is called when drawing. - """ + """Return whether `.tight_layout` is called when drawing.""" return self._tight def set_tight_layout(self, tight): @@ -517,7 +518,7 @@ def get_constrained_layout(self): """ Return a boolean: True means constrained layout is being used. - See :doc:`/tutorials/intermediate/constrainedlayout_guide` + See :doc:`/tutorials/intermediate/constrainedlayout_guide`. """ return self._constrained @@ -533,7 +534,7 @@ def set_constrained_layout(self, constrained): ACCEPTS: [True | False | dict | None ] - See :doc:`/tutorials/intermediate/constrainedlayout_guide` + See :doc:`/tutorials/intermediate/constrainedlayout_guide`. """ self._constrained_layout_pads = dict() self._constrained_layout_pads['w_pad'] = None @@ -555,7 +556,7 @@ def set_constrained_layout_pads(self, **kwargs): Set padding for ``constrained_layout``. Note the kwargs can be passed as a dictionary ``fig.set_constrained_layout(**paddict)``. - See :doc:`/tutorials/intermediate/constrainedlayout_guide` + See :doc:`/tutorials/intermediate/constrainedlayout_guide`. Parameters ---------- @@ -593,7 +594,7 @@ def get_constrained_layout_pads(self, relative=False): Returns a list of `w_pad, h_pad` in inches and `wspace` and `hspace` as fractions of the subplot. - See :doc:`/tutorials/intermediate/constrainedlayout_guide` + See :doc:`/tutorials/intermediate/constrainedlayout_guide`. Parameters ---------- @@ -626,17 +627,17 @@ def autofmt_xdate(self, bottom=0.2, rotation=30, ha='right', which=None): Parameters ---------- bottom : scalar - The bottom of the subplots for :meth:`subplots_adjust` + The bottom of the subplots for :meth:`subplots_adjust`. rotation : angle in degrees - The rotation of the xtick labels + The rotation of the xtick labels. ha : string - The horizontal alignment of the xticklabels + The horizontal alignment of the xticklabels. which : {None, 'major', 'minor', 'both'} - Selects which ticklabels to rotate (default is None which works - same as major) + Selects which ticklabels to rotate. Default is None which works + the same as major. """ allsubplots = all(hasattr(ax, 'is_last_row') for ax in self.axes) if len(self.axes) == 1: @@ -675,7 +676,9 @@ def contains(self, mouseevent): """ Test whether the mouse event occurred on the figure. - Returns True, {}. + Returns + ------- + bool, {} """ if callable(self._contains): return self._contains(self, mouseevent) @@ -684,7 +687,7 @@ def contains(self, mouseevent): def get_window_extent(self, *args, **kwargs): """ - Return figure bounding box in display space; arguments are ignored. + Return the figure bounding box in display space. Arguments are ignored. """ return self.bbox @@ -788,71 +791,74 @@ def hold(self, b=None): else: self._hold = b - def figimage(self, X, - xo=0, - yo=0, - alpha=None, - norm=None, - cmap=None, - vmin=None, - vmax=None, - origin=None, - resize=False, - **kwargs): + def figimage(self, X, xo=0, yo=0, alpha=None, norm=None, cmap=None, + vmin=None, vmax=None, origin=None, resize=False, **kwargs): """ - Adds a non-resampled image to the figure. + Add a non-resampled image to the figure. - call signatures:: + The image is attached to the lower or upper left corner depending on + *origin*. - figimage(X, **kwargs) + Parameters + ---------- + X + The image data. This is an array of one of the following shapes: - adds a non-resampled array *X* to the figure. + - MxN: luminance (grayscale) values + - MxNx3: RGB values + - MxNx4: RGBA values - :: + xo, yo : int + The *x*/*y* image offset in pixels. + + alpha : None or float + The alpha blending value. + + norm : :class:`matplotlib.colors.Normalize` + A :class:`.Normalize` instance to map the luminance to the + interval [0, 1]. + + cmap : str or :class:`matplotlib.colors.Colormap` + The colormap to use. Default: :rc:`image.cmap`. + + vmin, vmax : scalar + If *norm* is not given, these values set the data limits for the + colormap. + + origin : {'upper', 'lower'} + Indicates where the [0, 0] index of the array is in the upper left + or lower left corner of the axes. Defaults to :rc:`image.origin`. - figimage(X, xo, yo) - - with pixel offsets *xo*, *yo*, - - *X* must be a float array: - - * If *X* is MxN, assume luminance (grayscale) - * If *X* is MxNx3, assume RGB - * If *X* is MxNx4, assume RGBA - - Optional keyword arguments: - - ========= ========================================================= - Keyword Description - ========= ========================================================= - resize a boolean, True or False. If "True", then re-size the - Figure to match the given image size. - xo or yo An integer, the *x* and *y* image offset in pixels - cmap a :class:`matplotlib.colors.Colormap` instance, e.g., - cm.jet. If *None*, default to the rc ``image.cmap`` - value - norm a :class:`matplotlib.colors.Normalize` instance. The - default is normalization(). This scales luminance -> 0-1 - vmin|vmax are used to scale a luminance image to 0-1. If either - is *None*, the min and max of the luminance values will - be used. Note if you pass a norm instance, the settings - for *vmin* and *vmax* will be ignored. - alpha the alpha blending value, default is *None* - origin [ 'upper' | 'lower' ] Indicates where the [0,0] index of - the array is in the upper left or lower left corner of - the axes. Defaults to the rc image.origin value - ========= ========================================================= + resize : bool + If *True*, resize the figure to match the given image size. + Returns + ------- + :class:`matplotlib.image.FigureImage` + + Other Parameters + ---------------- + **kwargs + Additional kwargs are `.Artist` kwargs passed on to `.FigureImage`. + + Notes + ----- figimage complements the axes image (:meth:`~matplotlib.axes.Axes.imshow`) which will be resampled to fit the current axes. If you want a resampled image to fill the entire figure, you can define an :class:`~matplotlib.axes.Axes` with extent [0,0,1,1]. - An :class:`matplotlib.image.FigureImage` instance is returned. - Additional kwargs are Artist kwargs passed on to - :class:`~matplotlib.image.FigureImage` + Examples:: + + f = plt.figure() + nx = int(f.get_figwidth() * f.dpi) + ny = int(f.get_figheight() * f.dpi) + data = np.random.random((ny, nx)) + f.figimage(data) + plt.show() + """ if not self._hold: @@ -917,13 +923,12 @@ def set_size_inches(self, w, h=None, forward=True): def get_size_inches(self): """ - Returns the current size of the figure in inches (1in == 2.54cm) - as an numpy array. + Returns the current size of the figure in inches. Returns ------- size : ndarray - The size of the figure in inches + The size (width, height) of the figure in inches. See Also -------- @@ -940,24 +945,24 @@ def get_facecolor(self): return self.patch.get_facecolor() def get_figwidth(self): - """Return the figwidth as a float.""" + """Return the figure width as a float.""" return self.bbox_inches.width def get_figheight(self): - """Return the figheight as a float.""" + """Return the figure height as a float.""" return self.bbox_inches.height def get_dpi(self): - """Return the dpi as a float.""" + """Return the resolution in dots per inch as a float.""" return self.dpi def get_frameon(self): - """Get the boolean indicating frameon.""" + """Return whether the figure frame will be drawn.""" return self.frameon def set_edgecolor(self, color): """ - Set the edge color of the Figure rectangle + Set the edge color of the Figure rectangle. ACCEPTS: any matplotlib color - see help(colors) """ @@ -965,7 +970,7 @@ def set_edgecolor(self, color): def set_facecolor(self, color): """ - Set the face color of the Figure rectangle + Set the face color of the Figure rectangle. ACCEPTS: any matplotlib color - see help(colors) """ @@ -973,7 +978,7 @@ def set_facecolor(self, color): def set_dpi(self, val): """ - Set the dots-per-inch of the figure + Set the dots-per-inch of the figure. ACCEPTS: float """ @@ -982,7 +987,7 @@ def set_dpi(self, val): def set_figwidth(self, val, forward=True): """ - Set the width of the figure in inches + Set the width of the figure in inches. ACCEPTS: float """ @@ -990,7 +995,7 @@ def set_figwidth(self, val, forward=True): def set_figheight(self, val, forward=True): """ - Set the height of the figure in inches + Set the height of the figure in inches. ACCEPTS: float """ @@ -1007,7 +1012,8 @@ def set_frameon(self, b): def delaxes(self, ax): """ - Remove the `.Axes` *ax* from the figure and update the current axes. + Remove the `~matplotlib.axes.Axes` *ax* from the figure and update the + current axes. """ self._axstack.remove(ax) for func in self._axobservers: @@ -1046,18 +1052,20 @@ def fixlist(args): def add_axes(self, *args, **kwargs): """ - Add an axes at position *rect* [*left*, *bottom*, *width*, - *height*] where all quantities are in fractions of figure - width and height. + Add an axes to the figure. + + Call signature:: + + add_axes(rect, projection=None, polar=False, **kwargs) Parameters ---------- rect : sequence of float - A 4-length sequence of [left, bottom, width, height] quantities. + The dimensions [left, bottom, width, height] of the new axes. All + quantities are in fractions of figure width and height. - projection : - ['aitoff' | 'hammer' | 'lambert' | 'mollweide' | \ -'polar' | 'rectilinear'], optional + projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \ +'polar', rectilinear'}, optional The projection type of the axes. polar : boolean, optional @@ -1074,9 +1082,9 @@ def add_axes(self, *args, **kwargs): Examples -------- - A simple example:: + Some simple examples:: - rect = l,b,w,h + rect = l, b, w, h fig.add_axes(rect) fig.add_axes(rect, frameon=False, facecolor='g') fig.add_axes(rect, polar=True) @@ -1151,6 +1159,11 @@ def add_subplot(self, *args, **kwargs): """ Add a subplot. + Call signatures:: + + add_subplot(nrows, ncols, index, **kwargs) + add_subplot(pos, **kwargs) + Parameters ---------- *args @@ -1159,8 +1172,8 @@ def add_subplot(self, *args, **kwargs): integers are R, C, and P in order, the subplot will take the Pth position on a grid with R rows and C columns. - projection : ['aitoff' | 'hammer' | 'lambert' | \ -'mollweide' | 'polar' | 'rectilinear'], optional + projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \ +'polar', rectilinear'}, optional The projection type of the axes. polar : boolean, optional @@ -1497,6 +1510,15 @@ def draw_artist(self, a): a.draw(self._cachedRenderer) def get_axes(self): + """ + Return a list of axes in the Figure. You can access and modify the + axes in the Figure through this list. + + Do not modify the list itself. Instead, use `~Figure.add_axes`, + `~.Figure.subplot` or `~.Figure.delaxes` to add or remove an axes. + + Note: This is equivalent to the property `~.Figure.axes`. + """ return self.axes @docstring.dedent_interpd @@ -1776,7 +1798,7 @@ def _set_artist_props(self, a): @docstring.dedent_interpd def gca(self, **kwargs): """ - Get the current axes, creating one if necessary + Get the current axes, creating one if necessary. The following kwargs are supported for ensuring the returned axes adheres to the given projection etc., and for axes creation if @@ -2212,9 +2234,7 @@ def get_tightbbox(self, renderer): return bbox_inches def init_layoutbox(self): - """ - initilaize the layoutbox for use in constrained_layout. - """ + """Initialize the layoutbox for use in constrained_layout.""" if self._layoutbox is None: self._layoutbox = layoutbox.LayoutBox(parent=None, name='figlb', @@ -2225,7 +2245,7 @@ def execute_constrained_layout(self, renderer=None): """ Use ``layoutbox`` to determine pos positions within axes. - See also set_constrained_layout_pads + See also `.set_constrained_layout_pads`. """ from matplotlib._constrained_layout import (do_constrained_layout) @@ -2302,9 +2322,10 @@ def align_xlabels(self, axs=None): Parameters ---------- - axs : list of `~matplotlib.axes.Axes` (None) - Optional list of (or ndarray) `~matplotlib.axes.Axes` to align - the xlabels. Default is to align all axes on the figure. + axs : list of `~matplotlib.axes.Axes` + Optional list of (or ndarray) `~matplotlib.axes.Axes` + to align the xlabels. + Default is to align all axes on the figure. See Also -------- @@ -2370,9 +2391,10 @@ def align_ylabels(self, axs=None): Parameters ---------- - axs : list of `~matplotlib.axes.Axes` (None) - Optional list (or ndarray) of `~matplotlib.axes.Axes` to align - the ylabels. Default is to align all axes on the figure. + axs : list of `~matplotlib.axes.Axes` + Optional list (or ndarray) of `~matplotlib.axes.Axes` + to align the ylabels. + Default is to align all axes on the figure. See Also -------- @@ -2433,9 +2455,10 @@ def align_labels(self, axs=None): Parameters ---------- - axs : list of `~matplotlib.axes.Axes` (None) - Optional list (or ndarray) of `~matplotlib.axes.Axes` to - align the labels. Default is to align all axes on the figure. + axs : list of `~matplotlib.axes.Axes` + Optional list (or ndarray) of `~matplotlib.axes.Axes` + to align the labels. + Default is to align all axes on the figure. See Also -------- diff --git a/lib/matplotlib/legend.py b/lib/matplotlib/legend.py index c2affe93ef01..4e48a9509151 100644 --- a/lib/matplotlib/legend.py +++ b/lib/matplotlib/legend.py @@ -350,7 +350,7 @@ def __init__(self, parent, handles, labels, Parameters ---------- - parent : `.Axes` or `.Figure` + parent : `~matplotlib.axes.Axes` or `.Figure` The artist that contains the legend. handles : sequence of `.Artist` diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 31deddae91dd..fb5928dc65ff 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -863,9 +863,9 @@ def axes(arg=None, **kwargs): - 4-tuple of floats *rect* = ``[left, bottom, width, height]``. A new axes is added with dimensions *rect* in normalized (0, 1) units using `~.Figure.add_axes` on the current figure. - - `.Axes`: This is equivalent to `.pyplot.sca`. It sets the current - axes to *arg*. Note: This implicitly changes the current figure to - the parent of *arg*. + - `~matplotlib.axes.Axes`: This is equivalent to `.pyplot.sca`. + It sets the current axes to *arg*. Note: This implicitly + changes the current figure to the parent of *arg*. .. note:: The use of an Axes as an argument is deprecated and will be removed in v3.0. Please use `.pyplot.sca` instead. @@ -979,16 +979,16 @@ def subplot(*args, **kwargs): subplot(nrows, ncols, index, **kwargs) - In the current figure, create and return an `.Axes`, at position *index* - of a (virtual) grid of *nrows* by *ncols* axes. Indexes go from 1 to - ``nrows * ncols``, incrementing in row-major order. + In the current figure, create and return an `~matplotlib.axes.Axes`, + at position *index* of a (virtual) grid of *nrows* by *ncols* axes. + Indexes go from 1 to ``nrows * ncols``, incrementing in row-major order. If *nrows*, *ncols* and *index* are all less than 10, they can also be given as a single, concatenated, three-digit number. For example, ``subplot(2, 3, 3)`` and ``subplot(233)`` both create an - `.Axes` at the top right corner of the current figure, occupying half of - the figure height and a third of the figure width. + `matplotlib.axes.Axes` at the top right corner of the current figure, + occupying half of the figure height and a third of the figure width. .. note:: diff --git a/lib/mpl_toolkits/axes_grid1/colorbar.py b/lib/mpl_toolkits/axes_grid1/colorbar.py index 9475912e1e23..34bdf3618a75 100644 --- a/lib/mpl_toolkits/axes_grid1/colorbar.py +++ b/lib/mpl_toolkits/axes_grid1/colorbar.py @@ -1,4 +1,4 @@ -''' +""" Colorbar toolkit with two classes and a function: :class:`ColorbarBase` @@ -16,8 +16,8 @@ The :meth:`~matplotlib.figure.Figure.colorbar` method uses :func:`make_axes` and :class:`Colorbar`; the :func:`~matplotlib.pyplot.colorbar` function is a thin wrapper over :meth:`~matplotlib.figure.Figure.colorbar`. +""" -''' from __future__ import (absolute_import, division, print_function, unicode_literals) @@ -132,9 +132,9 @@ Additional keyword arguments are of two kinds: axes properties: -%s + %s colorbar properties: -%s + %s If *mappable* is a :class:`~matplotlib.contours.ContourSet`, its *extend* kwarg is included automatically. @@ -175,7 +175,7 @@ unconventional value is to prevent underflow when log scale is used. ''' % (make_axes_kw_doc, colormap_kw_doc) -docstring.interpd.update(colorbar_doc=colorbar_doc) +#docstring.interpd.update(colorbar_doc=colorbar_doc) class CbarAxesLocator(object): @@ -764,7 +764,9 @@ def update_bruteforce(self, mappable): def make_axes(parent, **kw): ''' Resize and reposition a parent axes, and return a child - axes suitable for a colorbar:: + axes suitable for a colorbar + + :: cax, kw = make_axes(parent, **kw) @@ -806,13 +808,14 @@ def make_axes(parent, **kw): cax.set_aspect(aspect, anchor=anchor, adjustable='box') return cax, kw - +@docstring.Substitution(colorbar_doc) def colorbar(mappable, cax=None, ax=None, **kw): """ Create a colorbar for a ScalarMappable instance. Documentation for the pylab thin wrapper: - %(colorbar_doc)s + + %s """ import matplotlib.pyplot as plt if ax is None: diff --git a/lib/mpl_toolkits/axes_grid1/inset_locator.py b/lib/mpl_toolkits/axes_grid1/inset_locator.py index e2d403e8aecf..9aeedcb0888f 100644 --- a/lib/mpl_toolkits/axes_grid1/inset_locator.py +++ b/lib/mpl_toolkits/axes_grid1/inset_locator.py @@ -4,6 +4,7 @@ from __future__ import (absolute_import, division, print_function, unicode_literals) +import warnings from matplotlib import docstring import six from matplotlib.offsetbox import AnchoredOffsetbox @@ -105,16 +106,16 @@ def get_extent(self, renderer): dpi = renderer.points_to_pixels(72.) r, a = self.x_size.get_size(renderer) - width = w*r + a*dpi + width = w * r + a * dpi r, a = self.y_size.get_size(renderer) - height = h*r + a*dpi + height = h * r + a * dpi xd, yd = 0, 0 fontsize = renderer.points_to_pixels(self.prop.get_size_in_points()) pad = self.pad * fontsize - return width+2*pad, height+2*pad, xd+pad, yd+pad + return width + 2 * pad, height + 2 * pad, xd + pad, yd + pad class AnchoredZoomLocator(AnchoredLocatorBase): @@ -122,7 +123,6 @@ def __init__(self, parent_axes, zoom, loc, borderpad=0.5, bbox_to_anchor=None, bbox_transform=None): - self.parent_axes = parent_axes self.zoom = zoom @@ -141,7 +141,7 @@ def get_extent(self, renderer): fontsize = renderer.points_to_pixels(self.prop.get_size_in_points()) pad = self.pad * fontsize - return abs(w*self.zoom)+2*pad, abs(h*self.zoom)+2*pad, pad, pad + return abs(w * self.zoom) + 2 * pad, abs(h * self.zoom) + 2 * pad, pad, pad class BboxPatch(Patch): @@ -184,6 +184,7 @@ def get_path(self): Path.CLOSEPOLY] return Path(verts, codes) + get_path.__doc__ = Patch.get_path.__doc__ @@ -318,6 +319,7 @@ def __init__(self, bbox1, bbox2, loc1, loc2=None, **kwargs): def get_path(self): return self.connect_bbox(self.bbox1, self.bbox2, self.loc1, self.loc2) + get_path.__doc__ = Patch.get_path.__doc__ @@ -373,6 +375,7 @@ def get_path(self): list(path2.vertices) + [path1.vertices[0]]) return Path(path_merged) + get_path.__doc__ = BboxConnector.get_path.__doc__ @@ -391,8 +394,16 @@ def inset_axes(parent_axes, width, height, loc=1, """ Create an inset axes with a given width and height. - Both sizes used can be specified either in inches or percentage of the - parent axes. + Both sizes used can be specified either in inches or percentage. + For example,:: + + inset_axes(parent_axes, width='40%%', height='30%%', loc=3) + + creates in inset axes in the lower left corner of *parent_axes* which spans + over 30%% in height and 40%% in width of the *parent_axes*. Since the usage + of `.inset_axes` may become slightly tricky when exceeding such standard + cases, it is recommended to read + :ref:`the examples `. Parameters ---------- @@ -400,7 +411,12 @@ def inset_axes(parent_axes, width, height, loc=1, Axes to place the inset axes. width, height : float or str - Size of the inset axes to create. + Size of the inset axes to create. If a float is provided, it is + the size in inches, e.g. *width=1.3*. If a string is provided, it is + the size in relative units, e.g. *width='40%%'*. By default, i.e. if + neither *bbox_to_anchor* nor *bbox_transform* are specified, those + are relative to the parent_axes. Otherwise they are to be understood + relative to the bounding box provided via *bbox_to_anchor*. loc : int or string, optional, default to 1 Location to place the inset axes. The valid locations are:: @@ -417,14 +433,29 @@ def inset_axes(parent_axes, width, height, loc=1, 'center' : 10 bbox_to_anchor : tuple or `matplotlib.transforms.BboxBase`, optional - Bbox that the inset axes will be anchored. Can be a tuple of - [left, bottom, width, height], or a tuple of [left, bottom]. + Bbox that the inset axes will be anchored to. If None, + *parent_axes.bbox* is used. If a tuple, can be either + [left, bottom, width, height], or [left, bottom]. + If the kwargs *width* and/or *height* are specified in relative units, + the 2-tuple [left, bottom] cannot be used. Note that + the units of the bounding box are determined through the transform + in use. When using *bbox_to_anchor* it almost always makes sense to + also specify a *bbox_transform*. This might often be the axes transform + *parent_axes.transAxes*. bbox_transform : `matplotlib.transforms.Transform`, optional - Transformation for the bbox. if None, `parent_axes.transAxes` is used. + Transformation for the bbox that contains the inset axes. + If None, a `.transforms.IdentityTransform` is used (i.e. pixel + coordinates). This is useful when not providing any argument to + *bbox_to_anchor*. When using *bbox_to_anchor* it almost always makes + sense to also specify a *bbox_transform*. This might often be the + axes transform *parent_axes.transAxes*. Inversely, when specifying + the axes- or figure-transform here, be aware that not specifying + *bbox_to_anchor* will use *parent_axes.bbox*, the units of which are + in display (pixel) coordinates. axes_class : `matplotlib.axes.Axes` type, optional - If specified, the inset axes created with be created with this class's + If specified, the inset axes created will be created with this class's constructor. axes_kwargs : dict, optional @@ -434,6 +465,8 @@ def inset_axes(parent_axes, width, height, loc=1, borderpad : float, optional Padding between inset axes and the bbox_to_anchor. Defaults to 0.5. + The units are axes font size, i.e. for a default font size of 10 points + *borderpad = 0.5* is equivalent to a padding of 5 points. Returns ------- @@ -450,9 +483,24 @@ def inset_axes(parent_axes, width, height, loc=1, inset_axes = axes_class(parent_axes.figure, parent_axes.get_position(), **axes_kwargs) + if bbox_transform in [parent_axes.transAxes, + parent_axes.figure.transFigure]: + if bbox_to_anchor is None: + warnings.warn("Using the axes or figure transform requires a " + "bounding box in the respective coordinates. " + "Using bbox_to_anchor=(0,0,1,1) now.") + bbox_to_anchor = (0, 0, 1, 1) + if bbox_to_anchor is None: bbox_to_anchor = parent_axes.bbox + if isinstance(bbox_to_anchor, tuple) and \ + (isinstance(width, str) or isinstance(height, str)): + if len(bbox_to_anchor) != 4: + raise ValueError("Using relative units for width or height " + "requires to provide a 4-tuple or a " + "`BBox` instance to `bbox_to_anchor.") + axes_locator = AnchoredSizeLocator(bbox_to_anchor, width, height, loc=loc, @@ -473,7 +521,8 @@ def zoomed_inset_axes(parent_axes, zoom, loc=1, axes_kwargs=None, borderpad=0.5): """ - Create an anchored inset axes by scaling a parent axes. + Create an anchored inset axes by scaling a parent axes. For usage, also see + :ref:`the examples `. Parameters ---------- @@ -500,14 +549,29 @@ def zoomed_inset_axes(parent_axes, zoom, loc=1, 'center' : 10 bbox_to_anchor : tuple or `matplotlib.transforms.BboxBase`, optional - Bbox that the inset axes will be anchored. Can be a tuple of - [left, bottom, width, height], or a tuple of [left, bottom]. + Bbox that the inset axes will be anchored to. If None, + *parent_axes.bbox* is used. If a tuple, can be either + [left, bottom, width, height], or [left, bottom]. + If the kwargs *width* and/or *height* are specified in relative units, + the 2-tuple [left, bottom] cannot be used. Note that + the units of the bounding box are determined through the transform + in use. When using *bbox_to_anchor* it almost always makes sense to + also specify a *bbox_transform*. This might often be the axes transform + *parent_axes.transAxes*. bbox_transform : `matplotlib.transforms.Transform`, optional - Transformation for the bbox. if None, `parent_axes.transAxes` is used. + Transformation for the bbox that contains the inset axes. + If None, a `.transforms.IdentityTransform` is used (i.e. pixel + coordinates). This is useful when not providing any argument to + *bbox_to_anchor*. When using *bbox_to_anchor* it almost always makes + sense to also specify a *bbox_transform*. This might often be the + axes transform *parent_axes.transAxes*. Inversely, when specifying + the axes- or figure-transform here, be aware that not specifying + *bbox_to_anchor* will use *parent_axes.bbox*, the units of which are + in display (pixel) coordinates. axes_class : `matplotlib.axes.Axes` type, optional - If specified, the inset axes created with be created with this class's + If specified, the inset axes created will be created with this class's constructor. axes_kwargs : dict, optional @@ -517,6 +581,8 @@ def zoomed_inset_axes(parent_axes, zoom, loc=1, borderpad : float, optional Padding between inset axes and the bbox_to_anchor. Defaults to 0.5. + The units are axes font size, i.e. for a default font size of 10 points + *borderpad = 0.5* is equivalent to a padding of 5 points. Returns ------- diff --git a/lib/mpl_toolkits/axisartist/axis_artist.py b/lib/mpl_toolkits/axisartist/axis_artist.py index 5e850330dd82..2650fc5fc534 100644 --- a/lib/mpl_toolkits/axisartist/axis_artist.py +++ b/lib/mpl_toolkits/axisartist/axis_artist.py @@ -59,7 +59,7 @@ The text angles are actually relative to (90 + angle of the direction to the ticklabel), which gives 0 for bottom axis. - left bottom right top + Parameter left bottom right top ticklabels location left right right left axislabel location left right right left ticklabels angle 90 0 -90 180 diff --git a/lib/mpl_toolkits/axisartist/floating_axes.py b/lib/mpl_toolkits/axisartist/floating_axes.py index bc67c7c42969..468413dbac4f 100644 --- a/lib/mpl_toolkits/axisartist/floating_axes.py +++ b/lib/mpl_toolkits/axisartist/floating_axes.py @@ -247,7 +247,7 @@ def __init__(self, aux_trans, extremes, objects which defines the transform and its inverse. The callables need take two arguments of array of source coordinates and should return two target coordinates: - e.g., x2, y2 = trans(x1, y1) + e.g., *x2, y2 = trans(x1, y1)* """ self._old_values = None diff --git a/lib/mpl_toolkits/tests/baseline_images/test_axes_grid1/inset_axes.png b/lib/mpl_toolkits/tests/baseline_images/test_axes_grid1/inset_axes.png new file mode 100644 index 000000000000..90498f5d441b Binary files /dev/null and b/lib/mpl_toolkits/tests/baseline_images/test_axes_grid1/inset_axes.png differ diff --git a/lib/mpl_toolkits/tests/test_axes_grid1.py b/lib/mpl_toolkits/tests/test_axes_grid1.py index 7914ad397215..48b589bdd5b6 100644 --- a/lib/mpl_toolkits/tests/test_axes_grid1.py +++ b/lib/mpl_toolkits/tests/test_axes_grid1.py @@ -9,13 +9,20 @@ from mpl_toolkits.axes_grid1 import host_subplot from mpl_toolkits.axes_grid1 import make_axes_locatable from mpl_toolkits.axes_grid1 import AxesGrid -from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes, mark_inset +from mpl_toolkits.axes_grid1.inset_locator import ( + zoomed_inset_axes, + mark_inset, + inset_axes +) from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar from matplotlib.colors import LogNorm from itertools import product +import pytest + import numpy as np +from numpy.testing import assert_array_equal, assert_array_almost_equal @image_comparison(baseline_images=['divider_append_axes']) @@ -155,6 +162,103 @@ def get_demo_image(): ax.add_artist(asb) +@image_comparison( + baseline_images=['inset_axes'], style='default', extensions=['png'], + remove_text=True) +def test_inset_axes(): + def get_demo_image(): + from matplotlib.cbook import get_sample_data + import numpy as np + f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False) + z = np.load(f) + # z is a numpy array of 15x15 + return z, (-3, 4, -4, 3) + + fig, ax = plt.subplots(figsize=[5, 4]) + + # prepare the demo image + Z, extent = get_demo_image() + Z2 = np.zeros([150, 150], dtype="d") + ny, nx = Z.shape + Z2[30:30 + ny, 30:30 + nx] = Z + + # extent = [-3, 4, -4, 3] + ax.imshow(Z2, extent=extent, interpolation="nearest", + origin="lower") + + # creating our inset axes with a bbox_transform parameter + axins = inset_axes(ax, width=1., height=1., bbox_to_anchor=(1, 1), + bbox_transform=ax.transAxes) + + axins.imshow(Z2, extent=extent, interpolation="nearest", + origin="lower") + axins.yaxis.get_major_locator().set_params(nbins=7) + axins.xaxis.get_major_locator().set_params(nbins=7) + # sub region of the original image + x1, x2, y1, y2 = -1.5, -0.9, -2.5, -1.9 + axins.set_xlim(x1, x2) + axins.set_ylim(y1, y2) + + plt.xticks(visible=False) + plt.yticks(visible=False) + + # draw a bbox of the region of the inset axes in the parent axes and + # connecting lines between the bbox and the inset axes area + mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5") + + asb = AnchoredSizeBar(ax.transData, + 0.5, + '0.5', + loc=8, + pad=0.1, borderpad=0.5, sep=5, + frameon=False) + ax.add_artist(asb) + + +def test_inset_axes_complete(): + dpi = 100 + figsize = (6, 5) + fig, ax = plt.subplots(figsize=figsize, dpi=dpi) + fig.subplots_adjust(.1, .1, .9, .9) + + ins = inset_axes(ax, width=2., height=2., borderpad=0) + fig.canvas.draw() + assert_array_almost_equal( + ins.get_position().extents, + np.array(((0.9*figsize[0]-2.)/figsize[0], + (0.9*figsize[1]-2.)/figsize[1], 0.9, 0.9))) + + ins = inset_axes(ax, width="40%", height="30%", borderpad=0) + fig.canvas.draw() + assert_array_almost_equal( + ins.get_position().extents, + np.array((.9-.8*.4, .9-.8*.3, 0.9, 0.9))) + + ins = inset_axes(ax, width=1., height=1.2, bbox_to_anchor=(200, 100), + loc=3, borderpad=0) + fig.canvas.draw() + assert_array_almost_equal( + ins.get_position().extents, + np.array((200./dpi/figsize[0], 100./dpi/figsize[1], + (200./dpi+1)/figsize[0], (100./dpi+1.2)/figsize[1]))) + + ins1 = inset_axes(ax, width="35%", height="60%", loc=3, borderpad=1) + ins2 = inset_axes(ax, width="100%", height="100%", + bbox_to_anchor=(0, 0, .35, .60), + bbox_transform=ax.transAxes, loc=3, borderpad=1) + fig.canvas.draw() + assert_array_equal(ins1.get_position().extents, + ins2.get_position().extents) + + with pytest.raises(ValueError): + ins = inset_axes(ax, width="40%", height="30%", + bbox_to_anchor=(0.4, 0.5)) + + with pytest.warns(UserWarning): + ins = inset_axes(ax, width="40%", height="30%", + bbox_transform=ax.transAxes) + + @image_comparison(baseline_images=['zoomed_axes', 'inverted_zoomed_axes'], extensions=['png']) diff --git a/tutorials/advanced/transforms_tutorial.py b/tutorials/advanced/transforms_tutorial.py index 2ea03567d70b..00e293b9fd00 100644 --- a/tutorials/advanced/transforms_tutorial.py +++ b/tutorials/advanced/transforms_tutorial.py @@ -25,9 +25,9 @@ | | |controlled by xlim and ylim. | +-----------+-----------------------------+-----------------------------------+ |"axes" |``ax.transAxes`` |The coordinate system of the | -| | |`.Axes`; (0, 0) is bottom left of | -| | |the axes, and (1, 1) is top right | -| | |of the axes. | +| | |`~matplotlib.axes.Axes`; (0, 0) | +| | |is bottom left of the axes, and | +| | |(1, 1) is top right of the axes. | +-----------+-----------------------------+-----------------------------------+ |"figure" |``fig.transFigure`` |The coordinate system of the | | | |`.Figure`; (0, 0) is bottom left | diff --git a/tutorials/intermediate/constrainedlayout_guide.py b/tutorials/intermediate/constrainedlayout_guide.py index b6f927b6f118..3f32968105c5 100644 --- a/tutorials/intermediate/constrainedlayout_guide.py +++ b/tutorials/intermediate/constrainedlayout_guide.py @@ -543,10 +543,11 @@ def docomplicated(suptitle=None): # Each item has a layoutbox associated with it. The nesting of gridspecs # created with `.GridSpecFromSubplotSpec` can be arbitrarily deep. # -# Each `.Axes` has *two* layoutboxes. The first one ``ax._layoutbox`` -# represents the outside of the Axes and all its decorations (i.e. ticklabels, -# axis labels, etc.). The second layoutbox corresponds to the Axes' -# `ax.position`, which sets where in the figure the spines are placed. +# Each ``~matplotlib.axes.Axes` has *two* layoutboxes. The first one, +# ``ax._layoutbox`` represents the outside of the Axes and all its +# decorations (i.e. ticklabels,axis labels, etc.). +# The second layoutbox corresponds to the Axes' `ax.position`, which sets +# where in the figure the spines are placed. # # Why so many stacked containers? Ideally, all that would be needed are the # Axes layout boxes. For the Gridspec case, a container is @@ -625,10 +626,11 @@ def docomplicated(suptitle=None): # constraint on their widths because their subplotspecs occupy the same # number of columns (one in this example). # -# The colorbar layout logic is contained in `~.colorbar.make_axes` which -# call `._constrained_layout.layoutcolorbarsingle` for cbars attached to -# a single axes, and `._constrained_layout.layoutcolorbargridspec` if the -# colorbar is associated wiht a gridspec. +# The colorbar layout logic is contained in `~matplotlib.colorbar.make_axes` +# which calls `._constrained_layout.layoutcolorbarsingle` +# for cbars attached to a single axes, and +# `._constrained_layout.layoutcolorbargridspec` if the colorbar is associated +# with a gridspec. fig, ax = plt.subplots(1, 2, constrained_layout=True) im = ax[0].pcolormesh(arr, **pc_kwargs) diff --git a/tutorials/text/text_intro.py b/tutorials/text/text_intro.py index 54896236779d..9009e4ee5b11 100644 --- a/tutorials/text/text_intro.py +++ b/tutorials/text/text_intro.py @@ -38,17 +38,20 @@ `.pyplot` API OO API description =================== =================== ====================================== `~.pyplot.text` `~.Axes.text` Add text at an arbitrary location of - the `.Axes`. + the `~matplotlib.axes.Axes`. `~.pyplot.annotate` `~.Axes.annotate` Add an annotation, with an optional arrow, at an arbitrary location of the - `.Axes`. + `~matplotlib.axes.Axes`. -`~.pyplot.xlabel` `~.Axes.set_xlabel` Add a label to the `.Axes`\\'s x-axis. +`~.pyplot.xlabel` `~.Axes.set_xlabel` Add a label to the + `~matplotlib.axes.Axes`\\'s x-axis. -`~.pyplot.ylabel` `~.Axes.set_ylabel` Add a label to the `.Axes`\\'s y-axis. +`~.pyplot.ylabel` `~.Axes.set_ylabel` Add a label to the + `~matplotlib.axes.Axes`\\'s y-axis. -`~.pyplot.title` `~.Axes.set_title` Add a title to the `.Axes`. +`~.pyplot.title` `~.Axes.set_title` Add a title to the + `~matplotlib.axes.Axes`. `~.pyplot.figtext` `~.Figure.text` Add text at an arbitrary location of the `.Figure`.