如何从嵌套字典中绘制箱线图

How to plot a boxplot from a nested dictionary

我有一个嵌套字典,下面给出了其中的一个子集:

dict_a = {
    '2019': {
        'Jan-Mar': {
            'category_A': [0.0, 11.344454217292942, 4.885790495524913], 
            'category_B': [0.0, 14.657371486574736, 0.0, 4.885790495524913]
            },
        'Apr-June': {
            'category_A': [4.885790495524913, 0.0, 7.7437947217868235, 7.7437947217868235],
            'category_B': [7.7437947217868235, 0.0, 0.0, 0.0]
            }
            },
    '2020': {
        'Jan-Mar': {
            'category_A': [7.7437947217868235, 7.7437947217868235, 21.787848617781385],
            'category_B': [4.885790495524913, 4.885790495524913, 0.0, 7.7437947217868235]
            },
        'Apr-June': {
            'category_A': [0.0, 11.344454217292942, 0.0, 7.7437947217868235], 
            'category_B': [4.885790495524913, 0.0, 4.885790495524913]
            }
            }
}

我正在尝试绘制给定类别数据的箱线图,以便 x 轴是月份组(例如 'Jan-Mar'),图例显示年份(例如“2019”)每个盒子。例如,对于 category_A,我会在每个月组中绘制两个箱线图,每个箱线图对应给定的年份,并用图例显示每个箱体的年份。

我曾尝试将字典转换为 pandas 数据框,但在多索引绘图方面遇到了困难。我想知道是否有使用原始字典的更简单的方法。任何帮助表示赞赏。谢谢。

对于多维度的箱线图,seaborn 的 sns.catplot 很方便。 Seaborn 更喜欢将其数据作为 "long form" 中的数据框。这样的数据框可以通过嵌套的 for 循环从给定的字典创建。 (当类别具有不同数量的值时,这也适用。)

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

dict_a = {'2019': {'Jan-Mar': {'category_A': [0.0, 11.344454217292942, 4.885790495524913], 'category_B': [0.0, 14.657371486574736, 0.0, 4.885790495524913]}, 'Apr-June': {'category_A': [4.885790495524913, 0.0, 7.7437947217868235, 7.7437947217868235], 'category_B': [7.7437947217868235, 0.0, 0.0, 0.0]}}, '2020': {'Jan-Mar': {'category_A': [7.7437947217868235, 7.7437947217868235, 21.787848617781385], 'category_B': [4.885790495524913, 4.885790495524913, 0.0, 7.7437947217868235]}, 'Apr-June': {'category_A': [0.0, 11.344454217292942, 0.0, 7.7437947217868235], 'category_B': [4.885790495524913, 0.0, 4.885790495524913]}}}

df = pd.DataFrame()
for year, months_groups in dict_a.items():
    for months, cat_groups in months_groups.items():
        for cat, values in cat_groups.items():
            df_cat = pd.DataFrame({'val': values})
            df_cat['cat'] = cat
            df_cat['months'] = months
            df_cat['year'] = year
            df = df.append(df_cat, ignore_index=True)
g = sns.catplot(data=df, kind='box', x='months', y='val', hue='year', col='cat',
                height=5, aspect=1.2, palette='spring')
plt.tight_layout()
plt.show()

Seaborn 让您可以轻松地交换 x=hue=col= and/or row= 的角色。它还可以让您尝试 different kinds of plots(例如 kind='violin')。