LoginSignup
5
2

More than 1 year has passed since last update.

Matplotlibでダークモード対応の図をいい感じに作る

Last updated at Posted at 2021-08-03

Matplotlibの表示要素に白色のボーダーを追加することで、同一の画像ファイルでライトモード(白背景)とダークモード(黒背景)の両方で見やすい表示となる作図方法をまとめました。以下の例のように、図の背景を透明にしても線やテキストが黒背景に埋もれず、そこそこ見やすい形で両立できるようになります。

darkmode-compatible-figure-light.png darkmode-compatible-figure-dark.png
ライトモード(白背景)での表示 ダークモード(黒背景)での表示

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

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2