Тепловая карта оттенков серого 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 кажется, уже разобрались, так что можно использовать здесь.

Другие вопросы по тегам