はじめに
ヒートマップ上で特定の値を示す部分に斜線('/')を描きたかったので,メモ.
やりたいこと
以下のようなヒートマップで,特定の値の部分を斜線でいい感じにしたい.
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
Z =np.random.rand(10, 10)
Zm = Z * 0
Z[3:5, 5:8] = 1
fig, ax = plt.subplots(figsize=(9, 7))
ax1 = ax.pcolormesh(Z)
fig.colorbar(ax1)
上の図では,Z[3:5, 5:8] = 1
として図の一部の値を1に設定しています.
このZ[3:5, 5:8]
の部分に斜線を引きます.
解決方法
最終的なコードは以下.
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
Z =np.random.rand(10, 10)
Zm = Z * 0
Z[3:5, 5:8] = 1
fig, ax = plt.subplots(figsize=(9, 7))
ax1 = ax.pcolormesh(Z)
Zm = np.ma.masked_where(Z!=1, Z)
ax2 = ax.pcolor(Zm, hatch='/', edgecolor='grey',facecolor='none', linewidth=0.0)
fig.colorbar(ax1)
何をしているか
上記のコードで,最初と異なるのは以下の2行です.
Zm = np.ma.masked_where(Z!=1, Z)
ax2 = ax.pcolor(Zm, hatch='/', edgecolor='grey',facecolor='none', linewidth=0.0)
1行目:行列のマスク
一部のみ斜線で示すために,コードの1行目でその部分を表す行列(Zm
)を作成しています.
numpy.ma.masked_where
を用いることで,条件に該当する部分が無効にされた(マスクされた)行列を作成することができます.
参考:numpy.ma.masked_where 公式ドキュメント
もともとの行列(Z
)とマスクされた行列(Zm
)は以下のようになっています.

行列の中身を見ると,Zm
では,条件式(Z!=1
)に該当する要素以外は--
で表されています.
プロット時にこの行列Zm
を用いることで,条件式に該当する部分は無視してプロットを行うことができます.
2行目:hatchで斜線を描画
参考:python – matplotlib 2.0で領域をハッチのみ(背景色なし)で埋めるにはどうすればいいですか?
コードの2行目では,行列Zm
を用いて斜線を描画しています.
matplotlib.pyplot.pcolor
では,以下のパターンのhatchを用いることができます.
/ - diagonal hatching
\ - back diagonal
| - vertical
-
- horizontal
-
- crossed
x - crossed diagonal
o - small circle
O - large circle
. - dots
- crossed
-
- stars
参考:matplotlib.collections.Collection.set_hatch
ここで使用したオプションは以下の通りです.
-
edgecolor
:hatch の色 -
facecolor
:hatchの背景色.'none'に設定することでヒートマップの色を残してhatchのみを表示させることができる. -
linewidth
:グリッドの太さ.0より大きい値を指定するとグリッドが表示される.
オプションを変更したときの図の外観は以下のようになります.
(ax.pcolor
の行以外は最終的なコードと同じです)
ax2 = ax.pcolor(Zm, hatch='/', edgecolor='grey',facecolor='none', linewidth=1.0)
ax2 = ax.pcolor(Zm, hatch='/', edgecolor='grey',linewidth=0.0)
ax2 = ax.pcolor(Zm, hatch='/', edgecolor='red',facecolor='none', linewidth=0.0)