はじめに
Matplotlib の 設定を直接書き散らすといたるところに分散して再利用することが難しくコードの管理が大変になります。
今回、私は Matplotlib の設定を オブジェクト指向でカプセル化し、再利用可能で、保守しやすい構成にまとめました。
本記事は第2断で、今回は特に軸の設定方法をまとめます。
なお、前回は、ベースの設定を行ったのでそちらも興味ある方はご覧ください
本記事のゴール
- Matplotlib の軸設定を 1ヶ所に集約して管理する
🎨 実装コード(完全版)
from dataclasses import dataclass
from datetime import timedelta
from matplotlib.axes import Axes
from src.domain.station_params import Period
@dataclass(frozen=True)
class AxisConfig:
y_label: str = "nT"
y_min: int = -100
y_max: int = 200
x_label: str = "UT"
xtick_divisions: int = 8 # x軸を何分割するか
class AxisConfigurator:
def __init__(self, ax: Axes, ut_period: Period, config: AxisConfig = AxisConfig()):
self.ax = ax
self.ut_period = ut_period
self.config = config
def apply(self) -> None:
"""外部から呼ぶメインメソッド。軸の設定をまとめて適用"""
self._set_y_axis()
self._set_x_axis_with_time_labels()
def _set_y_axis(self) -> None:
self.ax.set_ylabel(self.config.y_label, rotation=0)
self.ax.set_ylim(self.config.y_min, self.config.y_max)
def _set_x_axis_with_time_labels(self) -> None:
data_length = self.ut_period.total_minutes() + 1
self.ax.set_xlim(0, data_length)
self.ax.set_xlabel(self.config.x_label)
tick_interval = max(1, data_length // self.config.xtick_divisions)
ticks = range(0, data_length, tick_interval)
time_labels = []
prev_date = None
for i in ticks:
current_dt = self.ut_period.start + timedelta(minutes=i)
current_date = current_dt.date()
# 最初のラベル or 日付が変わった場合は「日付 + 時間」
if prev_date is None or current_date != prev_date:
label = current_dt.strftime("%m/%d %H:%M")
else:
# 同じ日なら時間だけ
label = current_dt.strftime("%H:%M")
prev_date = current_date
time_labels.append(label)
self.ax.set_xticks(ticks)
self.ax.set_xticklabels(time_labels)
なお、筆者は磁場データを描画するためにmatplotlibを使用しています。
縦軸の単位はnT(ナノテスラ)、横軸の単位はUT(時間)の大きさは-100~200で固定することがほとんどのため初期値を定義しています。
period等は自作クラスのためこのままだと動きません。x軸とy軸の設定をする方法を紹介しているため、雰囲気を掴んでもらえたらと思います。
呼び出し方法
プロット前に以下を 1 行書くだけで設定が適用されます。
self.fig, self.ax = plt.subplots()
#軸の設定
AxisConfigurator(self.ax, self.ut_period).apply()
これで、軸の設定を行う事ができます。
さいごに
本記事ではオブジェクト指向で軸の設定をする方法を紹介しました。
次回はホバー機能のカプセル化の方法を紹介したいと思います。
もし分からないことがあったら気軽に質問してください!