使用Seaborn,如何将点图中的所有元素显示在violoinplot元素的上方?

时间:2015-08-29 00:45:25

标签: python matplotlib seaborn z-order

使用Seaborn 0.6.0,我尝试在pointplot上叠加violinplot。我的问题是violinplot的个别观察中的'棍棒'被绘制在pointplot的标记之上,如下所示。

import seaborn as sns
import matplotlib.pyplot as plt

fig, ax = plt.subplots(1, figsize=[12,8])
sns.violinplot(x="day", y="total_bill", hue="smoker", data=tips,
               split=True, inner='stick', ax=ax, palette=['white']*2)
sns.pointplot(x="day", y='total_bill', hue="smoker",
                   data=tips, dodge=0.3, ax=ax, join=False)

enter image description here

仔细观察这个图,看起来绿色的误差栏是在violoin棒上方(周六看),但蓝色的误差条,以及蓝色和绿色的点都画在小提琴棒的下方。

我尝试将zorder的不同组合传递给两个函数,但这并没有改善情节外观。我能做些什么来让点图中的所有元素出现在violoinplot的所有元素之上?

2 个答案:

答案 0 :(得分:8)

类似于Diziet Asahi的答案,但更简单一点。由于我们正在设置zorder,因此我们不需要按照我们希望它们出现的顺序绘制绘图,这样可以省去排序艺术家的麻烦。我也是这样做的,所以点图没有出现在图例中,它没有用。

import seaborn as sns
import matploltlib.pyplot as plt

tips = sns.load_dataset("tips")

ax = sns.pointplot(x="day", y='total_bill', hue="smoker",
              data=tips, dodge=0.3, join=False, palette=['white'])
plt.setp(ax.lines, zorder=100)
plt.setp(ax.collections, zorder=100, label="")

sns.violinplot(x="day", y="total_bill", hue="smoker", data=tips,
               split=True, inner='stick', ax=ax)

enter image description here

答案 1 :(得分:3)

这有点黑客,我确定别人会有更好的解决方案。请注意,我已经改变了颜色以改善两个图之间的对比度

tips = sns.load_dataset("tips")

fig, ax = plt.subplots(1, figsize=[12,8])
sns.violinplot(x="day", y="total_bill", hue="smoker", data=tips,
               split=True, inner='stick', ax=ax)
a = list(ax.get_children()) # gets the artists created by violinplot
sns.pointplot(x="day", y='total_bill', hue="smoker",
                   data=tips, dodge=0.3, ax=ax, join=False, palette=['white'])
b = list(ax.get_children()) # gets the artists created by violinplot+pointplot

# get only the artists in `b` that are not in `a`
c = set(b)-set(a)
for d in c:
    d.set_zorder(1000) # set a-order to a high value to be sure they are on top

enter image description here

编辑:关注@tcaswell的评论,我还提出了另一个解决方案(创建2个轴,每种类型的一个图)。但请注意,如果你要去路线,那么你必须重新修改图例,因为它们最终会叠加在当前的例子中。

tips = sns.load_dataset("tips")

fig = plt.figure(figsize=[12,8])
ax1 = fig.add_subplot(111)
sns.violinplot(x="day", y="total_bill", hue="smoker", data=tips,
               split=True, inner='stick', ax=ax1)

ax2 = fig.add_subplot(111, frameon=False, sharex=ax1, sharey=ax1)
sns.pointplot(x="day", y='total_bill', hue="smoker",
                   data=tips, dodge=0.3, ax=ax2, join=False, palette=['white'])
ax2.set_xlabel('')
ax2.set_ylabel('')

enter image description here