GridSpec轴大小调整

2024-04-23 15:29:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我到处找都没有结果,但是我遇到了一个问题,我的python GridSpec multiplot不断地改变坐标轴。主要的问题是,即使我显式地设置了2dheatmap的范围和方面,它仍然改变了xaxis,这样我的图形周围就有了空白。在

我尝试过关闭自动缩放,但这会导致两侧的直方图出错,可能是因为共享轴?在

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。在


我做了进一步调查,发现它在以下情况下发生故障:

^{pr2}$

虽然我不知道为什么这会突然打破之前代码的轴大小。在


Tags: theimportgetnppltlabelsetlocator
1条回答
网友
1楼 · 发布于 2024-04-23 15:29:20

创建倍增管的其他部分时,中心打印的x轴将重新调整大小。这将覆盖对imshow调用中的纵横比定义。而不是:

aspect=((xmax-xmin)/(ymax-ymin))

使用:

^{pr2}$

有关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))  

有:

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')

看起来像:

final figure


this answer中所述,您可以使用以下命令保存已定义的纵横比:

axTemperature.set(adjustable='box-forced')

但是,这不会转化为顶部绘图的宽度正在调整,并且左栏中的x轴将不会对齐。这里提到它是为了完整性。在

相关问题 更多 >