Как нормализовать тепловые карты - PullRequest
0 голосов
/ 10 мая 2018

Я пытаюсь нормализовать тепловые карты, полученные из 2dhistogram. Я хотел бы, чтобы распределения были относительными, независимо от количества точек данных.

Прикрепленный код содержит два набора данных. Один имеет больше координат x, y по сравнению с другим. Хотя числа являются случайными, можно ли нормализовать эти графики, чтобы плотность представляла распределение, а не частоту. Используя приведенный ниже пример, x1-y1 будет иметь гораздо больше вариаций из-за количества выборок. Хотя основной вариант похож на x2-y2

import matplotlib.pyplot as plt
import random
import numpy as np

fig, ((ax1, ax2)) = plt.subplots(1,2)

x1 = [random.randrange(1,101,1) for _ in range (10000)]
y1 = [random.randrange(1,101,1) for _ in range (10000)]

x2 = [random.randrange(1,100,1) for _ in range (1000)]
y2 = [random.randrange(1,100,1) for _ in range (1000)]

zi, xi, yi = np.histogram2d(x1, y1, bins=40, normed = False)
im = ax1.imshow(zi, interpolation = 'gaussian', origin = 'lower', cmap = 'jet')

zi, xi, yi = np.histogram2d(x2, y2, bins=40, normed = False)
im = ax2.imshow(zi, interpolation = 'gaussian', origin = 'lower', cmap = 'jet')

Можно ли нормализовать строки, определив максимальную интенсивность или количество в каждом бине, и использовать их в качестве контрольной точки и построить там другие данные из диапазонов 0 - 1?

Примечание: это не относится к приведенному выше коду, но я приложу примеры, чтобы дать наглядное представление о том, чего я надеюсь достичь. Мой код выдает следующие изображения:

enter image description here

Хотя эти изображения и не воспроизводятся с помощью приведенного выше кода, они выглядят так:

C_f50,x,y,p = plt.hist2d(Con_F50X, Con_F50Y, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax9.imshow(C_f50.T, interpolation = 'gaussian', cmap = 'jet')

C_fmid,x,y,p = plt.hist2d(Con_FMIDX, Con_FMIDY, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax10.imshow(C_fmid.T, interpolation = 'gaussian', cmap = 'jet')

C_dmid,x,y,p = plt.hist2d(Con_DMIDX, Con_DMIDY, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax11.imshow(C_dmid.T, interpolation = 'gaussian', cmap = 'jet')

C_d50,x,y,p = plt.hist2d(Con_D50X, Con_D50Y, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax12.imshow(C_d50.T, interpolation = 'gaussian', cmap = 'jet')

В следующем наборе изображений используются vmin и vmax, детализированные @filippo в разделе ответов.

enter image description here

Как видите, плотность заметно изменилась. Основным отличием является функция vmin/vmax. Он получает эти меры с первого графика (C_f50).

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

C_f50,x,y,p = plt.hist2d(Con_F50X, Con_F50Y, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax9.imshow(C_f50.T, interpolation = 'gaussian', cmap = 'jet')

C_fmid,x,y,p = plt.hist2d(Con_FMIDX, Con_FMIDY, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax10.imshow(C_fmid.T, interpolation = 'gaussian', cmap = 'jet',vmin=C_f50.min(), vmax=C_f50.max())

C_dmid,x,y,p = plt.hist2d(Con_DMIDX, Con_DMIDY, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax11.imshow(C_dmid.T, interpolation = 'gaussian', cmap = 'jet', vmin=C_f50.min(), vmax=C_f50.max())

C_d50,x,y,p = plt.hist2d(Con_D50X, Con_D50Y, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax12.imshow(C_d50.T, interpolation = 'gaussian', cmap = 'jet',vmin=C_f50.min(), vmax=C_f50.max())

Имеет ли это смысл?

1 Ответ

0 голосов
/ 10 мая 2018

Не уверен, что полностью понял вопрос. Прикрепленный сюжет не имеет очевидного отношения к опубликованному вами коду.

Вы можете предварительно вычислить свою гистограмму, найти минимальные и максимальные значения и использовать их для нормализации с параметрами vmin и vmax imshow.

1008 * Е.Г. *

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# gen 9 2d gaussian samples and histogram
data = np.random.normal(size=(9, 10000, 2))
zidata = np.asarray([np.histogram2d(row[:,0], row[:,1], bins=40)[0] for row in data])

# plot 
gridspec = mpl.gridspec.GridSpec(3,3)
for zi, gs in zip(zidata, gridspec):
    ax = plt.subplot(gs)
    ax.imshow(zi, interpolation='gaussian', vmin=zidata.min(), vmax=zidata.max())
    ax.axis("tight")
plt.show()

По умолчанию imshow нормализует ваши данные с помощью Normalize , который в основном применяет простое линейное преобразование, например:

vmin = img.min()
vmax = img.max()
return (img - vmin)/(vmax - vmin)

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

В качестве альтернативы, если вам нужно больше контроля, вы можете установить norm=matplotlib.colors.NoNorm и нормализовать свои данные самостоятельно, чтобы они корректно отображались в цветовую карту matplotlib.

...