当前位置: 首页 > 知识库问答 >
问题:

Matplotlib直方图,带高值收集箱

呼延高超
2023-03-14

我有一个带有值的数组,我想创建它的直方图。我主要对低端号码感兴趣,想把300以上的每一个号码都收集在一个箱子里。此箱应与所有其他(等宽)箱具有相同的宽度。我该怎么做呢?

注:此问题与此问题相关:在Matplotlib直方图中定义仓位宽度/x轴比例

这就是我迄今为止所尝试的:

import matplotlib.pyplot as plt
import numpy as np

def plot_histogram_01():
    np.random.seed(1)
    values_A = np.random.choice(np.arange(600), size=200, replace=True).tolist()
    values_B = np.random.choice(np.arange(600), size=200, replace=True).tolist()

    bins = [0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300, 600]

    fig, ax = plt.subplots(figsize=(9, 5))
    _, bins, patches = plt.hist([values_A, values_B], normed=1,  # normed is deprecated and will be replaced by density
                                bins=bins,
                                color=['#3782CC', '#AFD5FA'],
                                label=['A', 'B'])

    xlabels = np.array(bins[1:], dtype='|S4')
    xlabels[-1] = '300+'

    N_labels = len(xlabels)
    plt.xlim([0, 600])
    plt.xticks(25 * np.arange(N_labels) + 12.5)
    ax.set_xticklabels(xlabels)

    plt.yticks([])
    plt.title('')
    plt.setp(patches, linewidth=0)
    plt.legend()

    fig.tight_layout()
    plt.savefig('my_plot_01.png')
    plt.close()

然后,我更改了其中包含xlim的行:

plt.xlim([0, 325])

它看起来或多或少像我想要的,但是最后一个垃圾箱现在看不见了。我错过了哪一个技巧来可视化宽度为25的最后一个垃圾箱?

共有2个答案

姬国安
2023-03-14

对不起,我不熟悉matplotlib。所以我有一个肮脏的黑客给你。我只是把所有大于300的值放在一个箱子里,然后改变箱子的大小。

问题的根源在于matplotlib试图将所有箱子放在绘图上。在R中,我会将我的箱子转换为因子变量,所以它们不会被视为实数。

import matplotlib.pyplot as plt
import numpy as np

def plot_histogram_01():
    np.random.seed(1)
    values_A = np.random.choice(np.arange(600), size=200, replace=True).tolist()
    values_B = np.random.choice(np.arange(600), size=200, replace=True).tolist()
    values_A_to_plot = [301 if i > 300 else i for i in values_A]
    values_B_to_plot = [301 if i > 300 else i for i in values_B]

    bins = [0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300, 325]

    fig, ax = plt.subplots(figsize=(9, 5))
    _, bins, patches = plt.hist([values_A_to_plot, values_B_to_plot], normed=1,  # normed is deprecated and will be replaced by density
                                bins=bins,
                                color=['#3782CC', '#AFD5FA'],
                                label=['A', 'B'])

    xlabels = np.array(bins[1:], dtype='|S4')
    xlabels[-1] = '300+'

    N_labels = len(xlabels)

    plt.xticks(25 * np.arange(N_labels) + 12.5)
    ax.set_xticklabels(xlabels)

    plt.yticks([])
    plt.title('')
    plt.setp(patches, linewidth=0)
    plt.legend()

    fig.tight_layout()
    plt.savefig('my_plot_01.png')
    plt.close()

plot_histogram_01()
东郭鹤龄
2023-03-14

Numpy有一个方便的函数来处理这个问题:np.clip。不管名称听起来像什么,它都不会删除值,只是将它们限制在您指定的范围内。基本上,它在线执行阿特姆的“肮脏黑客”。您可以保持这些值不变,但是在hist调用中,只需将数组包装成np.clip调用,就像这样

plt.hist(np.clip(values_A, bins[0], bins[-1]), bins=bins)

这是更好的一些原因:

>

  • 快多了-

    您可以在需要的地方正确地执行它,从而减少代码出错的机会。

    您不需要保留数组的第二个副本,这减少了内存使用(除了这一行),并进一步减少了出错的机会。

    使用bin[0],bin[-1]而不是硬编码,这些值可以减少再次出错的机会,因为您可以在定义bin的位置更改bin;您不需要记住在调用clip或其他任何地方更改它们。

    因此,将所有这些放在一起,如OP中所示:

    import matplotlib.pyplot as plt
    import numpy as np
    
    def plot_histogram_01():
        np.random.seed(1)
        values_A = np.random.choice(np.arange(600), size=200, replace=True)
        values_B = np.random.choice(np.arange(600), size=200, replace=True)
    
        bins = np.arange(0,350,25)
    
        fig, ax = plt.subplots(figsize=(9, 5))
        _, bins, patches = plt.hist([np.clip(values_A, bins[0], bins[-1]),
                                     np.clip(values_B, bins[0], bins[-1])],
                                    # normed=1,  # normed is deprecated; replace with density
                                    density=True,
                                    bins=bins, color=['#3782CC', '#AFD5FA'], label=['A', 'B'])
    
        xlabels = bins[1:].astype(str)
        xlabels[-1] += '+'
    
        N_labels = len(xlabels)
        plt.xlim([0, 325])
        plt.xticks(25 * np.arange(N_labels) + 12.5)
        ax.set_xticklabels(xlabels)
    
        plt.yticks([])
        plt.title('')
        plt.setp(patches, linewidth=0)
        plt.legend(loc='upper left')
    
        fig.tight_layout()
    plot_histogram_01()
    

  •  类似资料:
    • 直方图(Histogram),又称质量分布图,它是一种条形图的一种,由一系列高度不等的纵向线段来表示数据分布的情况。 直方图的横轴表示数据类型,纵轴表示分布情况。 首先,我们需要了解柱状图和直方图的区别。直方图用于概率分布,它显示了一组数值序列在给定的数值范围内出现的概率;而柱状图则用于展示各个类别的频数。 例如,我们对某工厂的员工年龄做直方图统计,首先我们要统计出每一位员工的年龄,然后设定一个

    • 我使用matplotlib创建直方图。仍然有一些问题我自己或借助互联网无法解决。 > 如何更改某些垃圾箱的颜色?详细地说,我想用:a.)value bin更改箱子的颜色 如何不仅用1个小数点的数字标记X轴,而且用2个小数点标记X轴(现在只是不打印)? 请参见下面绘制的柱状图: plt。迄今为止的直方图

    • 我有一个从sql数据库查询派生的直方图。代码如下: 输出如下:https://gyazo.com/d73b20a118db0088aab261c079613b00 我想显示为:https://gyazo.com/063990cd8741682f45b5a37ba594ff56 其中,x轴的编号向右侧移动了一点。有可能做到这一点吗?

    • NumPy有一个numpy.histogram()函数,它是数据频率分布的图形表示。 相等水平尺寸的矩形对应于称为bin类间隔和对应于频率的variable height 。 numpy.histogram() numpy.histogram()函数将输入数组和bin作为两个参数。 bin数组中的连续元素充当每个bin的边界。 import numpy as np a = np.array([2

    • 我想在同一个图上绘制多个直方图,我需要比较数据的分布。我想用每个直方图除以它的最大值,这样所有分布都有相同的比例。然而,根据matplotlib的直方图函数的工作方式,我还没有找到一种简单的方法来实现这一点。 这是因为n在 是计数的数量在每个箱,但我不能重传这到hist,因为它将重新计算。 我尝试了范数和密度函数,但这些函数使分布的面积正常化,而不是分布的高度。我可以复制n,然后使用箱输出重复箱边

    • numpy.histogram()函数将输入数组和作为两个参数。 bin数组中的连续元素用作每个bin的边界。 Matplotlib 可以将直方图的数字表示转换为图形。 pyplot子模块的plt()函数将包含数据和数组的数组作为参数,并转换为直方图。