Тепловая карта оттенков серого Matplotlib с визуально различимыми полями квадратов "NA"
Я создаю тепловую карту для использования в публикации. Публикация ограничена черно-белой печатью, поэтому я создаю тепловую карту в оттенках серого. У меня проблема в том, что на тепловой карте есть несколько квадратов, которые "не применимы", которые я хочу визуально отличить от других ячеек. Насколько я понимаю, это может (?) Быть возможно при использовании маскированных массивов numpy, если тепловая карта окрашена на обоих концах шкалы, а маскированные поля могут просто отображаться белым цветом. Проблема в том, что я хотел бы использовать полный спектр от белого до черного, чтобы проиллюстрировать диапазон данных, не относящихся к NA. Есть ли способ отличить клетки NA с помощью какого-либо другого визуального механизма, например, зачеркивания?
Ниже приведен минимальный пример градаций серого с замаскированным массивом (адаптировано здесь). Значения NA здесь, вероятно, замаскированы, вы просто не можете сказать, потому что он использует белый, который уже используется в качестве цвета на верхнем краю допустимого спектра.
import numpy as np
from pylab import *
z = rand(10, 25)
z = np.ma.masked_array(z,mask=z>0.8)
c = pcolor(z)
set_cmap('gray')
colorbar()
c = pcolor(z, edgecolors='w', linewidths=1)
axis([0,25,0,10])
savefig('plt.png')
show()
2 ответа
Простое решение - просто залатать патч фоновых осей. Например:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
np.random.seed(1977)
data = np.random.random((10,25))
data = np.ma.masked_greater(data, 0.8)
fig, ax = plt.subplots()
im = ax.pcolormesh(data, cmap=cm.gray, edgecolors='white', linewidths=1,
antialiased=True)
fig.colorbar(im)
ax.patch.set(hatch='xx', edgecolor='black')
plt.show()
Обратите внимание, что если вы предпочитаете, чтобы границы между пустыми ячейками не отображались, вы можете использовать pcolor
вместо pcolormesh
, Например, если мы изменим строку:
im = ax.pcolormesh(data, cmap=cm.gray, edgecolors='white', linewidths=1,
antialiased=True)
чтобы:
im = ax.pcolor(data, cmap=cm.gray, edgecolors='white', linewidths=1)
Мы получим:
Разница невелика - линии не рисуются между соседними пустыми ячейками с pcolor
, Какая эстетика вы предпочитаете, сугубо личная, но она подчеркивает ключевое различие между pcolor
а также pcolormesh
,
Я не смог воспроизвести ответ Джо, добавив патч ax.patch.set_hatch('x')
, Вместо этого я должен был создать патч в виде прямоугольника в соответствии с этим вопросом как
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib.patches as patches
data = np.random.random((10,25))
data = np.ma.masked_greater(data, 0.8)
fig, ax = plt.subplots()
im = ax.pcolormesh(data, cmap=cm.gray, edgecolors='white', linewidths=0)
fig.colorbar(im)
# ax.patch.set_hatch('x') replaced by:
p = patches.Rectangle((0,0), 25, 10, hatch='xx', fill=None,zorder=-10)
ax.add_patch(p)
plt.show()
Более того, pcolormesh
кажется, уже разобрались, так что можно использовать здесь.