如何将箱线图叠加在 Seaborn 的群图之上?
How can box plot be overlaid on top of swarm plot in Seaborn?
我正在尝试使用 matplotlib 和 Seaborn 一起绘制群图和箱线图。我找到了如何将它们绘制在一起,但箱形图出现在群图下方。这样做的问题是群图点淹没了箱线图,箱线图丢失了。我认为通过切换调用函数的顺序,首先调用箱线图而不是下面 link 中的第二个箱线图,会将箱线图覆盖在顶部,但事实并非如此。
是否可以将箱线图叠加在群体绘图点之上?如果不是,是否可以创建指示四分位数位置的线?
代码:
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()
这个问题与相关,但不完全相同,因为我想改变风格,而不是将两者放在一起。
您需要更改 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)
问题在于箱线图由许多不同的艺术家组成,并且由于 seaborn 包装机制,我们不能简单地将完整箱线图的 zorder 设置为某个更高的数字。
第一个天真的尝试是将群图的 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()
如果需要网格线,我们可以将群图的 zorder 设置为 1,使其出现在网格线上方,并将箱线图的 zorder 设置为较高的数字。如上所述,这需要将 zorder 属性 设置为其每个元素,因为 boxplot
调用中的 zorder=10
不会影响所有艺术家。相反,我们需要使用 boxprops
、whiskerprops
参数来为它们设置 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()
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)
我正在尝试使用 matplotlib 和 Seaborn 一起绘制群图和箱线图。我找到了如何将它们绘制在一起,但箱形图出现在群图下方。这样做的问题是群图点淹没了箱线图,箱线图丢失了。我认为通过切换调用函数的顺序,首先调用箱线图而不是下面 link 中的第二个箱线图,会将箱线图覆盖在顶部,但事实并非如此。
是否可以将箱线图叠加在群体绘图点之上?如果不是,是否可以创建指示四分位数位置的线?
代码:
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()
这个问题与
您需要更改 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)
问题在于箱线图由许多不同的艺术家组成,并且由于 seaborn 包装机制,我们不能简单地将完整箱线图的 zorder 设置为某个更高的数字。
第一个天真的尝试是将群图的 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()
如果需要网格线,我们可以将群图的 zorder 设置为 1,使其出现在网格线上方,并将箱线图的 zorder 设置为较高的数字。如上所述,这需要将 zorder 属性 设置为其每个元素,因为 boxplot
调用中的 zorder=10
不会影响所有艺术家。相反,我们需要使用 boxprops
、whiskerprops
参数来为它们设置 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()
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)