Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8a82ac1

Browse filesBrowse files
committed
DOC: cleanup constrained layout tutorial [skip actions] [skip azp] [skip appveyor]
DOC: CL - axes->Axes
1 parent d1f321f commit 8a82ac1
Copy full SHA for 8a82ac1

File tree

Expand file treeCollapse file tree

2 files changed

+80
-70
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+80
-70
lines changed

‎examples/subplots_axes_and_figures/colorbar_placement.py

Copy file name to clipboardExpand all lines: examples/subplots_axes_and_figures/colorbar_placement.py
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"""
2+
.. _colorbar_placement:
3+
24
=================
35
Placing Colorbars
46
=================

‎tutorials/intermediate/constrainedlayout_guide.py

Copy file name to clipboardExpand all lines: tutorials/intermediate/constrainedlayout_guide.py
+78-70Lines changed: 78 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,46 @@
33
Constrained Layout Guide
44
================================
55
6-
How to use constrained-layout to fit plots within your figure cleanly.
6+
Use *constrained layout* to fit plots within your figure cleanly.
77
8-
*constrained_layout* automatically adjusts subplots and decorations like
9-
legends and colorbars so that they fit in the figure window while still
10-
preserving, as best they can, the logical layout requested by the user.
8+
*Constrained layout* automatically adjusts subplots so that decorations like tick
9+
labels, legends, and colorbars do not overlap, while still preserving the
10+
logical layout requested by the user.
1111
12-
*constrained_layout* is similar to
13-
:doc:`tight_layout</tutorials/intermediate/tight_layout_guide>`,
14-
but uses a constraint solver to determine the size of axes that allows
15-
them to fit.
12+
*Constrained layout* is similar to :doc:`Tight
13+
layout</tutorials/intermediate/tight_layout_guide>`, but is substantially more
14+
flexible. It handles colorbars placed on multiple Axes
15+
(:ref:`colorbar_placement`) nested layouts (`~.Figure.subfigures`) and Axes that
16+
span rows or columns (`~.pyplot.subplot_mosaic`), striving to align spines from
17+
Axes in the same row or column. In addition, :ref:`Compressed layout
18+
<compressed_layout>` will try and move fixed aspect-ratio Axes closer together.
19+
These features are described in this document, as well as some
20+
:ref:`implementation details <cl_notes_on_algorithm>` discussed at the end.
1621
17-
*constrained_layout* typically needs to be activated before any axes are
18-
added to a figure. Two ways of doing so are
22+
*Constrained layout* typically needs to be activated before any Axes are added to
23+
a figure. Two ways of doing so are
1924
20-
* using the respective argument to :func:`~.pyplot.subplots` or
21-
:func:`~.pyplot.figure`, e.g.::
25+
* using the respective argument to `~.pyplot.subplots`,
26+
`~.pyplot.figure`, `~.pyplot.subplot_mosaic` e.g.::
2227
2328
plt.subplots(layout="constrained")
2429
25-
* activate it via :ref:`rcParams<customizing-with-dynamic-rc-settings>`,
26-
like::
30+
* activate it via :ref:`rcParams<customizing-with-dynamic-rc-settings>`, like::
2731
2832
plt.rcParams['figure.constrained_layout.use'] = True
2933
3034
Those are described in detail throughout the following sections.
3135
32-
Simple Example
36+
.. warning::
37+
38+
Calling ``plt.tight_layout()`` will turn off *constrained layout*!
39+
40+
Simple example
3341
==============
3442
35-
In Matplotlib, the location of axes (including subplots) are specified in
36-
normalized figure coordinates. It can happen that your axis labels or
37-
titles (or sometimes even ticklabels) go outside the figure area, and are thus
43+
In Matplotlib, the location of Axes (including subplots) are specified in
44+
normalized figure coordinates. It can happen that your axis labels or titles
45+
(or sometimes even ticklabels) go outside the figure area, and are thus
3846
clipped.
3947
"""
4048

@@ -67,7 +75,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
6775
example_plot(ax, fontsize=24)
6876

6977
# %%
70-
# To prevent this, the location of axes needs to be adjusted. For
78+
# To prevent this, the location of Axes needs to be adjusted. For
7179
# subplots, this can be done manually by adjusting the subplot parameters
7280
# using `.Figure.subplots_adjust`. However, specifying your figure with the
7381
# # ``layout="constrained"`` keyword argument will do the adjusting
@@ -78,7 +86,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
7886

7987
# %%
8088
# When you have multiple subplots, often you see labels of different
81-
# axes overlapping each other.
89+
# Axes overlapping each other.
8290

8391
fig, axs = plt.subplots(2, 2, layout=None)
8492
for ax in axs.flat:
@@ -93,21 +101,19 @@ def example_plot(ax, fontsize=12, hide_labels=False):
93101
example_plot(ax)
94102

95103
# %%
104+
#
96105
# Colorbars
97106
# =========
98107
#
99-
# If you create a colorbar with `.Figure.colorbar`,
100-
# you need to make room for it. ``constrained_layout`` does this
101-
# automatically. Note that if you specify ``use_gridspec=True`` it will be
102-
# ignored because this option is made for improving the layout via
103-
# ``tight_layout``.
108+
# If you create a colorbar with `.Figure.colorbar`, you need to make room for
109+
# it. *Constrained layout* does this automatically. Note that if you
110+
# specify ``use_gridspec=True`` it will be ignored because this option is made
111+
# for improving the layout via ``tight_layout``.
104112
#
105113
# .. note::
106114
#
107115
# For the `~.axes.Axes.pcolormesh` keyword arguments (``pc_kwargs``) we use a
108-
# dictionary. Below we will assign one colorbar to a number of axes each
109-
# containing a `~.cm.ScalarMappable`; specifying the norm and colormap
110-
# ensures the colorbar is accurate for all the axes.
116+
# dictionary to keep the calls consistent across this document.
111117

112118
arr = np.arange(100).reshape((10, 10))
113119
norm = mcolors.Normalize(vmin=0., vmax=100.)
@@ -118,17 +124,17 @@ def example_plot(ax, fontsize=12, hide_labels=False):
118124
fig.colorbar(im, ax=ax, shrink=0.6)
119125

120126
# %%
121-
# If you specify a list of axes (or other iterable container) to the
127+
# If you specify a list of Axes (or other iterable container) to the
122128
# ``ax`` argument of ``colorbar``, constrained_layout will take space from
123-
# the specified axes.
129+
# the specified Axes.
124130

125131
fig, axs = plt.subplots(2, 2, figsize=(4, 4), layout="constrained")
126132
for ax in axs.flat:
127133
im = ax.pcolormesh(arr, **pc_kwargs)
128134
fig.colorbar(im, ax=axs, shrink=0.6)
129135

130136
# %%
131-
# If you specify a list of axes from inside a grid of axes, the colorbar
137+
# If you specify a list of Axes from inside a grid of Axes, the colorbar
132138
# will steal space appropriately, and leave a gap, but all subplots will
133139
# still be the same size.
134140

@@ -142,7 +148,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
142148
# Suptitle
143149
# =========
144150
#
145-
# ``constrained_layout`` can also make room for `~.Figure.suptitle`.
151+
# *Constrained layout* can also make room for `~.Figure.suptitle`.
146152

147153
fig, axs = plt.subplots(2, 2, figsize=(4, 4), layout="constrained")
148154
for ax in axs.flat:
@@ -180,7 +186,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
180186
# however, that the legend's ``get_in_layout`` status will have to be
181187
# toggled again to make the saved file work, and we must manually
182188
# trigger a draw if we want constrained_layout to adjust the size
183-
# of the axes before printing.
189+
# of the Axes before printing.
184190

185191
fig, axs = plt.subplots(1, 2, figsize=(4, 2), layout="constrained")
186192

@@ -234,13 +240,13 @@ def example_plot(ax, fontsize=12, hide_labels=False):
234240
#
235241

236242
# %%
237-
# Padding and Spacing
243+
# Padding and spacing
238244
# ===================
239245
#
240-
# Padding between axes is controlled in the horizontal by *w_pad* and
246+
# Padding between Axes is controlled in the horizontal by *w_pad* and
241247
# *wspace*, and vertical by *h_pad* and *hspace*. These can be edited
242248
# via `~.layout_engine.ConstrainedLayoutEngine.set`. *w/h_pad* are
243-
# the minimum space around the axes in units of inches:
249+
# the minimum space around the Axes in units of inches:
244250

245251
fig, axs = plt.subplots(2, 2, layout="constrained")
246252
for ax in axs.flat:
@@ -274,7 +280,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
274280

275281
# %%
276282
# GridSpecs also have optional *hspace* and *wspace* keyword arguments,
277-
# that will be used instead of the pads set by ``constrained_layout``:
283+
# that will be used instead of the pads set by *constrained layout*:
278284

279285
fig, axs = plt.subplots(2, 2, layout="constrained",
280286
gridspec_kw={'wspace': 0.3, 'hspace': 0.2})
@@ -313,7 +319,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
313319
# file. They all have the prefix ``figure.constrained_layout``:
314320
#
315321
# - *use*: Whether to use constrained_layout. Default is False
316-
# - *w_pad*, *h_pad*: Padding around axes objects.
322+
# - *w_pad*, *h_pad*: Padding around Axes objects.
317323
# Float representing inches. Default is 3./72. inches (3 pts)
318324
# - *wspace*, *hspace*: Space between subplot groups.
319325
# Float representing a fraction of the subplot widths being separated.
@@ -376,7 +382,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
376382
# Note that in the above the left and right columns don't have the same
377383
# vertical extent. If we want the top and bottom of the two grids to line up
378384
# then they need to be in the same gridspec. We need to make this figure
379-
# larger as well in order for the axes not to collapse to zero height:
385+
# larger as well in order for the Axes not to collapse to zero height:
380386

381387
fig = plt.figure(figsize=(4, 6), layout="constrained")
382388

@@ -424,7 +430,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
424430

425431
# %%
426432
# Rather than using subgridspecs, Matplotlib now provides `~.Figure.subfigures`
427-
# which also work with ``constrained_layout``:
433+
# which also work with *constrained layout*:
428434

429435
fig = plt.figure(layout="constrained")
430436
sfigs = fig.subfigures(1, 2, width_ratios=[1, 2])
@@ -443,13 +449,13 @@ def example_plot(ax, fontsize=12, hide_labels=False):
443449
fig.suptitle('Nested plots using subfigures')
444450

445451
# %%
446-
# Manually setting axes positions
452+
# Manually setting Axes positions
447453
# ================================
448454
#
449455
# There can be good reasons to manually set an Axes position. A manual call
450-
# to `~.axes.Axes.set_position` will set the axes so constrained_layout has
451-
# no effect on it anymore. (Note that ``constrained_layout`` still leaves the
452-
# space for the axes that is moved).
456+
# to `~.axes.Axes.set_position` will set the Axes so constrained_layout has
457+
# no effect on it anymore. (Note that *constrained layout* still leaves the
458+
# space for the Axes that is moved).
453459

454460
fig, axs = plt.subplots(1, 2, layout="constrained")
455461
example_plot(axs[0], fontsize=12)
@@ -461,8 +467,8 @@ def example_plot(ax, fontsize=12, hide_labels=False):
461467
# Grids of fixed aspect-ratio Axes: "compressed" layout
462468
# =====================================================
463469
#
464-
# ``constrained_layout`` operates on the grid of "original" positions for
465-
# axes. However, when Axes have fixed aspect ratios, one side is usually made
470+
# *Constrained layout* operates on the grid of "original" positions for
471+
# Axes. However, when Axes have fixed aspect ratios, one side is usually made
466472
# shorter, and leaves large gaps in the shortened direction. In the following,
467473
# the Axes are square, but the figure quite wide so there is a horizontal gap:
468474

@@ -485,19 +491,19 @@ def example_plot(ax, fontsize=12, hide_labels=False):
485491

486492

487493
# %%
488-
# Manually turning off ``constrained_layout``
494+
# Manually turning off *constrained layout*
489495
# ===========================================
490496
#
491-
# ``constrained_layout`` usually adjusts the axes positions on each draw
497+
# *Constrained layout* usually adjusts the Axes positions on each draw
492498
# of the figure. If you want to get the spacing provided by
493-
# ``constrained_layout`` but not have it update, then do the initial
499+
# *Constrained layout* but not have it update, then do the initial
494500
# draw and then call ``fig.set_layout_engine('none')``.
495501
# This is potentially useful for animations where the tick labels may
496502
# change length.
497503
#
498-
# Note that ``constrained_layout`` is turned off for ``ZOOM`` and ``PAN``
504+
# Note that *Constrained layout* is turned off for ``ZOOM`` and ``PAN``
499505
# GUI events for the backends that use the toolbar. This prevents the
500-
# axes from changing position during zooming and panning.
506+
# Axes from changing position during zooming and panning.
501507
#
502508
#
503509
# Limitations
@@ -506,17 +512,17 @@ def example_plot(ax, fontsize=12, hide_labels=False):
506512
# Incompatible functions
507513
# ----------------------
508514
#
509-
# ``constrained_layout`` will work with `.pyplot.subplot`, but only if the
515+
# *Constrained layout* will work with `.pyplot.subplot`, but only if the
510516
# number of rows and columns is the same for each call.
511517
# The reason is that each call to `.pyplot.subplot` will create a new
512518
# `.GridSpec` instance if the geometry is not the same, and
513-
# ``constrained_layout``. So the following works fine:
519+
# *Constrained layout*. So the following works fine:
514520

515521
fig = plt.figure(layout="constrained")
516522

517523
ax1 = plt.subplot(2, 2, 1)
518524
ax2 = plt.subplot(2, 2, 3)
519-
# third axes that spans both rows in second column:
525+
# third Axes that spans both rows in second column:
520526
ax3 = plt.subplot(2, 2, (2, 4))
521527

522528
example_plot(ax1)
@@ -557,22 +563,22 @@ def example_plot(ax, fontsize=12, hide_labels=False):
557563
fig.suptitle('subplot2grid')
558564

559565
# %%
560-
# Other Caveats
566+
# Other caveats
561567
# -------------
562568
#
563-
# * ``constrained_layout`` only considers ticklabels, axis labels, titles, and
569+
# * *Constrained layout* only considers ticklabels, axis labels, titles, and
564570
# legends. Thus, other artists may be clipped and also may overlap.
565571
#
566572
# * It assumes that the extra space needed for ticklabels, axis labels,
567-
# and titles is independent of original location of axes. This is
573+
# and titles is independent of original location of Axes. This is
568574
# often true, but there are rare cases where it is not.
569575
#
570576
# * There are small differences in how the backends handle rendering fonts,
571577
# so the results will not be pixel-identical.
572578
#
573-
# * An artist using axes coordinates that extend beyond the axes
579+
# * An artist using Axes coordinates that extend beyond the Axes
574580
# boundary will result in unusual layouts when added to an
575-
# axes. This can be avoided by adding the artist directly to the
581+
# Axes. This can be avoided by adding the artist directly to the
576582
# :class:`~matplotlib.figure.Figure` using
577583
# :meth:`~matplotlib.figure.Figure.add_artist`. See
578584
# :class:`~matplotlib.patches.ConnectionPatch` for an example.
@@ -595,6 +601,8 @@ def example_plot(ax, fontsize=12, hide_labels=False):
595601
# not require outside data or dependencies (other than numpy).
596602

597603
# %%
604+
# .. _cl_notes_on_algorithm:
605+
#
598606
# Notes on the algorithm
599607
# ======================
600608
#
@@ -620,16 +628,16 @@ def example_plot(ax, fontsize=12, hide_labels=False):
620628
#
621629
# For a single Axes the layout is straight forward. There is one parent
622630
# layoutgrid for the figure consisting of one column and row, and
623-
# a child layoutgrid for the gridspec that contains the axes, again
631+
# a child layoutgrid for the gridspec that contains the Axes, again
624632
# consisting of one row and column. Space is made for the "decorations" on
625-
# each side of the axes. In the code, this is accomplished by the entries in
633+
# each side of the Axes. In the code, this is accomplished by the entries in
626634
# ``do_constrained_layout()`` like::
627635
#
628636
# gridspec._layoutgrid[0, 0].edit_margin_min('left',
629637
# -bbox.x0 + pos.x0 + w_pad)
630638
#
631-
# where ``bbox`` is the tight bounding box of the axes, and ``pos`` its
632-
# position. Note how the four margins encompass the axes decorations.
639+
# where ``bbox`` is the tight bounding box of the Axes, and ``pos`` its
640+
# position. Note how the four margins encompass the Axes decorations.
633641

634642
from matplotlib._layoutgrid import plot_children
635643

@@ -640,8 +648,8 @@ def example_plot(ax, fontsize=12, hide_labels=False):
640648
# %%
641649
# Simple case: two Axes
642650
# ---------------------
643-
# When there are multiple axes they have their layouts bound in
644-
# simple ways. In this example the left axes has much larger decorations
651+
# When there are multiple Axes they have their layouts bound in
652+
# simple ways. In this example the left Axes has much larger decorations
645653
# than the right, but they share a bottom margin, which is made large
646654
# enough to accommodate the larger xlabel. Same with the shared top
647655
# margin. The left and right margins are not shared, and hence are
@@ -682,16 +690,16 @@ def example_plot(ax, fontsize=12, hide_labels=False):
682690
# Uneven sized Axes
683691
# -----------------
684692
#
685-
# There are two ways to make axes have an uneven size in a
693+
# There are two ways to make Axes have an uneven size in a
686694
# Gridspec layout, either by specifying them to cross Gridspecs rows
687695
# or columns, or by specifying width and height ratios.
688696
#
689697
# The first method is used here. Note that the middle ``top`` and
690698
# ``bottom`` margins are not affected by the left-hand column. This
691699
# is a conscious decision of the algorithm, and leads to the case where
692-
# the two right-hand axes have the same height, but it is not 1/2 the height
693-
# of the left-hand axes. This is consistent with how ``gridspec`` works
694-
# without constrained layout.
700+
# the two right-hand Axes have the same height, but it is not 1/2 the height
701+
# of the left-hand Axes. This is consistent with how ``gridspec`` works
702+
# without *constrained layout*.
695703

696704
fig = plt.figure(layout="constrained")
697705
gs = gridspec.GridSpec(2, 2, figure=fig)
@@ -708,7 +716,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
708716
# constraining their width. In the case below, the right margin for column 0
709717
# and the left margin for column 3 have no margin artists to set their width,
710718
# so we take the maximum width of the margin widths that do have artists.
711-
# This makes all the axes have the same size:
719+
# This makes all the Axes have the same size:
712720

713721
fig = plt.figure(layout="constrained")
714722
gs = fig.add_gridspec(2, 4)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.