2021-07-18

お手軽データ解析サンプル (2)

前回紹介したサンプル demo_01 [1] では GUI に PySide2 を使いました。これはプロットを描画する matplotlib が PySide6 にまだ対応していなかったのが理由です。しかし、考えてみると、サンプルで示したプロットはシンプルなトレンドチャートです。このぐらいのプロットなら PySide6 の QChart で作るという選択肢もあります。matplotlib 一辺倒で QChart を利用していませんでしたので、練習がてら PySide6 の QChart 版を作ってみました。

PySide6 を使ったデモプログラム

プロットに QChart を利用したプログラム demo_02 を下記 Github に公開しました。

demo_02 (Github)

以下の説明では、下記の OS 環境を使用しています。

Fedora 34 Workstation x86_64
- Python 3.9.6
- PySide6 6.1.2 (venv)
- IDE: PyCharm 2021.1.3 (Community Edition)

プログラムの構成

プログラムの構成は下記のように、demo_01 と変わっていません。

demo_02 の構成

プログラムの動作

起動後

demo.py を実行すると下記のようなウィンドウが表示されます。

起動後のウィンドウ

読み込むファイルの選択

ボタンをクリックして、読み込むファイルを選択します。このデモプログラムではプロジェクトフォルダ内にある sample.csv という CSV ファイルの読み込みを想定しています。

読み込むファイル sample.csv の選択

ファイル選択ダイアログ内の sample.csv を選択してダブルクリックするか、Open ボタンをクリックします。

なお、この sample.csv は、参考サイト [2] から「船舶の航行データ」の CSV ファイルを編集して利用させていただいています。

プログラムでは、下記のように、選択したファイルのパスを、変数 filename へ格納します。

        filename: str = dialog.selectedFiles()[0]

次に filename を引数にして FileParser クラスのインスタンス file_obj を生成し、filename の内容を読み込み、プログラムで使用できる形式に変換します。このデモプログラムでは、CSV ファイルを読み込んでいるだけです。

        file_obj = FileParser(filename)

さらに、データベース処理を扱う DBObj クラスのインスタンス self.db_obj を、データベース名 name_dbfile_obj を引数にして生成します。チャート作成などでは、この self.db_obj からデータを取得します。

        self.db_obj = DBObj(self.name_db, file_obj)

このデモプログラムでは、新しい CSV ファイルを読み込む度にデータベースを初期化してしまいます。実際のアプリケーションへ転用する際には、データベースの初期化プロセスを分離する必要があります。

トレンドチャートの表示

サンプルファイルを読み込んだ後、最初のパラメータ、Parameter A のトレンドチャートが表示されます。

Parameter A のトレンドチャート

上部のツールバーにあるコンボボックスから、表示したいパラメータを選択するとトレンドチャートが更新されます。

コンボボックスから表示したいパラメータを選択

トレンドチャートは、最低限の機能しか実装していません。

Parameter E のトレンドチャート

プログラムでは、コンボボックスの状態を監視し、選択が変更されると、新しく選択されたパラメータ名を、変数 param に格納します。

        param: str = combo.currentText()

param を引数にして、デー手ベース処理をする self.db_obj インスタンスメソッド get_trend_data で指定したパラメータの時系列データをデータフレームとして取得します。

        df: pd.DataFrame = self.db_obj.get_trend_data(param)

データフレーム df を引数にして TrendChart クラスのインスタンス trend を生成して。Demo(QMainWindow) の中心部に配置します。

        trend = TrendChart(df)
        self.setCentralWidget(trend)

Excel ファイルへの出力

ボタンをクリックすると、データベースに格納されたデータすべてを Excel 形式 (xlsx) にして、tmp などの一時格納領域へ保存して、Excel(Linux では LibreOffice Calc など)を起動して表示します。

データを Excel ファイル形式 (xlsx) に変換して表示 (LibreOffice Calc)

Excel ファイルの生成は、Pandas のデータフレームのメソッド to_excel を利用しています。

        df.to_excel(save_path, index=False)

PowerPoint ファイルへの出力

ボタンをクリックすると、すべてのパラメータのトレンドチャートを各スライドに貼り付けた PowerPoint 形式 (pptx) のファイルを作成、tmp などの一時格納領域へ保存して、PowerPoint(Linux では LibreOffice Impress など)を起動して表示します。

トレンドチャートを PowerPoint ファイル形式 (pptx) に変換して表示 (LibreOffice Impress)

PowerPoint ファイルの生成は、ベースとする PowerPoint ファイル self.template を引数にして、python-pptx の Presentation 関数を用いています。

        ppt = Presentation(self.template)

詳細は、参考サイト [3] を参照してください。

なお、QChartView で生成したチャートは、QPixmap に変換して [4]、画像として保存してから PowerPoint 形式のファイルのスライドに貼り付けています。

        trend = TrendChart(df)
        w: int = int(Inches(13.3) / 10000)
        h: int = int(Inches(3.5) / 10000)
        pixmap: QPixmap = trend.getChartPixmap(w, h)

        image_path: str = tempfile.NamedTemporaryFile(suffix='.png').name
        pixmap.save(image_path)

アプリのバージョンなどを表示するダイアログ

ボタンをクリックすると、このデモプログラム demo_02 のバージョン情報が表示されます。

About this ダイアログ

プログラムは、AboutDlg クラスのインスタンス about を生成して show() メソッドを呼び出しているだけです。

        about = AboutDlg(self)
        about.show()

他愛のない機能ですが、アプリがある程度動くようになったら、アプリのバージョンなどを確認するために必要になります。あらためて何も無い状態から作るのは面倒で、後回しにしてしまいがちですので、必要最小限と思われる機能を実装したクラスを用意しておきました。

まとめ

QChart/QChartView を使うメリットは、チャートを比較的簡単にインタラクティブに扱えることです。ただ、大量のデータを扱う場合は、実用的な動作速度と、そこそこのメモリ消費の両立を、使用している環境で実現できるかどうかを確認する必要があります。

(クリックして)ポイントの値をラベルで表示

参考サイト

  1. bitWalk's: お手軽データ解析サンプル [2021-07-10]
  2. www.mi.u-tokyo.ac.jp/consortium2/time_series_data.html(東京大学 数理・情報教育研究センター)
  3. python-pptx — python-pptx 0.6.19 documentation
  4. qt - QtChart - C++ - Saving a chart which wasn't displayed - Stack Overflow [2017-03-17]

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ Linuxへ
にほんブログ村

0 件のコメント: