我陷入了相当复杂的境地。我正在使用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()时没有设置范围,但我需要它以便图像中的坐标和其他图(在这种情况下底部的彩色线条),在哪里相同(见Converting coordinates of a picture in matplotlib?)。 我尝试使用方面修复它。我试图这样做,它修复了像素'形状,但我有一个非常奇怪的图片:
问题是,稍后在代码中我明确地设置了这个:
ax1.set_ylim(0*resolution, length*resolution) #resolution=20000
但是在设定方面后,我得到了绝对不同的限制。最糟糕的是:ax1现在比底部另一个绘图的轴更宽,所以它们的坐标不再匹配了!我以这种方式添加它:
axPlotx = divider.append_axes("bottom", size=0.1, pad=0, sharex=ax1)
我非常感谢帮助修复它:正方形像素,两个(或更多,在其他情况下)图中相同的坐标。在我看来,图像的轴需要变宽(如方面所示),应该应用ylims,第二轴的宽度应该与图像相同。 感谢您阅读这个可能不清楚的解释,请让我知道,如果我应该澄清一切。
更新
根据评论中的建议,我尝试使用
ax1.set(adjustable='box-forced')
它确实有助于图像本身,但它导致两个轴被白色空间分开。有没有办法让它们彼此靠近?
答案 0 :(得分:2)
重新编辑了我的整个答案,因为我找到了解决问题的方法。我根据tcaswell的评论建议使用set_adjustable("box_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-axis
的图像:
希望有所帮助!