Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 608a6e6

Browse filesBrowse files
jklymakQuLogic
andcommitted
ENH: Subfigures
Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
1 parent 4438b25 commit 608a6e6
Copy full SHA for 608a6e6

File tree

Expand file treeCollapse file tree

21 files changed

+2194
-1542
lines changed
Filter options
Expand file treeCollapse file tree

21 files changed

+2194
-1542
lines changed

‎doc/api/figure_api.rst

Copy file name to clipboardExpand all lines: doc/api/figure_api.rst
+2-23Lines 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:
+17Lines 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*.
+53Lines 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

Copy file name to clipboardExpand all lines: examples/subplots_axes_and_figures/gridspec_nested.py
+4Lines 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
+148Lines 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

Copy file name to clipboardExpand all lines: examples/subplots_axes_and_figures/subplots_demo.py
+1-1Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.