Pandas 按类别对箱线图进行分组以比较 3 个数据集 Matplotlib

Pandas Grouped Boxplot by Category to Compare 3 Datasets Matplotlib

我正在尝试通过“site_name”为 3 个数据集生成单独的分组箱线图 - 'obs'、'raw' 和 'adj'。因此,最终图应该有 3 个分组的并排箱线图 'obs'、'raw' 和 'adj' 时间序列 'site_name' 或 SITE A、SITE B例子。我有这样的数据:

    site_name   obs         raw         adj
0   SITE A  6.418529189 11.23949224 6.985811001
1   SITE A  8.788185389 14.97198142 9.321099071
2   SITE A  9.150093299 15.03959828 9.974189383
3   SITE A  8.960796086 14.53909986 10.08513361
4   SITE A  7.04010526  11.32339089 7.496043956
5   SITE A  7.750408473 12.23209169 7.893739255
6   SITE A  5.396922286 9.262985075 5.584104478
7   SITE A  4.842398234 8.77877907  5.436729651
8   SITE A  2.46593252  4.809821429 2.779181548
9   SITE A  5.650324669 9.868885673 6.720622287
10  SITE B  12.98071991 14.58748261 13.09878999
11  SITE B  8.768521796 9.628748068 8.751576507
12  SITE B  7.163978706 8.305841446 7.146397775
13  SITE B  7.765772425 8.367532468 7.540894661
14  SITE B  6.370840508 5.733239437 5.893661972
15  SITE B  4.46220486  5.286569343 4.356613139
16  SITE B  8.766229103 9.188587732 8.637717546
17  SITE B  7.648023594 7.622237762 7.481734266
18  SITE B  6.26515501  6.109928058 6.035798561
19  SITE B  6.962116967 8.466759388 7.241140473

而且,我试过了,但它什么也没画,还给我一个错误 -

df.boxplot(column=['site_name'],by=['obs','raw','adj'])

和这个错误:

TypeError: ufunc 'true_divide' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

而且,我已经尝试了下面的这段代码,但它在 site_name 的单独组中绘制了 'obs'、'raw' 和 'adj' 列,这不是我想要的需要。这是未达到所需结果的代码:

df.boxplot(column=['obs','raw','adj'],by=['site_name'])

感谢您的帮助,

您可以先做 groupby,然后在 obs、raw、adj 列上做箱线图。

要自定义绘图属性,可以添加return_type='axes'获取matplotlib坐标轴,然后调用坐标轴上的自定义函数。

此 pandas 箱线图制作共享 y 轴图,这意味着您不能在每个图中有不同的 y 限制。

我不知道如何在此解决方案中禁用共享 y 轴,但是,我知道如何在替代解决方案中实现动态 y 轴限制。 (请参阅下面的更新)

axes = df.groupby('site_name').boxplot(column=['obs','raw','adj'], return_type='axes')

for ax in axes:
    ax.set_ylim(0, 20)  # Change y-axis limit to 0 - 20

============================================= ===

更新:

如果您想对每个图应用不同的 y 限制,请尝试 matplotlib 中的子图。

import matplotlib.pyplot as plt

# Create 2 subplots for SITE A, SITE B in 1 row. By default, this will create 2 subplots that does not share the y-axis.
# To make shared y-axis, use plt.subplots(1, 2, sharey=True)
fig, axs = plt.subplots(1, 2)

# Create a boxplot per site_name and render in the subplots by passing ax=axs
df.groupby('site_name').boxplot(column=['obs', 'raw', 'adj'], ax=axs)

# Apply different y limits
axs[0].set_ylim(0, 50)  # For SITE A
axs[1].set_ylim(0, 20)  # For SITE B

# display my plots
fig