将所有数据的聚合添加到框图 [英] Add aggregate of all data to boxplots
本文介绍了将所有数据的聚合添加到框图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个数据集,其中包含不同域的分数。因此可以将其视为具有列domain
和score
的DataFrame。我想画每个领域的框图。这很容易。对于海运,情况如下:
import seaborn as sns
data = {"domain": ["econ", "econ", "public_affairs", "culture", "communication", "public_affairs", "communication", "culture", "public_affairs", "econ", "culture", "econ", "communication"],
"score": [0.25, 0.3, 0.5684, 0.198, 0.15, 0.486, 0.78, 0.84, 0.48, 0.81, 0.1, 0.23, 0.5]}
ax = sns.boxplot(x="score", y="domain", data=data)
这将产生下图:
但是,我希望在y轴上添加另一个记号,其中为所有分数绘制了一个框图,而不考虑它们的域,记号标签为";all";。如果这个新的";all";盒图可以用水平线与其他数据分开,以表明";all";本身不是一个域,那就太好了。
我在一个照片编辑器程序中将一些东西混合在一起,以说明我正在寻找的东西,所以应该是这样的。特别重要的是所有绘图之间的共享轴。
我的最佳尝试如下,它看起来与我在上面的示例中期望的不太一样。
import seaborn as sns
data = {"domain": ["econ", "econ", "public_affairs", "culture", "communication", "public_affairs", "communication", "culture", "public_affairs", "econ", "culture", "econ", "communication"],
"score": [0.25, 0.3, 0.5684, 0.198, 0.15, 0.486, 0.78, 0.84, 0.48, 0.81, 0.1, 0.23, 0.5]}
fig, axes = plt.subplots(2, 1, sharex=True)
sns.boxplot(ax=axes[0], x="score", y="domain", data=data)
all_box = sns.boxplot(ax=axes[1], data=data["score"], orient="h")
推荐答案
您可以使用gridspec_kw
设置绘图之间的比率(例如,[1,4]
因为一个子图有4倍多的框)。子图之间的间距可以通过hspace
微调。axes[0].set_yticklabels()
用于设置标签。
import matplotlib.pyplot as plt
import seaborn as sns
data = {"domain": ["econ", "econ", "public_affairs", "culture", "communication", "public_affairs", "communication", "culture", "public_affairs", "econ", "culture", "econ", "communication"],
"score": [0.25, 0.3, 0.5684, 0.198, 0.15, 0.486, 0.78, 0.84, 0.48, 0.81, 0.1, 0.23, 0.5]}
fig, axes = plt.subplots(2, 1, sharex=True,
gridspec_kw={'height_ratios': [1, 4], 'hspace': 0})
sns.set_style('white')
sns.boxplot(ax=axes[0], data=data["score"], orient="h", color='0.6')
axes[0].set_yticklabels(['All'])
sns.boxplot(ax=axes[1], x="score", y="domain", palette='Set2', data=data)
plt.tight_layout()
plt.show()
另一种方法是将数据与一个副本和一个到处都是"All"
的标签连接在一起。对于 pandas 数据帧,您可以使用df.copy()
和pd.concat()
。只需一本列表字典,您就可以简单地复制列表。
这样,所有盒子的厚度都完全相同。因为它只使用一个ax
,所以更容易与其他子图结合。
import matplotlib.pyplot as plt
import seaborn as sns
data = {"domain": ["econ", "econ", "public_affairs", "culture", "communication", "public_affairs", "communication", "culture", "public_affairs", "econ", "culture", "econ", "communication"],
"score": [0.25, 0.3, 0.5684, 0.198, 0.15, 0.486, 0.78, 0.84, 0.48, 0.81, 0.1, 0.23, 0.5]}
data_concatenated = {"domain": ['All'] * len(data["domain"]) + data["domain"],
"score": data["score"] * 2}
sns.set_style('darkgrid')
palette = ['yellow'] + list(plt.cm.Set2.colors)
ax = sns.boxplot(x="score", y="domain", palette=palette, data=data_concatenated)
ax.axhline(0.5, color='0.5', ls=':')
plt.tight_layout()
plt.show()
这里是另一个示例,使用 pandas 和海运的航班数据集。它显示了在不添加额外水平线的情况下使摘要突出的不同方法:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
flights = sns.load_dataset('flights')
flights_all = flights.copy()
flights_all['year'] = 'All'
sns.set_style('darkgrid')
palette = ['crimson'] + sns.color_palette('crest', len(flights['year'].unique()))
ax = sns.boxplot(x="passengers", y="year", palette=palette, orient='h', data=pd.concat([flights_all, flights]))
ax.axhspan(-0.5, 0.5, color='0.85', zorder=-1)
# ax.axhline(0.5, color='red', ls=':') # optional separator line
# ax.get_yticklabels()[0].set_color('crimson')
ax.get_yticklabels()[0].set_weight('bold')
plt.tight_layout()
plt.show()
这篇关于将所有数据的聚合添加到框图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文