Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit1e3b3e7

Browse files
committed
Added an initial example and amended _do_layout.
1 parentd53576b commit1e3b3e7

File tree

5 files changed

+410
-25
lines changed

5 files changed

+410
-25
lines changed
Lines changed: 399 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,399 @@
1+
"""
2+
=================
3+
Subfigure mosaic
4+
=================
5+
6+
This example is inspired by the `subplot_mosaic()
7+
<https://matplotlib.org/devdocs/users/explain/axes/mosaic.html>`__
8+
and `subfigures()
9+
<https://matplotlib.org/devdocs/gallery/subplots_axes_and_figures/subfigures.html>`__
10+
examples. It especially aims to mimic the former. Most of the API
11+
that is going to be described below is analogous to the `.Figure.subplot_mosaic` API.
12+
13+
`.Figure.subfigure_mosaic` provides a simple way of constructing
14+
complex layouts, such as SubFigures that span multiple columns / rows
15+
of the layout or leave some areas of the Figure blank. The layouts are
16+
constructed either through ASCII art or nested lists.
17+
18+
This interface naturally supports naming your SubFigures. `.Figure.subfigure_mosaic`
19+
returns a dictionary keyed on the labels used to lay out the Figure.
20+
"""
21+
importmatplotlib.pyplotasplt
22+
importnumpyasnp
23+
24+
25+
# Let's define a function to help visualize
26+
defidentify_subfigs(subfig_dict,fontsize=36):
27+
"""
28+
Helper to identify the SubFigures in the examples below.
29+
30+
Draws the label in a large font in the center of the SubFigure.
31+
32+
Parameters
33+
----------
34+
subfig_dict : dict[str, SubFigure]
35+
Mapping between the title / label and the SubFigures.
36+
fontsize : int, optional
37+
How big the label should be.
38+
"""
39+
kw=dict(ha="center",va="center",fontsize=fontsize,color="darkgrey")
40+
fork,subfiginsubfig_dict.items():
41+
subfig.text(0.5,0.5,k,**kw)
42+
43+
44+
# %%
45+
# If we want a 2x2 grid we can use `.Figure.subfigures` which returns a 2D array
46+
# of `.figure.SubFigure` which we can index.
47+
48+
fig=plt.figure()
49+
subfigs=fig.subfigures(2,2)
50+
51+
subfigs[0,0].set_edgecolor('black')
52+
subfigs[0,0].set_linewidth(2.1)
53+
subfigs[1,1].set_edgecolor('yellow')
54+
subfigs[1,1].set_linewidth(2.1)
55+
subfigs[0,1].set_facecolor('green')
56+
57+
identify_subfigs(
58+
{(j,k):aforj,rinenumerate(subfigs)fork,ainenumerate(r)},
59+
)
60+
61+
# %%
62+
# Using `.Figure.subfigure_mosaic` we can produce the same mosaic but give the
63+
# SubFigures names
64+
65+
fig=plt.figure()
66+
subfigs=fig.subfigure_mosaic(
67+
[
68+
["First","Second"],
69+
["Third","Fourth"],
70+
],
71+
)
72+
subfigs["First"].set_edgecolor('black')
73+
subfigs["First"].set_linewidth(2.1)
74+
subfigs["Second"].set_facecolor('green')
75+
subfigs["Fourth"].set_edgecolor('yellow')
76+
subfigs["Fourth"].set_linewidth(2.1)
77+
78+
identify_subfigs(subfigs)
79+
80+
# %%
81+
# A key difference between `.Figure.subfigures` and
82+
# `.Figure.subfigure_mosaic` is the return value. While the former
83+
# returns an array for index access, the latter returns a dictionary
84+
# mapping the labels to the `.figure.SubFigure` instances created
85+
86+
print(subfigs)
87+
88+
# %%
89+
# String short-hand
90+
# =================
91+
#
92+
# By restricting our labels to single characters we can
93+
# "draw" the SubFigures we want as "ASCII art". The following
94+
95+
96+
mosaic="""
97+
AB
98+
CD
99+
"""
100+
101+
# %%
102+
# will give us 4 SubFigures laid out in a 2x2 grid and generate the same
103+
# subfigure mosaic as above (but now labeled with ``{"A", "B", "C",
104+
# "D"}`` rather than ``{"First", "Second", "Third", "Fourth"}``).
105+
# Bear in mind that subfigures do not come 'visible' the way subplots do.
106+
# In case you want them to be clearly visible - you will need to set certain
107+
# keyword arguments (such as edge/face color). This is discussed at length in the
108+
# :ref:`controlling-creation` part of this example.
109+
110+
fig=plt.figure()
111+
subfigs=fig.subfigure_mosaic(mosaic)
112+
identify_subfigs(subfigs)
113+
114+
# %%
115+
# Alternatively, you can use the more compact string notation:
116+
mosaic="AB;CD"
117+
118+
# %%
119+
# will give you the same composition, where the ``";"`` is used
120+
# as the row separator instead of newline.
121+
122+
fig=plt.figure()
123+
subfigs=fig.subfigure_mosaic(mosaic)
124+
identify_subfigs(subfigs)
125+
126+
# %%
127+
# SubFigures spanning multiple rows/columns
128+
# =========================================
129+
#
130+
# Something we can do with `.Figure.subfigure_mosaic`, that we cannot
131+
# do with `.Figure.subfigures`, is to specify that a SubFigure should span
132+
# several rows or columns.
133+
134+
135+
# %%
136+
# If we want to re-arrange our four SubFigures to have ``"C"`` be a horizontal
137+
# span on the bottom and ``"D"`` be a vertical span on the right we would do:
138+
139+
subfigs=plt.figure().subfigure_mosaic(
140+
"""
141+
ABD
142+
CCD
143+
"""
144+
)
145+
146+
# setting edges for clarity
147+
forsfinsubfigs.values():
148+
sf.set_edgecolor('black')
149+
sf.set_linewidth(2.1)
150+
151+
identify_subfigs(subfigs)
152+
153+
# %%
154+
# If we do not want to fill in all the spaces in the Figure with SubFigures,
155+
# we can specify some spaces in the grid to be blank, like so:
156+
157+
subfigs=plt.figure().subfigure_mosaic(
158+
"""
159+
A.C
160+
BBB
161+
.D.
162+
"""
163+
)
164+
165+
# setting edges for clarity
166+
forsfinsubfigs.values():
167+
sf.set_edgecolor('black')
168+
sf.set_linewidth(2.1)
169+
170+
identify_subfigs(subfigs)
171+
172+
# %%
173+
# If we prefer to use another character (rather than a period ``"."``)
174+
# to mark the empty space, we can use *empty_sentinel* to specify the
175+
# character to use.
176+
177+
subfigs=plt.figure().subfigure_mosaic(
178+
"""
179+
aX
180+
Xb
181+
""",
182+
empty_sentinel="X",
183+
)
184+
185+
# setting edges for clarity
186+
forsfinsubfigs.values():
187+
sf.set_edgecolor('black')
188+
sf.set_linewidth(2.1)
189+
identify_subfigs(subfigs)
190+
191+
# %%
192+
#
193+
# Internally there is no meaning attached to the letters we use, any
194+
# Unicode code point is valid!
195+
196+
subfigs=plt.figure().subfigure_mosaic(
197+
"""αя
198+
ℝ☢"""
199+
)
200+
201+
# setting edges for clarity
202+
forsfinsubfigs.values():
203+
sf.set_edgecolor('black')
204+
sf.set_linewidth(2.1)
205+
identify_subfigs(subfigs)
206+
207+
# %%
208+
# It is not recommended to use white space as either a label or an
209+
# empty sentinel with the string shorthand because it may be stripped
210+
# while processing the input.
211+
#
212+
# Controlling mosaic creation
213+
# ===========================
214+
#
215+
# This feature is built on top of `.gridspec` and you can pass the
216+
# keyword arguments through to the underlying `.gridspec.GridSpec`
217+
# (the same as `.Figure.subfigures`).
218+
#
219+
# In this case we want to use the input to specify the arrangement,
220+
# but set the relative widths of the rows / columns. For convenience,
221+
# `.gridspec.GridSpec`'s *height_ratios* and *width_ratios* are exposed in the
222+
# `.Figure.subfigure_mosaic` calling sequence.
223+
224+
subfigs=plt.figure().subfigure_mosaic(
225+
"""
226+
.a.
227+
bAc
228+
.d.
229+
""",
230+
# set the height ratios between the rows
231+
height_ratios=[1,3.5,1],
232+
# set the width ratios between the columns
233+
width_ratios=[1,3.5,1],
234+
)
235+
236+
# setting edges for clarity
237+
forsfinsubfigs.values():
238+
sf.set_edgecolor('black')
239+
sf.set_linewidth(2.1)
240+
identify_subfigs(subfigs)
241+
242+
# %%
243+
# You can also use the `.Figure.subfigures` functionality to
244+
# position the overall mosaic to put multiple versions of the same
245+
# mosaic in a figure.
246+
247+
mosaic="""AA
248+
BC"""
249+
fig=plt.figure()
250+
251+
left,right=fig.subfigures(nrows=1,ncols=2)
252+
253+
subfigs=left.subfigure_mosaic(mosaic)
254+
forsubfiginsubfigs.values():
255+
subfig.set_edgecolor('black')
256+
subfig.set_linewidth(2.1)
257+
identify_subfigs(subfigs)
258+
259+
subfigs=right.subfigure_mosaic(mosaic)
260+
forsubfiginsubfigs.values():
261+
subfig.set_edgecolor('black')
262+
subfig.set_linewidth(2.1)
263+
identify_subfigs(subfigs)
264+
265+
# %%
266+
# .. _controlling-creation:
267+
# Controlling subfigure creation
268+
# ==============================
269+
#
270+
# We can also pass through arguments used to create the subfigures
271+
# which will apply to all of the SubFigures created. So instead of iterating like so:
272+
273+
forsfinsubfigs.values():
274+
sf.set_edgecolor('black')
275+
sf.set_linewidth(2.1)
276+
277+
# %%
278+
# we would write:
279+
280+
subfigs=plt.figure().subfigure_mosaic(
281+
"A.B;A.C",subfigure_kw={"edgecolor":"black","linewidth":2.1}
282+
)
283+
identify_subfigs(subfigs)
284+
285+
# %%
286+
# Per-SubFigure keyword arguments
287+
# ----------------------------------
288+
#
289+
# If you need to control the parameters passed to each subfigure individually use
290+
# *per_subfigure_kw* to pass a mapping between the SubFigure identifiers (or
291+
# tuples of SubFigure identifiers) to dictionaries of keywords to be passed.
292+
#
293+
294+
fig,subfigs=plt.subfigure_mosaic(
295+
"AB;CD",
296+
per_subfigure_kw={
297+
"A": {"facecolor":"green"},
298+
("C","D"): {"edgecolor":"black","linewidth":1.1, }
299+
},
300+
)
301+
identify_subfigs(subfigs)
302+
303+
# %%
304+
# If the layout is specified with the string short-hand, then we know the
305+
# SubFigure labels will be one character and can unambiguously interpret longer
306+
# strings in *per_subfigure_kw* to specify a set of SubFigures to apply the
307+
# keywords to:
308+
309+
fig,subfigs=plt.subfigure_mosaic(
310+
"AB;CD",
311+
per_subfigure_kw={
312+
"AD": {"facecolor":".3"},
313+
"BC": {"edgecolor":"black","linewidth":2.1, }
314+
},
315+
)
316+
identify_subfigs(subfigs)
317+
318+
# %%
319+
# If *subfigure_kw* and *per_subfigure_kw* are used together, then they are
320+
# merged with *per_subfigure_kw* taking priority:
321+
322+
subfigs=plt.figure().subfigure_mosaic(
323+
"AB;CD",
324+
subfigure_kw={"facecolor":"xkcd:tangerine","linewidth":2},
325+
per_subfigure_kw={
326+
"B": {"facecolor":"xkcd:water blue"},
327+
"D": {"edgecolor":"yellow","linewidth":2.2,"facecolor":"g"},
328+
}
329+
)
330+
identify_subfigs(subfigs)
331+
332+
# %%
333+
# Nested list input
334+
# =================
335+
#
336+
# Everything we can do with the string shorthand we can also do when
337+
# passing in a list (internally we convert the string shorthand to a nested
338+
# list), for example using spans and blanks:
339+
340+
subfigs=plt.figure().subfigure_mosaic(
341+
[
342+
["main","zoom"],
343+
["main","BLANK"],
344+
],
345+
empty_sentinel="BLANK",
346+
width_ratios=[2,1],
347+
subfigure_kw={"facecolor":"xkcd:sea green","linewidth":2},
348+
)
349+
identify_subfigs(subfigs)
350+
351+
# %%
352+
# In addition, using the list input we can specify nested mosaics. Any element
353+
# of the inner list can be another set of nested lists:
354+
355+
inner= [
356+
["inner A"],
357+
["inner B"],
358+
]
359+
inner_three= [
360+
["inner Q"],
361+
["inner Z"],
362+
]
363+
inner_two= [
364+
["inner C"],
365+
[inner_three],
366+
]
367+
368+
layout= [["A", [[inner_two,"C"],
369+
["D","E"]]
370+
],
371+
["F","G"],
372+
[".", [["H", [["I"],
373+
["."]
374+
]
375+
]
376+
]
377+
]
378+
]
379+
fig,subfigs=plt.subfigure_mosaic(layout,subfigure_kw={'edgecolor':'black',
380+
'linewidth':1.5},
381+
per_subfigure_kw={"E": {'edgecolor':'xkcd:red'},
382+
"G": {'facecolor':'yellow'},
383+
"H": {'edgecolor':'blue',
384+
'facecolor':'xkcd:azure'}}
385+
)
386+
387+
identify_subfigs(subfigs,fontsize=12)
388+
389+
# %%
390+
# We can also pass in a 2D NumPy array to do things like:
391+
mosaic=np.zeros((4,4),dtype=int)
392+
forjinrange(4):
393+
mosaic[j,j]=j+1
394+
subfigs=plt.figure().subfigure_mosaic(
395+
mosaic,
396+
subfigure_kw={'edgecolor':'black','linewidth':1.5},
397+
empty_sentinel=0,
398+
)
399+
identify_subfigs(subfigs,fontsize=12)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp