Python 1ファイルに全ステップ分が記述されたcsvから散布図を作成する「時間に関する列がない場合」

'21/02/26更新:本文更新。

 下図のような行方向に全ステップの時系列データがあるとします。この例では、Time,1 Time,2 Time,3…で区切られています。

f:id:HK29:20191230235841p:plain

本プログラムを実行すると、下図のように時間毎にグラフにプロットした画像ファイルで保存します。

f:id:HK29:20200125145852j:plain

ちなみに、下図のように複数のcsvファイルに対して、そのフォルダを指定することで一枚ずつグラフ画像を作成する処理にしています。

f:id:HK29:20200125150623p:plain

  ■本プログラム

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, glob
import re
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import datetime
now = datetime.datetime.now()
now = now.strftime("%y%m%d")

def extract_data_from_one_file(my_file, my_header1, my_header2, my_columns):
    # csvファイルの読み込み
    df = pd.read_csv(my_file, sep=',', header=(my_header1-1), encoding='utf_8')
    print(df)
    x_list = df[my_columns[0]].values.tolist()
    y_list = df[my_columns[1]].values.tolist()
    
    # 同じ値が複数あるリストにおいて、その複数のインデックスをリストで返す
    index_list = [i for i, x in enumerate(x_list) if x == my_header2]
    print(index_list)
    
    # 行方向に時系列データの塊が複数ある。これをジャグ配列で格納してゆく
    x_jagged_list = []
    y_jagged_list = []
    # 各々のデータ取得の開始と終了のセット
    index_list_set = []
    for i, x in enumerate(index_list):
        if i == 0:
            x0 = 0
            x1 = x
            index_list_set.append([x0,x1])
        else:
            x1 = x - 1
            index_list_set.append([x0,x1])
        x0 = x + 2
    x1 = sum(1 for i in open(my_file)) - (my_header1+1) # 最終行の取得
    index_list_set.append([x0,x1])
    
    for x0, x1 in index_list_set:
        print(x0, x1)
        x_data = x_list[x0:x1]
        y_data = y_list[x0:x1]
        x_data = list(map(float, x_data))
        y_data = list(map(float, y_data))
        x_jagged_list.append(x_data)
        y_jagged_list.append(y_data)
    
    return x_jagged_list, y_jagged_list
        
def plot_scatter(num, my_fiel, my_XY):
    plt.figure(num=1, figsize=(8,6), dpi=100, facecolor='w', edgecolor='k')
    plt.scatter(my_XY[0], my_XY[1], s=50)
    plt.plot(my_XY[0], my_XY[1], label=str(num+1))
    
def initialize(my_save_dir):
    if os.path.isdir(my_save_dir):
        path_list = [my_save_dir, '*.jpg']
        path_list = [dir.replace('./', '') for dir in path_list]
        my_path = os.path.join(*path_list)
        print(my_path)
        delete_file_list = glob.glob(my_path)
        for file in delete_file_list:
            os.remove(file)
    else:
        os.mkdir(my_save_dir)

def main():
    initialize(my_save_dir)
    for my_file in my_files:
        print(my_file)
        fname = os.path.basename(my_file)
        x_jagged_list, y_jagged_list = extract_data_from_one_file(my_file, my_header1, my_header2, my_columns)
        i=0
        for x_list, y_list in zip(x_jagged_list, y_jagged_list):
            my_XY = [x_list, y_list]
            plot_scatter(i, my_file, my_XY)
            i += 1
        # 縦軸,横軸の線形 or 対数の指定
        if my_Xscale=='log':
            plt.xscale('log', nonposy='mask')
        else:
            plt.xscale(my_Xscale)
        if my_Yscale=='log':
            plt.yscale('log', nonposy='mask')
        else:
            plt.yscale(my_Yscale)
        # 縦軸のレンジの指定
        if my_y_range:
            plt.ylim(my_y_range[0], my_y_range[1])
        plt.grid(which="both")
        plt.title(fname, fontsize=18)
        plt.xlabel(my_columns[0], fontsize=18)
        plt.ylabel(my_columns[1], fontsize=18)
        plt.legend(loc='best', fontsize=18)
        plt.tick_params(labelsize=18)
        plt.savefig(my_save_dir + '/' + now + '_' + fname[:-4] + "_" \
                    + my_columns[0] + "_" + my_columns[1] + ".jpg")
        plt.close()

if __name__ == '__main__':
    ### parameter
    my_files = glob.glob("./Csv/*.csv")
    my_files = sorted(my_files, key=lambda x:int((re.search(r"[0-9]+", x)).group(0)))
    my_header1 = 2
    my_header2 = "Time"
    my_columns = ("x", "stress")
    my_Xscale = "linear" # log or linear
    my_Yscale = "linear" # log or linear
    my_y_range = () #(50, 900) # レンジの範囲を指定しない場合は空()
    my_save_dir = './Jpg'
    
    ### call function
    main()

●類似コード

hk29.hatenablog.jp

以上

<広告>