如何改变单个swarm组的位置

如何改变单个swarm组的位置

本文介绍了如何改变单个swarm组的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在绘制一个分组条形图,在该条形图上叠加了一个群图和误差条.其中一个组只有一个条形,我想在分配给这组条形的位置中间出现(带有群和误差条).

我设法移动了栏和错误栏,但不确定如何移动群.

这是我的代码:

将 seaborn 导入为 sns导入 matplotlib.pyplot 作为 pltmypallet = sns.color_palette([(190/256,7/256, 18/256),(127/256, 127/256, 127/256)])导入迭代工具将 numpy 导入为 npplt.rcParams['figure.figsize'] = 7, 5提示 = sns.load_dataset("提示")提示[(tips.day=='星期四') &(tips.sex=='女性')] = np.nan打印(sns.__version__)打印(提示.头())# 比普通字体大sns.set(font_scale=1.5)ax = sns.swarmplot(x="day", y="total_bill",hue="sex",数据=提示,拆分=真,颜色=k")ax = sns.barplot(x="day", y="total_bill", Hue="sex",数据=提示,倾覆=0.1,alpha=0.8,错误宽度=1.25,ci=无,调色板=我的托盘)xcentres = [0.2, 1, 2, 3]三角洲 = 0.2xneg = [x-delt for x in xcentres]xpos = [x+delt for x in xcentres]xvals = xneg + xposxvals.sort()yvals = tips.groupby(["day", "sex"]).mean().total_billyerr = tips.groupby(["day", "sex"]).std().total_bill(_, caps, _)=ax.errorbar(x=xvals, y=yvals, yerr=yerr, capsize=4,ecolor="red", elinewidth=1.25, fmt='none')盖帽:cap.set_markeredgewidth(2)句柄,标签 = ax.get_legend_handles_labels()l = ax.legend(handles[0:2], labels[0:2]) # 更改基于 https://stackoverflow.com/a/42768387/8508004#sns.ax.ylim([0,60]) #originalax.set_ylim([0,60]) # 改编自 https://stackoverflow.com/a/49049501/8508004 并改为图例ax.set_ylabel("Out-of-sample R2") # 基于 https://stackoverflow.com/a/46235777/8508004ax.set_xlabel("") # 基于 https://stackoverflow.com/a/46235777/8508004对于我,枚举中的栏(ax.patches):孵化 = '///'bar.set_hatch(舱口)bar.set_x(bar.get_x() + bar.get_width()/2)休息

我希望左侧栏的群与栏的中间位置对齐.

解决方案

让我们使用

I am plotting a grouped bar plot on which I overlay a swarmplot and errorbars. One of the groups only have one bar, which I want to appear (with the swarm and the errorbar) in the middle of the location allocated to this group of bars.

I managed to move the bar and the errorbar, but not sure how to move the swarm.

Here is the code I have:

import seaborn as sns
import matplotlib.pyplot as plt
mypallet = sns.color_palette([(190/256,7/256, 18/256),(127/256, 127/256, 127/256)])
import itertools
import numpy as np

plt.rcParams['figure.figsize'] = 7, 5
tips = sns.load_dataset("tips")
tips[(tips.day=='Thur') & (tips.sex=='Female') ] = np.nan
print(sns.__version__)
print(tips.head())
# Bigger than normal fonts
sns.set(font_scale=1.5)

ax = sns.swarmplot(x="day", y="total_bill", hue="sex",
                 data=tips, split=True, color='k')
ax = sns.barplot(x="day", y="total_bill", hue="sex",
                 data=tips, capsize=0.1, alpha=0.8,
                 errwidth=1.25, ci=None, palette=mypallet)
xcentres = [0.2, 1, 2, 3]
delt = 0.2
xneg = [x-delt for x in xcentres]
xpos = [x+delt for x in xcentres]
xvals = xneg + xpos
xvals.sort()
yvals = tips.groupby(["day", "sex"]).mean().total_bill
yerr = tips.groupby(["day", "sex"]).std().total_bill

(_, caps, _)=ax.errorbar(x=xvals, y=yvals, yerr=yerr, capsize=4,
                         ecolor="red", elinewidth=1.25, fmt='none')
for cap in caps:
    cap.set_markeredgewidth(2)

handles, labels = ax.get_legend_handles_labels()
l = ax.legend(handles[0:2], labels[0:2]) # changed based on https://stackoverflow.com/a/42768387/8508004
#sns.ax.ylim([0,60]) #original
ax.set_ylim([0,60]) # adapted from https://stackoverflow.com/a/49049501/8508004 and change to legend
ax.set_ylabel("Out-of-sample R2") # based on https://stackoverflow.com/a/46235777/8508004
ax.set_xlabel("") # based on https://stackoverflow.com/a/46235777/8508004

for i, bar in enumerate(ax.patches):
    hatch = '///'
    bar.set_hatch(hatch)
    bar.set_x(bar.get_x() + bar.get_width()/2)
    break

I'd like the swarm of the left bar to be aligned with the middle position of the bar.

解决方案

Let's use matplotlib.collections set_offsets:

import seaborn as sns
import matplotlib.pyplot as plt
mypallet = sns.color_palette([(190/256,7/256, 18/256),(127/256, 127/256, 127/256)])
import itertools
import numpy as np

plt.rcParams['figure.figsize'] = 7, 5
tips = sns.load_dataset("tips")
tips[(tips.day=='Thur') & (tips.sex=='Female') ] = np.nan
print(sns.__version__)
print(tips.head())
# Bigger than normal fonts
sns.set(font_scale=1.5)

ax = sns.swarmplot(x="day", y="total_bill", hue="sex",
                 data=tips, dodge=True, color='k')

#get first patchcollection
c0 = ax.get_children()[0]
x,y = np.array(c0.get_offsets()).T
#Add .2 to x values
xnew=x+.2
offsets = list(zip(xnew,y))
#set newoffsets
c0.set_offsets(offsets)

ax = sns.barplot(x="day", y="total_bill", hue="sex",
                 data=tips, capsize=0.1, alpha=0.8,
                 errwidth=1.25, ci=None, palette=mypallet)
xcentres = [0.2, 1, 2, 3]
delt = 0.2
xneg = [x-delt for x in xcentres]
xpos = [x+delt for x in xcentres]
xvals = xneg + xpos
xvals.sort()
yvals = tips.groupby(["day", "sex"]).mean().total_bill
yerr = tips.groupby(["day", "sex"]).std().total_bill

(_, caps, _)=ax.errorbar(x=xvals, y=yvals, yerr=yerr, capsize=4,
                         ecolor="red", elinewidth=1.25, fmt='none')
for cap in caps:
    cap.set_markeredgewidth(2)


handles, labels = ax.get_legend_handles_labels()
l = ax.legend(handles[0:2], labels[0:2]) # changed based on https://stackoverflow.com/a/42768387/8508004
#sns.ax.ylim([0,60]) #original
ax.set_ylim([0,60]) # adapted from https://stackoverflow.com/a/49049501/8508004 and change to legend
ax.set_ylabel("Out-of-sample R2") # based on https://stackoverflow.com/a/46235777/8508004
ax.set_xlabel("") # based on https://stackoverflow.com/a/46235777/8508004

for i, bar in enumerate(ax.patches):
    hatch = '///'
    bar.set_hatch(hatch)
    bar.set_x(bar.get_x() + bar.get_width()/2)
    break

Output:

这篇关于如何改变单个swarm组的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 00:09