使用python和matplotlib获取boxplot中使用的值

时间:2014-05-04 21:21:17

标签: python numpy matplotlib scipy

我可以从数据中绘制一个箱线图:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.rand(100)
plt.boxplot(data)

然后,盒子的范围从第25百分位到第75百分位,并且晶须的范围从最小值到最大值(第25百分位数 - 1.5 * IQR,第75百分位数+ 1.5 * IQR) ,其中IQR表示四分位数范围。 (当然,值1.5可以自定义)。

现在我想知道箱线图中使用的值,即中位数,上下四分位数,上晶须终点和下晶须终点。虽然通过使用np.median()和np.percentile()很容易获得前三个,但是胡须的终点将需要一些冗长的编码:

median = np.median(data)
upper_quartile = np.percentile(data, 75)
lower_quartile = np.percentile(data, 25)

iqr = upper_quartile - lower_quartile
upper_whisker = data[data<=upper_quartile+1.5*iqr].max()
lower_whisker = data[data>=lower_quartile-1.5*iqr].min()

我想知道,虽然这是可以接受的,但是有更简洁的方法吗?似乎值已经准备好从箱线图中拉出,因为它已经被绘制了。

谢谢!

2 个答案:

答案 0 :(得分:11)

你为什么要这样做?你正在做的事情已经非常直接了。

是的,如果您想为绘图获取它们,那么当绘图已经完成时,只需使用get_ydata()方法。

B=plt.boxplot(data)
[item.get_ydata() for item in B['whiskers']]

它为每个胡须返回一个形状(2,)的数组,第二个元素是我们想要的值:

[item.get_ydata()[0] for item in B['whiskers']]

答案 1 :(得分:4)

我最近遇到了这个问题,并编写了一个函数来从箱线图中提取箱线值作为熊猫数据框。

函数是:

def get_box_plot_data(labels, bp):
    rows_list = []

    for i in range(len(labels)):
        dict1 = {}
        dict1['label'] = labels[i]
        dict1['lower_whisker'] = bp['whiskers'][i*2].get_ydata()[1]
        dict1['lower_quartile'] = bp['boxes'][i].get_ydata()[1]
        dict1['median'] = bp['medians'][i].get_ydata()[1]
        dict1['upper_quartile'] = bp['boxes'][i].get_ydata()[2]
        dict1['upper_whisker'] = bp['whiskers'][(i*2)+1].get_ydata()[1]
        rows_list.append(dict1)

    return pd.DataFrame(rows_list)

并通过传递标签数组(将传递给boxplot绘图函数的标签)和boxplot函数本身返回的数据来调用。

例如:

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

def get_box_plot_data(labels, bp):
    rows_list = []

    for i in range(len(labels)):
        dict1 = {}
        dict1['label'] = labels[i]
        dict1['lower_whisker'] = bp['whiskers'][i*2].get_ydata()[1]
        dict1['lower_quartile'] = bp['boxes'][i].get_ydata()[1]
        dict1['median'] = bp['medians'][i].get_ydata()[1]
        dict1['upper_quartile'] = bp['boxes'][i].get_ydata()[2]
        dict1['upper_whisker'] = bp['whiskers'][(i*2)+1].get_ydata()[1]
        rows_list.append(dict1)

    return pd.DataFrame(rows_list)

data1 = np.random.normal(loc = 0, scale = 1, size = 1000)
data2 = np.random.normal(loc = 5, scale = 1, size = 1000)
data3 = np.random.normal(loc = 10, scale = 1, size = 1000)

labels = ['data1', 'data2', 'data3']
bp = plt.boxplot([data1, data2, data3], labels=labels)
print(get_box_plot_data(labels, bp))
plt.show()

get_box_plot_data输出以下内容:

   label  lower_whisker  lower_quartile    median  upper_quartile  upper_whisker
0  data1      -2.491652       -0.587869  0.047543        0.696750       2.559301
1  data2       2.351567        4.310068  4.984103        5.665910       7.489808
2  data3       7.227794        9.278931  9.947674       10.661581      12.733275

并生成以下图: enter image description here