[英]Changing aspect ratio of subplots in matplotlib
我创建了一系列简单的灰度图像,并将其绘制在网格中(不幸的是,由于我的信誉不高,所以无法上传图像:()。
伪代码是
# Define matplotlib PyPlot object
nrow = 8
ncol = 12
fig, axes = plt.subplots(nrow, ncol, subplot_kw={'xticks': [], 'yticks': []})
fig.subplots_adjust(hspace=0.05, wspace=0.05)
# Sample the fine scale model at random well locations
for ax in axes.flat:
plot_data = # some Python code here to create 2D grey scale array...
# ... create sub-plot
img = ax.imshow(plot_data, interpolation='none')
img.set_cmap('gray')
# Display the plot
plt.show()
我想更改纵横比,以使图垂直压缩并水平拉伸。 我尝试使用ax.set_aspect并将'aspect'作为subplot_kw参数传递,但无济于事。 我还关闭了“自动缩放”功能,但随后只能看到少量像素。 欢迎所有建议!
提前致谢!!
@JoeKington-谢谢! 这是一个很好的答复! 仍然想尽一切办法。 也感谢其他张贴者的建议。 因此,原始图如下所示: http : //imgur.com/Wi6v4cs当我设置'aspect ='auto'时,图如下所示: http : //imgur.com/eRBO6MZ这是一个很大的改进。 我现在要做的就是调整子图的大小,以便以例如2:1的纵向长宽比绘制子图,但该图会填满整个子图。 我猜“ colspan”会这样做吗?
您可能想致电:
ax.imshow(..., aspect='auto')
默认情况下, imshow
会在调用轴时将轴的纵横比设置为1。 这将覆盖您在创建轴时指定的任何方面。
但是,这是matplotlib中常见的混乱原因。 让我备份并详细说明正在发生的事情。
matplotlib中的aspect
是指数据坐标中xscale和yscale的比率。 它不直接控制轴的宽高比。
有以下三项控制matplotlib轴的“外部框”的大小和形状:
adjustable
参数)的机制。 换句话说,轴始终放置在图形坐标中,其形状/大小始终是图形形状/大小的比率。 (注意:某些东西,例如axes_grid
会在绘制时更改此值,以解决此限制。)
但是,给定轴的范围(从其子图位置或显式设置的范围)不一定要占用其大小。 根据aspect
和adjustable
参数, 轴将在其给定范围内收缩 。
要了解所有事物如何相互作用,让我们在许多不同的情况下画一个圆。
在基本情况下(没有为轴设置固定的纵横比),轴将填满图形坐标中分配给它的整个空间(由绿色框显示)。
x和y比例尺(由aspect
设置)可以自由更改,从而使圆变形:
当我们调整图形的大小(交互式或在图形创建时)时,轴将“挤压”它:
adjustable='box'
但是,如果设置了绘图的宽高比(默认情况下, imshow
将强制将宽高比设置为1),则轴将调整轴外部的大小,以将x和y数据比保持在指定的宽高比。
一个关键点在这里明白了,不过,是该aspect
的情节是x和y的数据规模方面。 这不是情节的宽度和高度的方面。 因此,如果aspect
为1
,则圆圈将始终是圆圈。
例如,假设我们做了类似的事情:
fig, ax = plt.subplots()
# Plot circle, etc, then:
ax.set(xlim=[0, 10], ylim=[0, 20], aspect=1)
默认情况下, adjustable
将是"box"
。 让我们看看发生了什么:
轴可以占用的最大空间由绿色框显示。 但是,它必须保持相同的x和y比例。 有两种方法可以完成此操作:更改x和y限制或更改“轴”边界框的形状/大小。 因为轴的adjustable
参数设置为默认的"box"
,所以轴会在其最大空间内收缩。
当我们调整图的大小时,它会不断缩小,但是通过使轴用尽分配给轴的最大空间(绿色框)来保持x和y比例:
两个简短的旁注:
adjustable="box"
,请改用adjustable="box-forced"
。 anchor
。 例如,使用ax.set_anchor('NE')
使其“固定”在“绿色框”的右上角,因为它会调整其大小以保持纵横比。 adjustable="datalim"
adjustable
的另一个主要选项是"datalim"
。
在这种情况下,matplotlib将通过更改轴限制之一来将x和y缩放比例保留在数据空间中。 轴将填满分配给它的整个空间。 但是,如果手动设置x或y限制,则它们可能会被覆盖以允许轴既填充分配给它的全部空间,又将x / y比例保持在指定的aspect
。
在这种情况下,将x限制设置为0-10,将y限制设置为0-20,并且aspect=1, adjustable='datalim'
。 请注意,不遵守y限制:
当我们调整图的大小时,宽高比表示相同,但是数据限制发生变化(在这种情况下,不遵守x限制)。
附带一提,生成上述所有数字的代码位于: https : //gist.github.com/joferkington/4fe0d9164b5e4fe1e247
imshow
有什么关系? 当imshow
被调用时,它调用ax.set_aspect(1.0)
默认情况下。 由于默认情况下imshow
adjustable="box"
,任何带有imshow
绘图的行为imshow
将类似于上面的第imshow
张图片。
例如:
但是,如果指定imshow(..., aspect='auto')
,则图的宽高比将不会被覆盖,并且图像将“压缩”以占用分配给轴的全部空间:
另一方面,如果您希望像素保持“正方形”(请注意:取决于extent
kwarg所指定的像素,它们可能不是正方形的),则可以忽略Aspect aspect='auto'
并设置轴改为"datalim"
。
例如
ax.imshow(data, cmap='gist_earth', interpolation='none')
ax.set(adjustable="datalim")
最后要记住的是,轴的形状/尺寸定义为图形形状/尺寸的百分比。
因此,如果要保留轴的长宽比并在相邻子图之间具有固定的间距,则需要定义要匹配的图形形状。 plt.figaspect
非常方便。 它仅根据指定的长宽比或2D数组生成width, height
的元组(它将从数组的形状而不是内容中获取长宽比)。
对于每个子图网格的示例,每个子图具有2x1的恒定纵横比,您可能会考虑以下内容(请注意,此处我不使用aspect="auto"
,因为我们希望图像中的像素保持正方形):
import numpy as np
import matplotlib.pyplot as plt
nrows, ncols = 8, 12
dx, dy = 1, 2
figsize = plt.figaspect(float(dy * nrows) / float(dx * ncols))
fig, axes = plt.subplots(nrows, ncols, figsize=figsize)
for ax in axes.flat:
data = np.random.random((10*dy, 10*dx))
ax.imshow(data, interpolation='none', cmap='gray')
ax.set(xticks=[], yticks=[])
pad = 0.05 # Padding around the edge of the figure
xpad, ypad = dx * pad, dy * pad
fig.subplots_adjust(left=xpad, right=1-xpad, top=1-ypad, bottom=ypad)
plt.show()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.