使用 Seaborn,如何让点图中的所有元素出现在 violoinplot 的元素上方?
Using Seaborn, how do I get all the elements from a pointplot to appear above the elements of a violoinplot?
使用 Seaborn 0.6.0,我试图在 violinplot
上叠加 pointplot
。我的问题是 violinplot
的个别观察结果中的 'sticks' 绘制在 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)
仔细观察此图,绿色误差线绘制在小提琴琴弦上方(看星期六),但蓝色误差线以及蓝点和绿点绘制在小提琴琴弦下方。
我尝试将 zorder
的不同组合传递给两个函数,但这并没有改善情节的外观。我能做些什么来让点图中的所有元素出现在 violoinplot 的所有元素之上吗?
这有点老套,我相信其他人会有更好的解决方案。请注意,我已经更改了您的颜色以提高两个图之间的对比度
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
编辑:根据@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('')
与 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)
使用 Seaborn 0.6.0,我试图在 violinplot
上叠加 pointplot
。我的问题是 violinplot
的个别观察结果中的 'sticks' 绘制在 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)
仔细观察此图,绿色误差线绘制在小提琴琴弦上方(看星期六),但蓝色误差线以及蓝点和绿点绘制在小提琴琴弦下方。
我尝试将 zorder
的不同组合传递给两个函数,但这并没有改善情节的外观。我能做些什么来让点图中的所有元素出现在 violoinplot 的所有元素之上吗?
这有点老套,我相信其他人会有更好的解决方案。请注意,我已经更改了您的颜色以提高两个图之间的对比度
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
编辑:根据@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('')
与 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)