[matplotlib] 125. マスク値とNaN値を含むデータのプロット

matplotlib

はじめに

データ可視化の際、欠損値を含むデータをプロットする必要がある場合があります。

欠損データを処理する一つの方法は、単にそのデータ点を削除することです。この方法では、残りのデータを通る線は連続的になりますが、どこにデータが欠損しているかは表示されません。

欠損データがある位置で線を途切れさせたい場合は、配列をマスク処理するか、値をNaNに設定します。xまたはy座標のいずれかがマスクされている位置ではマーカーは表示されず、線プロットではその位置で線が途切れます。

ここでは、これらの手法を使った実際のプロット例を見て、その挙動を確認します。

コード&解説

モジュールのインポートなど

バージョン

データの生成

  • x = np.linspace(-np.pi,np.pi, 51): -π から π までの範囲で51個の等間隔の点を生成しています。これはx軸の値となります。
  • y = np.sin(x): 生成したx値に対して、sin関数を適用してy値を計算しています。これによって正弦波のデータが作られます。

欠損データの作成

ここでは、y値が0.6以下のデータポイントだけを抽出しています:

  • y <= 0.6はブール配列を生成し、y値が0.6以下の位置にはTrue、それ以外にはFalseを設定します。
  • そのブール配列を使って、条件を満たす要素だけをxyから取り出し、それぞれx2y2に格納しています。

y2.shapeは、フィルタリング後の配列y2のサイズを確認しています。結果が(37,)であることから、元の51個のデータポイントから14個が除外され、37個のデータポイントが残った欠損データであることがわかります。

マスクデータの作成

NumPyのマスク配列機能を使って、特定の条件を満たすデータポイントをマスク(非表示)しています:

  • np.ma.masked_where(condition, array): 指定した条件が真(True)となる位置の値をマスクした配列を返す関数です。
  • y > 0.6: これは条件部分で、y値が0.6より大きい位置では True、それ以外では False となるブール配列を生成します。
  • y3 = np.ma.masked_where(y > 0.6, y): 元の配列 y から、y > 0.6 の条件を満たす(つまりy値が0.6より大きい)位置の値をマスクした新しい配列 y3 を作成しています。

Nanを含むデータの作成

  • y4 = y.copy(): まず元の配列 y のコピーを作成して y4 に格納します。これにより元のデータを変更せずに済みます。
  • y4[y3 > 0.6] = np.nan: y3 > 0.6 の条件に一致する位置(つまり y 値が 0.6 より大きい場所)に、NumPy の NaN (Not a Number) を代入しています。

プロット

  • fig, ax = plt.subplots(): 新しい図(Figure)とその中に描画エリア(Axes)を作成します。
  • ax.plot(x, y, 'o-', color='grey', label='No mask'): 元のデータをプロット。’o-‘は丸いマーカーと線を意味し、灰色で「No mask」というラベルを付けています。
  • ax.plot(x2+0.5, y2, 'o-', label='Points removed'): y>0.6のデータを削除したデータセットをプロット。視覚的に区別するためにx座標を0.5ずらしています。
  • ax.plot(x+1, y3, 'o-', label='Masked values'): マスク処理を施したデータをプロット。x座標を1.0ずらして表示しています。
  • ax.plot(x+1.5, y4, 'o-', label='NaN values'): NaN値を含むデータをプロット。x座標を1.5ずらして表示しています。
  • ax.legend(): 凡例を表示して、各線が何を表しているかを示します。
  • ax.set_title('Masked and NaN data'): グラフのタイトルを「Masked and NaN data」に設定します。
  • plt.savefig("masked_and_nan_plot.png",dpi=100): 作成したグラフを「masked_and_nan_plot.png」という名前で保存します。dpi=100は解像度の設定です。
  • plt.show(): プロットを表示します。

このコードは、欠損データの処理方法による違いを視覚的に比較するために、同じデータの4つの異なる表現方法を一つのグラフ上に表示しています。各プロットはx軸方向にずらして配置されているため、それぞれの処理方法による違いが明確に確認できます。

コードをダウンロード(.pyファイル)

コードをダウンロード(.ipynbファイル)

参考

NumPy で欠損値等を除く時は np.ma.masked_where が便利 - Qiita
要素削除の問題点 NumPyで欠損値や外れ値を除く時どうしてますか?多くの人が単純にその要素を配列から削除していると思います。例えばnanを除くなら以下のような感じ。 これでもいいが... a = np.array() ...
numpy.ma.masked_where — NumPy v2.3 Manual
Plotting masked and NaN values — Matplotlib 3.10.5 documentation

コメント