【问题标题】:Overlaying actual data on a boxplot from a pandas dataframe将实际数据覆盖在来自 pandas 数据框的箱线图上
【发布时间】:2014-05-27 00:13:45
【问题描述】:

我正在使用 Seaborn 从 pandas 数据框制作箱线图。 Seaborn boxplots 似乎基本上以与 pandas boxplot 功能相同的方式读取数据帧(所以我希望两者的解决方案相同——但我也可以使用 dataframe.boxplot 函数)。我的数据框有 12 列,以下代码生成一个图,每列有一个箱线图(就像 dataframe.boxplot() 函数一样)。

fig, ax = plt.subplots()
sns.set_style("darkgrid", {"axes.facecolor":"darkgrey"})
pal = sns.color_palette("husl",12)
sns.boxplot(dataframe, color = pal)

任何人都可以提出一种简单的方法来覆盖所有值(按列),同时从数据框制作箱线图吗? 我将不胜感激这方面的任何帮助。

【问题讨论】:

    标签: matplotlib pandas dataframe boxplot seaborn


    【解决方案1】:

    这还没有被添加到seaborn.boxplot 函数中,但是seaborn.violinplot 函数中有类似的东西,它有other advantages

    x = np.random.randn(30, 6)
    sns.violinplot(x, inner="points")
    sns.despine(trim=True)
    

    【讨论】:

      【解决方案2】:

      整个数据框的箱线图的通用解决方案,它应该适用于seabornpandas,因为它们都是基于底层的matplotlib,我将使用pandas 绘图作为示例,假设import matplotlib.pyplot as plt 已经到位。由于您已经拥有ax,因此最好使用ax.text(...) 而不是plt.text(...)

      In [35]:    
      print df
               V1        V2        V3        V4        V5
      0  0.895739  0.850580  0.307908  0.917853  0.047017
      1  0.931968  0.284934  0.335696  0.153758  0.898149
      2  0.405657  0.472525  0.958116  0.859716  0.067340
      3  0.843003  0.224331  0.301219  0.000170  0.229840
      4  0.634489  0.905062  0.857495  0.246697  0.983037
      5  0.573692  0.951600  0.023633  0.292816  0.243963
      
      [6 rows x 5 columns]
      
      In [34]:    
      df.boxplot()
      for x, y, s in zip(np.repeat(np.arange(df.shape[1])+1, df.shape[0]), 
                         df.values.ravel(), df.values.astype('|S5').ravel()):
          plt.text(x,y,s,ha='center',va='center')
      

      对于数据框中的单个系列,需要进行一些小的更改:

      In [35]:    
      sub_df=df.V1
      pd.DataFrame(sub_df).boxplot()
      for x, y, s in zip(np.repeat(1, df.shape[0]), 
                         sub_df.ravel(), sub_df.values.astype('|S5').ravel()):
          plt.text(x,y,s,ha='center',va='center')
      

      制作散点图也类似:

      #for the whole thing
      df.boxplot()
      plt.scatter(np.repeat(np.arange(df.shape[1])+1, df.shape[0]), df.values.ravel(), marker='+', alpha=0.5)
      #for just one column
      sub_df=df.V1
      pd.DataFrame(sub_df).boxplot()
      plt.scatter(np.repeat(1, df.shape[0]), sub_df.ravel(), marker='+', alpha=0.5)
      

      要在boxplot 上叠加内容,我们需要首先猜测每个框在xaxis 中的位置。他们似乎在1,2,3,4,....。因此,对于第一列中的值,我们希望它们绘制在 x=1; x=2 处的第二列,依此类推。

      任何有效的方法是使用np.repeat,重复1,2,3,4...,每次n 次,其中n 是观察次数。然后我们可以绘制一个图,使用这些数字作为x 坐标。由于它是一维的,对于y 坐标,我们需要一个扁平化的数据视图,由df.ravel() 提供

      为了覆盖文本字符串,我们需要另一个步骤(循环)。因为我们一次只能绘制一个 x 值、一个 y 值和一个文本字符串。

      【讨论】:

      • 对不起,“实际值”这个词令人困惑。我的意思是一种覆盖在箱线图上的散点图 - 即用点代替数值。感谢您查看我的问题!
      • 是的,那个令人困惑。见编辑。我会建议你使用一个合理的alpha 值,这样如果你有很多数据点,你可以更好地看到“云”。如果你想看起来花哨,考虑这个nbviewer.ipython.org/github/mgymrek/pybeeswarm/blob/master/…
      • 是的,这很花哨。感谢@CT Zhu 的快速回复!这就像一个魅力。我不得不承认,我将不得不更多地盯着解决方案来了解你在那里做了什么。我需要更多的点来给你一个赞成票。
      • 没问题,我又写了几行代码,这次用English 语言供你看。干杯!
      • @CTZhu 我想做一些与此非常相似的事情,但是我正在使用 dataframe.boxplot(by='column1') 这个分组似乎不适用于您的示例。你对此有什么建议吗?基本上我的箱线图是 xaxis df[column1], yaxis df[column2] 我想在它上面绘制散点图。但是将 xticks 设置为文本我很困惑。我能够找到箱线图设置的 xticks 和 xtick_labels。
      【解决方案3】:

      我有以下技巧:

      data = np.random.randn(6,5)
      
      df = pd.DataFrame(data,columns = list('ABCDE'))
      
      Now assign a dummy column to df:
      df['Group'] = 'A'
      
      print df
      
                A         B         C         D         E Group
      0  0.590600  0.226287  1.552091 -1.722084  0.459262     A
      1  0.369391 -0.037151  0.136172 -0.772484  1.143328     A
      2  1.147314 -0.883715 -0.444182 -1.294227  1.503786     A
      3 -0.721351  0.358747  0.323395  0.165267 -1.412939     A
      4 -1.757362 -0.271141  0.881554  1.229962  2.526487     A
      5 -0.006882  1.503691  0.587047  0.142334  0.516781     A
      

      使用df.groupby.boxplot(),你就搞定了。

      df.groupby('Group').boxplot()
      

      【讨论】:

        猜你喜欢
        • 2015-12-20
        • 1970-01-01
        • 1970-01-01
        • 2016-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-08
        • 2021-11-15
        相关资源
        最近更新 更多