将所有数据的聚合添加到框图 [英] Add aggregate of all data to boxplots

查看:29
本文介绍了将所有数据的聚合添加到框图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数据集,其中包含不同域的分数。因此可以将其视为具有列domainscore的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆