matplotlib sharex与colorbar无法正常工作

时间:2017-10-11 18:09:40

标签: python pandas matplotlib subplot colorbar

enter image description here我有2个子图 - 1个散点和1个条,我想要一个共享的x轴。散点图有一个颜色条。由于两个图的轴不重合,因此sharex似乎无法使用此功能。 我的代码:

B

2 个答案:

答案 0 :(得分:4)

Sharex表示轴限制相同且轴同步。它并不意味着它们彼此叠加。这一切都取决于你如何创建颜色条。

pandas scatterplot创建的颜色条就像matplotlib中的任何标准颜色条一样,通过取消与其相关的轴的部分空间来创建。因此,该轴比来自网格的其他轴小。

您拥有的选项包括:

  • 缩小网格的其他轴的数量与散点图轴的数量相同。
    这可以通过使用第一个轴的位置并使用ax.get_position()ax.set_postion()

    import matplotlib.pyplot as plt import pandas as pd import numpy as np import itertools as it xy = list( it.product( range(10), range(10) ) ) df = pd.DataFrame( xy, columns=['x','y'] ) df['score'] = np.random.random( 100 ) kw = {'height_ratios':[13,2]} fig, (ax,ax2) = plt.subplots(2,1, gridspec_kw=kw, sharex=True) df.plot(kind='scatter', x='x', y='y', c='score', s=100, cmap="PuRd", ax=ax, colorbar=True) df.groupby("x").mean().plot(kind = 'bar', y='score',ax=ax2, legend=False) ax2.legend(bbox_to_anchor=(1.03,0),loc=3) pos = ax.get_position() pos2 = ax2.get_position() ax2.set_position([pos.x0,pos2.y0,pos.width,pos2.height]) plt.show()

enter image description here

  • 创建一个包含颜色条轴的网格。
    在这种情况下,您可以创建一个4乘4的网格,并将颜色条添加到它的右上轴。这需要将散点图提供给fig.colorbar()并指定颜色条的轴,

    fig.colorbar(ax.collections[0], cax=cax)       
    

    然后移除右下轴,这是不需要的(ax.axis("off"))。如果需要,您可以通过ax2.get_shared_x_axes().join(ax, ax2)分享轴。

    import matplotlib.pyplot as plt
    import pandas as pd
    import numpy as np
    import itertools as it
    
    
    xy = list( it.product( range(10), range(10) ) )
    df = pd.DataFrame( xy, columns=['x','y'] )
    df['score'] = np.random.random( 100 )
    
    kw = {'height_ratios':[13,2], "width_ratios":[95,5]}
    fig, ((ax, cax),(ax2,aux)) = plt.subplots(2,2,  gridspec_kw=kw)
    
    df.plot(kind='scatter', x='x',  y='y', c='score', s=80, cmap="PuRd",
             ax=ax,colorbar=False)
    df.groupby("x").mean().plot(kind = 'bar', y='score',ax=ax2, legend=False)
    
    fig.colorbar(ax.collections[0], cax=cax, label="score")
    aux.axis("off")
    ax2.legend(bbox_to_anchor=(1.03,0),loc=3)
    ax2.get_shared_x_axes().join(ax, ax2)
    ax.tick_params(axis="x", labelbottom=0)
    ax.set_xlabel("")
    
    plt.show()
    

enter image description here

答案 1 :(得分:0)

基于ImportanceOfBeingErnest的回答,以下两个功能将使轴对齐:

def align_axis_x(ax, ax_target):
    """Make x-axis of `ax` aligned with `ax_target` in figure"""
    posn_old, posn_target = ax.get_position(), ax_target.get_position()
    ax.set_position([posn_target.x0, posn_old.y0, posn_target.width, posn_old.height])

def align_axis_y(ax, ax_target):
    """Make y-axis of `ax` aligned with `ax_target` in figure"""
    posn_old, posn_target = ax.get_position(), ax_target.get_position()
    ax.set_position([posn_old.x0, posn_target.y0, posn_old.width, posn_target.height])