はじめに
この実験では、Python の Matplotlib を使ってデータをダウンサンプリングする方法を学びます。ダウンサンプリングとは、信号のサンプリングレートまたはサンプルサイズを減らすプロセスです。データをダウンサンプリングし、ズーム操作時に再計算するクラスを使用します。
VM のヒント
VM の起動が完了したら、左上隅をクリックして ノートブック タブに切り替え、Jupyter Notebook を使って練習しましょう。
Jupyter Notebook の読み込みには数秒かかる場合があります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。
学習中に問題がある場合は、Labby にお問い合わせください。セッション終了後にフィードバックを提供してください。すぐに問題を解決いたします。
ライブラリのインポート
必要なライブラリをインポートして始めましょう。このタスクでは Matplotlib と NumPy のライブラリを使用します。
import matplotlib.pyplot as plt
import numpy as np
クラスの定義
データをダウンサンプリングし、ズーム操作時に再計算する DataDisplayDownsampler というクラスを定義します。このクラスのコンストラクタは、xdata と ydata を入力パラメータとして受け取ります。最大ポイント数を 50 に設定し、xdata の差分を計算します。
class DataDisplayDownsampler:
def __init__(self, xdata, ydata):
self.origYData = ydata
self.origXData = xdata
self.max_points = 50
self.delta = xdata[-1] - xdata[0]
データのダウンサンプリング
データをダウンサンプリングする downsample メソッドを定義します。このメソッドは、xstart と xend を入力パラメータとして受け取ります。表示範囲内のポイントを取得し、マスクを 1 つ拡大して表示範囲の外側のポイントをキャッチし、線を切り取らないようにします。削除するポイントの数を整理し、データをマスクします。最後に、データをダウンサンプリングして xdata と ydata を返します。
def downsample(self, xstart, xend):
## get the points in the view range
mask = (self.origXData > xstart) & (self.origXData < xend)
## dilate the mask by one to catch the points just outside
## of the view range to not truncate the line
mask = np.convolve([1, 1, 1], mask, mode='same').astype(bool)
## sort out how many points to drop
ratio = max(np.sum(mask) // self.max_points, 1)
## mask data
xdata = self.origXData[mask]
ydata = self.origYData[mask]
## downsample data
xdata = xdata[::ratio]
ydata = ydata[::ratio]
print(f"using {len(ydata)} of {np.sum(mask)} visible points")
return xdata, ydata
データの更新
データを更新する update メソッドを定義します。このメソッドは、ax(軸)を入力パラメータとして受け取ります。表示範囲の制限を取得し、表示範囲の幅が delta と異なるかどうかを確認することで線を更新します。表示範囲の幅が delta と異なる場合、delta を更新し、xstart と xend を取得します。その後、データをダウンサンプリングされたデータに設定し、アイドル状態を描画します。
def update(self, ax):
## Update the line
lims = ax.viewLim
if abs(lims.width - self.delta) > 1e-8:
self.delta = lims.width
xstart, xend = lims.intervalx
self.line.set_data(*self.downsample(xstart, xend))
ax.figure.canvas.draw_idle()
信号の作成
NumPy を使って信号を作成します。start=16、stop=365、num=(365-16)*4 として linspace 関数を使って配列 xdata を作成します。sin 関数と cos 関数を使って配列 ydata を作成します。
xdata = np.linspace(16, 365, (365-16)*4)
ydata = np.sin(2*np.pi*xdata/153) + np.cos(2*np.pi*xdata/127)
グラフの作成
Matplotlib を使ってグラフを作成します。xdata と ydata を使って DataDisplayDownsampler クラスのインスタンス d を作成します。subplots 関数を使って figure と axis を作成します。線を接続して autoscale を False に設定します。表示範囲を変更するために接続し、x 軸の範囲を設定してグラフを表示します。
d = DataDisplayDownsampler(xdata, ydata)
fig, ax = plt.subplots()
d.line, = ax.plot(xdata, ydata, 'o-')
ax.set_autoscale_on(False)
ax.callbacks.connect('xlim_changed', d.update)
ax.set_xlim(16, 365)
plt.show()
まとめ
この実験では、Python の Matplotlib を使ってデータをダウンサンプリングする方法を学びました。データをダウンサンプリングし、ズーム時に再計算するクラスを使用しました。NumPy を使って信号を作成し、Matplotlib を使ってグラフを作成しました。表示範囲を変更するために接続し、x 軸の範囲を設定しました。