Seaborn FacetGrid-在最后一个子图之后放置单个颜色条 [英] Seaborn FacetGrid - Place single colorbar after last subplot

查看:159
本文介绍了Seaborn FacetGrid-在最后一个子图之后放置单个颜色条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将色条添加到3个海洋图的网格中.我可以将颜色条添加到3个单独的图上,或将颜色条挤压在第3个图旁边.我希望在第三个图之后有一个颜色条,而不会更改最后一个图的大小.

I'm trying to add a colorbar to a grid of 3 seaborn plots. I am able to add the colorbar to the 3 individual plots, or squeeze a colour bar next to the 3rd plot. I would like to have a single colorbar after the 3rd plot, without changing the size of the last plot.

我从这个答案中得到了很多好主意,但无法解决我的确切问题:

I got lots of good ideas from this answer, but couldn't solve my exact problem: SO Question/Answer

这是我当前的代码:

import seaborn as sns

def masked_vs_unmasked_facets(output_dir, merged_df, target_col, thresholds):
    # defining the maximal values, to make the plot square
    z_min = merged_df[['z_full', 'z_masked']].min(axis=0, skipna=True).min(skipna=True)
    z_max = merged_df[['z_full', 'z_masked']].max(axis=0, skipna=True).max(skipna=True)
    z_range_value = max(abs(z_min), abs(z_max))

    # Setting the column values to create the facet grid
    for i, val in enumerate(thresholds):
        merged_df.loc[merged_df.info_score_masked > val, 'PlotSet'] = i

    # Start the actual plots
    g = sns.FacetGrid(merged_df, col='PlotSet', size=8)

    def facet_scatter(x, y, c, **kwargs):
        kwargs.pop("color")
        plt.scatter(x, y, c=c, **kwargs)
        # plt.colorbar() for multiple colourbars

    vmin, vmax = 0, 1
    norm=plt.Normalize(vmin=vmin, vmax=vmax)

    g = (g.map(facet_scatter, 'z_full', 'z_masked', 'info_score_masked', norm=norm, cmap='viridis'))

    ax = g.axes[0]
    for ax in ax:
        ax.set_xlim([-z_range_value * 1.1, z_range_value * 1.1])
        ax.set_ylim([-z_range_value * 1.1, z_range_value * 1.1])
        ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3")

    plt.colorbar() # Single squashed colorbar
    plt.show()

masked_vs_unmasked_facets(output_dir, masking_results, 'info_score_masked', [0, 0.7, 0.9])

单个配色条,但第三幅图被挤压 多个色标,但拥挤

Single colorbar, but 3rd plot squashed Multiple colorbars, but crowded

推荐答案

根据@ImportanceOfBeingEarnest的建议,我发现我需要向facetgrid添加另一组轴,然后将这些轴分配给颜色栏.为了将多余的元素保存到绘图中,我将bbox_extra_artist kwarg用于紧密边界框.另一个较小的补充是一个小条款,用于捕获我的一个方面没有数据的情况.在这种情况下,我将一个空行附加了一个实例类别,因此每个类别始终至少有1行.

Following advice from @ImportanceOfBeingEarnest, I found that I needed to add another set of axes to the facetgrid, and then assign these axes to the colorbar. In order to get this extra element saved to the plot, I used the bbox_extra_artist kwarg for the tight bounding box. Another minor addition was a small clause to catch edge cases where one of my facets had no data. In this case, I appended an empty row with a single instance the category, so there was always at least 1 row for each category.

import seaborn as sns

def masked_vs_unmasked_facets(output_dir, merged_df, target_col, thresholds):
    z_min = merged_df[['z_full', 'z_masked']].min(axis=0, skipna=True).min(skipna=True)
    z_max = merged_df[['z_full', 'z_masked']].max(axis=0, skipna=True).max(skipna=True)
    z_range_value = max(abs(z_min), abs(z_max))

    for i, val in enumerate(thresholds):
        merged_df.loc[merged_df.info_score_masked > val, 'PlotSet'] = i
        # Catch instances where there are no values in category, to ensure all facets are drawn each time
        if i not in merged_df['PlotSet'].unique():
            dummy_row = pd.DataFrame(columns=merged_df.columns, data={'PlotSet': [i]})
            merged_df = merged_df.append(dummy_row)

    g = sns.FacetGrid(merged_df, col='PlotSet', size=8)

    def facet_scatter(x, y, c, **kwargs):
        kwargs.pop("color")
        plt.scatter(x, y, c=c, **kwargs)

    vmin, vmax = 0, 1
    norm=plt.Normalize(vmin=vmin, vmax=vmax)

    g = (g.map(facet_scatter, 'z_full', 'z_masked', 'info_score_masked', norm=norm, cmap='viridis'))

    titles = ["Correlation for all masked / unmasked z-score with {} above {}".format(target_col, threshold) for threshold in thresholds]

    axs = g.axes.flatten()
    for i, ax in enumerate(axs):
        ax.set_title(titles[i])
        ax.set_xlim([-z_range_value * 1.1, z_range_value * 1.1])
        ax.set_ylim([-z_range_value * 1.1, z_range_value * 1.1])
        ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3")


    cbar_ax = g.fig.add_axes([1.015,0.13, 0.015, 0.8])
    plt.colorbar(cax=cbar_ax)
    # extra_artists used here
    plt.savefig(os.path.join(output_dir, 'masked_vs_unmasked_scatter_final.png'), bbox_extra_artists=(cbar_ax,),  bbox_inches='tight')

masked_vs_unmasked_facets(output_dir, masking_results, 'info_score_masked', [0, 0.7, 0.9])

这给了我

这篇关于Seaborn FacetGrid-在最后一个子图之后放置单个颜色条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆