はじめに
matplotlibでカラーバの表示される目盛を少し減らしたい場面があり、その際に色々と調べたので備忘録も兼ねて本記事を書きました。
本記事は、カラーバの目盛間隔を適当な数に指定したい、任意の等間隔にしたい、とにかくいじりたい方向けにまとめたつもりですので、もし参考になれば幸いです。
実装
Google Colabで作成した本記事のコードは、こちらにあります。
各種インポート
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np
実行時の各種バージョン
Name | Version |
---|---|
numpy | 1.22.4 |
matplotlib | 3.5.3 |
目盛数の指定
いい感じに目盛数を決めて表示するには、MaxNLocator()が便利です。とりあえず、目盛数の簡易的に調整したいだけの場合は、この関数を使えば事足りると思います。
実装例では、3個の目盛を表示をいい感じに表示するようにしています。この関数のnbins
に表示個数を指定します。
※この関数はnbins
よりも少なくor多く表示されるケースがあるので、詳しくは補足のMaxNLocator()の注意事項をご覧ください。
data = np.arange(100).reshape(10, 10)
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=mticker.MaxNLocator(nbins=3))
plt.show()
等間隔な目盛の指定
等間隔に目盛を表示するには、MultipleLocator()が便利です。
実装例では、22
置きに目盛を表示するようにしています。この関数のbase
に表示間隔を指定します。
data = np.arange(100).reshape(10, 10)
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=mticker.MultipleLocator(base=22))
plt.show()
基準値からの等間隔な目盛の指定
等間隔に目盛を表示するには、IndexLocator()が便利です。
実装例では、値5
を基準にして、25
置きに目盛を表示するようにしています。この関数のbase
, ofset
はそれぞれ、間隔と基準値を指定する引数です。
data = np.arange(100).reshape(10, 10)
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=mticker.IndexLocator(base=25, offset=5))
plt.show()
任意の目盛に指定
任意の目盛を表示するには、以下のように書きます。
data = np.arange(100).reshape(10, 10)
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=[33, 59, 72])
plt.show()
等分割な目盛に指定
LinearLocator()を使うと、カラーバの最小値と最大値の間を等分割に目盛を指定できます。引数のnumticks
は分割数を表し、実装例では5分割しています。
data = np.arange(100).reshape(10, 10)
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=mticker.LinearLocator(numticks=5))
plt.show()
※MaxNLocator()とLinearLocator()の棲み分け
対数スケールで目盛を指定
LogLocator()を使うと、カラーバの最小値と最大値の間を対数スケールで目盛を指定できます。引数のbase
は基底を表し、実装例では基底は2
にしているので、2の累乗が表示されています。
※この関数は全ての目盛が表示されない場合があるので、詳しくは補足のLogLocator()の注意事項をご覧ください。
data = np.arange(1, 101).reshape(10, 10)
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=mticker.LogLocator(base=2))
plt.show()
目盛の非表示
目盛を表示したくない場合は、NullLocator()を使います。
data = np.arange(100).reshape(10, 10)
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=mticker.NullLocator())
plt.show()
補足
MaxNLocator()の注意事項
ある特定の条件を満たす場合は目盛は0を基準として定義されます(区切りのいい数字が表示されるようにされるための仕様だと思います)。以下のような2つ例では、nbins=3
と指定しても2つしか目盛が表示されないので注意しましょう。また、0基準でないケースでは、nbins=3
と指定しても4つ表示されるといった場合もあるので、あくまで表示されるカラーバを確認しながら調整しましょう。
特定の条件とは
特定の条件とは、matplotlibのソースコードを追うと理解できます。matplotlib本家のMaxNLocator()
の中身を見ると、基準を決めている箇所があり、そこでは、ロカールで使われたscale_range()
と呼ばれる関数が呼び出されます。
この関数の中身では0を基準とする条件は以下のようにしています。カラーバの最大値(Max), 最小値(Min)が
\frac{abs(Max+Min)}{abs(Max-Min)} < 200
を満たす場合は、0を基準としています。この式の解釈は、カラーバの最大値と最小値が非常に大きくかつ近い値のときにこの条件を満たさない場合があり、その場合は基準が0ではない別で定義されたものが使われます。それ以外は基準は0となります。詳しくはmatplotlibのソースコードmatplotlib/lib/matplotlib/ticker.pyをご覧ください。
data = np.arange(-60, 40).reshape(10, 10)
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=mticker.MaxNLocator(nbins=3))
plt.show()
nbins=3
ですが、2個しか表示されていません。
data = np.arange(100, 110).reshape(5, 2)
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=mticker.MaxNLocator(nbins=3))
plt.show()
目盛が0基準であることがわかります。0から等間隔に引かれた目盛のため、スタートが102(3で割り切れる数)となっています。このケースを10倍にして同じように表示してみたのが次のカラーバです。
data = np.arange(1000, 1010).reshape(5, 2)
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=mticker.MaxNLocator(nbins=3))
plt.show()
nbins=3
ですが、4個も表示されています。上記で触れた特定の条件より、0基準でないです。0基準かどうかは、0から等間隔に計算された目盛を使っているといるかどうかで判断できます。以下のカラーバを見ると、3の倍数の等間隔な目盛ですが、1000は3の倍数ではないのでこの目盛は0基準では作られていないことが分かります。そして、このように0基準で作られないカラーバは、しばしばnbins
よりも大きくなることもあります。
LogLocator()の注意事項
この関数は負の値は使用できず、また0~1の値を含む場合は、全ての目盛を表示しない場合があります。以下では、例を2つ紹介し、その挙動を確認します。
data = np.arange(0, 100).reshape(10, 10) # 0~99の範囲のデータ
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=mticker.LogLocator(base=2))
plt.show()
data = np.arange(0, 100, dtype=np.float64).reshape(10, 10)
data += 0.2 # 0.2~99.2の範囲のデータ
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
cbar = plt.colorbar(heatmap, ticks=mticker.LogLocator(base=2))
plt.show()
まとめ
matplotlibでとにかく色々とカラーバをいじりたい方向けの記事を書いてみました。筆者は全てのカラーバで使えそうな関数を網羅できたていないので、詳しい情報はmatplotlibの本家のページをご覧ください。上記の関数を理解し使いこなしていきましょう。
参考資料