【问题标题】:How to make a grouped violinplot from dictionary如何从字典中制作分组小提琴图
【发布时间】:2020-11-25 15:15:46
【问题描述】:

我想根据字典制作小提琴图。这是我的字典的示例,虽然我的实际字典有更多的患者和更多的值。

paired_patients={'Patient_1': {'n':[1, nan, 3, 4], 't': [5,6,7,8]},
                 'Patient_2': {'n':[9,10,11,12], 't':[14,nan,16,17]},
                 'Patient_3': {'n':[1.5,nan,3.5,4.5], 't':[5.5,6.5,7.5,8.5]}}

对于每位患者,我希望有一组并排的两个小提琴图,一个 'n' 和一个 't'。我希望所有六个小提琴图都在同一个图表上,共享 y 轴。

我正在尝试使用matplotlib violinplot,但我不知道如何在'dataset' 选项中输入我的字典,也不知道如何将'n''t' 按患者分组。

【问题讨论】:

    标签: python dictionary matplotlib seaborn violin-plot


    【解决方案1】:

    回答

    我建议将您的数据保存在pandas.DataFrame
    首先,我遍历患者以将数据保存在数据框中:

    df = pd.DataFrame(columns = ['Patient', 'n', 't'])
    
    for key, value in paired_patients.items():
        patient_df = pd.DataFrame({'Patient': [key]*len(value['n']),
                                   'n': value['n'],
                                   't': value['t']})
        df = df.append(patient_df, ignore_index = True)
    

    所以我得到:

          Patient     n    t
    0   Patient_1   1.0    5
    1   Patient_1   NaN    6
    2   Patient_1   3.0    7
    3   Patient_1   4.0    8
    4   Patient_2   9.0   14
    5   Patient_2  10.0  NaN
    6   Patient_2  11.0   16
    7   Patient_2  12.0   17
    8   Patient_3   1.5  5.5
    9   Patient_3   NaN  6.5
    10  Patient_3   3.5  7.5
    11  Patient_3   4.5  8.5
    

    然后我需要通过pd.melt 堆叠'n''t' 列:

    df = pd.melt(frame = df,
                 id_vars = 'Patient',
                 value_vars = ['n', 't'],
                 var_name = 'type',
                 value_name = 'value')
    

    通过这种方式,数据框重新整形如下:

          Patient type value
    0   Patient_1    n     1
    1   Patient_1    n   NaN
    2   Patient_1    n     3
    3   Patient_1    n     4
    4   Patient_2    n     9
    5   Patient_2    n    10
    6   Patient_2    n    11
    7   Patient_2    n    12
    8   Patient_3    n   1.5
    9   Patient_3    n   NaN
    10  Patient_3    n   3.5
    11  Patient_3    n   4.5
    12  Patient_1    t     5
    13  Patient_1    t     6
    14  Patient_1    t     7
    15  Patient_1    t     8
    16  Patient_2    t    14
    17  Patient_2    t   NaN
    18  Patient_2    t    16
    19  Patient_2    t    17
    20  Patient_3    t   5.5
    21  Patient_3    t   6.5
    22  Patient_3    t   7.5
    23  Patient_3    t   8.5
    

    最后您可能需要将'value' 列类型转换为float

    df['value'] = df['value'].astype(float)
    

    现在可以使用seaborn.violinplot 绘制这些数据:

    fig, ax = plt.subplots()
    
    sns.violinplot(ax = ax,
                   data = df,
                   x = 'Patient',
                   y = 'value',
                   hue = 'type',
                   split = True)
    
    plt.show()
    

    完整代码

    import matplotlib.pyplot as plt
    import seaborn as sns
    import pandas as pd
    from math import nan
    
    paired_patients = {'Patient_1': {'n': [1, nan, 3, 4], 't': [5, 6, 7, 8]},
                       'Patient_2': {'n': [9, 10, 11, 12], 't': [14, nan, 16, 17]},
                       'Patient_3': {'n': [1.5, nan, 3.5, 4.5], 't': [5.5, 6.5, 7.5, 8.5]}}
    
    df = pd.DataFrame(columns = ['Patient', 'n', 't'])
    
    for key, value in paired_patients.items():
        patient_df = pd.DataFrame({'Patient': [key]*len(value['n']),
                                   'n': value['n'],
                                   't': value['t']})
        df = df.append(patient_df, ignore_index = True)
    
    df = pd.melt(frame = df,
                 id_vars = 'Patient',
                 value_vars = ['n', 't'],
                 var_name = 'type',
                 value_name = 'value')
    
    df['value'] = df['value'].astype(float)
    
    fig, ax = plt.subplots()
    
    sns.violinplot(ax = ax,
                   data = df,
                   x = 'Patient',
                   y = 'value',
                   hue = 'type',
                   split = True)
    
    plt.show()
    

    情节


    注意

    如果你有很多病人,你会在x轴上有太多的数据,所以我建议你设置split = True以节省一些空间。
    否则,如果你设置split = False,你会得到:

    【讨论】:

    • 这很好用并且解释得很好。谢谢!
    猜你喜欢
    • 2019-12-18
    • 2021-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 2023-03-06
    • 2018-01-15
    相关资源
    最近更新 更多