Pandas Matplotlib/Seaborn箱型图,包含大量信息

Pandas Matplotlib/Seaborn箱型图,包含大量信息,pandas,matplotlib,seaborn,Pandas,Matplotlib,Seaborn,我需要绘制3个不同数据集的实验结果,其中11个模型超过4个指标,每个数据集有100个数据点。我知道将所有这些信息整合到一个情节中是非常困难的,而且可能更难阅读。目前,我有12个图,每个实验/指标一个(3*4),所有11个模型的结果都在一个图中。我试图减少这4个图:在同一个图中有11个模型和3个实验,每个指标一个 更具体地说,我使用的指标是敏感性、特异性、PPV和AUC。共有三种不同的实验:笔记普通、完整普通、重要、完整普通。我有11个模型。目前,这是我必须为绘图准备好数据的代码: prefix

我需要绘制3个不同数据集的实验结果,其中11个模型超过4个指标,每个数据集有100个数据点。我知道将所有这些信息整合到一个情节中是非常困难的,而且可能更难阅读。目前,我有12个图,每个实验/指标一个(3*4),所有11个模型的结果都在一个图中。我试图减少这4个图:在同一个图中有11个模型和3个实验,每个指标一个

更具体地说,我使用的指标是敏感性、特异性、PPV和AUC。共有三种不同的实验:笔记普通、完整普通、重要、完整普通。我有11个模型。目前,这是我必须为绘图准备好数据的代码:

prefix = 'notes_common_vital'

bams = pickle.load(open(workdir/f'{prefix}_bams.pkl', 'rb'))
for k in bams.keys():
  bams[k.upper()] = bams.pop(k)
bams['AVG-ALL'] = bams.pop('AVG-LR-RF-GBM')
bams['MAX-ALL'] = bams.pop('MAX-LR-RF-GBM')

itr = iter(bams.keys())
bams.keys()

metrics = {}

for md in itr:
  df = pd.DataFrame()
  for k, m in bams[md].yield_metrics():
    df[k] = m
  df['model'] = md
  cols = list(df.columns)
  cols = [cols[-1]] + cols[:-1]
  df = df[cols]
  metrics[md] = df

plot_df = pd.concat(metrics.values())
met = 'Sensitivity'

fig, ax = plt.subplots(1,1,figsize=(15,8))
sns.boxplot(x='model', y=met, data=plot_df, ax=ax)
ax.set_xlabel('')
bams
只是一个自定义类的对象,我创建该类是为了在100次迭代中保存二进制平均度量

plot_df.shape
(1100, 5)

plot_df.columns
Index(['model', 'Sensitivity', 'Specificity', 'PPV', 'AUC'], dtype='object')

plot_df.head()

    model   Sensitivity Specificity PPV AUC
0   LR  0.782575    0.607646    0.389910    0.763138
1   LR  0.810860    0.537603    0.362753    0.752767
2   LR  0.823888    0.598635    0.341402    0.784208
3   LR  0.810928    0.617947    0.356734    0.782843
4   LR  0.833948    0.553218    0.333702    0.765500
用于打印:

prefix = 'notes_common_vital'

bams = pickle.load(open(workdir/f'{prefix}_bams.pkl', 'rb'))
for k in bams.keys():
  bams[k.upper()] = bams.pop(k)
bams['AVG-ALL'] = bams.pop('AVG-LR-RF-GBM')
bams['MAX-ALL'] = bams.pop('MAX-LR-RF-GBM')

itr = iter(bams.keys())
bams.keys()

metrics = {}

for md in itr:
  df = pd.DataFrame()
  for k, m in bams[md].yield_metrics():
    df[k] = m
  df['model'] = md
  cols = list(df.columns)
  cols = [cols[-1]] + cols[:-1]
  df = df[cols]
  metrics[md] = df

plot_df = pd.concat(metrics.values())
met = 'Sensitivity'

fig, ax = plt.subplots(1,1,figsize=(15,8))
sns.boxplot(x='model', y=met, data=plot_df, ax=ax)
ax.set_xlabel('')
导致

现在我通过改变
前缀来完成每个实验,通过改变
met来完成每个度量,得到12个这样的图。对于我来说,在演示文稿中呈现的图太多了,所以我需要一种更简洁地呈现这些结果的方法

我在想,我是否可以每个度量有一个绘图,并且在X轴上(但宽度非常小)有宽图像的每个实验的所有模型,这样在给定的图形中会有33个模型,这样我可以更容易地显示比较。我不知道该怎么做。我欢迎关于如何呈现这些结果的其他建议

谢谢。

使用每个数据集的标识符变量列将三个数据集中的每个数据集合并(连接)到一个数据框中。然后,您可以按原样绘制它,但需要包含
hue=
参数来分隔数据集。这里有一个例子

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

dates = pd.date_range('01-01-2000', '12-31-2002')
df = pd.DataFrame(np.random.randint(0,100,size=(len(dates), 11)), columns=list('ABCDEFGHIJK'))
df.index = dates
df = df.reset_index().melt(value_vars=list('ABCDEFGHIJK'), id_vars='index').set_index('index')
df['dataset'] = df.index.year
df

>     index    variable value   dataset         
>     2000-01-01    A   47  2000
>     2000-01-02    A   89  2000
>     2000-01-03    A   79  2000
>     2000-01-04    A   24  2000
>     2000-01-05    A   87  2000
>     ...   ... ... ...
>     2002-12-27    K   62  2002
>     2002-12-28    K   67  2002
>     2002-12-29    K   46  2002
>     2002-12-30    K   62  2002
>     2002-12-31    K   73  2002
>     12056 rows × 3 columns

plt.figure(figsize=(10,8))
sns.boxplot(x = 'variable', y = 'value', hue = 'dataset', data = df)

谢谢!这很有效。然而,情节有点嘈杂,找到分离点有点困难。有可能在a、B、C之间画一条线吗?您可以对范围内的i(len(df.columns)-1)执行
:plt.axvline(x=i+0.5)
。但是你给情节加的越多,它就越吵闹。