|
1 | 1 | """
|
2 |
| -============================================== |
3 |
| -Customizing Location of Subplot Using GridSpec |
4 |
| -============================================== |
| 2 | +============================================================= |
| 3 | +Customizing Figure Layouts Using GridSpec and Other Functions |
| 4 | +============================================================= |
5 | 5 |
|
6 | 6 | How to create grid-shaped combinations of axes.
|
7 | 7 |
|
8 | 8 | :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 |
11 | 11 | need to be set. Optionally, the subplot layout parameters
|
12 | 12 | (e.g., left, right, etc.) can be tuned.
|
13 | 13 |
|
14 | 14 | :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*. |
16 | 16 |
|
17 | 17 | :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`, |
19 | 19 | 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 | +
|
20 | 26 | """
|
| 27 | + |
21 | 28 | import matplotlib.pyplot as plt
|
22 | 29 | import matplotlib.gridspec as gridspec
|
23 | 30 |
|
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() |
27 | 125 |
|
| 126 | + |
| 127 | +############################################################################### |
| 128 | +# Using subplot2grid |
| 129 | +# ================== |
| 130 | +# |
28 | 131 | # 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: |
31 | 134 |
|
32 | 135 | fig = plt.figure()
|
33 |
| -ax = plt.subplot2grid((2, 2), (0, 0)) |
| 136 | +ax = plt.subplot2grid((2, 2), (0, 0), fig=fig) |
| 137 | + |
34 | 138 |
|
35 |
| -# is identical to |
| 139 | +############################################################################### |
| 140 | +# The example above is the same as the more common approach shown below. |
36 | 141 |
|
37 | 142 | fig = plt.figure()
|
38 |
| -ax = plt.subplot(2, 2, 1) |
| 143 | +ax = fig.add_subplot(2, 2, 1) |
39 | 144 |
|
40 | 145 | ###############################################################################
|
41 | 146 | # Note that, unlike Matplotlib's subplot, the index starts from 0 in GridSpec.
|
42 | 147 | #
|
43 | 148 | # To create a subplot that spans multiple cells:
|
44 | 149 |
|
45 | 150 | 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) |
48 | 153 |
|
49 | 154 | ###############################################################################
|
50 | 155 | # For example, see the output of the following commands:
|
51 | 156 |
|
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 |
| - |
67 | 157 | 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() |
93 | 164 |
|
94 | 165 | ###############################################################################
|
95 |
| -# Adjust GridSpec layout |
96 |
| -# ====================== |
| 166 | +# Fine Adjustments to a Gridspec Layout |
| 167 | +# ===================================== |
97 | 168 | #
|
98 | 169 | # When a GridSpec is explicitly used, you can adjust the layout
|
99 | 170 | # parameters of subplots that are created from the GridSpec.
|
100 | 171 |
|
101 | 172 | 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) |
104 | 174 |
|
105 | 175 | ###############################################################################
|
106 | 176 | # This is similar to :func:`~matplotlib.pyplot.subplots_adjust`, but it only
|
107 | 177 | # affects the subplots that are created from the given GridSpec.
|
108 | 178 | #
|
109 |
| -# For example, see this code and the resulting figure: |
| 179 | +# For example, compare the left and right sides of this figure: |
110 | 180 |
|
111 | 181 | 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]) |
117 | 187 |
|
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]) |
124 | 194 |
|
125 | 195 | ###############################################################################
|
126 | 196 | # GridSpec using SubplotSpec
|
@@ -183,21 +253,3 @@ def squiggle_xy(a, b, c, d, i=np.arange(0.0, 2*np.pi, 0.05)):
|
183 | 253 | ax.spines['right'].set_visible(True)
|
184 | 254 |
|
185 | 255 | 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