問題
pythonのmatplotlibで、年ごとの値の変化を表す折れ線グラフを書こうとして以下のコードを書きました。
import numpy as np import matplotlib.pyplot as plt x = np.array([2006, 2007, 2008]) y = np.array([35.2, 27.4, 41.2]) plt.plot(x, y) plt.show()
すると、以下のような期待に反したグラフが表示されてしまいます。
期待に反しているのは以下の2点です。
- 横軸の値に小数が出現している
- 横軸の値からそれぞれオフセット分が引かれている
- +2.006e3, つまり2006がオフセットとなっています
これを期待通りにするには以下の2種類の方法があるようです。
解決法1 - set_useOffset()とMaxNLocator()を使う方法
Matlabスタイルで書いているとき
import numpy as np import matplotlib.pyplot as plt import matplotlib.ticker as ticker # X軸の数字をオフセットを使わずに表現する plt.gca().get_xaxis().get_major_formatter().set_useOffset(False) # X軸の数字が必ず整数になるようにする plt.gca().get_xaxis().set_major_locator(ticker.MaxNLocator(integer=True)) x = np.array([2006, 2007, 2008]) y = np.array([35.2, 27.4, 41.2]) plt.plot(x, y) plt.show()
オブジェクト指向で書いているとき
import numpy as np import matplotlib.pyplot as plt import matplotlib.ticker as ticker x = np.array([2006, 2007, 2008]) y = np.array([35.2, 27.4, 41.2]) fig, ax = plt.subplots() ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.get_xaxis().set_major_locator(ticker.MaxNLocator(integer=True)) ax.plot(x, y) plt.plot() plt.show()
結果
期待通りのグラフが描画できました。
解決法2 - xticks()を使う方法
コメント欄で id:kochory さんに教えていただいた方法です。データの量によってはこの方法で済むこともあります。
Matlabスタイルで書いているとき
plt.xticks()という関数を使うと、X軸のラベルに任意の文字列を表示させることができます。例えば
x = np.array([2006, 2007, 2008]) y = np.array([35.2, 27.4, 41.2]) plt.plot(x, y) plt.xticks(x, ["year1", "year2", "year3"]) plt.show()
とすると のようにX軸のラベルを変更できます。この関数を利用して
plt.plot(x, y) plt.xticks(x, x) plt.show()
と書くと と、意図通りの表示になりました。ここではxticks()の第二引数に数字のリストを与えていますが、このリストの各要素が文字列として評価されてラベルとなっているように見えます。
オブジェクト指向で書いているとき
set_xticks()とset_xticklabels()に分けて呼ぶ必要があるそうです。
import numpy as np import matplotlib.pyplot as plt import matplotlib.ticker as ticker x = np.array([2006, 2007, 2008]) y = np.array([35.2, 27.4, 41.2]) fig, ax = plt.subplots() ax.plot(x, y) ax.set_xticks(x) ax.set_xticklabels(x) plt.plot() plt.show()
結果は同じなので省略します。
解決法2の補足
解決法2の場合、以下のようにデータ数が多いと
import numpy as np import matplotlib.pyplot as plt import matplotlib.ticker as ticker x = np.arange(10000,10016,1) y = np.arange(0,16,1) plt.plot(x, y) plt.show()
下図のようにX軸のラベルが混雑して破綻します。
コメント欄での指摘通り、ラベルを手調整するのが一案です。
x = np.arange(10000,10016,1) y = np.arange(0,16,1) plt.plot(x, y) xlabels = [10000,10005,10010,10015] plt.xticks(xlabels, xlabels) plt.show()
とラベルの場所とその値を明示的に指定することで となります。
参考URLs
- ticker — Matplotlib 1.5.1 documentation
- python - Matplotlib yaxis range display using absolute values rather than offset values? - Stack Overflow
- python - matplotlib remove axis label offset by default - Stack Overflow
- Python matplotlib restrict to integer tick locations - Stack Overflow
- ticks_and_spines example code: ticklabels_demo_rotation.py — Matplotlib 1.5.1 documentation
- matplotlib - Python xticks in subplots - Stack Overflow