【问题标题】:Plotting grouped data in same plot using Pandas使用 Pandas 在同一图中绘制分组数据
【发布时间】:2015-04-02 07:14:11
【问题描述】:

在 Pandas 中,我正在做:

bp = p_df.groupby('class').plot(kind='kde')

p_df 是一个dataframe 对象。

但是,这会产生两个图,每个类别一个。 如何在同一个情节中强制一个情节与两个类?

【问题讨论】:

    标签: python pandas matplotlib seaborn


    【解决方案1】:

    版本 1:

    您可以创建轴,然后使用 DataFrameGroupBy.plotax 关键字将所有内容添加到这些轴:

    import matplotlib.pyplot as plt
    
    p_df = pd.DataFrame({"class": [1,1,2,2,1], "a": [2,3,2,3,2]})
    fig, ax = plt.subplots(figsize=(8,6))
    bp = p_df.groupby('class').plot(kind='kde', ax=ax)
    

    这是结果:

    不幸的是,传说的标签在这里没有太多意义。

    版本 2:

    另一种方法是遍历组并手动绘制曲线:

    classes = ["class 1"] * 5 + ["class 2"] * 5
    vals = [1,3,5,1,3] + [2,6,7,5,2]
    p_df = pd.DataFrame({"class": classes, "vals": vals})
    
    fig, ax = plt.subplots(figsize=(8,6))
    for label, df in p_df.groupby('class'):
        df.vals.plot(kind="kde", ax=ax, label=label)
    plt.legend()
    

    这样您可以轻松控制图例。结果如下:

    【讨论】:

      【解决方案2】:

      另一种方法是使用seaborn 模块。这将在相同的轴上绘制两个密度估计值,而无需指定一个变量来保存轴,如下所示(使用其他答案中的一些数据框设置):

      import pandas as pd
      import seaborn as sns
      import matplotlib.pyplot as plt
      %matplotlib inline
      
      # data to create an example data frame
      classes = ["c1"] * 5 + ["c2"] * 5
      vals = [1,3,5,1,3] + [2,6,7,5,2]
      # the data frame 
      df = pd.DataFrame({"cls": classes, "indices":idx, "vals": vals})
      
      # this is to plot the kde
      sns.kdeplot(df.vals[df.cls == "c1"],label='c1');
      sns.kdeplot(df.vals[df.cls == "c2"],label='c2');
      
      # beautifying the labels
      plt.xlabel('value')
      plt.ylabel('density')
      plt.show()
      

      这会产生以下图像。

      【讨论】:

      • 如果我想要实际值而不是密度怎么办?
      • 请注意,通过这种方式,您不会像问题所要求的那样绘制分组数据,而是将数据框切成两个子数据框并将它们添加到同一个图中。如果您有很多组(特别是如果您不知道这些组实际上是什么),则此解决方案不适用。
      【解决方案3】:
      import matplotlib.pyplot as plt
      p_df.groupby('class').plot(kind='kde', ax=plt.gca())
      

      【讨论】:

      • 这个方法最简单,也很有效。
      【解决方案4】:

      也许你可以试试这个:

      fig, ax = plt.subplots(figsize=(10,8))
      classes = list(df.class.unique())
      for c in classes:
          df2 = data.loc[data['class'] == c]
          df2.vals.plot(kind="kde", ax=ax, label=c)
      plt.legend()
      

      【讨论】:

        【解决方案5】:
        • 有两种简单的方法可以在同一个图中绘制每个组。
          1. 使用pandas.DataFrame.groupby 时,应指定要绘制的列(例如聚合列)。
          2. 使用seaborn.kdeplotseaborn.displot 并指定hue 参数
        • 使用pandas v1.2.4matplotlib 3.4.2seaborn 0.11.1
        • OP 专门用于绘制kde,但对于许多绘图类型(例如kind='line'sns.lineplot 等),步骤都是相同的。

        导入和示例数据

        • 对于样本数据,组在'kind'列中,将绘制'duration'kde,忽略'waiting'
        import pandas as pd
        import seaborn as sns
        
        df = sns.load_dataset('geyser')
        
        # display(df.head())
           duration  waiting   kind
        0     3.600       79   long
        1     1.800       54  short
        2     3.333       74   long
        3     2.283       62  short
        4     4.533       85   long
        

        使用pandas.DataFrame.plot 绘图

        • 使用.groupby.pivot 重塑数据

        .groupby

        • 指定聚合列['duration']kind='kde'
        ax = df.groupby('kind')['duration'].plot(kind='kde', legend=True)
        

        .pivot

        ax = df.pivot(columns='kind', values='duration').plot(kind='kde')
        

        使用seaborn.kdeplot 绘图

        • 指定hue='kind'
        ax = sns.kdeplot(data=df, x='duration', hue='kind')
        

        使用seaborn.displot 绘图

        • 指定hue='kind'kind='kde'
        fig = sns.displot(data=df, kind='kde', x='duration', hue='kind')
        

        情节

        【讨论】:

          猜你喜欢
          • 2019-04-20
          • 2020-11-10
          • 2013-11-04
          • 1970-01-01
          • 2020-11-03
          • 2018-01-16
          • 1970-01-01
          相关资源
          最近更新 更多