我可以从数据中绘制一个箱线图:
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()
我想知道,虽然这是可以接受的,但是有更简洁的方法吗?似乎值已经准备好从箱线图中拉出,因为它已经被绘制了。
谢谢!
答案 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