【问题标题】:Seaborn boxplot with grouped data into categories with count columnSeaborn 箱线图,将数据分组到具有计数列的类别中
【发布时间】:2021-12-31 10:56:32
【问题描述】:

我在尝试使用 seaborn 箱线图绘制数据集时遇到问题。我收到了一个从数据库中分组的数据集,例如:

         region   age  total
0              STC   2.0  11024
1              PHA  84.0   3904
2              OLK  55.0  12944
3              VYS  72.0   5592
4              PAK  86.0   2168
...            ...   ...    ...
1460           KVK  62.0   4600
1461           MSK  41.0  26568
1462           LBK  13.0   6928
1463           JHC  18.0   8296
1464           HKK  88.0   2408

我想创建一个箱线图,该区域在 x 尺度上,年龄在 y 尺度上,基于观察的总数。

当我尝试ax = sns.boxplot(x='region', y='age', data=df) 时,我收到一个简单的箱线图,其中没有考虑总列。一个硬编码选项是按总数重复行,但我不喜欢这种解决方案。

【问题讨论】:

  • 欢迎来到Stack Overflow.。为了让我们为您提供帮助,您有必要提供一个最小的可重现问题集,其中包括样本输入、预期输出、实际输出以及重现该示例所需的所有相关代码。你所提供的没有达到这个目标。请编辑您的问题以显示最小的可重现集。详情请见Minimal Reproducible Example

标签: python pandas seaborn


【解决方案1】:

sns.histplotsns.kdeplot 支持 weigts= 参数,但 sns.boxplot 不支持。简单地重复值不一定是一个糟糕的解决方案,但在这种情况下,数字非常大。您可以创建一个包含重复数据的新数据框,但将 'total' 列分开以使值易于管理。

样本数据具有所有不同的区域,这使得创建箱线图相当奇怪。下面的代码假设没有太多区域(1400 个区域肯定不能很好地工作)。

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
from io import StringIO

df_str = ''' region   age  total
                STC   2.0  11024
                STC  84.0   3904
                STC  55.0  12944
                STC  72.0   5592
                STC  86.0   2168
                PHA  62.0   4600
                PHA  41.0  26568
                PHA  13.0   6928
                PHA  18.0   8296
                PHA  88.0   2408'''
df = pd.read_csv(StringIO(df_str), delim_whitespace=True)
# use a scaled down version of the totals as a repeat factor
repeats = df['total'].to_numpy(dtype=int) // 100
df_total = pd.DataFrame({'region': np.repeat(df['region'].values, repeats),
                         'age': np.repeat(df['age'].values, repeats)})

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(14, 4))
sns.kdeplot(data=df, x='age', weights='total', hue='region', ax=ax1)
sns.boxplot(data=df_total, y='age', x='region', ax=ax2)
plt.tight_layout()
plt.show()

另一种方法是在 seaborn 之外执行所有操作,使用 statsmodels.stats.weightstats.DescrStatsW 计算百分位数并通过 matplotlib 绘制箱线图。离群值仍然需要单独计算。 (另见this post

【讨论】:

  • 嗯,只有 14 个区域。我认为除以总数然后重复将是一个好方法。非常感谢您的建议!
  • 如果这回答了您的问题,您可能会将marking 的答案视为已接受。
猜你喜欢
  • 1970-01-01
  • 2019-04-29
  • 2021-02-03
  • 2016-12-18
  • 2021-03-08
  • 2018-12-05
  • 1970-01-01
  • 2021-04-18
  • 2021-02-28
相关资源
最近更新 更多