【问题标题】:Side-by-side boxplots with Pandas与 Pandas 并排的箱线图
【发布时间】:2017-12-12 00:30:27
【问题描述】:

我需要对存储在 pandas dataframe 中的五个变量进行比较。我使用了一个示例from here,它有效,但现在我需要更改轴和标题,但我正在努力这样做。

这是我的数据:

df1.groupby('cls').head()
Out[171]: 
   sensitivity  specificity  accuracy       ppv       auc       cls
0     0.772091     0.824487  0.802966  0.799290  0.863700       sig
1     0.748931     0.817238  0.776366  0.785910  0.859041       sig
2     0.774016     0.805909  0.801975  0.789840  0.853132       sig
3     0.826670     0.730071  0.795715  0.784150  0.850024       sig
4     0.781112     0.803839  0.824709  0.791530  0.863411       sig
0     0.619048     0.748290  0.694969  0.686138  0.713899  baseline
1     0.642348     0.702076  0.646216  0.674683  0.712632  baseline
2     0.567344     0.765410  0.710650  0.665614  0.682502  baseline
3     0.644046     0.733645  0.754621  0.683485  0.734299  baseline
4     0.710077     0.653871  0.707933  0.684313  0.732997  baseline

这是我的代码:

>> fig, axes = plt.subplots(ncols=5, figsize=(12, 5), sharey=True)
>> df1.query("cls in ['sig', 'baseline']").boxplot(by='cls', return_type='axes', ax=axes)

得到的图片是:

如何:

  • 更改标题(“按 cls 分组的箱线图”)
  • 摆脱沿水平线绘制的烦人 [cls]
  • 重新排列在 df1 中出现的绘制类别? (首先是敏感度,其次是特异性...)

【问题讨论】:

    标签: python pandas boxplot


    【解决方案1】:

    也许这对你有帮助:

    fig, axes = pyplot.subplots(ncols=4, figsize=(12, 5), sharey=True)
    df.query("E in [1, 2]").boxplot(by='E', return_type='axes', ax=axes, column=list('bcda')) # Keeping original columns order
    pyplot.suptitle('Boxplot') # Changing title
    [ax.set_xlabel('') for ax in axes] # Changing xticks for all plots
    

    【讨论】:

      【解决方案2】:

      我建议使用seaborn

      这是一个可能对您有所帮助的示例:

      进口

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

      制作数据

      data = {'sensitivity' : np.random.normal(loc = 0, size = 10),
              'specificity' : np.random.normal(loc = 0, size = 10),
              'accuracy' : np.random.normal(loc = 0, size = 10),
              'ppv' : np.random.normal(loc = 0, size = 10),
              'auc' : np.random.normal(loc = 0, size = 10),
              'cls' : ['sig', 'sig', 'sig', 'sig', 'sig', 'baseline', 'baseline', 'baseline', 'baseline', 'baseline']}
      
      df = pd.DataFrame(data)
      df
      

      Seaborn 有一个名为factorplot 的漂亮工具,它可以创建一个子图网格,其中行/列是用您的数据构建的。为了能够做到这一点,我们需要将df“融化”成更有用的形状。

      df_melt = df.melt(id_vars = 'cls',
                        value_vars = ['accuracy',
                                      'auc',
                                      'ppv',
                                      'sensitivity',
                                      'specificity'],
                        var_name = 'columns')
      

      现在我们可以使用 col "columns" 创建factorplot

      a = sns.factorplot(data = df_melt,
                         x = 'cls',
                         y = 'value',
                         kind = 'box', # type of plot
                         col = 'columns',
                         col_order = ['sensitivity', # custom order of boxplots
                                      'specificity',
                                      'accuracy',
                                      'ppv',
                                      'auc']).set_titles('{col_name}') # remove 'column = ' part of title
      
      plt.show()
      

      您也可以只使用 Seaborn 的箱线图。

      b = sns.boxplot(data = df_melt,
                      hue = 'cls', # different colors for different 'cls'
                      x = 'columns',
                      y = 'value',
                      order = ['sensitivity', # custom order of boxplots
                               'specificity',
                               'accuracy',
                               'ppv',
                               'auc'])
      
      sns.plt.title('Boxplot grouped by cls') # You can change the title here
      plt.show()
      

      这将为您提供相同的情节,但都在一个图中而不是子情节中。它还允许您用一行更改图形的标题。不幸的是,我找不到删除“列”副标题的方法,但希望这能满足您的需求。

      编辑

      要横向查看绘图: 因子图 交换xy 值,将col = 'columns' 更改为row = 'columns',将col_order = [...] 更改为row_order = [...],并将'{col_name}' 更改为'{row_name}',就像这样

      a1 = sns.factorplot(data = df_melt,
                          x = 'value',
                          y = 'cls',
                          kind = 'box', # type of plot
                          row = 'columns',
                          row_order = ['sensitivity', # custom order of boxplots
                                       'specificity',
                                       'accuracy',
                                       'ppv',
                                       'auc']).set_titles('{row_name}') # remove 'column = ' part of title
      
      plt.show()
      

      箱形图 交换您的 xy 值,然后像这样添加参数 orient = 'h'

      b1 = sns.boxplot(data = df_melt,
                       hue = 'cls',
                       x = 'value',
                       y = 'columns',
                       order = ['sensitivity', # custom order of boxplots
                               'specificity',
                               'accuracy',
                               'ppv',
                               'auc'],
                       orient = 'h')
      
      sns.plt.title('Boxplot grouped by cls')
      plt.show()
      

      【讨论】:

      • 谢谢!有没有办法垂直而不是水平显示图?我需要用factorplot转置并获得5X1图而不是1X5图?
      • 如何获得漂亮的灰色背景?
      • @YonatanSimson 在撰写本文时是默认设置。您可以将样式更改为与它类似的ggplotfrom matplotlib import stylestyle.use('ggplot')
      • @YonatanSimson 你也可以试试sns.set_style('dark')
      • @IanThompson 谢谢。我使用了 sns.set()。以前的版本曾经在导入过程中执行此操作,现在必须手动完成
      猜你喜欢
      • 2017-08-03
      • 2019-10-23
      • 2019-03-03
      • 2018-02-16
      • 1970-01-01
      • 1970-01-01
      • 2016-09-08
      • 2016-11-19
      相关资源
      最近更新 更多