8000 Merge pull request #8512 from phobson/gridspec-example · matplotlib/matplotlib@abaedab · GitHub
[go: up one dir, main page]

Skip to content

Commit abaedab

Browse files
authored
Merge pull request #8512 from phobson/gridspec-example
DOC: add quickstart section to the gridspec tutorial
2 parents 0d3beeb + e015f37 commit abaedab

File tree

1 file changed

+133
-109
lines changed

1 file changed

+133
-109
lines changed

tutorials/intermediate/gridspec.py

Lines changed: 133 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,126 +1,161 @@
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
8+
:func:`~matplotlib.pyplot.subplots`
9+
Perhaps the primary function used to create figures and axes.
10+
It's also similar to :func:`~matplotlib.pyplot.subplot`,
11+
but creates and places all axes on the figure at once.
12+
813
: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
14+
Specifies the geometry of the grid that a subplot will be
15+
placed. The number of rows and number of columns of the grid
1116
need to be set. Optionally, the subplot layout parameters
1217
(e.g., left, right, etc.) can be tuned.
1318
1419
:class:`~matplotlib.gridspec.SubplotSpec`
15-
specifies the location of the subplot in the given *GridSpec*.
20+
Specifies the location of the subplot in the given *GridSpec*.
1621
1722
:func:`~matplotlib.pyplot.subplot2grid`
18-
a helper function that is similar to :func:`~matplotlib.pyplot.subplot`
23+
A helper function that is similar to :func:`~matplotlib.pyplot.subplot`,
1924
but uses 0-based indexing and let subplot to occupy multiple cells.
25+
This function is not covered in this tutorial.
26+
2027
"""
28+
2129
import matplotlib.pyplot as plt
2230
import matplotlib.gridspec as gridspec
2331

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

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])
93125

94126
###############################################################################
95-
# Adjust GridSpec layout
96-
# ======================
127+
# Fine Adjustments to a Gridspec Layout
128+
# =====================================
97129
#
98130
# When a GridSpec is explicitly used, you can adjust the layout
99131
# parameters of subplots that are created from the GridSpec.
100132

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

105140
###############################################################################
106141
# This is similar to :func:`~matplotlib.pyplot.subplots_adjust`, but it only
107142
# affects the subplots that are created from the given GridSpec.
108143
#
109-
# For example, see this code and the resulting figure:
144+
# For example, compare the left and right sides of this figure:
110145

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

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

125160
###############################################################################
126161
# GridSpec using SubplotSpec
@@ -133,8 +168,15 @@
133168
fig = plt.figure()
134169
gs0 = gridspec.GridSpec(1, 2)
135170

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

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

185227
plt.show()
186-
187-
# GridSpec with Varying Cell Sizes
188-
# ================================
189-
#
190-
# By default, GridSpec creates cells of equal sizes. You can adjust
191 801C -
# 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