Как добавить крестик (X) в ячейки тепловой карты, как с языком R? - PullRequest
0 голосов
/ 03 января 2019

Я хотел бы добавить крестик (X) на ячейки карты тепла (в зависимости от уровня значимости, но вопрос заключается в добавлении X).

Как в языке R (sig.level = XXX).

См. Используемый код Python и R. и соответствующие выходные изображения.

Спасибо за вашу помощь.

# Draw the heatmap with the mask and correct aspect ratio
sns.heatmap(corr, mask=mask, cmap=cmap, center=0, vmin=-1, vmax=1, square=True, linewidths=0.5, fmt=".2f",
            cbar_kws={"shrink": .65, "orientation": "horizontal", "ticks":np.arange(-1, 1+1, 0.2)}, 
            annot = True, annot_kws={"weight": 'bold', "size":15})




corrplot(cor(subset (wqw, select = 
                       c(fixed.acidity:quality,ratio.sulfur.dioxide))),
         # compute the p matrix
         p.mat = cor.mtest(subset 
            (wqw, select = c(fixed.acidity:quality,ratio.sulfur.dioxide))), 
         # significance level 0.01
         sig.level = 0.01, 
         # Method to display : color (could be corcle, ...)
         method = "color",
         # color palette
         col = colorRampPalette(c("#BB4444", "#EE9988", 
                                  "#FFFFFF", "#77AADD", "#4477AA"))(200),


         )

```

python matrix R matrix

1 Ответ

0 голосов
/ 04 января 2019

Простое решение - добавить график рассеяния с X-образным маркером, чтобы вычеркнуть ненужные ячейки.

import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt

data = np.random.rand(10,10)
mask = np.zeros_like(data)
mask[np.triu_indices_from(mask)] = True

data_masked = np.ma.array(data, mask=mask)

fig, ax = plt.subplots()
im = ax.imshow(data_masked, cmap="YlGnBu", origin="upper")
fig.colorbar(im)

ax.scatter(*np.argwhere(data_masked.T < 0.4).T, marker="x", color="black", s=100)

plt.show()

enter image description here

Недостатком этого является то, что размер маркера (s) не зависит от количества ячеек и должен быть скорректирован для разных размеров фигуры.

Следовательно, альтернативой является рисование некоторых линий (X - две пересекающиеся линии) в соответствующих позициях. Здесь мы создаем функцию crossout(points, ax=None, scale=1, **kwargs), где scale - это процент, который должны брать строки из каждой ячейки.

import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

def crossout(points, ax=None, scale=1, **kwargs):
    ax = ax or plt.gca()
    l = np.array([[[1,1],[-1,-1]]])*scale/2.
    r = np.array([[[-1,1],[1,-1]]])*scale/2.
    p = np.atleast_3d(points).transpose(0,2,1)
    c = LineCollection(np.concatenate((l+p,r+p), axis=0), **kwargs)
    ax.add_collection(c)
    return c

data = np.random.rand(10,10)
mask = np.zeros_like(data)
mask[np.triu_indices_from(mask)] = True

data_masked = np.ma.array(data, mask=mask)

fig, ax = plt.subplots()
im = ax.imshow(data_masked, cmap="YlGnBu", origin="upper")
fig.colorbar(im)


crossout(np.argwhere(data_masked.T < 0.4), ax=ax, scale=0.8, color="black")


plt.show()

Для scale=0.8 это выглядит как

enter image description here

Обратите внимание , что для pcolormesh графика или тепловой карты морского дна (которая использует pcolormesh внутри), необходимо добавить 0.5 к данным, т.е.

np.argwhere(data_masked.T < 0.4)+0.5
...