【问题标题】:How to use twinx with ax created with make_axes_locatable如何将 twinx 与使用 make_axes_locatable 创建的 ax 一起使用
【发布时间】:2017-06-18 12:59:49
【问题描述】:

我想用下面的相关直方图绘制一个图像和颜色条。图像和直方图的两个轴必须具有相同的宽度。 此外,颜色条应与图像的高度相同。 复杂(并且不应该)复杂的部分是将累积直方图与每个 bin 相对于数据大小的百分比叠加在一起。

目前,我得到了这样的东西:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable


data = np.random.normal(0,2,size=(100,100))

fig     = plt.figure()
ax      = fig.add_subplot(2,1,1)
im      = ax.imshow(data,cmap="bone")
divider = make_axes_locatable(ax)
ax1     = divider.append_axes("right", size="5%", pad=0.05) 
plt.colorbar(im,cax=ax1)   
ax2     = divider.append_axes("bottom",size="100%",pad = 0.3)
n,bins,patches = ax2.hist(data.flatten(),bins=20)
ax3     = ax2.twinx()
ax3.plot(bins[:-1],np.cumsum(n*100/np.size(data)),lw=2)

plt.show()

在我尝试在 ax2 上使用 twinx 之前,一切都很顺利(为了在 ax3 上以不同的 y 比例绘制我的累积分布)。生成的轴,而不是与 ax2 一起,是环绕图形的所有轴。

我不明白出了什么问题以及如何解决这个问题。

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    这很难。问题是axes_grid1 工具包旨在在绘图时定位轴。显然,它首先绘制双轴,然后才根据分隔线重新定位轴。
    更糟糕的是,您希望将具有相等纵横比的轴绑定到具有不相等纵横比的轴,这使得无法使用AxisGrid

    虽然 equal+unequal 或 equal+twin 或 unequal+twin 的任何两种组合都会以一种或另一种方式起作用,但这三种组合都太多了。

    因此解决方案可能是从头开始,只需将轴放在画布上,然后仅在最后重新定位/调整它们的大小。这可以使用连接到函数的事件侦听器来完成,该函数获取具有相同纵横比的轴的位置并相应地调整其他两个轴的大小。

    import numpy as np
    import matplotlib.pyplot as plt
    from mpl_toolkits.axes_grid1 import make_axes_locatable
    
    data = np.random.normal(0,2,size=(100,100))
    
    fig     = plt.figure()
    ax  = fig.add_subplot(211)
    ax2 = fig.add_subplot(212)
    
    im      = ax.imshow(data,cmap="bone")
    n,bins,patches = ax2.hist(data.flatten(),bins=20)
    
    divider = make_axes_locatable(ax)
    cax     = divider.append_axes("right", size="5%", pad=0.05) 
    plt.colorbar(im, cax=cax)
    
    ax3     = ax2.twinx()
    ax3.plot(bins[:-1],np.cumsum(n*100/np.size(data)),lw=2, c=plt.cm.bone(0.4))
    
    def resize(event):
        axpos = ax.get_position()
        axpos2 = ax2.get_position()
        newpos = [axpos.x0, axpos2.y0,  axpos.width, axpos2.height] 
        ax2.set_position(newpos)
        ax3.set_position(newpos)
    
    cid = fig.canvas.mpl_connect('draw_event', resize)
    cid2 = fig.canvas.mpl_connect('resize_event', resize)
    
    #if you want to save the figure, trigger the event manually
    save=False
    if save:
        fig.canvas.draw()
        resize()
        plt.savefig(__file__+".png")
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-09
      • 2020-10-13
      • 1970-01-01
      • 2016-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-26
      相关资源
      最近更新 更多