Если вы установите bins=8
, seaborn установит 9 границ с равномерным распределением, от самого низкого значения во входном массиве (0) до самого высокого (23), то есть на [0.0, 2.875, 5.75, 8.625, 11.5, 14.375, 17.25, 20.125, 23.0]
. Чтобы получить 9 границ в 0, 3, 6, ...
, вам необходимо установить их явно.
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. Поскольку ширина каждого интервала составляет 3 часа, сумма всех высот интервалов будет 0.33
, а не 1.00
, как вы могли ожидать. Чтобы действительно получить ось Y с относительными частотами, вы можете сделать внутреннюю ширину бина 1
, разделив часы на 3
. Впоследствии вы можете изменить метку оси X на часы.
Таким образом, следующие изменения могут быть сделаны для всех интервалов, чтобы суммировать их до 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))