Python 范围和方面;matplotlib中具有共享轴的图像中的方形像素

Python 范围和方面;matplotlib中具有共享轴的图像中的方形像素,python,matplotlib,Python,Matplotlib,我的处境相当复杂。我正在使用imshow()将一些数据绘制为图像。不幸的是,我的脚本很长,有点凌乱,所以很难制作一个有效的示例,但我正在展示关键步骤。这是我从一个更大的数组中获取图像数据的方式,写入文件: data = np.tril(np.loadtxt('IC-heatmap-20K.mtx'), 1) # #Here goes lot's of other stuff, where I define start and end # chrdata = data[start:end, sta

我的处境相当复杂。我正在使用imshow()将一些数据绘制为图像。不幸的是,我的脚本很长,有点凌乱,所以很难制作一个有效的示例,但我正在展示关键步骤。这是我从一个更大的数组中获取图像数据的方式,写入文件:

data = np.tril(np.loadtxt('IC-heatmap-20K.mtx'), 1)
#
#Here goes lot's of other stuff, where I define start and end
#
chrdata = data[start:end, start:end]
chrdata = ndimage.rotate(chrdata, 45, order=0, reshape=True, 
                         prefilter=False, cval=0)
ax1 = host_subplot(111) 
#I don't really need host_subplot() in this case, I could use something more common;
#It is just divider.append_axes("bottom", ...) is really convenient.
plt.imshow(chrdata, origin='lower', interpolation='none',
           extent=[0, length*resolution, 0, length*resolution]) #resolution=20000
所以我感兴趣的值都在三角形中,在一个正方形的顶边中间有一个顶角。同时,我绘制了一些数据(在本例中是许多彩色线)以及底部附近的图像。

所以一开始这看起来不错,但实际上不是:图像中的所有像素都不是正方形,而是拉长的,它们的高度大于宽度。如果我放大,它们看起来就是这样:

如果调用imshow()时未设置区段,则不会发生这种情况,但我需要它使图像和其他绘图(在本例中为底部的彩色线)中的坐标相同(请参阅)。 我尝试使用aspect来修复它。我试着这样做,它修复了像素的形状,但我得到了一张非常奇怪的图片:

问题是,在后面的代码中,我明确地设置了:

ax1.set_ylim(0*resolution, length*resolution) #resolution=20000
但在设置了纵横比之后,我得到了完全不同的y极限。最糟糕的是:ax1现在比底部另一个绘图的轴宽,所以它们的坐标不再匹配!我这样加上:

axPlotx = divider.append_axes("bottom", size=0.1, pad=0, sharex=ax1)
我真的很感激能帮我把它修好:正方形像素,两个(或更多,在其他情况下)图中的相同坐标。正如我所看到的,图像的轴需要变得更宽(像纵横比一样),应该应用ylims,并且第二个轴的宽度应该与图像的宽度相同。 谢谢你阅读这个可能不清楚的解释,如果我需要澄清什么,请告诉我

更新

正如评论中所建议的,我尝试使用

ax1.set(adjustable='box-forced')
它确实有助于图像本身,但它导致两个轴被空白隔开。有没有办法让他们彼此靠近


当我找到您问题的解决方案时,重新编辑了我的整个答案。正如tcaswell的评论所建议的那样,我使用
set\u adjustable(“box\u forced”)
选项解决了这个问题

import numpy
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import host_subplot, make_axes_locatable


#Calculate aspect ratio
def determine_aspect(shape, extent):
    dx = (extent[1] - extent[0]) / float(shape[1])
    dy = (extent[3] - extent[2]) / float(shape[0])
    return dx / dy

data = numpy.random.random((30,60))

shape = data.shape
extent = [-10, 10, -20, 20]
x_size, y_size = 6, 6

fig = plt.figure(figsize = (x_size, y_size))
ax = host_subplot(1, 1, 1)
ax.imshow(data, extent = extent, interpolation = "None", aspect = determine_aspect(shape, extent))

#Determine width and height of the subplot frame
bbox = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
width, height = bbox.width, bbox.height

#Calculate distance, the second plot needs to be elevated by
padding = (y_size - (height - width)) / float(1 / (2. * determine_aspect(shape, extent)))

#Create second image in subplot with shared x-axis
divider = make_axes_locatable(ax)
axPlotx = divider.append_axes("bottom", size = 0.1, pad = -padding, sharex = ax)

#Turn off yticks for axPlotx and xticks for ax 
axPlotx.set_yticks([])
plt.setp(ax.get_xticklabels(), visible=False)

#Make the plot obey the frame
ax.set_adjustable("box-forced")

fig.savefig("test.png", dpi=300, bbox_inches = "tight")

plt.show()
这将导致下图中的x轴共享
x轴


希望有帮助

请看,问题是,由于使用了两个方面=1并将其链接到另一个轴,您过度限制了轴限制。@t对不起,我不太明白您所指的答案的哪一部分。是的,我设置了特定的纵横比并将其链接到另一个轴,但这就是我需要做的…可调节的kwarg,谢谢!这确实有帮助,但设置可调='box-forced'会导致两个轴彼此分离。我会用这个更新问题。谢谢你的回复!虽然您的函数工作得很好,但当我将两个轴绘制在一起时,它仍然会导致相同的问题:要么ax1内部有大量的空白,要么ax1和axPlotx之间有大量的空白(如果我设置了adjustable='bbox-forced')—请参见问题中的最后两张图片。我现在有点困惑。“ax1内部存在大量空白”是什么意思?你是指你在问题的第三张图片中看到的吗?如果是这样的话,你能试着用我的方法定义ax1吗?也就是说,没有
主机\u子批次
?正如代码注释中所指出的,它不是很重要。在我的上一张图片中,图框周围有很大的白色区域。但是,正如您所看到的,图形内部没有任何大的白色区域。保存图形时,可以使用
savefig
选项
bbox\u inches=“tight”
删除图形周围的白色区域,这就是我的意思。好的,我将去掉host_子图,希望它能起到作用,谢谢。您可以在包和绘图方面展示更多的代码吗?我将
host\u子批次
determinate\u aspect
结合使用(参见更新的答案)。然而,结果仍然是一样的,我没有在
ax
中得到大的白色区域,我认为重要的是,我在图像下有另一个绘图-你能尝试在你的示例中添加它吗?我只是使用plt.show()并手动保存图片。我真的不知道,在这里什么对包有帮助。。。在那一部分我没有做任何不寻常的事。