Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c61077a

Browse files
authored
Merge pull request #20562 from timhoffm/doc-faq
More concise how to for subplot adjustment
2 parents 26dc10f + 53f547f commit c61077a

File tree

4 files changed

+62
-116
lines changed

4 files changed

+62
-116
lines changed

doc/faq/howto_faq.rst

Lines changed: 13 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -137,106 +137,25 @@ The same can be done using the pgf backend::
137137

138138
from matplotlib.backends.backend_pgf import PdfPages
139139

140-
.. _howto-subplots-adjust:
141140

142-
Move the edge of an axes to make room for tick labels
143-
-----------------------------------------------------
144-
145-
For subplots, you can control the default spacing on the left, right,
146-
bottom, and top as well as the horizontal and vertical spacing between
147-
multiple rows and columns using the
148-
:meth:`matplotlib.figure.Figure.subplots_adjust` method (in pyplot it
149-
is :func:`~matplotlib.pyplot.subplots_adjust`). For example, to move
150-
the bottom of the subplots up to make room for some rotated x tick
151-
labels::
141+
.. _howto-auto-adjust:
152142

153-
fig = plt.figure()
154-
fig.subplots_adjust(bottom=0.2)
155-
ax = fig.add_subplot(111)
143+
Make room for tick labels
144+
-------------------------
156145

157-
You can control the defaults for these parameters in your
158-
:file:`matplotlibrc` file; see :doc:`/tutorials/introductory/customizing`. For
159-
example, to make the above setting permanent, you would set::
160-
161-
figure.subplot.bottom : 0.2 # the bottom of the subplots of the figure
162-
163-
The other parameters you can configure are, with their defaults
164-
165-
*left* = 0.125
166-
the left side of the subplots of the figure
167-
*right* = 0.9
168-
the right side of the subplots of the figure
169-
*bottom* = 0.1
170-
the bottom of the subplots of the figure
171-
*top* = 0.9
172-
the top of the subplots of the figure
173-
*wspace* = 0.2
174-
the amount of width reserved for space between subplots,
175-
expressed as a fraction of the average axis width
176-
*hspace* = 0.2
177-
the amount of height reserved for space between subplots,
178-
expressed as a fraction of the average axis height
179-
180-
If you want additional control, you can create an
181-
:class:`~matplotlib.axes.Axes` using the
182-
:func:`~matplotlib.pyplot.axes` command (or equivalently the figure
183-
:meth:`~matplotlib.figure.Figure.add_axes` method), which allows you to
184-
specify the location explicitly::
185-
186-
ax = fig.add_axes([left, bottom, width, height])
187-
188-
where all values are in fractional (0 to 1) coordinates. See
189-
:doc:`/gallery/subplots_axes_and_figures/axes_demo` for an example of
190-
placing axes manually.
146+
By default, Matplotlib uses fixed percentage margins around subplots. This can
147+
lead to labels overlapping or being cut off at the figure boundary. There are
148+
multiple ways to fix this:
191149

192-
.. _howto-auto-adjust:
150+
- Manually adapt the subplot parameters using `.Figure.subplots_adjust` /
151+
`.pyplot.subplots_adjust`.
152+
- Use one of the automatic layout mechanisms:
193153

194-
Automatically make room for tick labels
195-
---------------------------------------
154+
- constrained layout (:doc:`/tutorials/intermediate/constrainedlayout_guide`)
155+
- tight layout (:doc:`/tutorials/intermediate/tight_layout_guide`)
196156

197-
.. note::
198-
This is now easier to handle than ever before.
199-
Calling :func:`~matplotlib.pyplot.tight_layout` or alternatively using
200-
``constrained_layout=True`` argument in :func:`~matplotlib.pyplot.subplots`
201-
can fix many common layout issues. See the
202-
:doc:`/tutorials/intermediate/tight_layout_guide` and
203-
:doc:`/tutorials/intermediate/constrainedlayout_guide` for more details.
204-
205-
The information below is kept here in case it is useful for other
206-
purposes.
207-
208-
In most use cases, it is enough to simply change the subplots adjust
209-
parameters as described in :ref:`howto-subplots-adjust`. But in some
210-
cases, you don't know ahead of time what your tick labels will be, or
211-
how large they will be (data and labels outside your control may be
212-
being fed into your graphing application), and you may need to
213-
automatically adjust your subplot parameters based on the size of the
214-
tick labels. Any :class:`~matplotlib.text.Text` instance can report
215-
its extent in window coordinates (a negative x coordinate is outside
216-
the window), but there is a rub.
217-
218-
The :class:`~matplotlib.backend_bases.RendererBase` instance, which is
219-
used to calculate the text size, is not known until the figure is
220-
drawn (:meth:`~matplotlib.figure.Figure.draw`). After the window is
221-
drawn and the text instance knows its renderer, you can call
222-
:meth:`~matplotlib.text.Text.get_window_extent`. One way to solve
223-
this chicken and egg problem is to wait until the figure is draw by
224-
connecting
225-
(:meth:`~matplotlib.backend_bases.FigureCanvasBase.mpl_connect`) to the
226-
"on_draw" signal (:class:`~matplotlib.backend_bases.DrawEvent`) and
227-
get the window extent there, and then do something with it, e.g., move
228-
the left of the canvas over; see :ref:`event-handling-tutorial`.
229-
230-
Here is an example that gets a bounding box in relative figure coordinates
231-
(0..1) of each of the labels and uses it to move the left of the subplots
232-
over so that the tick labels fit in the figure:
233-
234-
.. figure:: ../gallery/pyplots/images/sphx_glr_auto_subplots_adjust_001.png
235-
:target: ../gallery/pyplots/auto_subplots_adjust.html
236-
:align: center
237-
:scale: 50
238-
239-
Auto Subplots Adjust
157+
- Calculate good values from the size of the plot elements yourself
158+
(:doc:`/gallery/pyplots/auto_subplots_adjust`)
240159

241160
.. _howto-align-label:
242161

examples/pyplots/auto_subplots_adjust.py

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,41 @@
11
"""
2-
====================
3-
Auto Subplots Adjust
4-
====================
2+
===============================================
3+
Programmatically controlling subplot adjustment
4+
===============================================
55
6-
Automatically adjust subplot parameters. This example shows a way to determine
7-
a subplot parameter from the extent of the ticklabels using a callback on the
8-
:doc:`draw_event</users/event_handling>`.
6+
.. note::
97
10-
Note that a similar result would be achieved using `~.Figure.tight_layout`
11-
or `~.Figure.set_constrained_layout`; this example shows how one could
12-
customize the subplot parameter adjustment.
8+
This example is primarily intended to show some advanced concepts in
9+
Matplotlib.
10+
11+
If you are only looking for having enough space for your labels, it is
12+
almost always simpler and good enough to either set the subplot parameters
13+
manually using `.Figure.subplots_adjust`, or use one of the automatic
14+
layout mechanisms
15+
(:doc:`/tutorials/intermediate/constrainedlayout_guide` or
16+
:doc:`/tutorials/intermediate/tight_layout_guide`).
17+
18+
This example describes a user-defined way to read out Artist sizes and
19+
set the subplot parameters accordingly. Its main purpose is to illustrate
20+
some advanced concepts like reading out text positions, working with
21+
bounding boxes and transforms and using
22+
:ref:`events <event-handling-tutorial>`. But it can also serve as a starting
23+
point if you want to automate the layouting and need more flexibility than
24+
tight layout and constrained layout.
25+
26+
Below, we collect the bounding boxes of all y-labels and move the left border
27+
of the subplot to the right so that it leaves enough room for the union of all
28+
the bounding boxes.
29+
30+
There's one catch with calculating text bounding boxes:
31+
Querying the text bounding boxes (`.Text.get_window_extent`) needs a
32+
renderer (`.RendererBase` instance), to calculate the text size. This renderer
33+
is only available after the figure has been drawn (`.Figure.draw`).
34+
35+
A solution to this is putting the adjustment logic in a draw callback.
36+
This function is executed after the figure has been drawn. It can now check
37+
if the subplot leaves enough room for the text. If not, the subplot parameters
38+
are updated and second draw is triggered.
1339
"""
1440

1541
import matplotlib.pyplot as plt
@@ -24,15 +50,16 @@
2450
def on_draw(event):
2551
bboxes = []
2652
for label in labels:
27-
bbox = label.get_window_extent()
28-
# the figure transform goes from relative coords->pixels and we
29-
# want the inverse of that
30-
bboxi = bbox.transformed(fig.transFigure.inverted())
31-
bboxes.append(bboxi)
53+
# Bounding box in pixels
54+
bbox_px = label.get_window_extent()
55+
# Transform to relative figure coordinates. This is the inverse of
56+
# transFigure.
57+
bbox_fig = bbox_px.transformed(fig.transFigure.inverted())
58+
bboxes.append(bbox_fig)
3259
# the bbox that bounds all the bboxes, again in relative figure coords
3360
bbox = mtransforms.Bbox.union(bboxes)
3461
if fig.subplotpars.left < bbox.width:
35-
# we need to move it over
62+
# Move the subplot left edge more to the right
3663
fig.subplots_adjust(left=1.1*bbox.width) # pad a little
3764
fig.canvas.draw()
3865

tutorials/intermediate/constrainedlayout_guide.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ def example_plot(ax, fontsize=12, hide_labels=False):
7777

7878
###############################################################################
7979
# To prevent this, the location of axes needs to be adjusted. For
80-
# subplots, this can be done by adjusting the subplot params
81-
# (:ref:`howto-subplots-adjust`). However, specifying your figure with the
82-
# ``constrained_layout=True`` keyword argument will do the adjusting
83-
# automatically.
80+
# subplots, this can be done manually by adjusting the subplot parameters
81+
# using `.Figure.subplots_adjust`. However, specifying your figure with the
82+
# # ``constrained_layout=True`` keyword argument will do the adjusting
83+
# # automatically.
8484

8585
fig, ax = plt.subplots(constrained_layout=True)
8686
example_plot(ax, fontsize=24)

tutorials/intermediate/tight_layout_guide.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ def example_plot(ax, fontsize=12):
4646

4747
###############################################################################
4848
# To prevent this, the location of axes needs to be adjusted. For
49-
# subplots, this can be done by adjusting the subplot params
50-
# (:ref:`howto-subplots-adjust`). Matplotlib v1.1 introduced
51-
# `.Figure.tight_layout` that does this automatically for you.
49+
# subplots, this can be done manually by adjusting the subplot parameters
50+
# using `.Figure.subplots_adjust`. `.Figure.tight_layout` does this
51+
# automatically.
5252

5353
fig, ax = plt.subplots()
5454
example_plot(ax, fontsize=24)

0 commit comments

Comments
 (0)