【问题标题】:pyplot x-axis tick mark spacing is not centered with all columnspyplot x轴刻度线间距未以所有列居中
【发布时间】:2018-06-11 03:46:07
【问题描述】:

我正在为 pyplot histogram 函数的错误指定而苦苦挣扎。正如您在图像中看到的,根据 align='mid' 参数,x 轴刻度线在列上的中心不一致。如有必要,我会将数据文件上传到 Dropbox。 谢谢你的帮助!

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import FormatStrFormatter

data = DRA_size_males_s

fig, ax = plt.subplots(nrows=1, ncols=1)
ax.hist(data, facecolor='blue', edgecolor='gray', bins=25, rwidth=1.10, align='mid')


bins=[1.4,1.5,1.6,1.7,1.9,2.0,2.1,2.2,2.3,2.4,2.5,2.6,2.7,2.8,2.9,3.1,3.2,3.5,3.6,3.8] 
ax.set_xticks(bins)

ax.set_ylabel('Frequency')
ax.set_xlabel('DRA Sizes(mm)')

ax.set_title('Frequencies of DRA Sizes in Males (mm)')

plt.show()

这是用于创建直方图的数据数组: 1.4, 1.4, 1.4, 1.5, 1.5, 1.6, 1.7, 1.7, 1.7, 1.9, 1.9, 1.9, 1.9, 2.0, 2.0, 2.0, 2.1, 2.1, 2.1, 2.1, 2.2, 2.2, 2.3, 2.3, 2.3, 2.4, 2.5, 2.6, 2.7, 2.7, 2.8, 2.8, 2.8, 2.9, 2.9, 3.1, 3.1, 3.2, 3.2, 3.5, 3.6, 3.8

【问题讨论】:

    标签: matplotlib histogram bins


    【解决方案1】:

    尝试使用binsrange 的值减去一个小的偏移量,如下例所示。

    In [100]: x = np.array([1, 2, 3, 4, 0, 3, 1, 7, 4, 5, 8, 8, 9, 7, 7, 3])
    
    In [101]: len(x)
    Out[101]: 16
    
    In [102]: bins = np.arange(10) - 0.5
    
    In [103]: plt.hist(x, facecolor='blue', edgecolor='gray', bins=bins, rwidth=2, alpha=0.75)
    

    现在,bin 编号将与 center 对齐。

    【讨论】:

    • 谢谢kmario,但我想查看与离散小数点值相关的x 轴箱。您的建议有效,但尝试了一些变化,要么创建 x 轴整数值,要么将十进制值的各种范围内的频率相加。我编辑了我的问题以包含原始数据。
    【解决方案2】:

    plt.histalign="mid" 参数将直方图的条形置于 bin 边缘之间的中间 - 这实际上是绘制直方图的常用方法。

    为了使直方图使用预定义的 bin 边缘,您需要将这些 bin 边缘提供给 plt.hist 函数。

    import matplotlib.pyplot as plt
    import numpy as np
    
    data = [1.4, 1.4, 1.4, 1.5, 1.5, 1.6, 1.7, 1.7, 1.7, 1.9, 1.9, 1.9, 1.9, 2.0, 
            2.0, 2.0, 2.1, 2.1, 2.1, 2.1, 2.2, 2.2, 2.3, 2.3, 2.3, 2.4, 2.5, 2.6, 
            2.7, 2.7, 2.8, 2.8, 2.8, 2.9, 2.9, 3.1, 3.1, 3.2, 3.2, 3.5, 3.6, 3.8]
    
    fig, ax = plt.subplots(nrows=1, ncols=1)
    
    bins=[1.4,1.5,1.6,1.7,1.9,2.0,2.1,2.2,2.3,2.4,2.5,2.6,2.7,2.8,2.9,3.1,3.2,3.5,3.6,3.8]
    
    ax.hist(data, bins=bins, facecolor='blue', edgecolor='gray', rwidth=1, align='mid') 
    ax.set_xticks(bins)
    
    ax.set_ylabel('Frequency')
    ax.set_xlabel('DRA Sizes(mm)')
    ax.set_title('Frequencies of DRA Sizes in Males (mm)')
    
    plt.show()
    

    【讨论】:

    • 谢谢!这让我更接近了,但我很困惑为什么当所有其他值都有自己的 bin 时,为什么将 3.6 和 3.8 的数据值合并到一个具有单个频率值为 2 的 bin 中(这是正确的)。
    • bins 是 bin 边缘的列表。位于 bin 边缘之间的所有值都包含在同一 bin bins[i] <= x < bins[i+1] 中。除了最后一个已关闭的 bin,bins[n-1] <= x <= bins[n].
    • 再次感谢!也许我还没有对其他方法进行足够的研究,但令我惊讶的是,没有一种方法可以将 x 轴值一对一地渲染到直方图条上,并且能够使该值相对于直方图居中酒吧。请确认这一点,我会接受您的回答。再次感谢您的时间和洞察力!
    • 也许在某些时候存在一些误解。 matplotlib 几乎可以实现任何类型的 2D 绘图。以上是我所理解的问题的解决方案。 “将 x 轴值一对一渲染到直方图条并能够使该值相对于直方图条居中” 到底是什么意思?这似乎是矛盾的。你是否例如希望第一个 bin 的标签为 1.45?
    • 对不起,如果我不清楚。例如,在直方图的最左侧,1.4 是出现 3 次的值,1.5 是出现 2 次的值。我希望 1.4 和 1.5 标签位于它们各自的直方图条下方的中心。同样,在直方图的右侧,3.6 是出现 1 次的值,3.8 是出现 1 次的值。我希望 3.6 和 3.8 有自己的条形图,都表示频率为 1,并且值标签位于各自的直方图条形下方的中心。看起来我可能对如何使用垃圾箱感到困惑。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多