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

Yux*_*ang 15 python numpy matplotlib scipy

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

import numpy as np
import matplotlib.pyplot as plt

data = np.random.rand(100)
plt.boxplot(data)
Run Code Online (Sandbox Code Playgroud)

然后,盒子将从第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()
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

CT *_*Zhu 13

你为什么要这样做?你在做什么已经很直接了.

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

B=plt.boxplot(data)
[item.get_ydata() for item in B['whiskers']]
Run Code Online (Sandbox Code Playgroud)

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

[item.get_ydata()[0] for item in B['whiskers']]
Run Code Online (Sandbox Code Playgroud)

  • 使用 matplotlib 使用的相同函数可能是最简单的:https://matplotlib.org/3.1.1/api/cbook_api.html#matplotlib.cbook.boxplot_stats (4认同)
  • 非常感谢!我实际上已经意识到,一旦我编写了示例代码片段,我就在问一个“贪婪”的问题——不像我想象的那么冗长。但是,很高兴知道 get_ydata() 可以做同样的事情! (2认同)

t_w*_*sop 9

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

功能是:

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)
Run Code Online (Sandbox Code Playgroud)

并通过传递一组标签(您将传递给 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()
Run Code Online (Sandbox Code Playgroud)

输出以下内容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
Run Code Online (Sandbox Code Playgroud)

并产生以下情节: 在此处输入图片说明