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

Skip to content

Commit 608a6e6

Browse files
jklymakQuLogic
andcommitted
ENH: Subfigures
Co-authored-by: Elliott Sales de Andrade <[email protected]>
1 parent 4438b25 commit 608a6e6

File tree

21 files changed

+2194
-1542
lines changed

21 files changed

+2194
-1542
lines changed

doc/api/figure_api.rst

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,5 @@
55
.. currentmodule:: matplotlib.figure
66

77
.. automodule:: matplotlib.figure
8-
:no-members:
9-
:no-inherited-members:
10-
11-
Classes
12-
-------
13-
14-
.. autosummary::
15-
:toctree: _as_gen/
16-
:template: autosummary.rst
17-
:nosignatures:
18-
19-
Figure
20-
SubplotParams
21-
22-
Functions
23-
---------
24-
25-
.. autosummary::
26-
:toctree: _as_gen/
27-
:template: autosummary.rst
28-
:nosignatures:
29-
30-
figaspect
8+
:members:
9+
:inherited-members:
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FigureBase class added, and Figure class made a child
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
The new subfigure feature motivated some re-organization of the
5+
`.figure.Figure` class, so that the new `.figure.SubFigure` class could have
6+
all the capabilities of a figure.
7+
8+
The `.figure.Figure` class is now a subclass of `.figure.FigureBase`, where
9+
`.figure.FigureBase` contains figure-level artist addition routines, and
10+
the `.figure.Figure` subclass just contains features that are unique to the
11+
outer figure.
12+
13+
Note that there is a new *transSubfigure* transform
14+
associated with the subfigure. This transform also exists for a
15+
`.Figure` instance, and is equal to *transFigure* in that case,
16+
so code that uses the transform stack that wants to place objects on either
17+
the parent figure or one of the subfigures should use *transSubfigure*.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
New subfigure functionality
2+
---------------------------
3+
New `.figure.Figure.add_subfigure` and `.figure.Figure.subfigures`
4+
functionalities allow creating virtual figures within figures. Similar
5+
nesting was previously done with nested gridspecs
6+
( see :doc:`/gallery/subplots_axes_and_figures/gridspec_nested`). However, this
7+
did not allow localized figure artists (i.e. a colorbar or suptitle) that
8+
only pertained to each subgridspec.
9+
10+
The new methods `.figure.Figure.add_subfigure` and `.figure.Figure.subfigures`
11+
are meant to rhyme with `.figure.Figure.add_subplot` and
12+
`.figure.Figure.subplots` and have most of the same arguments.
13+
14+
See :doc:`/gallery/subplots_axes_and_figures/subfigures`.
15+
16+
.. note::
17+
18+
The subfigure functionality is experimental API as of v3.4.
19+
20+
.. plot::
21+
22+
def example_plot(ax, fontsize=12, hide_labels=False):
23+
pc = ax.pcolormesh(np.random.randn(30, 30))
24+
if not hide_labels:
25+
ax.set_xlabel('x-label', fontsize=fontsize)
26+
ax.set_ylabel('y-label', fontsize=fontsize)
27+
ax.set_title('Title', fontsize=fontsize)
28+
return pc
29+
30+
np.random.seed(19680808)
31+
fig = plt.figure(constrained_layout=True, figsize=(10, 4))
32+
subfigs = fig.subfigures(1, 2, wspace=0.07)
33+
34+
axsLeft = subfigs[0].subplots(1, 2, sharey=True)
35+
subfigs[0].set_facecolor('0.75')
36+
for ax in axsLeft:
37+
pc = example_plot(ax)
38+
subfigs[0].suptitle('Left plots', fontsize='x-large')
39+
subfigs[0].colorbar(pc, shrink=0.6, ax=axsLeft, location='bottom')
40+
41+
axsRight = subfigs[1].subplots(3, 1, sharex=True)
42+
for nn, ax in enumerate(axsRight):
43+
pc = example_plot(ax, hide_labels=True)
44+
if nn == 2:
45+
ax.set_xlabel('xlabel')
46+
if nn == 1:
47+
ax.set_ylabel('ylabel')
48+
subfigs[1].colorbar(pc, shrink=0.6, ax=axsRight)
49+
subfigs[1].suptitle('Right plots', fontsize='x-large')
50+
51+
fig.suptitle('Figure suptitle', fontsize='xx-large')
52+
53+
plt.show()

examples/subplots_axes_and_figures/gridspec_nested.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
GridSpecs can be nested, so that a subplot from a parent GridSpec can
77
set the position for a nested grid of subplots.
88
9+
Note that the same functionality can be achieved more directly with
10+
`~.figure.FigureBase.subfigures`; see
11+
:doc:`/gallery/subplots_axes_and_figures/subfigures`.
12+
913
"""
1014
import matplotlib.pyplot as plt
1115
import matplotlib.gridspec as gridspec
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
"""
2+
=================
3+
Figure subfigures
4+
=================
5+
6+
Sometimes it is desirable to have a figure with two different layouts in it.
7+
This can be achieved with
8+
:doc:`nested gridspecs</gallery/subplots_axes_and_figures/gridspec_nested>`,
9+
but having a virtual figure with its own artists is helpful, so
10+
Matplotlib also has "subfigures", accessed by calling
11+
`matplotlib.figure.Figure.add_subfigure` in a way that is analagous to
12+
`matplotlib.figure.Figure.add_subplot`, or
13+
`matplotlib.figure.Figure.subfigures` to make an array of subfigures. Note
14+
that subfigures can also have their own child subfigures.
15+
16+
.. note::
17+
``subfigure`` is new in v3.4, and the API is still provisional.
18+
19+
"""
20+
import matplotlib.pyplot as plt
21+
import numpy as np
22+
23+
24+
def example_plot(ax, fontsize=12, hide_labels=False):
25+
pc = ax.pcolormesh(np.random.randn(30, 30), vmin=-2.5, vmax=2.5)
26+
if not hide_labels:
27+
ax.set_xlabel('x-label', fontsize=fontsize)
28+
ax.set_ylabel('y-label', fontsize=fontsize)
29+
ax.set_title('Title', fontsize=fontsize)
30+
return pc
31+
32+
np.random.seed(19680808)
33+
# gridspec inside gridspec
34+
fig = plt.figure(constrained_layout=True, figsize=(10, 4))
35+
subfigs = fig.subfigures(1, 2, wspace=0.07)
36+
37+
axsLeft = subfigs[0].subplots(1, 2, sharey=True)
38+
subfigs[0].set_facecolor('0.75')
39+
for ax in axsLeft:
40+
pc = example_plot(ax)
41+
subfigs[0].suptitle('Left plots', fontsize='x-large')
42+
subfigs[0].colorbar(pc, shrink=0.6, ax=axsLeft, location='bottom')
43+
44+
axsRight = subfigs[1].subplots(3, 1, sharex=True)
45+
for nn, ax in enumerate(axsRight):
46+
pc = example_plot(ax, hide_labels=True)
47+
if nn == 2:
48+
ax.set_xlabel('xlabel')
49+
if nn == 1:
50+
ax.set_ylabel('ylabel')
51+
52+
subfigs[1].set_facecolor('0.85')
53+
subfigs[1].colorbar(pc, shrink=0.6, ax=axsRight)
54+
subfigs[1].suptitle('Right plots', fontsize='x-large')
55+
56+
fig.suptitle('Figure suptitle', fontsize='xx-large')
57+
58+
plt.show()
59+
60+
##############################################################################
61+
# It is possible to mix subplots and subfigures using
62+
# `matplotlib.figure.Figure.add_subfigure`. This requires getting
63+
# the gridspec that the subplots are laid out on.
64+
65+
fig, axs = plt.subplots(2, 3, constrained_layout=True, figsize=(10, 4))
66+
gridspec = axs[0, 0].get_subplotspec().get_gridspec()
67+
68+
# clear the left column for the subfigure:
69+
for a in axs[:, 0]:
70+
a.remove()
71+
72+
# plot data in remaining axes:
73+
for a in axs[:, 1:].flat:
74+
a.plot(np.arange(10))
75+
76+
# make the subfigure in the empy gridspec slots:
77+
subfig = fig.add_subfigure(gridspec[:, 0])
78+
79+
axsLeft = subfig.subplots(1, 2, sharey=True)
80+
subfig.set_facecolor('0.75')
81+
for ax in axsLeft:
82+
pc = example_plot(ax)
83+
subfig.suptitle('Left plots', fontsize='x-large')
84+
subfig.colorbar(pc, shrink=0.6, ax=axsLeft, location='bottom')
85+
86+
fig.suptitle('Figure suptitle', fontsize='xx-large')
87+
plt.show()
88+
89+
##############################################################################
90+
# Subfigures can have different widths and heights. This is exactly the
91+
# same example as the first example, but *width_ratios* has been changed:
92+
93+
fig = plt.figure(constrained_layout=True, figsize=(10, 4))
94+
subfigs = fig.subfigures(1, 2, wspace=0.07, width_ratios=[2, 1])
95+
96+
axsLeft = subfigs[0].subplots(1, 2, sharey=True)
97+
subfigs[0].set_facecolor('0.75')
98+
for ax in axsLeft:
99+
pc = example_plot(ax)
100+
subfigs[0].suptitle('Left plots', fontsize='x-large')
101+
subfigs[0].colorbar(pc, shrink=0.6, ax=axsLeft, location='bottom')
102+
103+
axsRight = subfigs[1].subplots(3, 1, sharex=True)
104+
for nn, ax in enumerate(axsRight):
105+
pc = example_plot(ax, hide_labels=True)
106+
if nn == 2:
107+
ax.set_xlabel('xlabel')
108+
if nn == 1:
109+
ax.set_ylabel('ylabel')
110+
111+
subfigs[1].set_facecolor('0.85')
112+
subfigs[1].colorbar(pc, shrink=0.6, ax=axsRight)
113+
subfigs[1].suptitle('Right plots', fontsize='x-large')
114+
115+
fig.suptitle('Figure suptitle', fontsize='xx-large')
116+
117+
plt.show()
118+
119+
##############################################################################
120+
# Subfigures can be also be nested:
121+
122+
fig = plt.figure(constrained_layout=True, figsize=(10, 8))
123+
124+
fig.suptitle('fig')
125+
126+
subfigs = fig.subfigures(1, 2, wspace=0.07)
127+
128+
subfigs[0].set_facecolor('coral')
129+
subfigs[0].suptitle('subfigs[0]')
130+
131+
subfigs[1].set_facecolor('coral')
132+
subfigs[1].suptitle('subfigs[1]')
133+
134+
subfigsnest = subfigs[0].subfigures(2, 1, height_ratios=[1, 1.4])
135+
subfigsnest[0].suptitle('subfigsnest[0]')
136+
subfigsnest[0].set_facecolor('r')
137+
axsnest0 = subfigsnest[0].subplots(1, 2, sharey=True)
138+
for nn, ax in enumerate(axsnest0):
139+
pc = example_plot(ax, hide_labels=True)
140+
subfigsnest[0].colorbar(pc, ax=axsnest0)
141+
142+
subfigsnest[1].suptitle('subfigsnest[1]')
143+
subfigsnest[1].set_facecolor('g')
144+
axsnest1 = subfigsnest[1].subplots(3, 1, sharex=True)
145+
146+
axsRight = subfigs[1].subplots(2, 2)
147+
148+
plt.show()

examples/subplots_axes_and_figures/subplots_demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
# Still there remains an unused empty space between the subplots.
145145
#
146146
# To precisely control the positioning of the subplots, one can explicitly
147-
# create a `.GridSpec` with `.add_gridspec`, and then call its
147+
# create a `.GridSpec` with `.Figure.add_gridspec`, and then call its
148148
# `~.GridSpecBase.subplots` method. For example, we can reduce the height
149149
# between vertical subplots using ``add_gridspec(hspace=0)``.
150150
#

0 commit comments

Comments
 (0)