У меня есть ряд X, Y точки данных (о 10k), которые легко вывести на печать как диаграмма рассеяния, но что я хотел бы представить как heatmap.
Я просмотрел примеры в MatPlotLib, и они все, кажется, уже начинают с heatmap значений ячеек генерировать изображение.
Существует ли метод, который преобразовывает набор x, y, все отличающиеся, к heatmap (где зоны с верхней частотой x, y были бы "теплее")?
Если вам не нужны шестиугольники, вы можете использовать функцию numpy histogram2d
:
import numpy as np
import numpy.random
import matplotlib.pyplot as plt
# Generate some test data
x = np.random.randn(8873)
y = np.random.randn(8873)
heatmap, xedges, yedges = np.histogram2d(x, y, bins=50)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
plt.clf()
plt.imshow(heatmap.T, extent=extent, origin='lower')
plt.show()
Это создает тепловую карту 50x50. Если вы хотите, например, 512x384, вы можете поместить bins = (512, 384)
в вызов histogram2d
.
Пример:
В лексиконе Matplotlib, я думаю, вам нужен hexbin график.
Если вы не знакомы с этим типом графика, то это просто двумерная гистограмма, в которой плоскость xy тесселирована регулярной сеткой шестиугольников.
Таким образом, на основе гистограммы можно просто подсчитать количество точек, попадающих в каждый шестиугольник, дискретизировать область построения как набор окон, присвоить каждой точке одно из этих окон; наконец, отобразить окна на цветовой массив, и вы получите гексагональную диаграмму.
Хотя шестиугольники используются реже, чем, например, круги или квадраты, то, что шестиугольники являются лучшим выбором для геометрии контейнера бинов, интуитивно понятно:
шестиугольники обладают симметрией ближайших соседей (например, квадратные бины - нет, например, расстояние от точки на границе квадрата до точки внутри квадрата не везде одинаково) и
шестиугольник - это наибольший n-полигон, который дает регулярную плоскость тесселяцию (т.е. вы можете смело переделывать пол на кухне с помощью плиток шестиугольной формы, потому что у вас не будет пустоты между плитками, когда вы закончите - это не верно для всех других многоугольников с большим n, n >= 7).
(Matplotlib использует термин hexbin plot; так же (AFAIK) делают все библиотеки черчения для R; я все еще не знаю, является ли это общепринятым термином для графиков такого типа, хотя я подозреваю, что это вероятно, учитывая, что hexbin является сокращением от hexagonal binning, который описывает существенный шаг в подготовке данных для отображения. )
from matplotlib import pyplot as PLT
from matplotlib import cm as CM
from matplotlib import mlab as ML
import numpy as NP
n = 1e5
x = y = NP.linspace(-5, 5, 100)
X, Y = NP.meshgrid(x, y)
Z1 = ML.bivariate_normal(X, Y, 2, 2, 0, 0)
Z2 = ML.bivariate_normal(X, Y, 4, 1, 1, 1)
ZD = Z2 - Z1
x = X.ravel()
y = Y.ravel()
z = ZD.ravel()
gridsize=30
PLT.subplot(111)
# if 'bins=None', then color of each hexagon corresponds directly to its count
# 'C' is optional--it maps values to x-y coordinates; if 'C' is None (default) then
# the result is a pure 2D histogram
PLT.hexbin(x, y, C=z, gridsize=gridsize, cmap=CM.jet, bins=None)
PLT.axis([x.min(), x.max(), y.min(), y.max()])
cb = PLT.colorbar()
cb.set_label('mean value')
PLT.show()
Создайте двумерный массив, соответствующий ячейкам вашего конечного изображения, назовем его heatmap_cells
и создайте его со всеми нулями.
Выберите два коэффициента масштабирования, которые определяют разницу между каждым элементом массива в реальных единицах для каждого измерения, скажем x_scale
и y_scale
. Выберите их так, чтобы все точки данных попадали в границы массива тепловой карты.
Для каждой необработанной точки данных с x_value
и y_value
:
heatmap_cells[floor(x_value/x_scale),floor(y_value/y_scale)]+=1