見出し画像

【(後編)Python】別々のフォルダ内のcsvファイルをグラフ化する。


脱エクセルを目指してPythonを学んでいます。
前回に引き続き、今回は後編としてnoteを書いています。

【前回の内容】
1.複数のディレクトリを作成
2.データを作成
3.データをデータフレームに入れる
4.csvファイルを作成してフォルダに保存する
5.2~4を関数にまとめて複数のデータを各フォルダに保存する

今回やることは、以下の内容です。

【今回の内容】
1.フォルダ内から「data_A,
data_B,data_C,data_D」のフォルダのみ取得
2.フォルダにあるcsvファイルのみ取得
3.csvファイルをpandasで読み込む
4.csvファイルのヘッダーを取得
5.ひとつグラフを書いてみる
6.複数のグラフを書く
7.2~6を関数にしてまとめる
8.7で作成した関数を使って各フォルダにあるcsvファイルを作成する
【使用環境】
Pythonの使用環境はGoogle colaboratoryをしようしています。
Google のアカウントひとつでPythonが使用できるを作ることができます。

コードの詳細の説明はブログで解説します。

このnoteでは「Python初心者」に毛が生えた程度の人を想定しています

前回のおさらい

前回のコードを書いておいた方がわかりやすいと思いますので、こちらに載せておきます。

まず、各フォルダを作成

import os

path = os.getcwd()

dirs = ['data_A','data_B', 'data_C', 'data_D']

for dir in dirs:
 os.mkdir(dir)

print(path)
print(os.listdir())

次に各フォルダにcsvファイルを作成する関数を用意

import random
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def make_csv(i):
 time = np.linspace(0,100,101)
 x1 = np.sin(time*random.randint(0,5))
 x2 = np.sin(time*random.randint(0,5))
 x3 = np.sin(time*random.randint(0,5))
 x4 = np.sin(time*random.randint(0,5))
   
 df_t = pd.DataFrame(time)
 df_x1 = pd.DataFrame(x1)
 df_x2 = pd.DataFrame(x2)
 df_x3 = pd.DataFrame(x3)
 df_x4 = pd.DataFrame(x4)

 df = pd.concat([df_t, df_x1,df_x2,df_x3,df_x4], axis=1)
 df.columns = ['time(sec)', 'x1(m)','x2(m)','x3(m)','x4(m)']

 #csvで保存する
 save_dir = dirs[i] + '/test.csv'
 df.to_csv(save_dir,index=False, header=df.columns)

作成した関数をfor文で繰り返せばフォルダにcsvファイルが作成されます。

for i, dir_ in enumerate(dirs):
 make_csv(i)

画像1


では、さっそく今回の内容に入っていきます。

1.フォルダ内から「data_A,data_B,data_C,data_D」のフォルダのみ取得

フォルダ内にはいろいろな「ファイル」だったり「フォルダ」が存在しますよね。
↓こんな感じで。

画像2

今取得したいフォルダは「data_A,data_B,data_C,data_Dだけです。

これを取得します。

import os

path ='./'
files = os.listdir()
files_dir = [f for f in files if os.path.isdir(os.path.join(path, f))]

files_dir = [dir_ for dir_ in files_dir if dir_[:4]=='data']

files_dir =sorted(files_dir)
files_dir

画像3

取得できました。

2.フォルダにあるcsvファイルのみ取得

さらにフォルダの中にはいろいろな形式のファイルがありますよね。

例えばエクセルデータやパワポや動画など・・・・そのなかでcsvファイルのみを取得します。

csv_lists = os.listdir('./'+ files_dir[0])
for csv_list in csv_lists:
 if csv_list[-4:] == '.csv':
   csv_file=csv_list

dir_csv_file = files_dir[0]+ '/'+ csv_file
dir_csv_file    

画像4

files_dir[0]とすることで「data_A」のフォルダを指定しています。

3.csvファイルをpandasで読み込む

では、各フォルダにあるcsvファイル読み込んでpandasで表形式にで表示しています。

data = pd.read_csv(dir_csv_file,encoding='cp932',skiprows=0)

df = data
df

画像5

このようにpandasを使えば簡単にエクセルのような表を作成することがでできます。

4.csvファイルのヘッダーを取得

これは後で使うのでcsvファイルのヘッダーを取得しておきます。

前回のコードで

「 df.columns = ['time(sec)', 'x1(m)','x2(m)','x3(m)','x4(m)']」

と書いている部分でヘッダーを指定しています。

今回はこれを使います。

headers = df.columns
headers

画像6

ヘッダーの取得ができました。

5.ひとつグラフを書いてみる

今回は「data_A,data_B,data_C,data_D」という4つのフォルダに、「x1,x2,x3,x4」という4つのデータを扱うので、

4×4のグラフの枠を用意しておきます。

いきなり全部のグラフを描くのはややこしいのでひとつだけグラフを描いています。

fig, axes = plt.subplots(2,2,figsize=(20,12))

axes[0,0].legend(files_dir,bbox_to_anchor=(0, 1.3), loc='upper center')
fig.subplots_adjust(wspace=0.4, hspace=0.5)

axes[0,0].set_title(files_dir[0])
axes[0,0].grid()
axes[0,0].set_xlabel(headers[0],fontsize=10)
axes[0,0].set_ylabel(headers[1] ,fontsize=10)
axes[0,0].plot(df[headers[0]], df[headers[1]], label=files_dir[0])

画像7

うまくいきました。

今は、「data_A」のフォルダのcsvファイルの「x1」だけのデータを読み込んでグラフしたことになります。

6.複数のグラフを書く

では、ひとつグラフが描けたら4つグラフを描くこともできます。

fig, axes = plt.subplots(2,2,figsize=(20,12))

axes[0,0].legend(files_dir,bbox_to_anchor=(0, 1.3), loc='upper center')
fig.subplots_adjust(wspace=0.4, hspace=0.5)

axes[0,0].set_title(files_dir[0])
axes[0,0].grid()
axes[0,0].set_xlabel(headers[0],fontsize=10)
axes[0,0].set_ylabel(headers[1] ,fontsize=10)
axes[0,0].plot(df[headers[0]], df[headers[1]], label=files_dir[0])

axes[0,1].set_title(files_dir[0])
axes[0,1].grid()
axes[0,1].set_xlabel(headers[0],fontsize=10)
axes[0,1].set_ylabel(headers[2] ,fontsize=10)
axes[0,1].plot(df[headers[0]], df[headers[2]], label=files_dir[0])

axes[1,0].set_title(files_dir[0])
axes[1,0].grid()
axes[1,0].set_xlabel(headers[0],fontsize=10)
axes[1,0].set_ylabel(headers[2] ,fontsize=10)
axes[1,0].plot(df[headers[0]], df[headers[3]], label=files_dir[0])

axes[1,1].set_title(files_dir[0])
axes[1,1].grid()
axes[1,1].set_xlabel(headers[0],fontsize=10)
axes[1,1].set_ylabel(headers[3] ,fontsize=10)
axes[1,1].plot(df[headers[0]], df[headers[4]], label=files_dir[0])

画像8

「axes」は配列になっているので行と列を指定すればどの領域にグラフを描くかが指定できます。

ただ、これだとめちゃくちゃ効率が悪いコードの書き方なのでfor文を使ってまとめてやります。

fig, axes = plt.subplots(2,2,figsize=(20,12))

axes[0,0].legend(headers,bbox_to_anchor=(0, 1.3), loc='upper center')
fig.subplots_adjust(wspace=0.4, hspace=0.5)

for i , header in enumerate(headers[1:]):
 axes[i//2,i%2].set_title(files_dir[0])
 axes[i//2,i%2].grid()
 axes[i//2,i%2].set_xlabel(headers[0],fontsize=10)
 axes[i//2,i%2].set_ylabel(headers[i+1] ,fontsize=10)
 axes[i//2,i%2].plot(df[headers[0]], df[headers[i+1]], label=files_dir[0])

axes[i//2,i%2]と書いていますが、

●i//2:2で割ったときの商
●i%2:2で割ったときの余り

を意味しています。

for i , header in enumerate(headers[1:]):

の部分でiが「0,1,2,3」と順番に代入されます。

★[0,0]
→0を2で割ったときの商:0
→0を2で割ったときの余り:0

★[0,1]
→1を2で割ったときの商:0
→1を2で割ったときの余り:1

★[1,0]
→2を2で割ったときの商:1
→2を2で割ったときの余り:0

★[1,1]
→3を2で割ったときの商:1
→3を2で割ったときの余り:1

としていればうまくaxesの配列に当てはまっています。

7.2~6を関数にしてまとめる

では、今までやったことを関数にまとめておきます。

import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

path ='./'
files = os.listdir()
files_dir = [f for f in files if os.path.isdir(os.path.join(path, f))]

#フォルダ全体から「data_A~data_D」を取得
files_dir = [dir_ for dir_ in files_dir if dir_[:4]=='data']
files_dir =sorted(files_dir)

def data_graph(data_dir):
 #フォルダの中からcsvファイルを取得
 csv_lists = os.listdir('./'+ files_dir[data_dir])
 for csv_list in csv_lists:
   if csv_list[-4:] == '.csv':
     csv_file=csv_list

 #./フォルダ名/csvファイル
 dir_csv_file = files_dir[data_dir]+ '/'+ csv_file    

 #ファイルの読み込み
 data = pd.read_csv(dir_csv_file,encoding='cp932',skiprows=0)
 df = data

 #ヘッダーの取得
 headers = df.columns

 
 #axes[0,0].legend(files_dir[data_dir],bbox_to_anchor=(0, 1), loc='upper center')
 fig.subplots_adjust(wspace=0.4, hspace=0.5)

 for i , header in enumerate(headers[1:]):
   axes[i//2,i%2].plot(df[headers[0]], df[headers[i+1]], label=files_dir[data_dir])
   axes[0,0].legend(bbox_to_anchor=(0, 1, 0.5, 0.5))
 fig, axes = plt.subplots(2,2,figsize=(20,12))
data_graph(0)

とすれば「data_A」の「x1,x2,x3,x4」のデータをグラフ化してくれます。

画像9

うまくいきました。

これで大まかな流れはできました。

8.7で作成した関数を使って各フォルダにあるcsvファイルを作成する

あとは、関数をfor文で「data_A,data_B,data_C,data_D」のフォルダを繰り返して全てのデータをグラフ化することができます。

 fig, axes = plt.subplots(2,2,figsize=(20,12))

for i , file_dir in enumerate(files_dir):
 axes[i//2,i%2].set_title(headers[i+1])
 axes[i//2,i%2].grid()
 axes[i//2,i%2].set_xlabel(headers[0],fontsize=10)
 axes[i//2,i%2].set_ylabel(headers[i+1] ,fontsize=10)
 
 data_graph(i)

画像10

できました(^^)/

一応適当に「凡例(label)」「軸」「タイトル」などをつけておきました。

全体のコード

全体のコードを載せておきます。

フォルダ内に「csvファイル」があってそれをまとめてグラフ化したいというときに使ってください。
↓こんな状況で・・・・

画像11


import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

path ='./'
files = os.listdir()
files_dir = [f for f in files if os.path.isdir(os.path.join(path, f))]

#フォルダ全体から「data_A~data_D」を取得
files_dir = [dir_ for dir_ in files_dir if dir_[:4]=='data']
files_dir =sorted(files_dir)

def data_graph(data_dir):
 #フォルダの中からcsvファイルを取得
 csv_lists = os.listdir('./'+ files_dir[data_dir])
 for csv_list in csv_lists:
   if csv_list[-4:] == '.csv':
     csv_file=csv_list

 #./フォルダ名/csvファイル
 dir_csv_file = files_dir[data_dir]+ '/'+ csv_file    

 #ファイルの読み込み
 data = pd.read_csv(dir_csv_file,encoding='cp932',skiprows=0)
 df = data

 #ヘッダーの取得
 headers = df.columns

 
 #axes[0,0].legend(files_dir[data_dir],bbox_to_anchor=(0, 1), loc='upper center')
 fig.subplots_adjust(wspace=0.4, hspace=0.5)

 for i , header in enumerate(headers[1:]):
   axes[i//2,i%2].plot(df[headers[0]], df[headers[i+1]], label=files_dir[data_dir])
   axes[0,0].legend(bbox_to_anchor=(0, 1, 0.5, 0.5))
 fig, axes = plt.subplots(2,2,figsize=(20,12))

for i , file_dir in enumerate(files_dir):
 axes[i//2,i%2].set_title(headers[i+1])
 axes[i//2,i%2].grid()
 axes[i//2,i%2].set_xlabel(headers[0],fontsize=10)
 axes[i//2,i%2].set_ylabel(headers[i+1] ,fontsize=10)
 
 data_graph(i)

はい、グラフ完成(^^)/

画像12

今回は以上です。

Twitter➡@t_kun_kamakiri
ブログ➡宇宙に入ったカマキリ(物理ブログ)

この記事が気に入ったらサポートをしてみませんか?