Я думаю, что в этом типе приложений абсолютно необходима хорошая информативная палитра, даже если ОП не упоминает палитру в своем Q…
Приведенный ниже код основан на предположении, что целые числа, используемые в массиве, представляют собой только нули и единицы
import numpy as np
import matplotlib.pyplot as plt
from itertools import count
a = np.array([[ 0 , 0 , 'g', 'g', 'g'],
[ 0 , 0 , 0 , 'g', 'g'],
['d', 0 , 1 , 1 , 'g'],
['d', 'd', 1 , 1 , 'g'],
['d', 'd', 'd', 'd', 'g']], dtype=object)
# we want to build a dictionary mapping objects to integers
seq2 = count(2) # we don't know in advance how many different objects we'll see
d = {0:0, 1:1} # but we know that the integers are either 0 or 1
for o in a.flatten():
if o not in d: d[o] = next(seq2)
# with the help of the dictionary, here it is a plottable matrix
b = np.array([d[x] for x in a.flatten()]).reshape(a.shape)
N = len(d)
# to avoid a continuous colorbar, we sample the needed colors
cmap = plt.cm.get_cmap('viridis', N)
# eventually,
# we can plot the matrix, the colorbar and fix the colorbar labelling
plt.imshow(b, cmap=cmap)
cb = plt.colorbar(drawedges=True)
dc = (N-1)/N
cb.set_ticks([dc*(n+1/2) for n in range(N)])
cb.set_ticklabels([v for k, v in sorted((v,k) for k,v in d.items())])
plt.show()
Post Scriptum
В другом ответе упоминается, что (курсив мой)
Из документов imshow
соответствует исключительно массивы с типом float
, но ① единственные требования касаются скалярных данных, потому что «непрерывное» отображение на цветовую карту делегировано классу matplotlib.colors.Normalize
и ② с использованием специализированного подкласса matplotlib.colors.Normalize
можно напрямую используйте отдельные целые числа в матрице для индексации списка цветов, связанных с каждой цветовой картой, например,
In [34]: import matplotlib.pyplot as plt
...: import numpy as np
...: from matplotlib.colors import NoNorm
...: %matplotlib
...:
...: mat_r, mat_i = (np.array(np.arange(6), dtype=float)[None,:],
...: np.array(np.arange(6), dtype=int)[None,:])
...:
...: def show(ax, mat, title, norm=None):
...: ax.imshow(mat, norm=norm)
...: ax.set_title(title)
...: ax.set_yticks([])
...:
...: fig, axes = plt.subplots(6,1, figsize=(3, 6))
...:
...: for ax, mat, norm, title in zip(
...: axes,
...: (mat_r, mat_i, mat_i, 30*mat_r, 30*mat_i, 30*mat_i),
...: (None, None, NoNorm(), None, None, NoNorm()),
...: ('mat_r','mat_i','mat_i NoNorm','30×mat_r','30×mat_i','30×mat_i NoNorm')):
...: show(ax, mat, title, norm)
...: fig.tight_layout()
In [35]: plt.cm.viridis.colors[:151:30]
Out[35]:
[[0.267004, 0.004874, 0.329415],
[0.280255, 0.165693, 0.476498],
[0.237441, 0.305202, 0.541921],
[0.182256, 0.426184, 0.55712],
[0.13777, 0.537492, 0.554906],
[0.128087, 0.647749, 0.523491]]
In [36]: