Matplotlibの表示要素に白色のボーダーを追加することで、同一の画像ファイルでライトモード(白背景)とダークモード(黒背景)の両方で見やすい表示となる作図方法をまとめました。以下の例のように、図の背景を透明にしても線やテキストが黒背景に埋もれず、そこそこ見やすい形で両立できるようになります。
ライトモード(白背景)での表示 | ダークモード(黒背景)での表示 |
Qiitaの制限によりHTMLを使って背景色を変えられないため、上の例は画像自体に黒背景を描画しています。実際に背景色に応じて表示が変わる様子はこちらをご覧ください。
Path effects
表示要素(artists)にボーダーを追加するにはpath effects(matplotlib.patheffects
)を使用します。名前から分かるように、ボーダーを追加できるのはテキストやラインプロットなど線(パス)を持つ要素のみとなります。今回の場合、withStroke()
でボーダーの線の色と線幅を設定したpath effectオブジェクトを作成します。
import matplotlib as plt
from matplotlib.patheffects import withStroke
border = withStroke(linewidth=3, foreground="white")
Examples
ボーダーを追加するには、作成したpath effectオブジェクトを(1)rcParamsでグローバルに設定するか、(2)プロット関連の関数やメソッドが持つpath_effects
オプションで個別に設定するか、(3)表示要素が持つset_path_effects()
メソッドで個別に設定します。以下では(1)の例を紹介します。
with plt.rc_context({"path.effects": [border]}):
plt.plot([1, 2, 1, 3], label="A")
plt.plot([2, 1, 3, 2], label="B")
plt.title("Darkmode-compatible figure")
plt.legend()
plt.savefig("figure.png", transparent=True)
rcParamsの"path.effects"は複数の設定を受け取るため、[border]のように配列で渡します
rc_context()を使うと、withブロックに書かれた要素のみにボーダーを適用することができます
上の例では図(画像)の外周にもボーダーが追加されてしまうため若干見づらいかもしれません。少し複雑になりますが、以下のように書くことで外周のボーダーを消すことができます。
fig = plt.figure()
with plt.rc_context({"path.effects": [border]}):
ax = fig.add_subplot()
ax.plot([1, 2, 1, 3], label="A")
ax.plot([2, 1, 3, 2], label="B")
ax.set_title("Darkmode-compatible figure")
ax.legend()
fig.savefig("figure.png", transparent=True)
References