我环顾四周无济于事,但我遇到了一个问题,我的python GridSpec多重插槽不断改变轴。主要问题是即使我明确设置了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))
应该(我认为)只有最大值刻度标记,但这不是't}是一致的。顶部直方图没有问题,但侧面直方图在轴上只有0。
我做了进一步调查,发现它在以下情况后发生故障:
axHistx = plt.subplot(gs[0,0], sharex=axTemperature)
axHisty = plt.subplot(gs[1,1], sharey=axTemperature)
虽然我不确定为什么这会突然破坏前一代码的轴大小。
答案 0 :(得分:0)
在创建多重绘图的其他部分时,会重新调整中心图的x轴。这会在调用imshow
时覆盖您的宽高比定义。而不是:
aspect=((xmax-xmin)/(ymax-ymin))
使用:
aspect='auto'
有关imshow
的不同宽高比设置的演示,请参阅this answer。
MaxNLocator(1)
决定最好的刻度是第一个。要仅获得最大/最后一个刻度,可以将所有先前的刻度设置为空字符串。为此,请替换此块:
# 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))
with:
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轴将不对齐。这里提到完整性。