GUIで時系列データのグラフを作成してみた。


環境

Python version:3.9.7
OS: windows 10.0
Anaconda:conda 4.11.0
※PySimpleGUI、dataframe_image は、condaのライブラリに標準で入っていなかったので、追加した。

実装したかった、やりたかったこと

・集計したいcsvファイルをGUIで選択する。
・logをまとめるフォルダを作成し、新規で作成したデータを保存する。保存したフォルダを開く。
・3つのグラフを同じ時系列でまとめる。
・describe(count,mean,std,min,25%,50%,75%,max)データの表をつくること。
・defを使ってみる。
・GUIに作成したファイルを出力する。

課題

・matplotlibを使用して表を作成する。dataframe から簡単に作成できると思ったが、よくわからなかった。
 dataframeを作成し、csvファイルを作ることにした。
 追記、dataframe_imageを使用し、作成した。

code

type_1.1.py
import PySimpleGUI as sg
import pandas as pd
import matplotlib.pyplot as plt
import ntpath
import os
import subprocess
import dataframe_image as dfi
# User Function
import gui_operation

# Get csv data from GUI
file_path = gui_operation.read_csv_file()

if file_path != "NULL": # run only selecting csv file,

    # Variable setting 
    file_name = ntpath.basename(file_path)
    axis_name = ['pressure','temperature','humidity']
    axis_len = len(axis_name) # axis_name couont.

    #絶対ディレクトリでファイル指定する。
    df = pd.read_csv(file_path)

    #保存先のディレクトリ作成
    os.makedirs('log', exist_ok=True)

    #group化し、describeの取得。
    grouped = df.groupby('date')

    for i in range (axis_len):
        df_sescribe = grouped.describe()[axis_name[i]]
        df_sescribe.insert(0, 'item',axis_name[i])

        if  i == 0 :
            df_append = df_sescribe
        else:
            df_append = df_append.append(df_sescribe, ignore_index=True)

    df_append.to_csv( "./log/" + file_name[4:8] + "_output_pd.csv", encoding="shift_jis")
    dfi.export(df_append, "./log/" + file_name[4:8] + "dataframe.png")

    # フォルダを開く
    cwd = os.getcwd() #現在のディレクトリ情報を取得
    subprocess.Popen(["explorer",  cwd + "\log" ], shell=True) #file open

    # pandas のdate time編集
    df['daytime'] = pd.to_datetime( file_name[0:4] + '/' + df['date'] + ' ' + df['time'])

    # set up figure size
    fig = plt.figure(figsize=(8,6))

    # X軸の値取得 - 共通部分
    x1 = pd.to_datetime(df['daytime'])

    for i in range (axis_len):
        ax = fig.add_subplot(3,1,i+1)

        if   i == 0 :                         # 最初
            ax.set_title(file_name[4:8] + ' vs pressure,temperature,humidity')      # グラフ タイトル

        if i == (axis_len - 1):
            ax.set_xlabel("time")              # x 軸 ラベル         
        else:
            ax.axes.xaxis.set_ticklabels([])   #ラベル/テキストを非表示にする

        y1 =pd.Series(df[axis_name[i]],    dtype='float')
        ax.plot(x1, y1)                          # 値のplot

        ax.set_ylabel(axis_name[i])             # y 軸 ラベル
        ax.grid(True)                          # grid 表示 ON
        ax.legend([axis_name[i]])              # 凡例 を 表示

    plt.xticks(rotation=45)                    # 軸のローテーション
    plt.rcParams['figure.subplot.bottom'] = 0.25 #下端の調整

    plt.show()

    #画像の表示
    fig.savefig("./log/" + file_name[4:8] +"_img.png")

    sg.theme('SystemDefault')
    layout = [
      [sg.Image('./log/' + file_name[4:8] +'_img.png'),sg.Image("./log/" + file_name[4:8] + "dataframe.png")]
    ]
    window = sg.Window('画像', layout=layout)

    # イベントループ
    while True:
        event, values = window.read()
        if event == sg.WIN_CLOSED:
            break
    window.close()


defを別ファイルに定義してみたかったので、ファイルを選択する部分は、gui_operation.pyとして記述した。
ファイルを選択しなかった場合、event操作後は、InputTextにある文字、そうでない場合は、何も入らない。
event操作後の条件分岐で、csvファイルを選択したSubmit以外は、NULLとして出すようにし、データ処理をしないようにした。

gui_operation.py

import PySimpleGUI as sg

def read_csv_file():

    # GUI color select
    sg.change_look_and_feel('Light Blue 2')

    layout = [[sg.Text('Data'),
               sg.InputText(' file path',key='-file-'),
               sg.FilesBrowse('Read file', target='-file-', file_types=(('csv file', '.csv'),))],
              [sg.Submit(), sg.Cancel()]
    ]

    # Make a window
    window = sg.Window('Charting', layout)#window title

    # Event operation
    while True:
        event, values = window.read() # Event read 
        if event in 'Submit': 
            Get_file = values['-file-'] # Get file path
            if  Get_file == ' file path':
                Get_file = 'NULL'
            break
        else:
            Get_file = 'NULL' # Get file path
            break
    window.close()
    return Get_file

使用した入力ファイルの添付方法が分からなったため、ここには入れていません。
やり方わかったら、追記します。