【问题标题】:Difficulty aligning xticks to edge of Histogram bin难以将 xticks 对齐到直方图 bin 的边缘
【发布时间】:2020-05-29 01:24:11
【问题描述】:

我正在尝试使用直方图以 3 小时为间隔显示一天中数据的频率。因此,我使用 8 个垃圾箱。

plt.style.use('seaborn-colorblind')

plt.figure(figsize=(10,5))
plt.hist(comments19['comment_hour'], bins = 8, alpha = 1, align='mid', edgecolor = 'white', label = '2019', density=True)
plt.title('2019 comments, 8 bins')
plt.xticks([0,3,6,9,12,15,18,21,24])
plt.xlabel('Hours of Day')
plt.ylabel('Relative Frequency')
plt.tight_layout()
plt.legend()
plt.show()

但是,如下图所示,刻度未与 bin 边缘对齐。

【问题讨论】:

  • 他们不是因为8个边界值和他们自己的xticks不同而关闭吗?我从 CODE 判断,因为我无法在我的环境中运行它。

标签: python matplotlib histogram


【解决方案1】:

您可以:

plt.figure(figsize=(10,5))

# define the bin and pass to plt.hist
bins = [0,3,6,9,12,15,18,21,24]
plt.hist(comments19['comment_hour'], bins = bins, alpha = 1, align='mid', 

# remove this line
# plt.xticks([0,3,6,9,12,15,18,21,24])
edgecolor = 'white', label = '2019', density=True)
plt.title('2019 comments, 8 bins')
plt.xlabel('Hours of Day')
plt.ylabel('Relative Frequency')
plt.tight_layout()
plt.legend()
plt.show()

或者:

fig, ax = plt.subplots()

bins = np.arange(0,25,3)
comments19['comment_hour'].plot.hist(ax=ax,bins=bins)

# other plt format

【讨论】:

    【解决方案2】:

    如果设置bins=8,seaborn 会设置9 个均匀分布的边界,从输入数组中的最小值(0)到最大值(23),所以在[0.0, 2.875, 5.75, 8.625, 11.5, 14.375, 17.25, 20.125, 23.0]。要获得0, 3, 6, ... 的 9 个边界,您需要明确设置它们。

    import numpy as np
    import pandas as pd
    import seaborn as sns
    from matplotlib import pyplot as plt
    
    plt.style.use('seaborn-colorblind')
    
    comments19 = pd.DataFrame({'comment_hour': np.random.randint(0, 24, 100)})
    
    plt.figure(figsize=(10, 5))
    plt.hist(comments19['comment_hour'], bins=np.arange(0, 25, 3), alpha=1, align='mid', edgecolor='white', label='2019',
             density=True)
    plt.title('2019 comments, 8 bins')
    plt.xticks(np.arange(0, 25, 3))
    plt.xlabel('Hours of Day')
    plt.ylabel('Relative Frequency')
    plt.tight_layout()
    plt.legend()
    plt.show()
    

    请注意,您的 density=True 表示直方图的总面积为 1。由于每个 bin 的宽度为 3 小时,因此所有 bin 高度的总和将是 0.33,而不是您可能期望的 1.00。要真正获得具有相对频率的 y 轴,您可以通过将小时除以 3 来制作内部 bin 宽度 1。之后,您可以将 x 轴重新标记为小时。

    因此,可以对所有 bin 进行以下更改以使总和为 100 %:

    from matplotlib.ticker import PercentFormatter
    
    plt.hist(comments19['comment_hour'] / 3, bins=np.arange(9), alpha=1, align='mid', edgecolor='white', label='2019',
             density=True)
    plt.xticks(np.arange(9), np.arange(0, 25, 3))
    plt.gca().yaxis.set_major_formatter(PercentFormatter(1))
    

    【讨论】:

    • 感谢您提供有关密度的其他提示!你会说图表预调整被认为是不准确的吗?我还注意到在你的第二张照片中有 7 个垃圾箱。这是一个错误还是应该是这样的?
    • 感谢您的通知。 7 个 bin 是一个错字:应该是 np.arange(9) 来获得数字 0,1,..,8(我错误地写成了 np.arange(8))。如果不调整,y 轴将是相对频率除以 3。
    猜你喜欢
    • 2021-05-11
    • 2018-01-12
    • 1970-01-01
    • 2015-01-20
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 2022-10-07
    • 1970-01-01
    相关资源
    最近更新 更多