df.plot()後にset_major_formatter()すると、xtickの年や月の表記が壊れる問題に悩まされていたが、解決したのでメモ。
前提
pandas:0.24.2
matplotlib:3.1.0
データの準備
import pandas as pd
import numpy as np
N = 100
x = np.random.rand(N)
y = x**2
df = pd.DataFrame(
index=pd.date_range('2020-01-01', periods=N, freq='D'),
data=dict(x=x, y=y)
)
df.head()
問題ないケース
# pandasのプロット機能を使用
df.plot()
DataFrameのindexがDatetimeIndexの場合、自動的にtickをフォーマットしてくれる。
このフォーマットでOKなら、それでよし。
問題になるケース
import matplotlib.dates as mdates
# pandasのプロット機能を使用
ax = df.plot()
# フォーマットし直す
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y/%m/%d'))
%Yに対する表示がおかしい。0051年て何・・・。
下記サイトによれば、pandasとmatplotlibのdatetimeユーティリティは互換性がないことが原因らしい。
https://code-examples.net/ja/q/2a2a615
解決策
import matplotlib.dates as mdates
# x_compatオプションを渡す。これでtickの自動調整が抑制される。
ax = df.plot(x_compat=True)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y/%m/%d'))
%Yが正しく2020年になった!
※この例だと「pandasのフォーマットのほうがよくない?」となってしまいますが、そこはご容赦を・・
x_compatはx_compatibilityの略?
公式ドキュメントによれば、x_compatはtickの自動調整を抑制するパラメータとのこと。
https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html#suppressing-tick-resolution-adjustment
もっとスマートなやり方がありましたら、ご教授いただければ幸いです。