【问题标题】:How can box plot be overlaid on top of swarm plot in Seaborn?箱线图如何覆盖在 Seaborn 的群体图之上?
【发布时间】:2021-08-28 03:32:51
【问题描述】:

我正在尝试使用 matplotlib 和 Seaborn 一起绘制群体图和箱线图。我找到了如何将它们绘制在一起,但箱形图出现在群体图下方。这样做的问题是群体图点淹没了箱线图并且箱线图丢失了。我认为通过切换调用函数的顺序,首先调用箱形图而不是下面链接中的第二个,将箱形图覆盖在顶部,但事实并非如此。

是否可以将箱线图叠加在群体图点之上?如果没有,是否可以创建指示四分位数所在位置的线条?

代码:

swarm_name = "Swarm_Plot_01"
#
sns.set_style("whitegrid")
ax = sns.boxplot(   data = [df.Rate_VL1R, df.Rate_V12R, df.Rate_V23R, df.Rate_VM3R ],
   showcaps=False,boxprops={'facecolor':'None'},
   showfliers=False,whiskerprops={'linewidth':0})
ax = sns.swarmplot( data = [df.Rate_VL1R, df.Rate_V12R, df.Rate_V23R, df.Rate_VM3R ] )
plt.show()
fig = ax.get_figure()
fig.savefig(swarm_name)
plt.figure()

这个问题与How to create a swarm plot with matplotlib 相关但不完全相同,因为我希望改变风格,而不仅仅是将两者放在一起。

【问题讨论】:

    标签: python matplotlib data-visualization seaborn boxplot


    【解决方案1】:

    问题是箱线图由许多不同的艺术家组成,并且由于 seaborn 包装机制,我们不能简单地将完整箱线图的 zorder 设置为更高的数字。

    第一次天真的尝试是将 swarmplot 的 zorder 设置为零。虽然这将 swarmplot 点放在箱线图后面,但它也将它们放在网格线后面。因此,只有在不使用网格线的情况下,该解决方案才是最优的。

    import seaborn as sns
    import matplotlib.pyplot as plt
    tips = sns.load_dataset("tips")
    
    # plot swarmplot
    ax = sns.swarmplot(x="day", y="total_bill", data=tips, zorder=0)
    # plot boxplot
    sns.boxplot(x="day", y="total_bill", data=tips, 
                     showcaps=False,boxprops={'facecolor':'None'},
                     showfliers=False,whiskerprops={'linewidth':0}, ax=ax)
    
    plt.show()
    

    如果需要网格线,我们可以将 swarmplot 的 zorder 设置为 1,使其显示在网格线上方,并将箱线图的 zorder 设置为较高的数字。如上所述,这需要将 zorder 属性设置为它的每个元素,因为 zorder=10boxplot 调用中不会影响所有艺术家。相反,我们需要使用 boxpropswhiskerprops 参数来设置这些参数的 zorder 属性。

    import seaborn as sns
    import matplotlib.pyplot as plt
    tips = sns.load_dataset("tips")
    
    # plot swarmplot
    ax = sns.swarmplot(x="day", y="total_bill", data=tips, zorder=1)
    # plot boxplot
    sns.boxplot(x="day", y="total_bill", data=tips, 
                     showcaps=False,boxprops={'facecolor':'None', "zorder":10},
                     showfliers=False,whiskerprops={'linewidth':0, "zorder":10},
                     ax=ax, zorder=10)
    
    plt.show()
    

    最终的解决方案,可以应用于根本无法访问艺术家属性的一般情况,是遍历轴艺术家并根据他们是否属于一个或另一个情节为他们设置 zorder。

    import seaborn as sns
    import matplotlib.pyplot as plt
    tips = sns.load_dataset("tips")
    
    # plot swarmplot
    ax = sns.swarmplot(x="day", y="total_bill", data=tips)
    #get all children of axes
    children1 = ax.get_children()
    # plot boxplot
    sns.boxplot(x="day", y="total_bill", data=tips, 
                     showcaps=False,boxprops={'facecolor':'None'},
                     showfliers=False,whiskerprops={'linewidth':0}, ax=ax)
    # again, get all children of axes.
    children2 = ax.get_children()
    # now those children which are in children2 but not in children1
    # must be part of the boxplot. Set zorder high for those.
    for child in children2:
        if not child in children1:
            child.set_zorder(10)
    
    plt.show()
    

    【讨论】:

    • “问题是箱线图由许多不同的艺术家组成,并且由于 seaborn 包装机制,我们无法直接访问所有这些艺术家。”您无法接触到哪些艺术家?
    • 我最初的意思是对 sns.boxplot 的调用只返回一个轴而不是要使用的集合。我同意这是误导性的,并且会改变它。
    • 这很好,但我很难弄清楚如何在无法看到“提示”数据集的情况下重现。请问可以发个链接吗?
    【解决方案2】:

    您需要更改swarmplot上的zorder

    import seaborn.apionly as sns 
    tips = sns.load_dataset("tips")
    sns.boxplot("day", "tip", data=tips, boxprops={'facecolor':'None'})
    sns.swarmplot("day", "tip", data=tips, zorder=.5)
    

    【讨论】:

      【解决方案3】:

      ImportanceOfBeingErnest 的最后一个通用解决方案几乎对我有用(Python 3.5.4),除了中位数不可见。显然,彩色箱线图主体的 zorder 隐藏了中位数。我的解决方案是将较低的 zorder 应用于补丁。

      from matplotlib.patches import PathPatch
      
      children2 = axarr[j].get_children()
      for child in children2:
          if not child in children1:
              if isinstance(child, PathPatch):
                  child.set_zorder(10)
              else:
                  child.set_zorder(11)
      

      【讨论】:

        猜你喜欢
        • 2017-01-05
        • 2019-10-12
        • 2017-05-14
        • 2021-09-08
        • 2023-03-29
        • 1970-01-01
        • 2021-10-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多