如何使用带有make_axes_locatable创建的ax的twinx

时间:2017-02-01 17:07:47

标签: python matplotlib

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

目前,我获得了类似的东西:

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,而是包裹图形的所有轴。

我不明白什么是错的以及如何解决这个问题。

1 个答案:

答案 0 :(得分:3)

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

虽然任何等于+不等或相等+双胞胎或不等于+双胞胎的双重组合会以某种方式起作用,但这三种组合都太多了。

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

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

enter image description here