はじめに
Matplotlib では複数系列を描画するとき、色は通常「カラサイクル」に従って自動的に切り替わります。ところが、特定の条件下ではカラサイクルが進まず、すべて同じ色で描画されてしまうことがあります。
ここでは、その典型例と簡単に使える回避策を紹介します。
(動作確認環境: matplotlib v3.10.0)
なお、確認用コードは Google Colab でも公開しています → こちら
問題の再現
以下の例のように、errorbar
に fmt='none'
を指定するとマーカーも線も描かれないため、カラーサイクルが進みません。その結果、全て同じ色(デフォルトではC0
、通常は青系)で描画されます。
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(5)
y = np.arange(5)
fig, axes = plt.subplots(2, 1, figsize=(6, 6))
# 1. fmt='o' → サイクルが回る
for i in range(3):
axes[0].errorbar(x, y + i, yerr=0.2, fmt='o', label=f'errorbar {i}')
axes[0].set_title("errorbar 'o' → cycle ok")
axes[0].legend(loc='upper left')
# 2. fmt='none' → サイクルが回らない
for i in range(3):
axes[1].errorbar(x, y + i, yerr=0.2, fmt='none', label=f'errorbar {i}')
axes[1].set_title("errorbar none → no cycle")
axes[1].legend(loc='upper left')
plt.tight_layout()
plt.show()
実行結果(下段)では、fmt='none'
の場合に全て同じ色で描かれてしまっています。
対処法
カラーサイクルを回す解決策としては、「マーカーを指定した上でサイズをゼロにして見えなくする」 方法が最も簡単だと思います。
例えば fmt='o', markersize=0
のように指定すれば、見た目にはマーカーが表示されない一方でカラーサイクルは進みます。
(なお、マーカーは 'o'
に限らず '.'
や 'x'
など任意のものを指定可能です。)
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(5)
y = np.arange(5)
fig, ax = plt.subplots(figsize=(6, 3))
# マーカーを指定 (ここでは 'o') + markersize=0 → サイクルが回る
for i in range(3):
ax.errorbar(x, y + i, yerr=0.2, fmt='o', markersize=0, label=f'errorbar {i}')
ax.set_title("errorbar with invisible marker → cycle ok")
ax.legend()
plt.tight_layout()
plt.show()
カラーサイクルが機能していますね!
おわりに
errorbar
に fmt='none'
を指定すると、カラーサイクルが進まず全て同じ色になってしまうことがあります。
今回はその簡単な回避方法のひとつとして、任意のマーカーを指定して markersize=0
に設定してみました。
個人的には、このカラーがサイクル しているところが好きなのですが、やはり Matplotlib は多機能な分、思った通りに動かないこともありますね。
ときに挙動や実装が カラーブルー(空振る)こともありますが、気楽に乗り越えていきましょう。