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

Commit141f811

Browse files
committed
DOC: manually placing images example
1 parent3a0bc88 commit141f811

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
"""
2+
=========================================
3+
Placing images, preserving relative sizes
4+
=========================================
5+
6+
By default Matplotlib resamples images created with `~.Axes.imshow` to
7+
fit inside the parent ~.Axes`. This can mean that images that have very
8+
different original sizes can appear similar in size.
9+
10+
Sometimes, however, it is desirable to keep the images the same relative size, or
11+
even to make the images keep exactly the same pixels as the original data.
12+
Matplotlib does not automatically make either of these things happen,
13+
but it is possible with some manual manipulation.
14+
15+
Preserving relative sizes
16+
=========================
17+
18+
If the size of the images are amenable, we can preserve the relative sizes of two
19+
images by using either the *width_ratio* or *height_ratio* of the subplots. Which
20+
one you use depends on the shape of the image and the size of the figure.
21+
22+
By default the two images are made a similar size, despite one being 1.5 times the width
23+
of the other:
24+
"""
25+
importmatplotlib.pyplotasplt
26+
importnumpyasnp
27+
28+
importmatplotlib.patchesasmpatches
29+
30+
# make the data:
31+
N=450
32+
x=np.arange(N)/N
33+
y=np.arange(N)/N
34+
35+
X,Y=np.meshgrid(x,y)
36+
R=np.sqrt(X**2+Y**2)
37+
f0=5
38+
k=100
39+
a=np.sin(np.pi*2* (f0*R+k*R**2/2))
40+
A=a[:100, :300]
41+
B=A[:40, :200]
42+
43+
# plot with default axes handling:
44+
fig,axs=plt.subplots(1,2,facecolor='aliceblue')
45+
46+
axs[0].imshow(A,vmin=-1,vmax=1)
47+
axs[1].imshow(B,vmin=-1,vmax=1)
48+
rect=mpatches.Rectangle((0,0),200,40,linewidth=1,edgecolor='r',facecolor='none')
49+
axs[0].add_patch(rect)
50+
51+
# %%
52+
# Note that both images are rendered at a 1:1 ratio, but are made to look almost the
53+
# same width, despite image B being smaller than image A.
54+
#
55+
# We can control the relative sizes using the *width_ratios* argument *if* the images
56+
# are wider than they are tall and shown side by side, as is the case here.
57+
58+
fig,axs=plt.subplots(1,2,width_ratios=[300/200,1],facecolor='aliceblue')
59+
60+
axs[0].imshow(A,vmin=-1,vmax=1)
61+
rect=mpatches.Rectangle((0,0),200,40,linewidth=1,edgecolor='r',facecolor='none')
62+
axs[0].add_patch(rect)
63+
axs[1].imshow(B,vmin=-1,vmax=1)
64+
65+
# %%
66+
# Given that the data subsample is in the upper left of the larger image,
67+
# it might make sense if the top of the smaller Axes aligned with the top of the larger.
68+
# This can be done manually by using `~.Axes.set_anchor`, and using "NW" (for
69+
# northwest).
70+
71+
fig,axs=plt.subplots(1,2,width_ratios=[300/200,1],facecolor='aliceblue')
72+
73+
axs[0].imshow(A,vmin=-1,vmax=1)
74+
rect=mpatches.Rectangle((0,0),200,40,linewidth=1,edgecolor='r',facecolor='none')
75+
axs[0].add_patch(rect)
76+
axs[0].set_anchor('NW')
77+
axs[1].imshow(B,vmin=-1,vmax=1)
78+
axs[1].set_anchor('NW')
79+
80+
# %%
81+
# Note that this procedure still leaves large white spaces (that can be trimmed
82+
# in a final product by ``bbox_inches="tight"`` in `~.Figure.savefig`), and is
83+
# not very general. For instance, if the axes had been arranged vertically
84+
# instead of horizontally, setting the height aspect ratio would not have
85+
# helped because the axes are wider than they are tall. For more complicated
86+
# situations it is necessary to place the axes manually.
87+
#
88+
# Manual placement
89+
# ================
90+
#
91+
# We can manually place axes when they are created by passing a position to
92+
# `~.Figure.add_axes`. This position takes the form ``[left bottom width height]`` and
93+
# is in units that are a fraction of the figure width and height. Here we decide how
94+
# large to make the axes based on the size of the images, and add a small buffer of
95+
# 0.35 inches. We do all this at 100 dpi.
96+
97+
dpi=100# 100 pixels is one inch
98+
buffer=0.35*dpi# pixels
99+
left=buffer
100+
bottom=buffer
101+
ny,nx=np.shape(A)
102+
posA= [left,bottom,nx,ny]
103+
# we know this is tallest, so we can get the fig height:
104+
figh=bottom+ny+buffer
105+
106+
# place the B axes
107+
left=left+nx+buffer
108+
ny,nx=np.shape(B)
109+
posB= [left,figh-buffer-ny,nx,ny]
110+
111+
# get the fig width
112+
figw=left+nx+buffer
113+
114+
fig=plt.figure(figsize=(figw/dpi,figh/dpi),facecolor='aliceblue')
115+
116+
ax=fig.add_axes([posA[0]/figw,posA[1]/figh,posA[2]/figw,posA[3]/figh])
117+
ax.imshow(A,vmin=-1,vmax=1)
118+
rect=mpatches.Rectangle((0,0),200,40,linewidth=1,edgecolor='r',facecolor='none')
119+
ax.add_patch(rect)
120+
121+
ax=fig.add_axes([posB[0]/figw,posB[1]/figh,posB[2]/figw,posB[3]/figh])
122+
ax.imshow(B,vmin=-1,vmax=1)
123+
124+
# %%
125+
# Inspection of the image will show that it is exactly 3* 35 + 300 + 200 = 605
126+
# pixels wide, and 2 * 35 + 100 = 170 pixels high (or twice that if the 2x
127+
# version is used by the browser instead). The images should be rendered with
128+
# exactly 1 pixel per data point (or four, if 2x).

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp