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

Skip to content

Commit 1352c5c

Browse files
committed
DOC: expand gridspec tutorial
* add brief quickstart section * remove subplot2grid section * word smithing * added axes to previous examples
1 parent 3bb328f commit 1352c5c

File tree

1 file changed

+134
-109
lines changed

1 file changed

+134
-109
lines changed

tutorials/intermediate/gridspec.py

Lines changed: 134 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,126 +1,162 @@
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-
import matplotlib.pyplot as plt
22-
import matplotlib.gridspec as gridspec
2320
24-
###############################################################################
25-
# Basic Example of using subplot2grid
26-
# ===================================
27-
28-
# 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
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.
3125
32-
fig = plt.figure()
33-
ax = plt.subplot2grid((2, 2), (0, 0))
34-
35-
# is identical to
36-
37-
fig = plt.figure()
38-
ax = plt.subplot(2, 2, 1)
39-
40-
###############################################################################
41-
# Note that, unlike Matplotlib's subplot, the index starts from 0 in GridSpec.
42-
#
43-
# To create a subplot that spans multiple cells:
44-
45-
fig = plt.figure()
46-
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
47-
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
48-
49-
###############################################################################
50-
# For example, see the output of the following commands:
26+
"""
5127

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))
28+
import matplotlib.pyplot as plt
29+
import matplotlib.gridspec as gridspec
5730

58-
###############################################################################
59-
# GridSpec and SubplotSpec
60-
# ========================
31+
############################################################################
32+
# Basic Quickstart Guide
33+
# ======================
6134
#
62-
# You can create :class:`~matplotlib.gridspec.GridSpec` explicitly and use
63-
# them to create a subplot.
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`.
6437
#
65-
# For example:
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 a simple use case such as this, :mod:`~matplotlib.gridspec` is
47+
# perhaps overly verbose.
48+
# You have to create the figure and :class:`~matplotlib.gridspec.GridSpec`
49+
# instance separately, then pass elements of 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 in generally the same manner as
53+
# numpy arrays.
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 subplots 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+
# Other option is to use the ``width_ratios`` and ``height_ratios``
85+
# parameters.
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+
# For the sake of demonstration, we'll blindly create the axes within
92+
# ``for`` loops since we won't need 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 the top-level function :func:`~matplotlib.pyplot.subplots`
110+
# accepts them within the ``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()
66125

67-
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])
93126

94127
###############################################################################
95-
# Adjust GridSpec layout
96-
# ======================
128+
# Fine Adjustments to a Gridspec Layout
129+
# =====================================
97130
#
98131
# When a GridSpec is explicitly used, you can adjust the layout
99132
# parameters of subplots that are created from the GridSpec.
100133

101134
fig = plt.figure()
102-
gs1 = gridspec.GridSpec(3, 3)
103-
gs1.update(left=0.05, right=0.48, wspace=0.05)
135+
gs1 = gridspec.GridSpec(nrows=3, ncols=3, left=0.05, right=0.48, wspace=0.05)
136+
ax1 = fig.add_subplot(gs1[:-1, :])
137+
ax2 = fig.add_subplot(gs1[-1, :-1])
138+
ax3 = fig.add_subplot(gs1[-1, -1])
139+
104140

105141
###############################################################################
106142
# This is similar to :func:`~matplotlib.pyplot.subplots_adjust`, but it only
107143
# affects the subplots that are created from the given GridSpec.
108144
#
109-
# For example, see this code and the resulting figure:
145+
# For example, compare the left and right sides of this figure:
110146

111147
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])
148+
gs1 = gridspec.GridSpec(nrows=3, ncols=3, left=0.05, right=0.48,
149+
wspace=0.05)
150+
ax1 = fig.add_subplot(gs1[:-1, :])
151+
ax2 = fig.add_subplot(gs1[-1, :-1])
152+
ax3 = fig.add_subplot(gs1[-1, -1])
117153

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])
154+
155+
gs2 = gridspec.GridSpec(nrows=3, ncols=3, left=0.55, right=0.98,
156+
hspace=0.05)
157+
ax4 = fig.add_subplot(gs2[:, :-1])
158+
ax5 = fig.add_subplot(gs2[:-1, -1])
159+
ax6 = fig.add_subplot(gs2[-1, -1])
124160

125161
###############################################################################
126162
# GridSpec using SubplotSpec
@@ -133,8 +169,15 @@
133169
fig = plt.figure()
134170
gs0 = gridspec.GridSpec(1, 2)
135171

136-
gs00 = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=gs0[0])
137-
gs01 = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=gs0[1])
172+
gs00 = gridspec.GridSpecFromSubplotSpec(2, 3, subplot_spec=gs0[0])
173+
gs01 = gridspec.GridSpecFromSubplotSpec(3, 2, subplot_spec=gs0[1])
174+
175+
for a in range(2):
176+
for b in range(3):
177+
fig.add_subplot(gs00[a, b])
178+
fig.add_subplot(gs01[b, a])
179+
180+
fig.tight_layout()
138181

139182
###############################################################################
140183
# A Complex Nested GridSpec using SubplotSpec
@@ -183,21 +226,3 @@ def squiggle_xy(a, b, c, d, i=np.arange(0.0, 2*np.pi, 0.05)):
183226
ax.spines['right'].set_visible(True)
184227

185228
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