Matplotlib Xticks未与直方图对齐

发布于 2021-01-29 16:33:57

我正在使用matplotlib生成一些直方图,并且在弄清楚如何获取直方图的xticks以使其与条形对齐方面遇到一些麻烦。

这是我用来生成直方图的代码示例:

from matplotlib import pyplot as py

py.hist(histogram_data, 49, alpha=0.75)
py.title(column_name)
py.xticks(range(49))
py.show()

我知道histogram_data数组中的所有值都在中[0,1,...,48]。假设我数学正确,则意味着有49个唯一值。我想显示每个值的直方图。这是生成的图片。

测试

如何设置图形,使所有xtick对准每个条形的左,中或右?

关注者
0
被浏览
138
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    简短答案:plt.hist(data, bins=range(50))改用获取左对齐的垃圾箱,plt.hist(data, bins=np.arange(50)-0.5)获取中心对齐的垃圾箱等。

    另外,如果性能很重要,则由于您需要计数唯一的整数,因此np.bincount我将在后面显示一些更有效的方法()。

    问题陈述


    作为您所看到的独立示例,请考虑以下内容:

    import matplotlib.pyplot as plt
    import numpy as np
    
    # Generate a random array of integers between 0-9
    # data.min() will be 0 and data.max() will be 9 (not 10)
    data = np.random.randint(0, 10, 1000)
    
    plt.hist(data, bins=10)
    plt.xticks(range(10))
    plt.show()
    

    在此处输入图片说明

    您已经注意到,垃圾箱没有以整数间隔对齐。这基本上是因为您要求 0到9 之间的 10个bin ,与要求10个唯一值的bin不太一样。

    您想要的箱数与唯一值的数目不完全相同。在这种情况下,您实际应该做的是手动指定纸槽边缘。

    为了解释正在发生的事情,让我们跳过matplotlib.pyplot.hist而仅使用底层numpy.histogram函数。

    例如,假设您有值[0, 1, 2, 3]。您的第一个本能是:

    In [1]: import numpy as np
    
    In [2]: np.histogram([0, 1, 2, 3], bins=4)
    Out[2]: (array([1, 1, 1, 1]), array([ 0.  ,  0.75,  1.5 ,  2.25,  3.  ]))
    

    返回的第一个数组是计数,第二个是bin边(换句话说,条形边在您的绘图中)。

    注意,我们得到了期望的计数,但是因为我们要求在数据的最小值和最大值之间有4个bin,所以bin的边缘不在整数值上。

    接下来,您可以尝试:

    In [3]: np.histogram([0, 1, 2, 3], bins=3)
    Out[3]: (array([1, 1, 2]), array([ 0.,  1.,  2.,  3.]))
    

    请注意,bin边缘(第二个数组)是您所期望的,但计数不是。这是因为最后一个垃圾箱的行为不同于其他垃圾箱,如文档中所述numpy.histogram

    Notes
    -----
    All but the last (righthand-most) bin is half-open.  In other words, if
    `bins` is::
    
      [1, 2, 3, 4]
    
    then the first bin is ``[1, 2)`` (including 1, but excluding 2) and the
    second ``[2, 3)``.  The last bin, however, is ``[3, 4]``, which *includes*
    4.
    

    因此,您实际应该做的是准确指定所需的bin边缘,并在最后一个数据点之外添加一个或将bin边缘移至0.5间隔。例如:

    In [4]: np.histogram([0, 1, 2, 3], bins=range(5))
    Out[4]: (array([1, 1, 1, 1]), array([0, 1, 2, 3, 4]))
    

    箱对齐


    现在,将其应用于第一个示例,看看它是什么样的:

    import matplotlib.pyplot as plt
    import numpy as np
    
    # Generate a random array of integers between 0-9
    # data.min() will be 0 and data.max() will be 9 (not 10)
    data = np.random.randint(0, 10, 1000)
    
    plt.hist(data, bins=range(11)) # <- The only difference
    plt.xticks(range(10))
    plt.show()
    

    在此处输入图片说明

    好的,太好了!但是,我们现在实际上具有左对齐的垃圾箱。如果我们希望使居中对齐的垃圾箱更好地反映这些是唯一值的事实,该怎么办?

    快速的方法是仅移动垃圾箱边缘:

    import matplotlib.pyplot as plt
    import numpy as np
    
    # Generate a random array of integers between 0-9
    # data.min() will be 0 and data.max() will be 9 (not 10)
    data = np.random.randint(0, 10, 1000)
    
    bins = np.arange(11) - 0.5
    plt.hist(data, bins)
    plt.xticks(range(10))
    plt.xlim([-1, 10])
    
    plt.show()
    

    在此处输入图片说明

    同样,对于右对齐的垃圾箱,只需移动即可-1

    另一种方法


    对于唯一整数值​​的特殊情况,我们可以采用另一种更有效的方法。

    如果要处理以0开头的唯一整数,最好使用而numpy.bincount不是numpy.hist

    例如:

    import matplotlib.pyplot as plt
    import numpy as np
    
    data = np.random.randint(0, 10, 1000)
    counts = np.bincount(data)
    
    # Switching to the OO-interface. You can do all of this with "plt" as well.
    fig, ax = plt.subplots()
    ax.bar(range(10), counts, width=1, align='center')
    ax.set(xticks=range(10), xlim=[-1, 10])
    
    plt.show()
    

    在此处输入图片说明

    这种方法有两个很大的优点。一是速度。
    numpy.histogram(因此plt.hist)基本上通过numpy.digitize然后运行数据numpy.bincount。因为您要处理唯一的整数值,所以无需执行此numpy.digitize步骤。

    但是,更大的优势是对显示的更多控制。如果您希望使用更薄的矩形,请使用较小的宽度:

    import matplotlib.pyplot as plt
    import numpy as np
    
    data = np.random.randint(0, 10, 1000)
    counts = np.bincount(data)
    
    # Switching to the OO-interface. You can do all of this with "plt" as well.
    fig, ax = plt.subplots()
    ax.bar(range(10), counts, width=0.8, align='center')
    ax.set(xticks=range(10), xlim=[-1, 10])
    
    plt.show()
    

    在此处输入图片说明



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看