代码之家  ›  专栏  ›  技术社区  ›  user3725021

用共享轴创建一个2x2网格的python seaborn热图

  •  2
  • user3725021  · 技术社区  · 6 年前

    我正在寻找从python中的pandas数据帧创建一个2x 2网格的海生热图,但是我很难得到想要的结果。目前,此代码…

    import numpy as np
    import pandas as pd
    import seaborn as sns
    
    df = pd.DataFrame({'x': np.random.uniform(0, 100, 1000), 
                       'y': np.random.uniform(0, 100, 1000), 
                       'z1': np.random.uniform(0, 1, 1000),
                       'z2': np.random.uniform(0, 1, 1000),
                       'z3': np.random.uniform(0, 1, 1000),
                       'z4': np.random.uniform(0, 1, 1000)})
    
    fig,axn = plt.subplots(2, 2, sharex=True, sharey=True)
    result0 = df.pivot(index='x', columns='y', values='z1')
    result1 = df.pivot(index='x', columns='y', values='z2')
    result2 = df.pivot(index='x', columns='y', values='z3')
    result3 = df.pivot(index='x', columns='y', values='z4')
    
    plt.subplot(2, 2, 1)
    sns.heatmap(result0, annot=False, cmap='RdBu_r')
    plt.subplot(2, 2, 2)
    sns.heatmap(result1, annot=False, cmap='RdBu_r')
    plt.subplot(2, 2, 3)
    sns.heatmap(result2, annot=False, cmap='RdBu_r')        
    plt.subplot(2, 2, 4)
    sns.heatmap(result3, annot=False, cmap='RdBu_r') 
    

    生成一个像这样的图形… enter image description here

    但我要添加的功能是:

    • 反转每个Y轴,使0位于底部,100位于顶部
    • 网格应该共享x轴和y轴,这样就不会不必要地显示记号。
    • y轴和x轴刻度应该是整数,而不是小数(尽管y系列是浮动的
    • 每个网格应该有一个单独的标题
    • 色条应在所有图表中共享

    这些样本数据并没有真正起到作用,但我想不出一种更好的ATM方式。如能帮忙解决以上五点,将不胜感激。谢谢!

    2 回复  |  直到 6 年前
        1
  •  1
  •   chthonicdaemon    6 年前

    关于你这里的数据, hexbin 更有意义的是 heatmap . 此解决方案使用 ImageGrid 很自然地处理大多数需求。请注意,我正在传递max和min的特定值,以便colorbar正常工作。

    from mpl_toolkits.axes_grid1 import ImageGrid
    
    fig = plt.figure()
    grid = ImageGrid(fig, 111, nrows_ncols=(2, 2), axes_pad=0.3, cbar_mode='single')
    
    for ax, col in zip(grid, ['z1', 'z2', 'z3', 'z4']):
        hb = ax.hexbin(df.x, df.y, C=df[col], cmap='RdBu_r', vmin=0, vmax=1)
        ax.set_title(col)
        ax.set_xlabel('x')
        ax.set_ylabel('y')
    
    grid.cbar_axes[0].colorbar(hb)
    

    sample hexbin

        2
  •  2
  •   phi    6 年前

    你可以玩 xticklabels , yticklabels , cbar 参数。

    fig,axn = plt.subplots(2, 2, sharex=True, sharey=True, figsize=(6, 6))
    xticks = ['{0:.0%}'.format(i/1000) if i % 100 == 0 else '' for i in range(1000)]
    yticks = ['{0:.0%}'.format(i/1000) if i % 100 == 0 else '' for i in range(999, 0, -1)]
    ax = plt.subplot(2, 2, 1)
    cbar_ax = fig.add_axes([.91, .3, .03, .4])
    
    sns.heatmap(
        result0.iloc[-1::-1, -1::-1], annot=False, cmap='RdBu_r',
        xticklabels=False, yticklabels=yticks, cbar=False, ax=ax)
    ax.set_title('Title 1')
    ax.set_aspect('equal')
    
    ax = plt.subplot(2, 2, 2)
    sns.heatmap(
        result1.iloc[-1::-1, -1::-1], annot=False, cmap='RdBu_r',
        xticklabels=False, yticklabels=False, cbar=False, ax=ax)
    ax.set_title('Title 2')
    ax.set_aspect('equal')
    
    ax = plt.subplot(2, 2, 3)
    sns.heatmap(
        result2.iloc[-1::-1, -1::-1], annot=False, cmap='RdBu_r',
        xticklabels=xticks, yticklabels=yticks, cbar=False, ax=ax)
    ax.set_title('Title 3')
    ax.set_aspect('equal')
    
    ax = plt.subplot(2, 2, 4)
    sns.heatmap(
        result3.iloc[-1::-1, -1::-1], annot=False, cmap='RdBu_r',
        xticklabels=xticks, yticklabels=False, cbar=True, cbar_ax=cbar_ax, ax=ax)
    ax.set_title('Title 4')
    ax.set_aspect('equal')
    fig.tight_layout(rect=[0, 0, .9, 1])
    

    工具书类

    One colorbar for seaborn heatmaps in subplot

    How can I set the aspect ratio in matplotlib?

    enter image description here