Python: создание двумерной гистограммы из матрицы numpy

Я новичок в python.

У меня есть матрица numpy размером 42x42 с значениями в диапазоне 0-996. Я хочу создать двумерную гистограмму с использованием этих данных. Я изучал учебные пособия, но все они, похоже, показывают, как создавать 2D-гистограммы из случайных данных, а не матрицу.

До сих пор я импортировал:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors

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

У меня есть матрица numpy M со всеми значениями в ней (как описано выше). В конце концов, я хочу, чтобы он выглядел примерно так:

2D histogram

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

Изменить: В моих целях пример Hooked ниже, используя matshow, именно то, что я ищу.

Ответ 1

Если у вас есть необработанные данные из подсчетов, вы можете использовать plt.hexbin для создания графиков для вас (IMHO это лучше, чем квадратная решетка): Адаптировано из примера hexbin:

import numpy as np
import matplotlib.pyplot as plt

n = 100000
x = np.random.standard_normal(n)
y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
plt.hexbin(x,y)

plt.show()

enter image description here

Если у вас уже есть значения Z в матрице, как вы упоминаете, просто используйте plt.imshow или plt.matshow:

XB = np.linspace(-1,1,20)
YB = np.linspace(-1,1,20)
X,Y = np.meshgrid(XB,YB)
Z = np.exp(-(X**2+Y**2))
plt.imshow(Z,interpolation='none')

enter image description here

Ответ 2

Если у вас есть не только матрица двумерных гистограмм, но и базовые данные (x, y), вы можете сделать график рассеяния точек (x, y) и покрасить каждую точку в соответствии со своим значением бинарного счета в матрице 2D-гистограммы

import numpy as np
import matplotlib.pyplot as plt

n = 10000
x = np.random.standard_normal(n)
y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
xedges, yedges = np.linspace(-4, 4, 42), np.linspace(-25, 25, 42)
hist, xedges, yedges = np.histogram2d(x, y, (xedges, yedges))
xidx = np.clip(np.digitize(x, xedges), 0, hist.shape[0]-1)
yidx = np.clip(np.digitize(y, yedges), 0, hist.shape[1]-1)
c = hist[xidx, yidx]
plt.scatter(x, y, c=c)

plt.show()

Example scatter plot of 2D histogram

Ответ 3

@unutbu answer содержит ошибку: xidx и yidx вычисляются неверно (по крайней мере, на моем примере данных). Правильный способ:

xidx = np.clip(np.digitize(x, xedges) - 1, 0, hist.shape[0] - 1)
yidx = np.clip(np.digitize(y, yedges) - 1, 0, hist.shape[1] - 1)

Поскольку интересующее нас измерение возврата np.digitize находится между 1 и len(xedges) - 1, но для c = hist[xidx, yidx] нужны индексы между 0 и hist.shape - 1.


Ниже приведено сравнение результатов. Как вы можете видеть, вы получаете похожий, но не тот же результат.

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)

n = 10000
x = np.random.standard_normal(n)
y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
xedges, yedges = np.linspace(-4, 4, 42), np.linspace(-25, 25, 42)
hist, xedges, yedges = np.histogram2d(x, y, (xedges, yedges))

xidx = np.clip(np.digitize(x, xedges), 0, hist.shape[0] - 1)
yidx = np.clip(np.digitize(y, yedges), 0, hist.shape[1] - 1)
c = hist[xidx, yidx]
old = ax1.scatter(x, y, c=c, cmap='jet')

xidx = np.clip(np.digitize(x, xedges) - 1, 0, hist.shape[0] - 1)
yidx = np.clip(np.digitize(y, yedges) - 1, 0, hist.shape[1] - 1)

c = hist[xidx, yidx]
new = ax2.scatter(x, y, c=c, cmap='jet')


plt.show()

То же самое, но различно