【问题标题】:How to turn groupby() and value_counts() into multiple pie/bar charts如何将 groupby() 和 value_counts() 变成多个饼图/条形图
【发布时间】:2019-12-28 07:45:15
【问题描述】:

假设我有一个数据框,我正在查看它的 2 列(2 系列)。

使用其中一列 - "no_employees" 下面 - 有人可以帮我弄清楚如何创建 6 个不同的饼图或条形图(每个 no_employees 分组 1 个)来说明是/否值的值计数在治疗栏中?我会使用matplotlibseaborn,随便你觉得最简单。

我正在使用附加的代码行来生成下面的代码。

dataframe_title.groupby(['no_employees']).treatment.value_counts(). 

但现在我被困住了。我使用seaborn 吗? .plot?这似乎应该很容易,而且我知道在某些情况下我可以制作subplots=True,但我真的很困惑。非常感谢。

no_employees    treatment
1-5             Yes           88
                No            71
100-500         Yes           95
                No            80
26-100          Yes          149
                No           139
500-1000        No            33
                Yes           27
6-25            No           162
                Yes          127
More than 1000  Yes          146
                No           135

【问题讨论】:

    标签: python pandas matplotlib pandas-groupby seaborn


    【解决方案1】:

    数据编码的重要性:

    1. 数据可视化的目的是更容易地传达信息(例如,在这种情况下,每个类别的 'treatments' 的相对数量)
    2. 条形图可轻松显示重要信息
      • 每组有多少人说'Yes''No'
      • 每组的相对大小
    3. 饼图更常用于显示样本,其中样本中的组总和为 100%。
      • Wikipedia: Pie Chart
        • 研究表明,按角度比较不如按长度比较准确,因为人们无法辨别差异。
        • Statisticians 普遍认为饼图是一种糟糕的信息显示方式,在科学文献中并不常见。
      • 饼图不能很好地表示此数据,因为每个公司规模都是一个单独的总体,这需要 6 个饼图才能正确表示。
      • 数据可以像其他人所展示的那样放入饼图中,但这并不意味着它应该如此。
    • 无论绘图类型如何,数据的形状都必须适合绘图 API。
    • 使用pandas 1.3.0seaborn 0.11.1matplotlib 3.4.2 测试

    设置测试数据帧

    import pandas as pd
    import seaborn as sns
    import matplotlib.pyplot as plt
    import numpy as np  # for sample data only
    
    np.random.seed(365)
    cats = ['1-5', '6-25', '26-100', '100-500', '500-1000', '>1000']
    
    data = {'no_employees': np.random.choice(cats, size=(1000,)),
            'treatment': np.random.choice(['Yes', 'No'], size=(1000,))}
    
    df = pd.DataFrame(data)
    
    # set a categorical order for the x-axis to be ordered
    df.no_employees = pd.Categorical(df.no_employees, categories=cats, ordered=True)
    
      no_employees treatment
    0       26-100        No
    1          1-5       Yes
    2        >1000        No
    3      100-500       Yes
    4     500-1000       Yes
    

    pandas.DataFrame.plot()绘图:

    # to get the dataframe in the correct shape, unstack the groupby result
    dfu = df.groupby(['no_employees']).treatment.value_counts().unstack()
    
    treatment     No  Yes
    no_employees         
    1-5           78   72
    6-25          83   86
    26-100        83   76
    100-500       91   84
    500-1000      78   83
    >1000         95   91
    
    # plot
    ax = dfu.plot(kind='bar', figsize=(7, 5), xlabel='Number of Employees in Company', ylabel='Count', rot=0)
    ax.legend(title='treatment', bbox_to_anchor=(1, 1), loc='upper left')
    


    seaborn绘图

    • seaborn 是 matplotlib 的高级 API。

    seaborn.barplot()

    • 需要一个整齐(长)格式的DataFrame,这是通过将dataframe分组以获得.value_counts,并使用pandas.Series.reset_index重置索引来完成的
    • 也可以通过使用sns.catplot()kind='bar' 的图形级界面来完成
    # groupby, get value_counts, and reset the index
    dft = df.groupby(['no_employees']).treatment.value_counts().reset_index(name='Count')
    
       no_employees treatment  Count
    0           1-5        No     78
    1           1-5       Yes     72
    2          6-25       Yes     86
    3          6-25        No     83
    4        26-100        No     83
    5        26-100       Yes     76
    6       100-500        No     91
    7       100-500       Yes     84
    8      500-1000       Yes     83
    9      500-1000        No     78
    10        >1000        No     95
    11        >1000       Yes     91
    
    # plot
    p = sns.barplot(x='no_employees', y='Count', data=dft, hue='treatment')
    p.legend(title='treatment', bbox_to_anchor=(1, 1), loc='upper left')
    p.set(xlabel='Number of Employees in Company')
    

    seaborn.countplot()

    • 使用原始数据框df,不进行任何转换。
    • 也可以通过使用sns.catplot()kind='count' 的图形级界面来完成
    p = sns.countplot(data=df, x='no_employees', hue='treatment')
    p.legend(title='treatment', bbox_to_anchor=(1, 1), loc='upper left')
    p.set(xlabel='Number of Employees in Company')
    
    • barplotcountplot 的输出

    【讨论】:

      【解决方案2】:

      让我们重塑数据框并使用 subplots=True 进行绘图:

      df_chart = df1.unstack()['Pct'] 
      
      axs = df_chart.plot.pie(subplots=True, figsize=(4,9), layout=(2,1), legend=False, title=df_chart.columns.tolist())
      ax_flat = axs.flatten()
      for ax in ax_flat:
          ax.yaxis.label.set_visible(False)
      

      输出:

      【讨论】:

        猜你喜欢
        • 2017-12-28
        • 2023-04-06
        • 1970-01-01
        • 2021-01-12
        • 1970-01-01
        • 1970-01-01
        • 2015-07-23
        • 1970-01-01
        相关资源
        最近更新 更多