pyplot.hist()
文档指定在设置直方图的范围时,“忽略较低和较高的异常值”。
是否可以使直方图的第一个和最后一个包含所有异常值而不改变bin的宽度?
例如,假设我想查看范围为0-3
的3个区间:0-1, 1-2, 2-3
(为简单起见,我们忽略完全相等的情况)。我希望第一个bin包含从负无穷大到1的所有值,最后一个bin包含从2到无穷大的所有值。但是,如果我明确地将这些箱子设置为跨越该范围,它们将非常宽。我希望他们有相同的宽度。我正在寻找的行为就像Matlab中hist()
的行为一样。
显然我可以numpy.clip()
数据和情节,这将给我我想要的东西。但我感兴趣的是,如果有一个内置的解决方案。
答案 0 :(得分:8)
没有。看matplotlib.axes.Axes.hist
并直接使用numpy.histogram
我相当自信地说没有比使用剪辑更聪明的解决方案(除了扩展直方图所用的箱子)。
我建议您查看matplotlib.axes.Axes.hist
的来源(它只是Python代码,尽管可以说,hist比大多数Axes方法稍微复杂一点) - 它是 验证此类问题的最佳方法。
HTH
答案 1 :(得分:5)
我也在为此而苦苦挣扎,并且不想使用.clip()
,因为它可能会引起误解,所以我写了一个小函数(从this大量借用)来指示上半部分和上半部分下层垃圾箱包含异常值:
def outlier_aware_hist(data, lower=None, upper=None):
if not lower or lower < data.min():
lower = data.min()
lower_outliers = False
else:
lower_outliers = True
if not upper or upper > data.max():
upper = data.max()
upper_outliers = False
else:
upper_outliers = True
n, bins, patches = plt.hist(data, range=(lower, upper), bins='auto')
if lower_outliers:
n_lower_outliers = (data < lower).sum()
patches[0].set_height(patches[0].get_height() + n_lower_outliers)
patches[0].set_facecolor('c')
patches[0].set_label('Lower outliers: ({:.2f}, {:.2f})'.format(data.min(), lower))
if upper_outliers:
n_upper_outliers = (data > upper).sum()
patches[-1].set_height(patches[-1].get_height() + n_upper_outliers)
patches[-1].set_facecolor('m')
patches[-1].set_label('Upper outliers: ({:.2f}, {:.2f})'.format(upper, data.max()))
if lower_outliers or upper_outliers:
plt.legend()
您还可以将其与自动离群值检测器(从here借来的)组合,如下所示:
def mad(data):
median = np.median(data)
diff = np.abs(data - median)
mad = np.median(diff)
return mad
def calculate_bounds(data, z_thresh=3.5):
MAD = mad(data)
median = np.median(data)
const = z_thresh * MAD / 0.6745
return (median - const, median + const)
outlier_aware_hist(data, *calculate_bounds(data))