8000 DOC: expand gridspec tutorial · matplotlib/matplotlib@14a80bb · GitHub
[go: up one dir, main page]

Skip to content

Commit 14a80bb

Browse files
committed
DOC: expand gridspec tutorial
1 parent 3bb328f commit 14a80bb

File tree

1 file changed

+143
-91
lines changed

1 file changed

+143
-91
lines changed

tutorials/intermediate/gridspec.py

Lines changed: 143 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,126 +1,196 @@
11
"""
2-
==============================================
3-
Customizing Location of Subplot Using GridSpec
4-
==============================================
2+
=============================================================
3+
Customizing Figure Layouts Using GridSpec and Other Functions
4+
=============================================================
55
66
How to create grid-shaped combinations of axes.
77
88
:class:`~matplotlib.gridspec.GridSpec`
9-
specifies the geometry of the grid that a subplot will be
10-
placed in. The number of rows and number of columns of the grid
9+
Specifies the geometry of the grid that a subplot will be
10+
placed. The number of rows and number of columns of the grid
1111
need to be set. Optionally, the subplot layout parameters
1212
(e.g., left, right, etc.) can be tuned.
1313
1414
:class:`~matplotlib.gridspec.SubplotSpec`
15-
specifies the location of the subplot in the given *GridSpec*.
15+
Specifies the location of the subplot in the given *GridSpec*.
1616
1717
:func:`~matplotlib.pyplot.subplot2grid`
18-
a helper function that is similar to :func:`~matplotlib.pyplot.subplot`
18+
A helper function that is similar to :func:`~matplotlib.pyplot.subplot`,
1919
but uses 0-based indexing and let subplot to occupy multiple cells.
20+
21+
:func:`~matplotlib.pyplot.subplots`
22+
perhaps the primary function used to create figures and axes.
23+
It's also similar to :func:`~matplotlib.pyplot.subplot`,
24+
but creates and places all axes on the figure at once.
25+
2026
"""
27+
2128
import matplotlib.pyplot as plt
2229
import matplotlib.gridspec as gridspec
2330

24-
###############################################################################
25-
# Basic Example of using subplot2grid
26-
# ===================================
31+
############################################################################
32+
# Basic Quickstart Guide
33+
# ======================
34+
#
35+
# These first two examples show how to create a basic 4-by-4 grid using
36+
# both :func:`~matplotlib.pyplot.subplots` and :mod:`~matplotlib.gridspec`.
37+
#
38+
# Using :func:`~matplotlib.pyplot.subplots` is quite simple.
39+
# It returns a :class:`~matplotlib.figure.Figure` instance and an array of
40+
# :class:`~matplotlib.axes.Axes` objects.
41+
42+
fig1, f1_axes = plt.subplots(ncols=2, nrows=2)
43+
fig1.tight_layout()
44+
45+
############################################################################
46+
# For such a simple use case, :mod:`~matplotlib.gridspec` is perhaps overly
47+
# verbose.
48+
# You have to create the figure and :class:`~matplotlib.gridspec.GridSpec`
49+
# instance separately, then pass the elements gridspec instance to the
50+
# :func:`~matplotlib.figure.Figure.add_subplot` method to create the axes
51+
# objects.
52+
# The elements of the gridspec are accessed as if they where elements of
53+
# a numpy array of the same shape.
54+
55+
fig2 = plt.figure()
56+
spec2 = gridspec.GridSpec(ncols=2, nrows=2)
57+
f2_ax1 = fig2.add_subplot(spec2[0, 0])
58+
f2_ax2 = fig2.add_subplot(spec2[0, 1])
59+
f2_ax3 = fig2.add_subplot(spec2[1, 0])
60+
f2_ax4 = fig2.add_subplot(spec2[1, 1])
61+
fig2.tight_layout()
62+
63+
#############################################################################
64+
# When you want to have plots of different sizes, however,
65+
# :mod:`~matplotlib.gridspec` becomes indispensable and provides a couple
66+
# of options.
67+
# The method shown here initializes a uniform grid specification,
68+
# and then uses typical numpy indexing and slices to allocate multiple
69+
# "cells" for a given subplot.
70+
71+
fig3 = plt.figure()
72+
spec3 = gridspec.GridSpec(ncols=3, nrows=3)
73+
anno_opts = dict(xy=(0.5, 0.5), xycoords='axes fraction',
74+
va='center', ha='center')
75+
76+
fig3.add_subplot(spec3[0, 0]).annotate('GridSpec[0, 0]', **anno_opts)
77+
fig3.add_subplot(spec3[0, 1:]).annotate('GridSpec[0, 1:]', **anno_opts)
78+
fig3.add_subplot(spec3[1:, 0]).annotate('GridSpec[1:, 0]', **anno_opts)
79+
fig3.add_subplot(spec3[1:, 1:]).annotate('GridSpec[1:, 1:]', **anno_opts)
80+
81+
fig3.tight_layout()
82+
83+
############################################################################
84+
# This example shows off using the ``width_ratios`` and ``height_ratios``
85+
# options.
86+
# These keyword arguments are lists of numbers.
87+
# Note that absolute values are meaningless, only their relative ratios
88+
# matter.
89+
# That means that ``width_ratios=[2, 4, 8]`` is equivalent to
90+
# ``width_ratios=[1, 2, 4]`` within equally wide figures.
91+
# We'll blindly create the axes within ``for`` loops since we won't need
92+
# them later.
93+
94+
fig4 = plt.figure()
95+
widths = [2, 3, 1.5]
96+
heights = [1, 3, 2]
97+
spec4 = gridspec.GridSpec(ncols=3, nrows=3, width_ratios=widths,
98+
height_ratios=heights)
99+
for row in range(3):
100+
for col in range(3):
101+
ax = fig4.add_subplot(spec4[row, col])
102+
label = 'Width: {}\nHeight: {}'.format(widths[col], heights[row])
103+
ax.annotate(label, (0.1, 0.5), xycoords='axes fraction', va='center')
104+
105+
fig4.tight_layout()
106+
107+
############################################################################
108+
# Learning to use ``width_ratios`` and ``height_ratios`` is particularly
109+
# useful since :func:`~matplotlib.pyplot.subplots` accepts them within the
110+
# ``gridspec_kw`` parameter.
111+
# For that matter, any parameter accepted by
112+
# :class:`~matplotlib.gridspec.GridSpec` can be passed to
113+
# :func:`~matplotlib.pyplot.subplots` via the ``gridspec_kw`` parameter.
114+
# This example recreates the previous figure without directly using a
115+
# gridspec instance.
116+
117+
gs_kw = dict(width_ratios=widths, height_ratios=heights)
118+
fig5, f5_axes = plt.subplots(ncols=3, nrows=3, gridspec_kw=gs_kw)
119+
for r, row in enumerate(f5_axes):
120+
for c, ax in enumerate(row):
121+
label = 'Width: {}\nHeight: {}'.format(widths[c], heights[r])
122+
ax.annotate(label, (0.1, 0.5), xycoords='axes fraction', va='center')
123+
124+
fig5.tight_layout()
27125

126+
127+
###############################################################################
128+
# Using subplot2grid
129+
# ==================
130+
#
28131
# To use :func:`~matplotlib.pyplot.subplot2grid`, you provide geometry of
29-
# the grid and the location of the subplot in the grid. For a simple
30-
# single-cell subplot
132+
# the grid and the location of the subplot in the grid.
133+
# For a simple single-cell subplot:
31134

32135
fig = plt.figure()
33-
ax = plt.subplot2grid((2, 2), (0, 0))
136+
ax = plt.subplot2grid((2, 2), (0, 0), fig=fig)
137+
34138

35-
# is identical to
139+
###############################################################################
140+
# The example above is the same as the more common approach shown below.
36141

37142
fig = plt.figure()
38-
ax = plt.subplot(2, 2, 1)
143+
ax = fig.add_subplot(2, 2, 1)
39144

40145
###############################################################################
41146
# Note that, unlike Matplotlib's subplot, the index starts from 0 in GridSpec.
42147
#
43148
# To create a subplot that spans multiple cells:
44149

45150
fig = plt.figure()
46-
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
47-
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
151+
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2, fig=fig)
152+
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2, fig=fig)
48153

49154
###############################################################################
50155
# For example, see the output of the following commands:
51156

52-
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3)
53-
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
54-
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
55-
ax4 = plt.subplot2grid((3, 3), (2, 0))
56-
ax5 = plt.subplot2grid((3, 3), (2, 1))
57-
58-
###############################################################################
59-
# GridSpec and SubplotSpec
60-
# ========================
61-
#
62-
# You can create :class:`~matplotlib.gridspec.GridSpec` explicitly and use
63-
# them to create a subplot.
64-
#
65-
# For example:
66-
67157
fig = plt.figure()
68-
ax = plt.subplot2grid((2, 2), (0, 0))
69-
70-
# is equal to:
71-
72-
fig = plt.figure()
73-
gs = gridspec.GridSpec(2, 2)
74-
ax = plt.subplot(gs[0, 0])
75-
76-
# A GridSpec instance provides array-like (2d or 1d) indexing that
77-
# returns the SubplotSpec instance. For a SubplotSpec that spans multiple
78-
# cells, use slice.
79-
80-
ax2 = plt.subplot(gs[1, :-1])
81-
ax3 = plt.subplot(gs[1:, -1])
82-
83-
###############################################################################
84-
# The above example becomes
85-
86-
fig = plt.figure()
87-
gs = gridspec.GridSpec(3, 3)
88-
ax1 = plt.subplot(gs[0, :])
89-
ax2 = plt.subplot(gs[1, :-1])
90-
ax3 = plt.subplot(gs[1:, -1])
91-
ax4 = plt.subplot(gs[-1, 0])
92-
ax5 = plt.subplot(gs[-1, -2])
158+
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3, fig=fig)
159+
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2, fig=fig)
160+
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2, fig=fig)
161+
ax4 = plt.subplot2grid((3, 3), (2, 0), fig=fig)
162+
ax5 = plt.subplot2grid((3, 3), (2, 1), fig=fig)
163+
fig.tight_layout()
93164

94165
###############################################################################
95-
# Adjust GridSpec layout
96-
# ======================
166+
# Fine Adjustments to a Gridspec Layout
167+
# =====================================
97168
#
98169
# When a GridSpec is explicitly used, you can adjust the layout
99170
# parameters of subplots that are created from the GridSpec.
100171

101172
fig = plt.figure()
102-
gs1 = gridspec.GridSpec(3, 3)
103-
gs1.update(left=0.05, right=0.48, wspace=0.05)
173+
gs1 = gridspec.GridSpec(nrows=3, ncols=3, left=0.05, right=0.48, wspace=0.05)
104174

105175
###############################################################################
106176
# This is similar to :func:`~matplotlib.pyplot.subplots_adjust`, but it only
107177
# affects the subplots that are created from the given GridSpec.
108178
#
109-
# For example, see this code and the resulting figure:
179+
# For example, compare the left and right sides of this figure:
110180

111181
fig = plt.figure()
112-
gs1 = gridspec.GridSpec(3, 3)
113-
gs1.update(left=0.05, right=0.48, wspace=0.05)
114-
ax1 = plt.subplot(gs1[:-1, :])
115-
ax2 = plt.subplot(gs1[-1, :-1])
116-
ax3 = plt.subplot(gs1[-1, -1])
182+
gs1 = gridspec.GridSpec(nrows=3, ncols=3, left=0.05, right=0.48,
183+
wspace=0.05, fig=fig)
184+
ax1 = fig.add_subplot(gs1[:-1, :])
185+
ax2 = fig.add_subplot(gs1[-1, :-1])
186+
ax3 = fig.add_subplot(gs1[-1, -1])
117187

118-
fig = plt.figure()
119-
gs2 = gridspec.GridSpec(3, 3)
120-
gs2.update(left=0.55, right=0.98, hspace=0.05)
121-
ax4 = plt.subplot(gs2[:, :-1])
122-
ax5 = plt.subplot(gs2[:-1, -1])
123-
ax6 = plt.subplot(gs2[-1, -1])
188+
189+
gs2 = gridspec.GridSpec(nrows=3, ncols=3, left=0.55, right=0.98,
190+
hspace=0.05, fig=fig)
191+
ax4 = fig.add_subplot(gs2[:, :-1])
192+
ax5 = fig.add_subplot(gs2[:-1, -1])
193+
ax6 = fig.add_subplot(gs2[-1, -1])
124194

125195
###############################################################################
126196
# GridSpec using SubplotSpec
@@ -183,21 +253,3 @@ def squiggle_xy(a, b, c, d, i=np.arange(0.0, 2*np.pi, 0.05)):
183253
ax.spines['right'].set_visible(True)
184254

185255
plt.show()
186-
187-
# GridSpec with Varying Cell Sizes
188-
# ================================
189-
#
190-
# By default, GridSpec creates cells of equal sizes. You can adjust
191-
# relative heights and widths of rows and columns. Note that absolute
192-
# values are meaningless, only their relative ratios matter.
193-
194-
fig = plt.figure()
195-
gs = gridspec.GridSpec(2, 2,
196-
width_ratios=[1, 2],
197-
height_ratios=[4, 1]
198-
)
199-
200-
ax1 = plt.subplot(gs[0])
201-
ax2 = plt.subplot(gs[1])
202-
ax3 = plt.subplot(gs[2])
203-
ax4 = plt.subplot(gs[3])

0 commit comments

Comments
 (0)
0