Python 使pyplot.hist()的第一个和最后一个容器包含异常值

Python 使pyplot.hist()的第一个和最后一个容器包含异常值,python,numpy,matplotlib,Python,Numpy,Matplotlib,pyplot.hist()文档指定在设置直方图范围时“忽略下限和上限异常值” 是否可以使直方图的第一个和最后一个存储单元包含所有异常值,而不改变存储单元的宽度 例如,假设我想查看范围0-3,有3个箱子:0-1、1-2、2-3(为了简单起见,我们忽略完全相等的情况)。我希望第一个容器包含从负无穷大到1的所有值,最后一个容器包含从2到无穷大的所有值。但是,如果我明确地将这些容器设置为跨越该范围,它们将非常宽。我希望它们有相同的宽度。我正在寻找的行为类似于Matlab中的hist() 显然,我可以nu

pyplot.hist()
文档指定在设置直方图范围时“忽略下限和上限异常值”

是否可以使直方图的第一个和最后一个存储单元包含所有异常值,而不改变存储单元的宽度

例如,假设我想查看范围
0-3
,有3个箱子:
0-1、1-2、2-3
(为了简单起见,我们忽略完全相等的情况)。我希望第一个容器包含从负无穷大到1的所有值,最后一个容器包含从2到无穷大的所有值。但是,如果我明确地将这些容器设置为跨越该范围,它们将非常宽。我希望它们有相同的宽度。我正在寻找的行为类似于Matlab中的
hist()


显然,我可以
numpy.clip()
数据和绘图,这将给我想要的。但是我很感兴趣的是是否有一个内置的解决方案。

没有。看看
matplotlib.axes.axes.hist
和直接使用
numpy.histogram
我很有信心地说,没有比使用clip更聪明的解决方案了(除了扩展直方图所使用的存储箱)


我鼓励您查看
matplotlib.axes.axes.hist
(它只是Python代码,尽管承认hist比大多数axes方法稍微复杂一些)-它是验证此类问题的最佳方法。

我也在努力解决这个问题,不想使用
.clip()
因为它可能会误导,所以我编写了一个小函数(大量借用)来指示上下料仓包含异常值:

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()

听起来您有一个两行解决方案(
numpy.clip();pyplot.hist()
),您需要一行。虽然我想一个
clip
关键字到
hist()
会很好,但我认为没有人费心去实现它,因为它太基本了。当然,您可以随时向matplotlib:-)提交补丁。是的,@Evert是对的,clip是最好的解决方案。我想说的是,
pyplot.hist()
没有在中构建它,可能是因为如果不仔细注释,它会生成误导性的绘图。@Evert ok,谢谢。我只是想看看,我没有错过一些更好的解决方案来获得这种行为。很好,我偷了它。但是,我认为您在使用它时必须注意,直方图的第一个和最后一个仓位包括异常值。对于离群者来说,这不是一个单独的锅
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))