我环顾四周没有结果,但我遇到一个问题,我的 python GridSpec multiplot 不断改变轴。主要问题是,即使我明确设置了 2dheatmap 的范围和方面,它仍然会更改 x 轴,以便我的图形周围有空白。
我尝试关闭自动缩放,但这会导致侧翼直方图出错,可能是因为共享轴?
def hist2d_flanking1d(x, y, xlims, ylims, bins=50,
weights=None,xlabel="xlabel", ylabel="ylabel", cbarlabel='Testing'):
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter, MaxNLocator
from numpy import linspace
import matplotlib.gridspec as gridspec
from matplotlib import cm as cm
import pdb
from matplotlib import ticker
from mpl_toolkits.axes_grid1 import make_axes_locatable
plt.close('all')
fig = plt.figure()
gs = gridspec.GridSpec(2,2, width_ratios=[3,1], height_ratios=[1,3])
axTemperature = plt.subplot(gs[1,0])
# Find the min/max of the data
xmin = np.float(xlims[0])
xmax = np.float(xlims[1])
ymin = np.float(ylims[0])
ymax = np.float(ylims[1])
xbins = linspace(start = xmin, stop = xmax, num = bins)
ybins = linspace(start = ymin, stop = ymax, num = bins)
H, xedges,yedges = np.histogram2d(y,x,bins=(ybins,xbins), weights=weights)
extent=[xmin,xmax,ymin,ymax]
cax = (axTemperature.imshow(H, extent=extent,
interpolation='nearest', origin='lower',aspect=((xmax-xmin)/(ymax-ymin)),
cmap=cm.cubehelix_r))
#Set up the plot limits
axTemperature.set_xlim(xmin,xmax)
axTemperature.set_ylim(ymin,ymax)
axTemperature.set_xlabel(xlabel, fontsize=22, labelpad=20)
axTemperature.set_ylabel(ylabel, fontsize=22, labelpad=20)
#Make the tickmarks pretty
ticklabels = axTemperature.get_xticklabels()
for label in ticklabels:
label.set_fontsize(18)
ticklabels = axTemperature.get_yticklabels()
for label in ticklabels:
label.set_fontsize(18)
# Now setup the two flanking histograms
axHistx = plt.subplot(gs[0,0], sharex=axTemperature)
axHisty = plt.subplot(gs[1,1], sharey=axTemperature)
# Remove the inner axes numbers of the histograms
plt.setp(axHisty.get_yticklabels(), visible=False)
plt.setp(axHistx.get_xticklabels(), visible=False)
# Add labels
axHistx.set_ylabel('N', fontsize=22, labelpad=20)
axHisty.set_xlabel('N', fontsize=22, labelpad=20)
#Plot the histograms
axHistx.hist(x, bins=xbins, color = 'blue', histtype='step')
axHisty.hist(y, bins=ybins, orientation='horizontal', color ='red',histtype='step')
# Make the tickmarks pretty
ticklabels = axHistx.get_yticklabels()
for label in ticklabels:
label.set_fontsize(18)
# Make the tickmarks pretty
ticklabels = axHisty.get_xticklabels()
for label in ticklabels:
label.set_fontsize(18)
#Cool trick that changes the number of tickmarks for the histogram axes
axHisty.xaxis.set_major_locator(MaxNLocator(1))
axHistx.yaxis.set_major_locator(MaxNLocator(1))
# This should create an axes on the rightside of the vertical
# histogram. Width is argument 2, padding argument 3, reduce
# the number of ticks to make it less messy
divider = make_axes_locatable(axHisty)
extend = divider.append_axes("right", "20%", pad=0.2)
cb = plt.colorbar(cax, cax=extend)
tick_locator = ticker.MaxNLocator(nbins=5)
cb.locator = tick_locator
cb.update_ticks()
# Have to draw first, then tightlayout then draw again, otherwise
# the axes labels are cut off. If you do it before drawing it
# complains that CGContextRef is NULL
plt.draw()
gs.tight_layout(fig)
plt.draw()
return axTemperature, axHistx, axHisty
我无法向您展示结果,因为我没有上传图像的声誉。
顺便说一句,我在更改刻度数方面也遇到了问题,我设置了 set_major_locator(MaxNLocator(1))
,它应该(我认为)只有最大值刻度线,但这并不一致。顶部直方图没有问题,但侧面直方图的轴上只有 0。
我做了进一步的调查,发现它在以下时间后崩溃了:
axHistx = plt.subplot(gs[0,0], sharex=axTemperature)
axHisty = plt.subplot(gs[1,1], sharey=axTemperature)
虽然我不确定为什么这会突然破坏之前代码的轴大小。
最佳答案
当您创建多重图的其他部分时,中心图的 x 轴会重新调整大小。这会覆盖调用 imshow
时的宽高比定义。而不是:
aspect=((xmax-xmin)/(ymax-ymin))
使用:
aspect='auto'
参见this answer演示 imshow
的不同宽高比设置。
MaxNLocator(1)
决定最好的刻度是第一个。要仅获取最大/最后一个刻度,可以将所有先前的刻度设置为空字符串。为此,请替换此 block :
# Make the tickmarks pretty
ticklabels = axHistx.get_yticklabels()
for label in ticklabels:
label.set_fontsize(18)
# Make the tickmarks pretty
ticklabels = axHisty.get_xticklabels()
for label in ticklabels:
label.set_fontsize(18)
#Cool trick that changes the number of tickmarks for the histogram axes
axHisty.xaxis.set_major_locator(MaxNLocator(1))
axHistx.yaxis.set_major_locator(MaxNLocator(1))
与:
yticklabels=axHistx.get_yticks().tolist()
yticklabels[:-1] = [' '] * len(yticklabels[:-1])
yticklabels[-1] = '{0:.0f}'.format(yticklabels[-1])
axHistx.set_yticklabels(yticklabels,fontsize=18)
xticklabels=axHisty.get_xticks().tolist()
xticklabels[:-1] = [' '] * len(xticklabels[:-1])
xticklabels[-1] = '{0:.0f}'.format(xticklabels[-1])
axHisty.set_xticklabels(xticklabels,fontsize=18)
在这里,首先检索刻度标签(请参阅 this answer )。接下来,除了最后一个之外的所有字符串都设置为空字符串,最后一个格式化为整数表示形式。最后,重新贴上标签。
使用以下测试数据得到的图:
x = np.random.randn(100000)
y = np.random.randn(100000)+5
xlims = [0,1]
ylims = [0,5]
axTemperature, axHistx, axHisty = hist2d_flanking1d(x, y,
xlims, ylims,
bins=50, weights=None,
xlabel="xlabel",
ylabel="ylabel",
cbarlabel='Testing')
看起来像这样:
如 this answer 中所述,您可以使用此命令保持定义的宽高比:
axTemperature.set(adjustable='box-forced')
但是,这不会转化为调整顶部图的宽度,并且左列中的 x 轴不会对齐。这里提到它是为了完整性。
关于python - GridSpec 轴调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29104485/