numpy.histogram2d

numpy.histogram2d(x, y, bins=10, range=None, normed=None, weights=None, density=None)

Функция histogram2d() вычисляет двумерную гистограмму двух наборов данных.

Наборы x и y должны быть одинаковой длинны, и по сути выступают в роли единого набора координат точек на плоскости. А функция histogram2d(), по сути, просто разбивает плоскость на прямоугольные области и занимается подсчетом вхождений точек в каждую из них.

Параметры:
x - массив NumPy или подобный массиву объект.
Входные данные в виде одномерного массива.
y - массив NumPy или подобный массиву объект.
Входные данные в виде одномерного массива, той же длинны что и x.
bins - целое число, последовательность целых чисел или строка (необязательный параметр), список из двух целых чисел или список из двух массивов или список из одного целого числа и массива (необязательный параметр).
  • Если указано одно число, то оно определяет одинаковое количество интервалов одинаковой ширины сразу по двум осям, т.е. nx = ny = bins;
  • Если указан массив то его значения задают идентичные границы интервалов сразу по двум осям x_edges = y_edges = bins. В данном случае можно задать длины интервалов разной ширины;
  • Если bins = [int_1, int_2], то nx = int_1, а ny = int_2;
  • Если bins = [array_1, array_2], то x_edges = array_1 а y_edges = array_2, т.е. плоскость может разбиваться на прямоугольные ячейки произвольного размера;
  • Если bins = [int, array] или bins = [array, int], то одна ось разбивается на интервалы произвольной ширины а другая на интервалы равной ширины.
range - массив NumPy или подобный массиву объект (необязательный параметр).
Массив с размером (2, 2) вида [[xmin, xmax], [ymin, ymax]], который определяет допустимые крайние значения по двум осям. Все значения из массивов x и y, которые не входят в данный интервал будут считаться недопустимыми (считаться выбросами) и не учитываться при расчете гистограммы. Данный параметр может не указываться, если границы заданы явно в параметре bins.
density - True или False (необязательный параметр).
Если density = True, то результатом вычислений окажется функция (точнее ее значения) плотности вероятности - bin_count / sample_count / bin_area, а интеграл по диапазону значений range будет равен 1. Однако, интеграл не будет равен 1 если ширина ячеек не равна 1. Не путайте данную функцию плотности вероятности с функцией вероятности. Если density = False, товозвращается обычное количество вхождений значений в каждую ячейку.
normed - True или False (необязательный параметр).
Является псевдонимом для density и считается устаревшим начиная с версии 1.6.0.
weights - массив NumPy или подобный массиву объект (необязательный параметр).
Массив весовых коэфициентов той же длины, что и x. Каждое значение в weights добавляет соответствующий вес к паре соответствующих элементов из x и y. Если параметр density = True, то все коэфициенты в weights нормализуются так, что интеграл плотности по диапазону range будет равен 1.
Возвращает:
hist - массив NumPy
Значения двумерной гистограммы для двух наборов данных x и y.
x_edges - массив NumPy
Массив с границами каждой ячейки по первому измерению len(x_edges) = len(x) + 1.
y_edges - массив NumPy
Массив с границами каждой ячейки по второму измерению. len(y_edges) = len(y) + 1.

Смотрите так же:
histogram, histogramdd, histogram_bin_edges, bincount, digitize


Примеры

Интерпретация двумерных гистограмм

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

>>> import numpy as np
>>> 
>>> x = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         2, 2, 2, 2, 2,
         3, 3, 3,
         4, 4, 4,
         5]
>>> 
>>> y = [1, 1, 1, 1,
         2, 2, 2, 2, 2, 2, 2, 2, 2,
         3, 3, 3, 3, 3, 3,
         4, 4, 4, 4,
         5, 5]
>>> 
>>> 
>>> hist, x_edges, y_edges = np.histogram2d(x, y)
>>> hist
array([[4., 0., 9., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 2., 0., 1.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 1.]])
>>> 
>>> x_edges
array([1. , 1.4, 1.8, ..., 4.2, 4.6, 5. ])
>>> 
>>> y_edges
array([1. , 1.4, 1.8, ..., 4.2, 4.6, 5. ])

Как видим, в результате получилась двумерная гистограмма и два массивами со значениями границ интервалов, причем ширины интервалов по обеим осям одинаковые. Попробуем отобразить данную гистограмму на графике с помощь метода imshow()

>>> import matplotlib.pyplot as plt
>>> 
>>> plt.imshow(hist)
>>> plt.show()

Простейший график двумерной гистограммы, вычисленной в NumPy

Конечно этот график несет какую-то информацию, но пока ее довольно трудно интерпретировать. Отчасти, дело в автоматическом вычислении границ ячеек. Давайте зададим границы ячеек вручную (границы интервалов являются полуоткрытыми. Подробнее см. в замечанни к функции histogram()):

>>> >>> hist, x_edges, y_edges = np.histogram2d(x, y, bins = 5)
>>> 
>>> plt.imshow(hist)
>>> plt.show()

Улучшение графика двумерной гистограммы

Теперь данные более сгруппированы, но не мешало бы привести в порядок оси и вывести цветовую карту, что бы можно было сопоставлять цвет с его числовым значением:

>>> plt.imshow(hist.T, origin = 'lower',
... extent = [x_edges[0], x_edges[-1], y_edges[0], y_edges[-1]])
>>> plt.xticks(ticks = x_edges)
>>> plt.xlabel('x')
>>> plt.yticks(ticks = y_edges)
>>> plt.ylabel('y')
>>> plt.colorbar()
>>> plt.show()

Наилучшее для интерпретации отображение графика двумерной гистограммы

Командой hist.T мы транспонировали массив, что бы его строки соответствовали оси y, а столбцы - оси x. с помощью параметра origin = 'lower' мы заставили рисовать гистограмму с левого нижнего угла (это необязательно, но изображение графика в декартовых координатах более привычно).

Теперь займемся интерпретацией получившегося графика двумерной гистограммы, что на самом деле очень просто - давайте добавим на наш график с гистограммой график разброса:

>>> plt.scatter(y, x, color = 'r')
>>> plt.show()

Интерпретация графика двумерной гистограммы с помощью графика разброса первоначальных точек

Как видите, каждая пара соответствующих значений из массивов x и y является координатой точки, а функция histogram2d() занимается простым подсчетом количества вхождений точек в заданные прямоугольные области. Так, например, точек с координатами [1, 1] всего 4, точек с координатами [1, 2] больше всего - 9 штук, точек с координатами [2, 3] - 5 штук и т.д.

Границы ячеек

В случае если плоскость необходимо разбить на прямоугольные области разного размера, то отобразить получившуюся гистограмму можно с помощью метода pcolormesh() библиотеки Matplotlib.

Для начала отобразим гистограмму с интервалами ячеек вычисленными автоматически:

>>> rng = np.random.RandomState(777)
>>> 
>>> x = rng.beta(2, 5, size = 1000)
>>> y = rng.normal(1, 4, size = 1000)
>>> 
>>> hist, x_edges, y_edges = np.histogram2d(x, y)
>>> 
>>> hist = hist.T    #  Что бы строки строки соответствовали оси 'y'
>>>                  #  а столбцы оси 'x'
... 
>>> X, Y = np.meshgrid(x_edges, y_edges)
>>> 
>>> plt.pcolormesh(X, Y, hist)
>>> plt.show()

Двумерная гистограмма с границами ячеек установленными по умолчанию

Теперь попробуем задать границы ячеек самостоятельно:

>>> x_edges = np.linspace(x.min(), x.max(), 100)
>>> y_edges = np.linspace(y.min(), y.max(), 20)
>>> 
>>> hist = np.histogram2d(x, y, bins = [x_edges, y_edges])[0]
>>> 
>>> hist = hist.T
>>> 
>>> X, Y = np.meshgrid(x_edges, y_edges)
>>> 
>>> plt.pcolormesh(X, Y, hist)
>>> plt.show()

Двумерная гистограмма с границами ячеек установленными вручную

В некоторых случаях когда точек очень много и на графике разброса происходит их многократное наложение друг на друга, двумерная гистограмма может оказаться абсолютно незаменимой. Например, рассмотрим график разброса на котором 15000 точек:

>>> x = rng.beta(2, 5, size = 15000)
>>> y = rng.normal(1, 4, size = 15000)
>>> 
>>> plt.scatter(x, y, s = 1)
>>> plt.show()

Сложноинтерпретируемые графики разброса

А теперь построим двумерную гистограмму с небольшими ячейками:

>>> x_edges = np.linspace(x.min(), x.max(), 100)
>>> y_edges = np.linspace(y.min(), y.max(), 100)
>>> 
>>> hist = np.histogram2d(x, y, bins = [x_edges, y_edges])[0]
>>> 
>>> hist = hist.T
>>> 
>>> X, Y = np.meshgrid(x_edges, y_edges)
>>> 
>>> plt.pcolormesh(X, Y, hist, cmap = 'nipy_spectral')
>>> plt.colorbar()
>>> plt.show()

Двумерная гистограмма помогает лучше понять график разброса

Вообще, ширина ячеек может быть задана какой угодно возрастающей функцией:

>>> x = rng.beta(2, 5, size = 10000)
>>> y = rng.normal(1, 4, size = 10000)
>>> 
>>> 
>>> x_edges = np.linspace(x.min()**0.5, x.max()**0.5, 200)**2
>>> y_edges = 0.001*np.linspace(y.min(), y.max(), 75)**3
>>> 
>>> hist = np.histogram2d(x, y, bins = [x_edges, y_edges])[0]
>>> 
>>> hist = hist.T
>>> 
>>> X, Y = np.meshgrid(x_edges, y_edges)
>>> 
>>> plt.pcolormesh(X, Y, hist)
>>> plt.show()

Двумерная гистограмма с границами ячеек заданными функцией

Прочие параметры

Использование остальных параметров данной функции абсолютно аналогично их использованию в функции histogram().