キー列ごとにグラフを描画したい

時系列の波形データを例に、キー列ごとに別々にグラフを作成する方法を解説します。MSIP既存の可視化機能では物足りない時にグラフを作成する際に参考になる情報を記載しています。

説明

テーブルに複数種類のデータが格納されているとき、キー列の値に応じてそれぞれ種類ごとにデータをプロットする Python Script を作成します。

例えば、サンプルデータである「時系列波形データ.dft」を用いて、複数の波形をそれぞれプロットすることを考えます。「時系列波形データ.dft」は複数の時系列波形を格納したデータであり、各々の波形を識別するための「番号」列や、波形の値を表す「値」列を持ちます。 ここではこの「番号」列をキー列とみなして、それぞれの番号ごとに波形データをプロットしてみましょう。

Alt text

時系列波形データ.dft は ワークスペースブラウザの

共有ワークスペース > サンプル > Alkano > データ > 時系列波形データ.dft

にあります。

使い方

  1. 時系列波形データ.dft をシナリオ上に配置し、ノードを追加から Python script ノードを追加します。

Python script 配置

  1. Python script ノードのパラメータ設定画面の出力設定を開き、result の型をpng[]とします。入力データは変数名 table、型 table の状態のままにします。

入出力設定

  1. Python script の設定画面のスクリプト記述部分に次のコードをコピー&ペーストしてください。このコードは、キーとなる番号ごとに波形を描画するスクリプトです。キー列の始端key_startとキー列の末端key_endの間の番号の波形を描画します。
from msi.common.visualization import PNGObject
import pandas as pd
import matplotlib.pyplot as plt
import os

# MSIP_GUI_Definition_v1.0.0

# MSIP_Group 数値列の設定
value = {"name":"値","type":"float"} # { "type": "inputcolumn", "title": "描画する数値列(y軸の値)", "table": "table","comment":"y軸の値として描画する数値列(integer, float)を選択してください。" }

# MSIP_Group キー列、ラベル列の設定
key = {"name":"番号","type":"integer"} # { "type": "inputcolumn", "title": "キー列", "table": "table","comment":"キーごとに別ファイルで出力します。キー列(整数値)を選択してください。" }

label = {"name":"ラベル","type":"category"} # { "type": "inputcolumn", "title": "ラベル列", "table": "table","comment":"タイトルにラベルを付与します。ラベル列(カテゴリ値)を選択してください。" }

# MSIP_Group キー列の範囲

key_start = 0 # { "type":"integer", "title":"キー列の値の始端","comment":"始端から終端までの範囲の時系列をプロットします。キー列の値の終端以下の値を入力してください。" }

key_end = 20 # { "type":"integer", "title":"キー列の値の終端","comment":"始端から終端までの範囲の時系列をプロットします。キー列の値の始端以上の値を入力してください。" }


# MSIP_GUI_Definition_v1.0.0


value = value["name"]
key = key["name"]
label = label["name"]



# 入力 DataFrame に対してプロットを行う関数 
def plt_ts(df):

    # 描画するデータ
    y = df[value]

    # 該当の列の値とラベルを取り出す
    key_val = df.reset_index()[key][0]
    label_val = df.reset_index()[label][0]

    # データを描画
    fig, ax = plt.subplots()
    ax.plot(y)

    # 軸とタイトルを追加
    ax.set_ylabel(value)
    ax.set_title(f"{key}={key_val}, {label}={label_val}")

    # png を保存
    png_file_path = os.path.abspath(f'./figure_{key_val}.png')
    plt.savefig(png_file_path)
    plt.cla()

    # PNGObject を生成します
    png_obj = PNGObject(png_file_path)

    # PNGObject を 出力に追加
    result.append(png_obj)


# matplotlibのフォントをMS Gothicとして日本語に対応
plt.rcParams['font.family'] = 'MS Gothic'

# 入力テーブルを pandas へ変換
df = table.to_pandas()

# png オブジェクトを返すリストを作成
result = []

# key の対象範囲を絞る
df = df[(df[key]>= key_start)&(df[key]<= key_end)]

# key 列ごとに時系列プロット
df.groupby(key).apply(plt_ts)

  1. Python script のパラメータ設定画面の右下の実行ボタンを押し、可視化画面から結果を確認します。可視化画面のノード結果一覧内にキー列ごとの波形が描画されています。

result

分析への応用

Python scriptを記述した後に保存もしくは実行をすると、次のようなGUI画面が作成されます。

Alt text

GUI画面の「キー列の範囲」を変更することで、別の番号の波形データを描画することができます。

また、別の入力データに対しても、「数値列の設定」や「キー列、ラベル列の設定」を適切に設定することで、グラフを描画することができます。

OnePoint

利用しているパッケージ

pandas と matplotlib を利用し、データ加工やグラフ作成を行っています。具体的には、

  • スクリプト内の df = table.to_pandas() で、pandas のデータフレーム型に変換し、pandas のデータフレームでデータ加工を行っています。
  • plt_ts 関数内の時系列プロットは、matplotlib を利用しています。

本記事作成時に利用した pandas と matplotlib のバージョンは下記です。

pandas 1.3.4
matplotlib 3.7.1

Python script アイコンでのグラフの出力

スクリプト内では、次の手順で可視化画面にグラフ出力を行っています。

  1. 出力設定で、png 型 もしくは png[] 型を出力とする。 png を設定した場合は、1つのグラフを出力します。png[]を設定した場合は、複数のグラフを出力します。本記事では、キー列ごとの複数のグラフを出力させるために、出力をpng[]としています。

  2. matplotlib.pyplot.savefig を利用して、グラフを描画した png ファイルをストレージに出力します。

import matplotlib.pyplot as plt
# png を保存
png_file_path = os.path.abspath(f'./figure_{key_val}.png')
plt.savefig(png_file_path)
  1. msi.common.visualization.PNGObject を利用し、出力した pngファイルから、PNGObjectを生成します。
from msi.common.visualization import PNGObject
# PNGObject を生成します
png_obj = PNGObject(png_file_path)
  1. 出力設定がpng[](複数のグラフの出力)の場合は、生成したPNGObjectをリストに追加します。
# 描画結果を result に追加
result.append(png_obj)

関連項目