2D визуализация данных сетки в Python - PullRequest
25 голосов
/ 29 августа 2011

Мне нужно визуализировать некоторые данные.Это базовая 2D-сетка, где каждая ячейка имеет значение с плавающей точкой.Я знаю, как например присвоить цвет значению и нарисовать сетку в OpenCV.Но дело здесь в том, что существует так много ценностей, что почти невозможно сделать это.Я ищу какой-нибудь метод, где я мог бы использовать градиент.Например, значение -5.0 будет представлено синим цветом, 0 - черным, а +5.0 - красным.Есть ли способ сделать это в Python?

Вот пример данных, о которых я говорю

        A       B       C        D
A    -1.045    2.0     3.5    -4.890
B    -5.678    3.2     2.89    5.78

Ответы [ 2 ]

46 голосов
/ 29 августа 2011

Matplotlib имеет метод imshow для построения массивов:

import matplotlib as mpl
from matplotlib import pyplot
import numpy as np

# make values from -5 to 5, for this example
zvals = np.random.rand(100,100)*10-5

# make a color map of fixed colors
cmap = mpl.colors.ListedColormap(['blue','black','red'])
bounds=[-6,-2,2,6]
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)

# tell imshow about color map so that only set colors are used
img = pyplot.imshow(zvals,interpolation='nearest',
                    cmap = cmap,norm=norm)

# make a color bar
pyplot.colorbar(img,cmap=cmap,
                norm=norm,boundaries=bounds,ticks=[-5,0,5])

pyplot.show()

Вот как это выглядит:

enter image description here

Подробности настройки цветовой шкалы были взяты из примера matplotlib: colorbar_only.py. Это объясняет, что число boundaries должно быть на единицу больше, чем количество цветов.

РЕДАКТИРОВАТЬ

Вы должны отметить , что imshow принимает ключевое слово origin, которое задает, где назначена первая точка. По умолчанию используется «верхний левый угол», поэтому на моем опубликованном графике ось y имеет 0 в левом верхнем углу и 99 (не показано) в левом нижнем углу. Альтернативой является установка origin="lower", чтобы первая точка отображалась в левом нижнем углу.

РЕДАКТИРОВАТЬ 2

Если вам нужен градиент, а не дискретная карта цветов, создайте карту цветов с помощью , линейно интерполируя через серию цветов:

fig = pyplot.figure(2)

cmap2 = mpl.colors.LinearSegmentedColormap.from_list('my_colormap',
                                           ['blue','black','red'],
                                           256)

img2 = pyplot.imshow(zvals,interpolation='nearest',
                    cmap = cmap2,
                    origin='lower')

pyplot.colorbar(img2,cmap=cmap2)

fig.savefig("image2.png")

Это производит: enter image description here

РЕДАКТИРОВАТЬ 3

Чтобы добавить сетку, как показано в этом примере , используйте метод grid. Установка цвета сетки на «белый» хорошо работает с цветами, используемыми цветовой картой (т. Е. Черный по умолчанию плохо отображается).

pyplot.grid(True,color='white')

Включая это до того, как вызов savefig создаст этот график (для ясности сделанный с использованием сетки 11x11): enter image description here Существует множество опций для grid, которые описаны в документации matplotlib . Возможно, вас заинтересует linewidth.

9 голосов
/ 29 августа 2011

Как насчет использования matplotlib?

from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FixedLocator, FormatStrFormatter
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = Axes3D(fig)

Z = np.array([[-1.045, 2.0, 3.5, -4.890],
              [-5.678, 3.2, 2.89, 5.78]])

X = np.zeros_like(Z)
X[1,:] = 1
Y = np.zeros_like(Z)
Y[:,1] = 1
Y[:,2] = 2
Y[:,3] = 3

surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet,
        linewidth=0, antialiased=False)
ax.set_zlim3d(-10.0, 10.0)

ax.w_zaxis.set_major_locator(LinearLocator(10))
ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f'))

m = cm.ScalarMappable(cmap=cm.jet)
m.set_array(Z)
fig.colorbar(m)

plt.show()

Это показывает:

enter image description here

...