Python 使用 matplotlib imshow 和 scatter 获得相同的子图大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44654421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting the same subplot size using matplotlib imshow and scatter
提问by DavidG
I am trying to plot an image (using matplotlib.imshow
) and a scatter plot within the same figure. When trying this, the image appears smaller than the scatter plot. Small example code is shown below:
我正在尝试matplotlib.imshow
在同一图中绘制图像(使用)和散点图。尝试此操作时,图像看起来比散点图小。小示例代码如下所示:
import matplotlib.pyplot as plt
import numpy as np
image = np.random.randint(100,200,(200,200))
x = np.arange(0,10,0.1)
y = np.sin(x)
fig, (ax1, ax2) = plt.subplots(1,2)
ax1.imshow(image)
ax2.scatter(x,y)
plt.show()
Which gives the following figure:
这给出了下图:
How can I get the two sublpots to have the same height? (and width I suppose)
如何让两个 sublpots 具有相同的高度?(和我想的宽度)
I have tried using gridspec
as shown in thisanswer:
fig=plt.figure()
gs=GridSpec(1,2)
ax1=fig.add_subplot(gs[0,0])
ax2=fig.add_subplot(gs[0,1])
ax1.imshow(image)
ax2.scatter(x,y)
But this gives the same result. I have also tried to adjust the subplot sizes manually by using:
但这给出了相同的结果。我还尝试使用以下方法手动调整子图大小:
fig = plt.figure()
ax1 = plt.axes([0.05,0.05,0.45,0.9])
ax2 = plt.axes([0.55,0.19,0.45,0.62])
ax1.imshow(image)
ax2.scatter(x,y)
By trial and error I can get the two subplots to the correct size, though any change in the overall figure size will mean that the subplots will no longer be the same size.
通过反复试验,我可以使两个子图达到正确的大小,尽管整体图形大小的任何变化都意味着子图将不再具有相同的大小。
Is there a way to make imshow
and a scatter
plot appear the same size in a figure without manually changing the axes sizes?
有没有一种方法,使imshow
和scatter
情节出现在图中相同的尺寸,而无需手动更改轴的尺寸?
I am using Python 2.7 and matplotlib 2.0.0
我正在使用 Python 2.7 和 matplotlib 2.0.0
回答by ImportanceOfBeingErnest
It's not perfectly clear what your desired outcome is.
目前还不清楚您想要的结果是什么。
You may use automatic aspect on the image
ax.imshow(z, aspect="auto")
Or you may set the aspect of the line plot depending on its axis limits such that it gets the same size as the image (in case the image has equal x and y sizes)
asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0] ax2.set_aspect(asp)
import numpy as np import matplotlib.pyplot as plt x = np.linspace(0,10,20) y = np.sin(x) z = np.random.rand(100,100) fig, (ax, ax2) = plt.subplots(ncols=2) ax.imshow(z) ax2.plot(x,y, marker=".") asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0] ax2.set_aspect(asp) plt.show()
If the image does not have equal limits (is not square), one still needs to divide by the aspect of the image:
asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0] asp /= np.abs(np.diff(ax1.get_xlim())[0] / np.diff(ax1.get_ylim())[0]) ax2.set_aspect(asp)
More sophisticated solutions:
This answerfor using the subplot parameters to achieve a certain aspect.
If you want to use
mpl_toolkits
and make your hands dirty, this answerwould be a good read.
您可以在图像上使用自动外观
ax.imshow(z, aspect="auto")
或者您可以根据其轴限制设置线图的方面,使其与图像大小相同(如果图像具有相同的 x 和 y 大小)
asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0] ax2.set_aspect(asp)
import numpy as np import matplotlib.pyplot as plt x = np.linspace(0,10,20) y = np.sin(x) z = np.random.rand(100,100) fig, (ax, ax2) = plt.subplots(ncols=2) ax.imshow(z) ax2.plot(x,y, marker=".") asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0] ax2.set_aspect(asp) plt.show()
如果图像没有相等的界限(不是正方形),仍然需要除以图像的纵横比:
asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0] asp /= np.abs(np.diff(ax1.get_xlim())[0] / np.diff(ax1.get_ylim())[0]) ax2.set_aspect(asp)
更复杂的解决方案:
回答by Tonechas
I had the same problem and asked a very similar question in SO. The solution proposed by @ImportanceOfBeingErnest worked like a charm for me, but for completeness, I'd like to mention a pretty simple workaround I was suggested to apply (credit to @Yilun Zhang) before my question was marked as an exact duplicate of this one:
我遇到了同样的问题,并在 SO 中问了一个非常相似的问题。@ImportanceOfBeingErnest 提出的解决方案对我来说很有吸引力,但为了完整起见,我想提一个非常简单的解决方法,在我的问题被标记为完全重复之前,我被建议应用(归功于@Yilun Zhang)一:
The problem is that the plot region height is too large and this is leaving empty placein the image.
问题是绘图区域高度太大,这在图像中留下了空白位置。
If you change your code to:
如果您将代码更改为:
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
then you get the desired outcome:
然后你会得到想要的结果:
回答by mauve
Here's some code I use:
这是我使用的一些代码:
fig, axis_array = plt.subplots(1, 2, figsize=(chosen_value, 1.05 * chosen_value / 2),
subplot_kw={'aspect': 1})
I'm explicitly selecting that there will be 2 sub plots in my figure, and that the figure will be chosen_value tall and each subplot will be about half that size wide, and that the subplots will have an aspect ratio of 1 (i.e., they will both be square). The figure size is a specific ratio which forces the spacing.
我明确地选择在我的图中将有 2 个子图,并且该图将被选择为高值,每个子图的宽度大约是该尺寸的一半,并且子图的纵横比为 1(即,它们都是方形的)。图形大小是强制间距的特定比率。