3
3
Constrained Layout Guide
4
4
================================
5
5
6
- How to use constrained- layout to fit plots within your figure cleanly.
6
+ Use Constrained layout to fit plots within your figure cleanly.
7
7
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.
11
11
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.
16
21
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
19
24
20
25
* using the respective argument to :func:`~.pyplot.subplots` or
21
26
:func:`~.pyplot.figure`, e.g.::
22
27
23
28
plt.subplots(layout="constrained")
24
29
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::
27
31
28
32
plt.rcParams['figure.constrained_layout.use'] = True
29
33
30
34
Those are described in detail throughout the following sections.
31
35
36
+ .. warning::
37
+
38
+ Calling ``plt.tight_layout()`` will turn off Constrained layout!
39
+
32
40
Simple Example
33
41
==============
34
42
35
43
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
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
38
46
clipped.
39
47
"""
40
48
@@ -92,22 +100,18 @@ def example_plot(ax, fontsize=12, hide_labels=False):
92
100
for ax in axs .flat :
93
101
example_plot (ax )
94
102
95
- # %%
96
- # Colorbars
103
+ # %% Colorbars
97
104
# =========
98
105
#
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``.
106
+ # If you create a colorbar with `.Figure.colorbar`, you need to make room for
107
+ # it. Constrained layout does this automatically. Note that if you
108
+ # specify ``use_gridspec=True`` it will be ignored because this option is made
109
+ # for improving the layout via ``tight_layout``.
104
110
#
105
111
# .. note::
106
112
#
107
113
# 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.
114
+ # dictionary to keep the calls consistent across this document.
111
115
112
116
arr = np .arange (100 ).reshape ((10 , 10 ))
113
117
norm = mcolors .Normalize (vmin = 0. , vmax = 100. )
@@ -142,7 +146,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
142
146
# Suptitle
143
147
# =========
144
148
#
145
- # ``constrained_layout`` can also make room for `~.Figure.suptitle`.
149
+ # Constrained layout can also make room for `~.Figure.suptitle`.
146
150
147
151
fig , axs = plt .subplots (2 , 2 , figsize = (4 , 4 ), layout = "constrained" )
148
152
for ax in axs .flat :
@@ -274,7 +278,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
274
278
275
279
# %%
276
280
# GridSpecs also have optional *hspace* and *wspace* keyword arguments,
277
- # that will be used instead of the pads set by ``constrained_layout`` :
281
+ # that will be used instead of the pads set by Constrained layout :
278
282
279
283
fig , axs = plt .subplots (2 , 2 , layout = "constrained" ,
280
284
gridspec_kw = {'wspace' : 0.3 , 'hspace' : 0.2 })
@@ -424,7 +428,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
424
428
425
429
# %%
426
430
# Rather than using subgridspecs, Matplotlib now provides `~.Figure.subfigures`
427
- # which also work with ``constrained_layout`` :
431
+ # which also work with Constrained layout :
428
432
429
433
fig = plt .figure (layout = "constrained" )
430
434
sfigs = fig .subfigures (1 , 2 , width_ratios = [1 , 2 ])
@@ -448,7 +452,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
448
452
#
449
453
# There can be good reasons to manually set an Axes position. A manual call
450
454
# 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
455
+ # no effect on it anymore. (Note that Constrained layout still leaves the
452
456
# space for the axes that is moved).
453
457
454
458
fig , axs = plt .subplots (1 , 2 , layout = "constrained" )
@@ -461,7 +465,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
461
465
# Grids of fixed aspect-ratio Axes: "compressed" layout
462
466
# =====================================================
463
467
#
464
- # ``constrained_layout`` operates on the grid of "original" positions for
468
+ # Constrained layout operates on the grid of "original" positions for
465
469
# axes. However, when Axes have fixed aspect ratios, one side is usually made
466
470
# shorter, and leaves large gaps in the shortened direction. In the following,
467
471
# the Axes are square, but the figure quite wide so there is a horizontal gap:
@@ -485,17 +489,17 @@ def example_plot(ax, fontsize=12, hide_labels=False):
485
489
486
490
487
491
# %%
488
- # Manually turning off ``constrained_layout``
492
+ # Manually turning off Constrained layout
489
493
# ===========================================
490
494
#
491
- # ``constrained_layout`` usually adjusts the axes positions on each draw
495
+ # Constrained layout usually adjusts the axes positions on each draw
492
496
# of the figure. If you want to get the spacing provided by
493
- # ``constrained_layout`` but not have it update, then do the initial
497
+ # Constrained layout but not have it update, then do the initial
494
498
# draw and then call ``fig.set_layout_engine(None)``.
495
499
# This is potentially useful for animations where the tick labels may
496
500
# change length.
497
501
#
498
- # Note that ``constrained_layout`` is turned off for ``ZOOM`` and ``PAN``
502
+ # Note that Constrained layout is turned off for ``ZOOM`` and ``PAN``
499
503
# GUI events for the backends that use the toolbar. This prevents the
500
504
# axes from changing position during zooming and panning.
501
505
#
@@ -506,11 +510,11 @@ def example_plot(ax, fontsize=12, hide_labels=False):
506
510
# Incompatible functions
507
511
# ----------------------
508
512
#
509
- # ``constrained_layout`` will work with `.pyplot.subplot`, but only if the
513
+ # Constrained layout will work with `.pyplot.subplot`, but only if the
510
514
# number of rows and columns is the same for each call.
511
515
# The reason is that each call to `.pyplot.subplot` will create a new
512
516
# `.GridSpec` instance if the geometry is not the same, and
513
- # ``constrained_layout`` . So the following works fine:
517
+ # Constrained layout . So the following works fine:
514
518
515
519
fig = plt .figure (layout = "constrained" )
516
520
@@ -560,7 +564,7 @@ def example_plot(ax, fontsize=12, hide_labels=False):
560
564
# Other Caveats
561
565
# -------------
562
566
#
563
- # * ``constrained_layout`` only considers ticklabels, axis labels, titles, and
567
+ # * Constrained layout only considers ticklabels, axis labels, titles, and
564
568
# legends. Thus, other artists may be clipped and also may overlap.
565
569
#
566
570
# * It assumes that the extra space needed for ticklabels, axis labels,
@@ -595,6 +599,8 @@ def example_plot(ax, fontsize=12, hide_labels=False):
595
599
# not require outside data or dependencies (other than numpy).
596
600
597
601
# %%
602
+ # .. _cl_notes_on_algorithm:
603
+ #
598
604
# Notes on the algorithm
599
605
# ======================
600
606
#
0 commit comments