diff --git a/galleries/users_explain/artists/artist_intro.rst b/galleries/users_explain/artists/artist_intro.rst new file mode 100644 index 000000000000..5f82c972ca00 --- /dev/null +++ b/galleries/users_explain/artists/artist_intro.rst @@ -0,0 +1,187 @@ +.. _users_artists: + +Introduction to Artists +----------------------- + +Almost all objects you interact with on a Matplotlib plot are called "Artist" +(and are subclasses of the `.Artist` class). :doc:`Figure <../figure/index>` +and :doc:`Axes <../axes/index>` are Artists, and generally contain :doc:`Axis +<../axis/index>` Artists and Artists that contain data or annotation +information. + + +Creating Artists +~~~~~~~~~~~~~~~~ + +Usually we do not instantiate Artists directly, but rather use a plotting +method on `~.axes.Axes`. Some examples of plotting methods and the Artist +object they create is given below: + +========================================= ================= +Axes helper method Artist +========================================= ================= +`~.axes.Axes.annotate` - text annotations `.Annotation` +`~.axes.Axes.bar` - bar charts `.Rectangle` +`~.axes.Axes.errorbar` - error bar plots `.Line2D` and + `.Rectangle` +`~.axes.Axes.fill` - shared area `.Polygon` +`~.axes.Axes.hist` - histograms `.Rectangle` +`~.axes.Axes.imshow` - image data `.AxesImage` +`~.axes.Axes.legend` - Axes legend `.Legend` +`~.axes.Axes.plot` - xy plots `.Line2D` +`~.axes.Axes.scatter` - scatter charts `.PolyCollection` +`~.axes.Axes.text` - text `.Text` +========================================= ================= + +As an example, we can save the Line2D Artist returned from `.axes.Axes.plot`: + +.. sourcecode:: ipython + + In [209]: import matplotlib.pyplot as plt + In [210]: import matplotlib.artist as martist + In [211]: import numpy as np + + In [212]: fig, ax = plt.subplots() + In [213]: x, y = np.random.rand(2, 100) + In [214]: lines = ax.plot(x, y, '-', label='example') + In [215]: print(lines) + [] + +Note that ``plot`` returns a _list_ of lines because you can pass in multiple x, +y pairs to plot. The line has been added to the Axes, and we can retrieve the +Artist via `~.Axes.get_lines()`: + +.. sourcecode:: ipython + + In [216]: print(ax.get_lines()) + + In [217]: print(ax.get_lines()[0]) + Line2D(example) + +Changing Artist properties +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Getting the ``lines`` object gives us access to all the properties of the +Line2D object. So if we want to change the *linewidth* after the fact, we can do so using `.Artist.set`. + +.. plot:: + :include-source: + + fig, ax = plt.subplots(figsize=(4, 2.5)) + x = np.arange(0, 13, 0.2) + y = np.sin(x) + lines = ax.plot(x, y, '-', label='example', linewidth=0.2, color='blue') + lines[0].set(color='green', linewidth=2) + +We can interrogate the full list of settable properties with +`matplotlib.artist.getp`: + +.. sourcecode:: ipython + + In [218]: martist.getp(lines[0]) + agg_filter = None + alpha = None + animated = False + antialiased or aa = True + bbox = Bbox(x0=0.004013842290585101, y0=0.013914221641967... + children = [] + clip_box = TransformedBbox( Bbox(x0=0.0, y0=0.0, x1=1.0, ... + clip_on = True + clip_path = None + color or c = blue + dash_capstyle = butt + dash_joinstyle = round + data = (array([0.91377845, 0.58456834, 0.36492019, 0.0379... + drawstyle or ds = default + figure = Figure(550x450) + fillstyle = full + gapcolor = None + gid = None + in_layout = True + label = example + linestyle or ls = - + linewidth or lw = 2.0 + marker = None + markeredgecolor or mec = blue + markeredgewidth or mew = 1.0 + markerfacecolor or mfc = blue + markerfacecoloralt or mfcalt = none + markersize or ms = 6.0 + markevery = None + mouseover = False + path = Path(array([[0.91377845, 0.51224793], [0.58... + path_effects = [] + picker = None + pickradius = 5 + rasterized = False + sketch_params = None + snap = None + solid_capstyle = projecting + solid_joinstyle = round + tightbbox = Bbox(x0=70.4609002763619, y0=54.321277798941786, x... + transform = CompositeGenericTransform( TransformWrapper( ... + transformed_clip_path_and_affine = (None, None) + url = None + visible = True + window_extent = Bbox(x0=70.4609002763619, y0=54.321277798941786, x... + xdata = [0.91377845 0.58456834 0.36492019 0.03796664 0.884... + xydata = [[0.91377845 0.51224793] [0.58456834 0.9820474 ] ... + ydata = [0.51224793 0.9820474 0.24469912 0.61647032 0.483... + zorder = 2 + +Note most Artists also have a distinct list of setters; e.g. +`.Line2D.set_color` or `.Line2D.set_linewidth`. + +Changing Artist data +~~~~~~~~~~~~~~~~~~~~ + +In addition to styling properties like *color* and *linewidth*, the Line2D +object has a *data* property. You can set the data after the line has been +created using `.Line2D.set_data`. This is often used for Animations, where the +same line is shown evolving over time (see :doc:`../animations/index`) + +.. plot:: + :include-source: + + fig, ax = plt.subplots(figsize=(4, 2.5)) + x = np.arange(0, 13, 0.2) + y = np.sin(x) + lines = ax.plot(x, y, '-', label='example') + lines[0].set_data([x, np.cos(x)]) + +Manually adding Artists +~~~~~~~~~~~~~~~~~~~~~~~ + +Not all Artists have helper methods, or you may want to use a low-level method +for some reason. For example the `.patches.Circle` Artist does not have a +helper, but we can still create and add to an Axes using the +`.axes.Axes.add_artist` method: + +.. plot:: + :include-source: + + import matplotlib.patches as mpatches + + fig, ax = plt.subplots(figsize=(4, 2.5)) + circle = mpatches.Circle((0.5, 0.5), 0.25, ec="none") + ax.add_artist(circle) + clipped_circle = mpatches.Circle((1, 0.5), 0.125, ec="none", facecolor='C1') + ax.add_artist(clipped_circle) + ax.set_aspect(1) + +The Circle takes the center and radius of the Circle as arguments to its +constructor; optional arguments are passed as keyword arguments. + +Note that when we add an Artist manually like this, it doesn't necessarily +adjust the axis limits like most of the helper methods do, so the Artists can +be clipped, as is the case above for the ``clipped_circle`` patch. + +See :ref:`artist_reference` for other patches. + +Removing Artists +~~~~~~~~~~~~~~~~ + +Sometimes we want to remove an Artist from a figure without re-specifying the +whole figure from scratch. Most Artists have a usable *remove* method that +will remove the Artist from its Axes list. For instance ``lines[0].remove()`` +would remove the *Line2D* artist created in the example above. diff --git a/galleries/users_explain/artists/index.rst b/galleries/users_explain/artists/index.rst index 1b5e248d1ea7..26164d51f3a3 100644 --- a/galleries/users_explain/artists/index.rst +++ b/galleries/users_explain/artists/index.rst @@ -1,7 +1,6 @@ -.. _users_artists: - -Using Artists -------------- ++++++++ +Artists ++++++++ Almost all objects you interact with on a Matplotlib plot are called "Artist" (and are subclasses of the `.Artist` class). :doc:`Figure <../figure/index>` @@ -9,192 +8,17 @@ and :doc:`Axes <../axes/index>` are Artists, and generally contain :doc:`Axis <../axis/index>` Artists and Artists that contain data or annotation information. +.. toctree:: + :maxdepth: 2 -Creating Artists -~~~~~~~~~~~~~~~~ - -Usually we do not instantiate Artists directly, but rather use a plotting -method on `~.axes.Axes`. Some examples of plotting methods and the Artist -object they create is given below: - -========================================= ================= -Axes helper method Artist -========================================= ================= -`~.axes.Axes.annotate` - text annotations `.Annotation` -`~.axes.Axes.bar` - bar charts `.Rectangle` -`~.axes.Axes.errorbar` - error bar plots `.Line2D` and - `.Rectangle` -`~.axes.Axes.fill` - shared area `.Polygon` -`~.axes.Axes.hist` - histograms `.Rectangle` -`~.axes.Axes.imshow` - image data `.AxesImage` -`~.axes.Axes.legend` - Axes legend `.Legend` -`~.axes.Axes.plot` - xy plots `.Line2D` -`~.axes.Axes.scatter` - scatter charts `.PolyCollection` -`~.axes.Axes.text` - text `.Text` -========================================= ================= - -As an example, we can save the Line2D Artist returned from `.axes.Axes.plot`: - -.. sourcecode:: ipython - - In [209]: import matplotlib.pyplot as plt - In [210]: import matplotlib.artist as martist - In [211]: import numpy as np - - In [212]: fig, ax = plt.subplots() - In [213]: x, y = np.random.rand(2, 100) - In [214]: lines = ax.plot(x, y, '-', label='example') - In [215]: print(lines) - [] - -Note that ``plot`` returns a _list_ of lines because you can pass in multiple x, -y pairs to plot. The line has been added to the Axes, and we can retrieve the -Artist via `~.Axes.get_lines()`: - -.. sourcecode:: ipython - - In [216]: print(ax.get_lines()) - - In [217]: print(ax.get_lines()[0]) - Line2D(example) - -Changing Artist properties -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Getting the ``lines`` object gives us access to all the properties of the -Line2D object. So if we want to change the *linewidth* after the fact, we can do so using `.Artist.set`. - -.. plot:: - :include-source: - - fig, ax = plt.subplots(figsize=(4, 2.5)) - x = np.arange(0, 13, 0.2) - y = np.sin(x) - lines = ax.plot(x, y, '-', label='example', linewidth=0.2, color='blue') - lines[0].set(color='green', linewidth=2) - -We can interrogate the full list of settable properties with -`matplotlib.artist.getp`: - -.. sourcecode:: ipython - - In [218]: martist.getp(lines[0]) - agg_filter = None - alpha = None - animated = False - antialiased or aa = True - bbox = Bbox(x0=0.004013842290585101, y0=0.013914221641967... - children = [] - clip_box = TransformedBbox( Bbox(x0=0.0, y0=0.0, x1=1.0, ... - clip_on = True - clip_path = None - color or c = blue - dash_capstyle = butt - dash_joinstyle = round - data = (array([0.91377845, 0.58456834, 0.36492019, 0.0379... - drawstyle or ds = default - figure = Figure(550x450) - fillstyle = full - gapcolor = None - gid = None - in_layout = True - label = example - linestyle or ls = - - linewidth or lw = 2.0 - marker = None - markeredgecolor or mec = blue - markeredgewidth or mew = 1.0 - markerfacecolor or mfc = blue - markerfacecoloralt or mfcalt = none - markersize or ms = 6.0 - markevery = None - mouseover = False - path = Path(array([[0.91377845, 0.51224793], [0.58... - path_effects = [] - picker = None - pickradius = 5 - rasterized = False - sketch_params = None - snap = None - solid_capstyle = projecting - solid_joinstyle = round - tightbbox = Bbox(x0=70.4609002763619, y0=54.321277798941786, x... - transform = CompositeGenericTransform( TransformWrapper( ... - transformed_clip_path_and_affine = (None, None) - url = None - visible = True - window_extent = Bbox(x0=70.4609002763619, y0=54.321277798941786, x... - xdata = [0.91377845 0.58456834 0.36492019 0.03796664 0.884... - xydata = [[0.91377845 0.51224793] [0.58456834 0.9820474 ] ... - ydata = [0.51224793 0.9820474 0.24469912 0.61647032 0.483... - zorder = 2 - -Note most Artists also have a distinct list of setters; e.g. -`.Line2D.set_color` or `.Line2D.set_linewidth`. - -Changing Artist data -~~~~~~~~~~~~~~~~~~~~ - -In addition to styling properties like *color* and *linewidth*, the Line2D -object has a *data* property. You can set the data after the line has been -created using `.Line2D.set_data`. This is often used for Animations, where the -same line is shown evolving over time (see :doc:`../animations/index`) - -.. plot:: - :include-source: - - fig, ax = plt.subplots(figsize=(4, 2.5)) - x = np.arange(0, 13, 0.2) - y = np.sin(x) - lines = ax.plot(x, y, '-', label='example') - lines[0].set_data([x, np.cos(x)]) - -Manually adding Artists -~~~~~~~~~~~~~~~~~~~~~~~ - -Not all Artists have helper methods, or you may want to use a low-level method -for some reason. For example the `.patches.Circle` Artist does not have a -helper, but we can still create and add to an Axes using the -`.axes.Axes.add_artist` method: - -.. plot:: - :include-source: - - import matplotlib.patches as mpatches - - fig, ax = plt.subplots(figsize=(4, 2.5)) - circle = mpatches.Circle((0.5, 0.5), 0.25, ec="none") - ax.add_artist(circle) - clipped_circle = mpatches.Circle((1, 0.5), 0.125, ec="none", facecolor='C1') - ax.add_artist(clipped_circle) - ax.set_aspect(1) - -The Circle takes the center and radius of the Circle as arguments to its -constructor; optional arguments are passed as keyword arguments. - -Note that when we add an Artist manually like this, it doesn't necessarily -adjust the axis limits like most of the helper methods do, so the Artists can -be clipped, as is the case above for the ``clipped_circle`` patch. - -See :ref:`artist_reference` for other patches. - -Removing Artists -~~~~~~~~~~~~~~~~ - -Sometimes we want to remove an Artist from a figure without re-specifying the -whole figure from scratch. Most Artists have a usable *remove* method that -will remove the Artist from its Axes list. For instance ``lines[0].remove()`` -would remove the *Line2D* artist created in the example above. - -More details -~~~~~~~~~~~~ + artist_intro .. toctree:: :maxdepth: 1 - Concept: Automated color cycle - Concept: optimizing Artists for performance - Concept: Paths - Concept: Path effects guide - In Depth: understanding the extent keyword argument of imshow + Automated color cycle + Optimizing Artists for performance + Paths + Path effects guide + Understanding the extent keyword argument of imshow transforms_tutorial diff --git a/galleries/users_explain/axes/axes_intro.rst b/galleries/users_explain/axes/axes_intro.rst new file mode 100644 index 000000000000..17f9059b80af --- /dev/null +++ b/galleries/users_explain/axes/axes_intro.rst @@ -0,0 +1,180 @@ +################################## +Introduction to Axes (or Subplots) +################################## + + +Matplotlib `~.axes.Axes` are the gateway to creating your data visualizations. +Once an Axes is placed on a figure there are many methods that can be used to +add data to the Axes. An Axes typically has a pair of :doc:`Axis <../axis/index>` +Artists that define the data coordinate system, and include methods to add +annotations like x- and y-labels, titles, and legends. + +.. _anatomy_local: + +.. figure:: /_static/anatomy.png + :width: 80% + + Anatomy of a Figure + +In the picture above, the Axes object was created with ``ax = fig.subplots()``. +Everything else on the figure was created with methods on this ``ax`` object, +or can be accessed from it. If we want to change the label on the x-axis, we +call ``ax.set_xlabel('New Label')``, if we want to plot some data we call +``ax.plot(x, y)``. Indeed, in the figure above, the only Artist that is not +part of the Axes is the Figure itself, so the `.axes.Axes` class is really the +gateway to much of Matplotlib's functionality. + +Note that Axes are so fundamental to the operation of Matplotlib that a lot of +material here is duplicate of that in :ref:`quick_start`. + +Creating Axes +------------- + +.. plot:: + :include-source: + + import matplotlib.pyplot as plt + import numpy as np + + fig, axs = plt.subplots(ncols=2, nrows=2, figsize=(3.5, 2.5), + layout="constrained") + # for each Axes, add an artist, in this case a nice label in the middle... + for row in range(2): + for col in range(2): + axs[row, col].annotate(f'axs[{row}, {col}]', (0.5, 0.5), + transform=axs[row, col].transAxes, + ha='center', va='center', fontsize=18, + color='darkgrey') + fig.suptitle('plt.subplots()') + + +Axes are added using methods on `~.Figure` objects, or via the `~.pyplot` interface. These methods are discussed in more detail in :ref:`creating_figures` and :doc:`arranging_axes`. However, for instance `~.Figure.add_axes` will manually position an Axes on the page. In the example above `~.pyplot.subplots` put a grid of subplots on the figure, and ``axs`` is a (2, 2) array of Axes, each of which can have data added to them. + +There are a number of other methods for adding Axes to a Figure: + +* `.Figure.add_axes`: manually position an Axes. ``fig.add_axes([0, 0, 1, + 1])`` makes an Axes that fills the whole figure. +* `.pyplot.subplots` and `.Figure.subplots`: add a grid of Axes as in the example + above. The pyplot version returns both the Figure object and an array of + Axes. Note that ``fig, ax = plt.subplots()`` adds a single Axes to a Figure. +* `.pyplot.subplot_mosaic` and `.Figure.subplot_mosaic`: add a grid of named + Axes and return a dictionary of axes. For ``fig, axs = + plt.subplot_mosaic([['left', 'right'], ['bottom', 'bottom']])``, + ``axs['left']`` is an Axes in the top row on the left, and ``axs['bottom']`` + is an Axes that spans both columns on the bottom. + +See :doc:`arranging_axes` for more detail on how to arrange grids of Axes on a +Figure. + + +Axes plotting methods +--------------------- + +Most of the high-level plotting methods are accessed from the `.axes.Axes` +class. See the API documentation for a full curated list, and +:ref:`plot_types` for examples. A basic example is `.axes.Axes.plot`: + +.. plot:: + :include-source: + + fig, ax = plt.subplots(figsize=(4, 3)) + np.random.seed(19680801) + t = np.arange(100) + x = np.cumsum(np.random.randn(100)) + lines = ax.plot(t, x) + +Note that ``plot`` returns a list of *lines* Artists which can subsequently be +manipulated, as discussed in :ref:`users_artists`. + +A very incomplete list of plotting methods is below. Again, see :ref:`plot_types` +for more examples, and `.axes.Axes` for the full list of methods. + +========================= ================================================== +:ref:`basic_plots` `~.axes.Axes.plot`, `~.axes.Axes.scatter`, + `~.axes.Axes.bar`, `~.axes.Axes.step`, +:ref:`arrays` `~.axes.Axes.pcolormesh`, `~.axes.Axes.contour`, + `~.axes.Axes.quiver`, `~.axes.Axes.streamplot`, + `~.axes.Axes.imshow` +:ref:`stats_plots` `~.axes.Axes.hist`, `~.axes.Axes.errorbar`, + `~.axes.Axes.hist2d`, `~.axes.Axes.pie`, + `~.axes.Axes.boxplot`, `~.axes.Axes.violinplot` +:ref:`unstructured_plots` `~.axes.Axes.tricontour`, `~.axes.Axes.tripcolor` +========================= ================================================== + +Axes labelling and annotation +----------------------------- + +Usually we want to label the Axes with an xlabel, ylabel, and title, and often we want to have a legend to differentiate plot elements. The `~.axes.Axes` class has a number of methods to create these annotations. + +.. plot:: + :include-source: + + fig, ax = plt.subplots(figsize=(5, 3), layout='constrained') + np.random.seed(19680801) + t = np.arange(200) + x = np.cumsum(np.random.randn(200)) + y = np.cumsum(np.random.randn(200)) + linesx = ax.plot(t, x, label='Random walk x') + linesy = ax.plot(t, y, label='Random walk y') + + ax.set_xlabel('Time [s]') + ax.set_ylabel('Distance [km]') + ax.set_title('Random walk example') + ax.legend() + +These methods are relatively straight-forward, though there are a number of :ref:`text_props` that can be set on the text objects, like *fontsize*, *fontname*, *horizontalalignment*. Legends can be much more complicated; see :ref:`legend_guide` for more details. + +Note that text can also be added to axes using `~.axes.Axes.text`, and `~.axes.Axes.annotate`. This can be quite sophisticated: see :ref:`text_props` and :ref:`annotations` for more information. + + +Axes limits, scales, and ticking +-------------------------------- + +Each Axes has two (or more) `~.axis.Axis` objects, that can be accessed via :attr:`~matplotlib.axes.Axes.xaxis` and :attr:`~matplotlib.axes.Axes.yaxis` properties. These have substantial number of methods on them, and for highly customizable Axis-es it is useful to read more about that API (:doc:`../axis/index`). However, the Axes class offers a number of helpers for the most common of these methods. Indeed, the `~.axes.Axes.set_xlabel`, discussed above, is a helper for the `~.Axis.set_label_text`. + +Other important methods set the extent on the axes (`~.axes.Axes.set_xlim`, `~.axes.Axes.set_ylim`), or more fundamentally the scale of the axes. So for instance, we can make an Axis have a logarithmic scale, and zoom in on a sub-portion of the data: + +.. plot:: + :include-source: + + fig, ax = plt.subplots(figsize=(4, 2.5), layout='constrained') + np.random.seed(19680801) + t = np.arange(200) + x = 2**np.cumsum(np.random.randn(200)) + linesx = ax.plot(t, x) + ax.set_yscale('log') + ax.set_xlim([20, 180]) + +The Axes class also has helpers to deal with Axis ticks and their labels. Most straight-forward is `~.axes.Axes.set_xticks` and `~.axes.Axes.set_yticks` which manually set the tick locations and optionally their labels. Minor ticks can be toggled with `~.axes.Axes.minorticks_on` or `~.axes.Axes.minorticks_off`. + +Many aspects of Axes ticks and tick labeling can be adjusted using `~.axes.Axes.tick_params`. For instance, to label the top of the axes instead of the bottom,color the ticks red, and color the ticklabels green: + +.. plot:: + :include-source: + + fig, ax = plt.subplots(figsize=(4, 2.5)) + ax.plot(np.arange(10)) + ax.tick_params(top=True, labeltop=True, color='red', axis='x', + labelcolor='green') + + +More fine-grained control on ticks, setting scales, and controlling the Axis can be highly customized beyond these Axes-level helpers. An introduction to these methods can be found in :ref:`users_axis`, or the API reference for `.axis.Axis`. + +Axes layout +----------- + +Sometimes it is important to set the aspect ratio of a plot in data space, which we can do with `~.axes.Axes.set_aspect`: + +.. plot:: + :include-source: + + fig, axs = plt.subplots(ncols=2, figsize=(7, 2.5), layout='constrained') + np.random.seed(19680801) + t = np.arange(200) + x = np.cumsum(np.random.randn(200)) + axs[0].plot(t, x) + axs[0].set_title('aspect="auto"') + + axs[1].plot(t, x) + axs[1].set_aspect(3) + axs[1].set_title('aspect=3') diff --git a/galleries/users_explain/axes/index.rst b/galleries/users_explain/axes/index.rst index 8bcf51add979..a4df627c0671 100644 --- a/galleries/users_explain/axes/index.rst +++ b/galleries/users_explain/axes/index.rst @@ -1,7 +1,6 @@ -################## -Axes (or Subplots) -################## - ++++++++++++++++++ +Axes and subplots ++++++++++++++++++ Matplotlib `~.axes.Axes` are the gateway to creating your data visualizations. Once an Axes is placed on a figure there are many methods that can be used to @@ -9,29 +8,7 @@ add data to the Axes. An Axes typically has a pair of :doc:`Axis <../axis/index> Artists that define the data coordinate system, and include methods to add annotations like x- and y-labels, titles, and legends. -.. _anatomy_local: - -.. figure:: /_static/anatomy.png - :width: 80% - - Anatomy of a Figure - -In the picture above, the Axes object was created with ``ax = fig.subplots()``. -Everything else on the figure was created with methods on this ``ax`` object, -or can be accessed from it. If we want to change the label on the x-axis, we -call ``ax.set_xlabel('New Label')``, if we want to plot some data we call -``ax.plot(x, y)``. Indeed, in the figure above, the only Artist that is not -part of the Axes is the Figure itself, so the `.axes.Axes` class is really the -gateway to much of Matplotlib's functionality. - -Note that Axes are so fundamental to the operation of Matplotlib that a lot of -material here is duplicate of that in :ref:`quick_start`. - -Creating Axes -------------- - .. plot:: - :include-source: import matplotlib.pyplot as plt import numpy as np @@ -48,144 +25,18 @@ Creating Axes fig.suptitle('plt.subplots()') -Axes are added using methods on `~.Figure` objects, or via the `~.pyplot` interface. These methods are discussed in more detail in :ref:`creating_figures` and :doc:`arranging_axes`. However, for instance `~.Figure.add_axes` will manually position an Axes on the page. In the example above `~.pyplot.subplots` put a grid of subplots on the figure, and ``axs`` is a (2, 2) array of Axes, each of which can have data added to them. - -There are a number of other methods for adding Axes to a Figure: - -* `.Figure.add_axes`: manually position an Axes. ``fig.add_axes([0, 0, 1, - 1])`` makes an Axes that fills the whole figure. -* `.pyplot.subplots` and `.Figure.subplots`: add a grid of Axes as in the example - above. The pyplot version returns both the Figure object and an array of - Axes. Note that ``fig, ax = plt.subplots()`` adds a single Axes to a Figure. -* `.pyplot.subplot_mosaic` and `.Figure.subplot_mosaic`: add a grid of named - Axes and return a dictionary of axes. For ``fig, axs = - plt.subplot_mosaic([['left', 'right'], ['bottom', 'bottom']])``, - ``axs['left']`` is an Axes in the top row on the left, and ``axs['bottom']`` - is an Axes that spans both columns on the bottom. - -See :doc:`arranging_axes` for more detail on how to arrange grids of Axes on a -Figure. - - -Axes plotting methods ---------------------- - -Most of the high-level plotting methods are accessed from the `.axes.Axes` -class. See the API documentation for a full curated list, and -:ref:`plot_types` for examples. A basic example is `.axes.Axes.plot`: - -.. plot:: - :include-source: - - fig, ax = plt.subplots(figsize=(4, 3)) - np.random.seed(19680801) - t = np.arange(100) - x = np.cumsum(np.random.randn(100)) - lines = ax.plot(t, x) - -Note that ``plot`` returns a list of *lines* Artists which can subsequently be -manipulated, as discussed in :ref:`users_artists`. - -A very incomplete list of plotting methods is below. Again, see :ref:`plot_types` -for more examples, and `.axes.Axes` for the full list of methods. - -========================= ================================================== -:ref:`basic_plots` `~.axes.Axes.plot`, `~.axes.Axes.scatter`, - `~.axes.Axes.bar`, `~.axes.Axes.step`, -:ref:`arrays` `~.axes.Axes.pcolormesh`, `~.axes.Axes.contour`, - `~.axes.Axes.quiver`, `~.axes.Axes.streamplot`, - `~.axes.Axes.imshow` -:ref:`stats_plots` `~.axes.Axes.hist`, `~.axes.Axes.errorbar`, - `~.axes.Axes.hist2d`, `~.axes.Axes.pie`, - `~.axes.Axes.boxplot`, `~.axes.Axes.violinplot` -:ref:`unstructured_plots` `~.axes.Axes.tricontour`, `~.axes.Axes.tripcolor` -========================= ================================================== - -Axes labelling and annotation ------------------------------ - -Usually we want to label the Axes with an xlabel, ylabel, and title, and often we want to have a legend to differentiate plot elements. The `~.axes.Axes` class has a number of methods to create these annotations. - -.. plot:: - :include-source: - - fig, ax = plt.subplots(figsize=(5, 3), layout='constrained') - np.random.seed(19680801) - t = np.arange(200) - x = np.cumsum(np.random.randn(200)) - y = np.cumsum(np.random.randn(200)) - linesx = ax.plot(t, x, label='Random walk x') - linesy = ax.plot(t, y, label='Random walk y') - - ax.set_xlabel('Time [s]') - ax.set_ylabel('Distance [km]') - ax.set_title('Random walk example') - ax.legend() - -These methods are relatively straight-forward, though there are a number of :ref:`text_props` that can be set on the text objects, like *fontsize*, *fontname*, *horizontalalignment*. Legends can be much more complicated; see :ref:`legend_guide` for more details. - -Note that text can also be added to axes using `~.axes.Axes.text`, and `~.axes.Axes.annotate`. This can be quite sophisticated: see :ref:`text_props` and :ref:`annotations` for more information. - - -Axes limits, scales, and ticking --------------------------------- - -Each Axes has two (or more) `~.axis.Axis` objects, that can be accessed via :attr:`~matplotlib.axes.Axes.xaxis` and :attr:`~matplotlib.axes.Axes.yaxis` properties. These have substantial number of methods on them, and for highly customizable Axis-es it is useful to read more about that API (:doc:`../axis/index`). However, the Axes class offers a number of helpers for the most common of these methods. Indeed, the `~.axes.Axes.set_xlabel`, discussed above, is a helper for the `~.Axis.set_label_text`. - -Other important methods set the extent on the axes (`~.axes.Axes.set_xlim`, `~.axes.Axes.set_ylim`), or more fundamentally the scale of the axes. So for instance, we can make an Axis have a logarithmic scale, and zoom in on a sub-portion of the data: - -.. plot:: - :include-source: - - fig, ax = plt.subplots(figsize=(4, 2.5), layout='constrained') - np.random.seed(19680801) - t = np.arange(200) - x = 2**np.cumsum(np.random.randn(200)) - linesx = ax.plot(t, x) - ax.set_yscale('log') - ax.set_xlim([20, 180]) - -The Axes class also has helpers to deal with Axis ticks and their labels. Most straight-forward is `~.axes.Axes.set_xticks` and `~.axes.Axes.set_yticks` which manually set the tick locations and optionally their labels. Minor ticks can be toggled with `~.axes.Axes.minorticks_on` or `~.axes.Axes.minorticks_off`. - -Many aspects of Axes ticks and tick labeling can be adjusted using `~.axes.Axes.tick_params`. For instance, to label the top of the axes instead of the bottom,color the ticks red, and color the ticklabels green: - -.. plot:: - :include-source: - - fig, ax = plt.subplots(figsize=(4, 2.5)) - ax.plot(np.arange(10)) - ax.tick_params(top=True, labeltop=True, color='red', axis='x', - labelcolor='green') - - -More fine-grained control on ticks, setting scales, and controlling the Axis can be highly customized beyond these Axes-level helpers. An introduction to these methods can be found in :ref:`users_axis`, or the API reference for `.axis.Axis`. - -Axes layout ------------ - -Sometimes it is important to set the aspect ratio of a plot in data space, which we can do with `~.axes.Axes.set_aspect`: - -.. plot:: - :include-source: - - fig, axs = plt.subplots(ncols=2, figsize=(7, 2.5), layout='constrained') - np.random.seed(19680801) - t = np.arange(200) - x = np.cumsum(np.random.randn(200)) - axs[0].plot(t, x) - axs[0].set_title('aspect="auto"') +.. toctree:: + :maxdepth: 2 - axs[1].plot(t, x) - axs[1].set_aspect(3) - axs[1].set_title('aspect=3') + axes_intro .. toctree:: :maxdepth: 1 arranging_axes colorbar_placement - In depth: Autoscaling axes - In depth: Legends - In depth: Subplot mosaic - In depth: Constrained layout guide - In depth: Tight layout guide (mildly discouraged) + Autoscaling axes + Legends + Subplot mosaic + Constrained layout guide + Tight layout guide (mildly discouraged) diff --git a/galleries/users_explain/figure/figure_intro.rst b/galleries/users_explain/figure/figure_intro.rst new file mode 100644 index 000000000000..9eda8acc92a1 --- /dev/null +++ b/galleries/users_explain/figure/figure_intro.rst @@ -0,0 +1,257 @@ + +.. redirect-from:: /users/explain/figure + +.. _figure_explanation: + ++++++++++++++++++++++++ +Introduction to Figures ++++++++++++++++++++++++ + +.. plot:: + :include-source: + + fig = plt.figure(figsize=(2, 2), facecolor='lightskyblue', + layout='constrained') + fig.suptitle('Figure') + ax = fig.add_subplot() + ax.set_title('Axes', loc='left', fontstyle='oblique', fontsize='medium') + +When looking at Matplotlib visualization, you are almost always looking at +Artists placed on a `~.Figure`. In the example above, the figure is the +blue region and `~.Figure.add_subplot` has added an `~.axes.Axes` artist to the +`~.Figure` (see :ref:`figure_parts`). A more complicated visualization can add +multiple Axes to the Figure, colorbars, legends, annotations, and the Axes +themselves can have multiple Artists added to them +(e.g. ``ax.plot`` or ``ax.imshow``). + +.. contents:: :local: + + +.. _viewing_figures: + +Viewing Figures +================ + +We will discuss how to create Figures in more detail below, but first it is +helpful to understand how to view a Figure. This varies based on how you are +using Matplotlib, and what :ref:`Backend ` you are using. + +Notebooks and IDEs +------------------ + +.. figure:: /_static/FigureInline.png + :alt: Image of figure generated in Jupyter Notebook with inline backend. + :width: 400 + + Screenshot of a `Jupyter Notebook `_, with a figure + generated via the default `inline + `_ backend. + + +If you are using a Notebook (e.g. `Jupyter `_) or an IDE +that renders Notebooks (PyCharm, VSCode, etc), then they have a backend that +will render the Matplotlib Figure when a code cell is executed. One thing to +be aware of is that the default Jupyter backend (``%matplotlib inline``) will +by default trim or expand the figure size to have a tight box around Artists +added to the Figure (see :ref:`saving_figures`, below). If you use a backend +other than the default "inline" backend, you will likely need to use an ipython +"magic" like ``%matplotlib notebook`` for the Matplotlib :ref:`notebook +` or ``%matplotlib widget`` for the `ipympl +`_ backend. + +.. figure:: /_static/FigureNotebook.png + :alt: Image of figure generated in Jupyter Notebook with notebook + backend, including a toolbar. + :width: 400 + + Screenshot of a Jupyter Notebook with an interactive figure generated via + the ``%matplotlib notebook`` magic. Users should also try the similar + `widget `_ backend if using `JupyterLab + `_. + + +.. seealso:: + :ref:`interactive_figures`. + +Standalone scripts and interactive use +-------------------------------------- + +If the user is on a client with a windowing system, there are a number of +:ref:`Backends ` that can be used to render the Figure to +the screen, usually using a Python Qt, Tk, or Wx toolkit, or the native MacOS +backend. These are typically chosen either in the user's :ref:`matplotlibrc +`, or by calling, for example, +``matplotlib.use('QtAgg')`` at the beginning of a session or script. + +.. figure:: /_static/FigureQtAgg.png + :alt: Image of figure generated from a script via the QtAgg backend. + :width: 370 + + Screenshot of a Figure generated via a python script and shown using the + QtAgg backend. + +When run from a script, or interactively (e.g. from an +`iPython shell `_) the Figure +will not be shown until we call ``plt.show()``. The Figure will appear in +a new GUI window, and usually will have a toolbar with Zoom, Pan, and other tools +for interacting with the Figure. By default, ``plt.show()`` blocks +further interaction from the script or shell until the Figure window is closed, +though that can be toggled off for some purposes. For more details, please see +:ref:`controlling-interactive`. + +Note that if you are on a client that does not have access to a windowing +system, the Figure will fallback to being drawn using the "Agg" backend, and +cannot be viewed, though it can be :ref:`saved `. + +.. seealso:: + :ref:`interactive_figures`. + +.. _creating_figures: + +Creating Figures +================ + +By far the most common way to create a figure is using the +:ref:`pyplot ` interface. As noted in +:ref:`api_interfaces`, the pyplot interface serves two purposes. One is to spin +up the Backend and keep track of GUI windows. The other is a global state for +Axes and Artists that allow a short-form API to plotting methods. In the +example above, we use pyplot for the first purpose, and create the Figure object, +``fig``. As a side effect ``fig`` is also added to pyplot's global state, and +can be accessed via `~.pyplot.gcf`. + +Users typically want an Axes or a grid of Axes when they create a Figure, so in +addition to `~.pyplot.figure`, there are convenience methods that return both +a Figure and some Axes. A simple grid of Axes can be achieved with +`.pyplot.subplots` (which +simply wraps `.Figure.subplots`): + +.. plot:: + :include-source: + + fig, axs = plt.subplots(2, 2, figsize=(4, 3), layout='constrained') + +More complex grids can be achieved with `.pyplot.subplot_mosaic` (which wraps +`.Figure.subplot_mosaic`): + +.. plot:: + :include-source: + + fig, axs = plt.subplot_mosaic([['A', 'right'], ['B', 'right']], + figsize=(4, 3), layout='constrained') + for ax_name in axs: + axs[ax_name].text(0.5, 0.5, ax_name, ha='center', va='center') + +Sometimes we want to have a nested layout in a Figure, with two or more sets of +Axes that do not share the same subplot grid. +We can use `~.Figure.add_subfigure` or `~.Figure.subfigures` to create virtual +figures inside a parent Figure; see +:doc:`/gallery/subplots_axes_and_figures/subfigures` for more details. + +.. plot:: + :include-source: + + fig = plt.figure(layout='constrained', facecolor='lightskyblue') + fig.suptitle('Figure') + figL, figR = fig.subfigures(1, 2) + figL.set_facecolor('thistle') + axL = figL.subplots(2, 1, sharex=True) + axL[1].set_xlabel('x [m]') + figL.suptitle('Left subfigure') + figR.set_facecolor('paleturquoise') + axR = figR.subplots(1, 2, sharey=True) + axR[0].set_title('Axes 1') + figR.suptitle('Right subfigure') + +It is possible to directly instantiate a `.Figure` instance without using the +pyplot interface. This is usually only necessary if you want to create your +own GUI application or service that you do not want carrying the pyplot global +state. See the embedding examples in :ref:`user_interfaces` for examples of +how to do this. + +Figure options +-------------- + +There are a few options available when creating figures. The Figure size on +the screen is set by *figsize* and *dpi*. *figsize* is the ``(width, height)`` +of the Figure in inches (or, if preferred, units of 72 typographic points). *dpi* +are how many pixels per inch the figure will be rendered at. To make your Figures +appear on the screen at the physical size you requested, you should set *dpi* +to the same *dpi* as your graphics system. Note that many graphics systems now use +a "dpi ratio" to specify how many screen pixels are used to represent a graphics +pixel. Matplotlib applies the dpi ratio to the *dpi* passed to the figure to make +it have higher resolution, so you should pass the lower number to the figure. + +The *facecolor*, *edgecolor*, *linewidth*, and *frameon* options all change the appearance of the +figure in expected ways, with *frameon* making the figure transparent if set to *False*. + +Finally, the user can specify a layout engine for the figure with the *layout* +parameter. Currently Matplotlib supplies +:ref:`"constrained" `, +:ref:`"compressed" ` and +:ref:`"tight" ` layout engines. These +rescale axes inside the Figure to prevent overlap of ticklabels, and try and align +axes, and can save significant manual adjustment of artists on a Figure for many +common cases. + +Adding Artists +-------------- + +The `~.FigureBase` class has a number of methods to add artists to a `~.Figure` or +a `~.SubFigure`. By far the most common are to add Axes of various configurations +(`~.FigureBase.add_axes`, `~.FigureBase.add_subplot`, `~.FigureBase.subplots`, +`~.FigureBase.subplot_mosaic`) and subfigures (`~.FigureBase.subfigures`). Colorbars +are added to Axes or group of Axes at the Figure level (`~.FigureBase.colorbar`). +It is also possible to have a Figure-level legend (`~.FigureBase.legend`). +Other Artists include figure-wide labels (`~.FigureBase.suptitle`, +`~.FigureBase.supxlabel`, `~.FigureBase.supylabel`) and text (`~.FigureBase.text`). +Finally, low-level Artists can be added directly using `~.FigureBase.add_artist` +usually with care being taken to use the appropriate transform. Usually these +include ``Figure.transFigure`` which ranges from 0 to 1 in each direction, and +represents the fraction of the current Figure size, or ``Figure.dpi_scale_trans`` +which will be in physical units of inches from the bottom left corner of the Figure +(see :ref:`transforms_tutorial` for more details). + + +.. _saving_figures: + +Saving Figures +============== + +Finally, Figures can be saved to disk using the `~.Figure.savefig` method. +``fig.savefig('MyFigure.png', dpi=200)`` will save a PNG formatted figure to +the file ``MyFigure.png`` in the current directory on disk with 200 dots-per-inch +resolution. Note that the filename can include a relative or absolute path to +any place on the file system. + +Many types of output are supported, including raster formats like PNG, GIF, JPEG, +TIFF and vector formats like PDF, EPS, and SVG. + +By default, the size of the saved Figure is set by the Figure size (in inches) and, for the raster +formats, the *dpi*. If *dpi* is not set, then the *dpi* of the Figure is used. +Note that *dpi* still has meaning for vector formats like PDF if the Figure includes +Artists that have been :doc:`rasterized `; the +*dpi* specified will be the resolution of the rasterized objects. + +It is possible to change the size of the Figure using the *bbox_inches* argument +to savefig. This can be specified manually, again in inches. However, by far +the most common use is ``bbox_inches='tight'``. This option "shrink-wraps", trimming +or expanding as needed, the size of the figure so that it is tight around all the artists +in a figure, with a small pad that can be specified by *pad_inches*, which defaults to +0.1 inches. The dashed box in the plot below shows the portion of the figure that +would be saved if ``bbox_inches='tight'`` were used in savefig. + +.. plot:: + + import matplotlib.pyplot as plt + from matplotlib.patches import FancyBboxPatch + + fig, ax = plt.subplots(figsize=(4, 2), facecolor='lightskyblue') + ax.set_position([0.1, 0.2, 0.8, 0.7]) + ax.set_aspect(1) + bb = ax.get_tightbbox() + bb = bb.padded(10) + fancy = FancyBboxPatch(bb.p0, bb.width, bb.height, fc='none', + ec=(0, 0.0, 0, 0.5), lw=2, linestyle='--', + transform=None, clip_on=False) + ax.add_patch(fancy) diff --git a/galleries/users_explain/figure/index.rst b/galleries/users_explain/figure/index.rst index 5e2ecc17d2c1..4433246e4074 100644 --- a/galleries/users_explain/figure/index.rst +++ b/galleries/users_explain/figure/index.rst @@ -1,270 +1,36 @@ - -.. redirect-from:: /users/explain/figure -.. _figure_explanation: - -+++++++++++++++++ -Figures -+++++++++++++++++ - -.. plot:: - :include-source: - - fig = plt.figure(figsize=(2, 2), facecolor='lightskyblue', - layout='constrained') - fig.suptitle('Figure') - ax = fig.add_subplot() - ax.set_title('Axes', loc='left', fontstyle='oblique', fontsize='medium') +++++++++++++++++++++ +Figures and backends +++++++++++++++++++++ When looking at Matplotlib visualization, you are almost always looking at -Artists placed on a `~.Figure`. In the example above, the figure is the +Artists placed on a `~.Figure`. In the example below, the figure is the blue region and `~.Figure.add_subplot` has added an `~.axes.Axes` artist to the `~.Figure` (see :ref:`figure_parts`). A more complicated visualization can add multiple Axes to the Figure, colorbars, legends, annotations, and the Axes themselves can have multiple Artists added to them (e.g. ``ax.plot`` or ``ax.imshow``). -.. contents:: :local: - - -.. _viewing_figures: - -Viewing Figures -================ - -We will discuss how to create Figures in more detail below, but first it is -helpful to understand how to view a Figure. This varies based on how you are -using Matplotlib, and what :ref:`Backend ` you are using. - -Notebooks and IDEs ------------------- - -.. figure:: /_static/FigureInline.png - :alt: Image of figure generated in Jupyter Notebook with inline backend. - :width: 400 - - Screenshot of a `Jupyter Notebook `_, with a figure - generated via the default `inline - `_ backend. - - -If you are using a Notebook (e.g. `Jupyter `_) or an IDE -that renders Notebooks (PyCharm, VSCode, etc), then they have a backend that -will render the Matplotlib Figure when a code cell is executed. One thing to -be aware of is that the default Jupyter backend (``%matplotlib inline``) will -by default trim or expand the figure size to have a tight box around Artists -added to the Figure (see :ref:`saving_figures`, below). If you use a backend -other than the default "inline" backend, you will likely need to use an ipython -"magic" like ``%matplotlib notebook`` for the Matplotlib :ref:`notebook -` or ``%matplotlib widget`` for the `ipympl -`_ backend. - -.. figure:: /_static/FigureNotebook.png - :alt: Image of figure generated in Jupyter Notebook with notebook - backend, including a toolbar. - :width: 400 - - Screenshot of a Jupyter Notebook with an interactive figure generated via - the ``%matplotlib notebook`` magic. Users should also try the similar - `widget `_ backend if using `JupyterLab - `_. - - -.. seealso:: - :ref:`interactive_figures`. - -Standalone scripts and interactive use --------------------------------------- - -If the user is on a client with a windowing system, there are a number of -:ref:`Backends ` that can be used to render the Figure to -the screen, usually using a Python Qt, Tk, or Wx toolkit, or the native MacOS -backend. These are typically chosen either in the user's :ref:`matplotlibrc -`, or by calling, for example, -``matplotlib.use('QtAgg')`` at the beginning of a session or script. - -.. figure:: /_static/FigureQtAgg.png - :alt: Image of figure generated from a script via the QtAgg backend. - :width: 370 - - Screenshot of a Figure generated via a python script and shown using the - QtAgg backend. - -When run from a script, or interactively (e.g. from an -`iPython shell `_) the Figure -will not be shown until we call ``plt.show()``. The Figure will appear in -a new GUI window, and usually will have a toolbar with Zoom, Pan, and other tools -for interacting with the Figure. By default, ``plt.show()`` blocks -further interaction from the script or shell until the Figure window is closed, -though that can be toggled off for some purposes. For more details, please see -:ref:`controlling-interactive`. - -Note that if you are on a client that does not have access to a windowing -system, the Figure will fallback to being drawn using the "Agg" backend, and -cannot be viewed, though it can be :ref:`saved `. - -.. seealso:: - :ref:`interactive_figures`. - -.. _creating_figures: - -Creating Figures -================ - -By far the most common way to create a figure is using the -:ref:`pyplot ` interface. As noted in -:ref:`api_interfaces`, the pyplot interface serves two purposes. One is to spin -up the Backend and keep track of GUI windows. The other is a global state for -Axes and Artists that allow a short-form API to plotting methods. In the -example above, we use pyplot for the first purpose, and create the Figure object, -``fig``. As a side effect ``fig`` is also added to pyplot's global state, and -can be accessed via `~.pyplot.gcf`. - -Users typically want an Axes or a grid of Axes when they create a Figure, so in -addition to `~.pyplot.figure`, there are convenience methods that return both -a Figure and some Axes. A simple grid of Axes can be achieved with -`.pyplot.subplots` (which -simply wraps `.Figure.subplots`): - -.. plot:: - :include-source: - - fig, axs = plt.subplots(2, 2, figsize=(4, 3), layout='constrained') - -More complex grids can be achieved with `.pyplot.subplot_mosaic` (which wraps -`.Figure.subplot_mosaic`): - -.. plot:: - :include-source: - - fig, axs = plt.subplot_mosaic([['A', 'right'], ['B', 'right']], - figsize=(4, 3), layout='constrained') - for ax_name in axs: - axs[ax_name].text(0.5, 0.5, ax_name, ha='center', va='center') - -Sometimes we want to have a nested layout in a Figure, with two or more sets of -Axes that do not share the same subplot grid. -We can use `~.Figure.add_subfigure` or `~.Figure.subfigures` to create virtual -figures inside a parent Figure; see -:doc:`/gallery/subplots_axes_and_figures/subfigures` for more details. - .. plot:: :include-source: - fig = plt.figure(layout='constrained', facecolor='lightskyblue') - fig.suptitle('Figure') - figL, figR = fig.subfigures(1, 2) - figL.set_facecolor('thistle') - axL = figL.subplots(2, 1, sharex=True) - axL[1].set_xlabel('x [m]') - figL.suptitle('Left subfigure') - figR.set_facecolor('paleturquoise') - axR = figR.subplots(1, 2, sharey=True) - axR[0].set_title('Axes 1') - figR.suptitle('Right subfigure') - -It is possible to directly instantiate a `.Figure` instance without using the -pyplot interface. This is usually only necessary if you want to create your -own GUI application or service that you do not want carrying the pyplot global -state. See the embedding examples in :ref:`user_interfaces` for examples of -how to do this. - -Figure options --------------- - -There are a few options available when creating figures. The Figure size on -the screen is set by *figsize* and *dpi*. *figsize* is the ``(width, height)`` -of the Figure in inches (or, if preferred, units of 72 typographic points). *dpi* -are how many pixels per inch the figure will be rendered at. To make your Figures -appear on the screen at the physical size you requested, you should set *dpi* -to the same *dpi* as your graphics system. Note that many graphics systems now use -a "dpi ratio" to specify how many screen pixels are used to represent a graphics -pixel. Matplotlib applies the dpi ratio to the *dpi* passed to the figure to make -it have higher resolution, so you should pass the lower number to the figure. - -The *facecolor*, *edgecolor*, *linewidth*, and *frameon* options all change the appearance of the -figure in expected ways, with *frameon* making the figure transparent if set to *False*. - -Finally, the user can specify a layout engine for the figure with the *layout* -parameter. Currently Matplotlib supplies -:ref:`"constrained" `, -:ref:`"compressed" ` and -:ref:`"tight" ` layout engines. These -rescale axes inside the Figure to prevent overlap of ticklabels, and try and align -axes, and can save significant manual adjustment of artists on a Figure for many -common cases. - -Adding Artists --------------- - -The `~.FigureBase` class has a number of methods to add artists to a `~.Figure` or -a `~.SubFigure`. By far the most common are to add Axes of various configurations -(`~.FigureBase.add_axes`, `~.FigureBase.add_subplot`, `~.FigureBase.subplots`, -`~.FigureBase.subplot_mosaic`) and subfigures (`~.FigureBase.subfigures`). Colorbars -are added to Axes or group of Axes at the Figure level (`~.FigureBase.colorbar`). -It is also possible to have a Figure-level legend (`~.FigureBase.legend`). -Other Artists include figure-wide labels (`~.FigureBase.suptitle`, -`~.FigureBase.supxlabel`, `~.FigureBase.supylabel`) and text (`~.FigureBase.text`). -Finally, low-level Artists can be added directly using `~.FigureBase.add_artist` -usually with care being taken to use the appropriate transform. Usually these -include ``Figure.transFigure`` which ranges from 0 to 1 in each direction, and -represents the fraction of the current Figure size, or ``Figure.dpi_scale_trans`` -which will be in physical units of inches from the bottom left corner of the Figure -(see :ref:`transforms_tutorial` for more details). - - -.. _saving_figures: - -Saving Figures -============== - -Finally, Figures can be saved to disk using the `~.Figure.savefig` method. -``fig.savefig('MyFigure.png', dpi=200)`` will save a PNG formatted figure to -the file ``MyFigure.png`` in the current directory on disk with 200 dots-per-inch -resolution. Note that the filename can include a relative or absolute path to -any place on the file system. - -Many types of output are supported, including raster formats like PNG, GIF, JPEG, -TIFF and vector formats like PDF, EPS, and SVG. - -By default, the size of the saved Figure is set by the Figure size (in inches) and, for the raster -formats, the *dpi*. If *dpi* is not set, then the *dpi* of the Figure is used. -Note that *dpi* still has meaning for vector formats like PDF if the Figure includes -Artists that have been :doc:`rasterized `; the -*dpi* specified will be the resolution of the rasterized objects. - -It is possible to change the size of the Figure using the *bbox_inches* argument -to savefig. This can be specified manually, again in inches. However, by far -the most common use is ``bbox_inches='tight'``. This option "shrink-wraps", trimming -or expanding as needed, the size of the figure so that it is tight around all the artists -in a figure, with a small pad that can be specified by *pad_inches*, which defaults to -0.1 inches. The dashed box in the plot below shows the portion of the figure that -would be saved if ``bbox_inches='tight'`` were used in savefig. - -.. plot:: - - import matplotlib.pyplot as plt - from matplotlib.patches import FancyBboxPatch + fig = plt.figure(figsize=(4, 2), facecolor='lightskyblue', + layout='constrained') + fig.suptitle('A nice Matplotlib Figure') + ax = fig.add_subplot() + ax.set_title('Axes', loc='left', fontstyle='oblique', fontsize='medium') - fig, ax = plt.subplots(figsize=(4, 2), facecolor='lightskyblue') - ax.set_position([0.1, 0.2, 0.8, 0.7]) - ax.set_aspect(1) - bb = ax.get_tightbbox() - bb = bb.padded(10) - fancy = FancyBboxPatch(bb.p0, bb.width, bb.height, fc='none', - ec=(0, 0.0, 0, 0.5), lw=2, linestyle='--', - transform=None, clip_on=False) - ax.add_patch(fancy) +.. toctree:: + :maxdepth: 2 -More reading -============ + Introduction to figures .. toctree:: :maxdepth: 1 - Concept: Output backends - Concept: Matplotlib Application Interfaces (APIs) - In depth: Interacting with figures - In depth: Interactive figures and asynchronous programming - In depth: Event handling - In depth: Writing a backend -- the pyplot interface + Output backends + Matplotlib Application Interfaces (APIs) + Interacting with figures + Interactive figures and asynchronous programming + Event handling + Writing a backend -- the pyplot interface pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy