Нормализовать гистограмму для трех наборов данных в python - PullRequest
0 голосов
/ 27 мая 2020
plt.subplots(figsize=(12,9))
n, bins, patches = plt.hist(x, 50, normed=1, histtype='step', lw=2, color='blue', 
                   label='color _22')
n, bins, patches = plt.hist(y, 50, normed=1, histtype='step', lw=2, color='red', 
                   label='color _20')
n, bins, patches = plt.hist(z, 50, normed=1, histtype='step', lw=2, color='green', 
                   label='color _18')
plt.legend(loc='upper left')

Я хочу нормализовать эти три набора данных. Когда я рисую, используя приведенный выше сценарий, я получаю ненормализованный график. Пожалуйста, дайте мне знать, что я могу сделать для нормализации.

enter image description here

Ответы [ 2 ]

2 голосов
/ 27 мая 2020

Вы используете normed=1, старый параметр, который теперь называется density=True. В последней версии normed вызывает сообщение об ошибке; в предыдущих версиях он генерирует предупреждение об устаревании.

В любом случае, с normed=1 (или density=True) вы уже получаете нормализованную гистограмму. Обратите внимание, что нормализация здесь означает: общая площадь равна единице. Это относится к ширине ячейки: ширина ячейки, умноженная на сумму всех высот ячейки, равна единице.

Вы заметите, что синяя гистограмма шире, а пик зеленой гистограммы поглощает разницу в ширине. Итак, оба имеют фактически ту же область (1), что и красная гистограмма.

В качестве альтернативы вы можете предложить другой тип нормализации, где высота гистограммы определяется как процент от самого высокого столбца. В приведенном ниже коде показано, как это может выглядеть. Чтобы избежать необходимости рисовать гистограммы дважды, np.histogram используется для вычисления значений бинов, которые могут быть построены с помощью plt.step.

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

N = 1000
x = np.concatenate([np.random.normal(0, 0.04, N), np.random.uniform(-3, 3, 10)])
y = np.concatenate([np.random.normal(0, 0.06, N), np.random.uniform(-3, 3, 10)])
z = np.concatenate([np.random.normal(0, 0.08, N), np.random.uniform(-3, 3, 10)])
for data, color, label in zip((x, y, z), ('b', 'r', 'g'), ('x', 'y', 'z')):
    hist, bins = np.histogram(data, 50)
    plt.step(bins, np.pad(hist, (1, 0)) / hist.max(), where='pre', lw=2, color=color, alpha=0.8, label=label)
plt.ylim(0, None)
plt.gca().yaxis.set_major_formatter(PercentFormatter(1))
plt.legend()
plt.show()

example plot

Обратите внимание, что по умолчанию ячейки гистограммы принимают диапазон от x.min() до x.max(), который делится на равные части (50 в примере). Поскольку 3 массива данных не имеют одинаковых min и max, границы несколько произвольны. Вы можете установить все эти границы равными, явно указав range=(-2, 2) либо plt.hist, либо np.histogram. Если вас интересует только центральная часть, вы можете установить более узкий диапазон.

1 голос
/ 27 мая 2020

Вы можете передать density=True в plt.hist, чтобы получить нормализованную гистограмму. То есть:

plt.subplots(figsize=(12,9))
n, bins, patches = plt.hist(x, 50, density=True,
                            histtype='step', lw=2, 
                            color='blue', label='color _22')
...
...