14

在 Python 中使用箱线图时,有什么方法可以自动/轻松地在每个框的顶部(或至少是中位数的数值)叠加中位数和方差的值?

例如,在下面的箱线图中,我想在每个箱线图上覆盖文本(中位数,+-std)。

                              在此处输入图像描述

4

2 回答 2

25

假设您使用 boxplot 函数来绘制箱线图,它会返回一个包含图形组件的字典。请注意,该框表示内部四分位数范围(25 到 75 个百分位数),而不是标准偏差。

>>> bp_dict = boxplot(data, vert=False) # draw horizontal boxplot
>>> bp_dict.keys()
>>> bp_dict.keys()
['medians', 'fliers', 'whiskers', 'boxes', 'caps']

这些包含构成每个绘图元素的 Line2D 对象。您可以使用 Line2D.get_xydata 方法获取中值和框位置(在数据坐标中),以确定文本的位置。

from pylab import *

# from http://matplotlib.org/examples/pylab_examples/boxplot_demo.html

# fake up some data
spread= rand(50) * 100
center = ones(25) * 50
flier_high = rand(10) * 100 + 100
flier_low = rand(10) * -100
data =concatenate((spread, center, flier_high, flier_low), 0)

# fake up some more data
spread= rand(50) * 100
center = ones(25) * 40
flier_high = rand(10) * 100 + 100
flier_low = rand(10) * -100
d2 = concatenate( (spread, center, flier_high, flier_low), 0 )
data.shape = (-1, 1)
d2.shape = (-1, 1)
#data = concatenate( (data, d2), 1 )
# Making a 2-D array only works if all the columns are the
# same length.  If they are not, then use a list instead.
# This is actually more efficient because boxplot converts
# a 2-D array into a list of vectors internally anyway.
data = [data, d2, d2[::2,0]]

# multiple box plots on one figure
figure()

# get dictionary returned from boxplot
bp_dict = boxplot(data, vert=False)

for line in bp_dict['medians']:
    # get position data for median line
    x, y = line.get_xydata()[1] # top of median line
    # overlay median value
    text(x, y, '%.1f' % x,
         horizontalalignment='center') # draw above, centered

for line in bp_dict['boxes']:
    x, y = line.get_xydata()[0] # bottom of left line
    text(x,y, '%.1f' % x,
         horizontalalignment='center', # centered
         verticalalignment='top')      # below
    x, y = line.get_xydata()[3] # bottom of right line
    text(x,y, '%.1f' % x,
         horizontalalignment='center', # centered
             verticalalignment='top')      # below

show()

箱线图输出

于 2013-09-17T23:51:20.300 回答
-1

一点修正:

for line in bp_dict['medians']:
  # get position data for median line
  x, y = line.get_xydata()[1]  # top of median line
  # overlay median value
  text(x, y, '%.1f' % x, horizontalalignment='center')  # draw above, centered

for box in bp_dict['boxes']:
  x, y = box.get_path().vertices[0]  # bottom of left line
  text(x, y, '%.1f' % x, horizontalalignment='center',  # centered
  verticalalignment='top')      # below
  x, y = box.get_path().vertices[6]  # bottom of right line
  text(x, y, '%.1f' % x,
    horizontalalignment='center',  # centered
    verticalalignment='top')      # below
于 2021-03-14T16:17:57.533 回答