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

joe*_*lom 4 python matplotlib z-order seaborn

使用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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

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

mwa*_*kom 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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Diz*_*ahi 6

这有点hack-ish,我相信其他人会有更好的解决方案。请注意,我更改了您的颜色以提高两个图之间的对比度

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
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

编辑:根据 @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('')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 应该有一种方法可以询问seaborn返回的对象调用它创建的新艺术家,这样你就不必执行“设置”逻辑。如果没有,我将被动地主动要求您将其报告为针对seaborn的错误;) (2认同)