はじめに
matplotlib.datesのConciseDateFormatterで時系列グラフの目盛りラベルを簡潔に表示する方法について説明する。
コード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ConciseDateFormatterを使用した日付フォーマット変更
%matplotlib inline
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
#the default formatter
base = datetime.datetime(2019, 10, 1)
dates = np.array([base + datetime.timedelta(hours=(0.5*i))
for i in range(24*256)])
N = len(dates)
np.random.seed(19423521)
y = np.cumsum(np.random.randn(N))
lims = [(np.datetime64('2019-10'), np.datetime64('2020-02')),
(np.datetime64('2019-12-03'), np.datetime64('2019-12-15')),
(np.datetime64('2019-12-03 13:00'), np.datetime64('2019-12-04 13:00')),
(np.datetime64('2019-12-03 11:00'), np.datetime64('2019-12-03 11:01'))]
fig, axs = plt.subplots(4, 1, constrained_layout=True, figsize=(6, 8))
for nn, ax in enumerate(axs):
locator = mdates.AutoDateLocator(minticks=4, maxticks=9)
formatter = mdates.ConciseDateFormatter(locator)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
ax.plot(dates, y,'g-')
ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter')
plt.savefig("Concisedateformatter.png", dpi=100,transparent = False, bbox_inches = 'tight')
plt.show()

解説
モジュールのインポート
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%matplotlib inline
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
バージョン
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version
import matplotlib
print(matplotlib.__version__)
3.3.4
print(np.__version__)
1.20.1
print(pd.__version__)
1.2.3
データの生成
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
base = datetime.datetime(2019, 10, 1)
dates = np.array([base + datetime.timedelta(hours=(0.5*i))
for i in range(24*256)])
N = len(dates)
np.random.seed(19423521)
y = np.cumsum(np.random.randn(N))
dates = np.array([base + datetime.timedelta(hours=(0.5*i)) for i in range(24*256)])で baseの日付から、0.5h刻みで24 ✕256 = 6144回時間を増加させた配列が得られる。
表示範囲の設定
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
lims = [(np.datetime64('2019-10'), np.datetime64('2020-02')),
(np.datetime64('2019-12-03'), np.datetime64('2019-12-15')),
(np.datetime64('2019-12-03 13:00'), np.datetime64('2019-12-04 13:00')),
(np.datetime64('2019-12-03 11:00'), np.datetime64('2019-12-03 11:01'))]
デフォルト設定の時系列グラフ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fig, axs = plt.subplots(4, 1, constrained_layout=True, figsize=(6, 8))
lims = [(np.datetime64('2019-10'), np.datetime64('2020-02')),
(np.datetime64('2019-12-03'), np.datetime64('2019-12-15')),
(np.datetime64('2019-12-03 13:00'), np.datetime64('2019-12-04 13:00')),
(np.datetime64('2019-12-03 11:00'), np.datetime64('2019-12-03 11:01'))]
for nn, ax in enumerate(axs):
ax.plot(dates, y,'g-')
ax.set_xlim(lims[nn])
# rotate_labels...
for label in ax.get_xticklabels():
label.set_rotation(30)
label.set_horizontalalignment('right')
axs[0].set_title('Default Date Formatter')
plt.savefig("defaultdateformatter.png", dpi=100,transparent = False, bbox_inches = 'tight')
plt.show()

時間の表示範囲によって目盛りラベルが変化するが基本的にどれも長いので、重なりを防ぐ必要がある。ここでは、label.set_rotation(30)で30°回転している。
ConciseDateFormatterを使った時系列グラフ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fig, axs = plt.subplots(4, 1, constrained_layout=True, figsize=(6, 8))
for nn, ax in enumerate(axs):
locator = mdates.AutoDateLocator(minticks=4, maxticks=9)
formatter = mdates.ConciseDateFormatter(locator)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
ax.plot(dates, y,'g-')
ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter')
plt.savefig("Concisedateformatter.png", dpi=100,transparent = False, bbox_inches = 'tight')
plt.show()
最初に、locator = mdates.AutoDateLocator(minticks=4, maxticks=9)
で目盛りの数などを決め、formatter = mdates.ConciseDateFormatter(locator)
により、ConciseDateFormatter
をlocato
rに適用する。
グラフに設定を反映させるには、ax.xaxis.set_major_locator(locator)
とax.xaxis.set_major_formatter(formatter)
とする必要がある。

units registryを使ってConciseDateFormatterを適用させる方法
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import matplotlib.units as munits
converter = mdates.ConciseDateConverter()
munits.registry[np.datetime64] = converter
munits.registry[datetime.date] = converter
munits.registry[datetime.datetime] = converter
fig, axs = plt.subplots(4, 1, figsize=(6, 8), constrained_layout=True)
for nn, ax in enumerate(axs):
ax.plot(dates, y,'g-')
ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter')
plt.savefig("Concisedateformatter_regist.png", dpi=100,transparent = False, bbox_inches = 'tight')
plt.show()

converter = mdates.ConciseDateConverter()
とし、munits.registry[np.datetime64] = converter
としておけば、set_major_formatter
などをする必要がないので、より簡単に軸ラベルを簡素化できる。
参考
Formatting date ticks using ConciseDateFormatter — Matplotlib 3.4.3 documentation
コメント