matplotlib 如何在Seaborn中将箱线图叠加在群图之上?

nkhmeac6  于 2023-03-30  发布在  其他
关注(0)|答案(3)|浏览(180)

我试图使用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()

这个问题与如何使用matplotlib创建一个swarm plot有关,但并不完全相同,因为我希望改变风格,而不仅仅是将两者放在一起。

bbmckpt7

bbmckpt71#

问题是箱线图由许多不同的艺术家组成,并且由于seaborn Package 机制,我们不能简单地将完整箱线图的zorder设置为更高的数字。
第一个简单的尝试是将群体图的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=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,这样它就出现在网格线的上方,并将boxplot的zorder设置为一个大的数字。如上所述,这需要将zorder属性设置为其每个元素,因为boxplot调用中的zorder=10不会影响所有艺术家。相反,我们需要使用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()

bz4sfanl

bz4sfanl2#

您需要更改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)

tvokkenx

tvokkenx3#

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)

相关问题