1.はじめに
今回はPythonを使って大量のグラフを一括で作成していきます。比較的によく使われる機能だと思うので、参考になれば幸いです。
グラフ作成といえばExcelなのですが、一括作成に関しましてはPythonのほうが圧倒的に便利です。その理由としまして、Excelは基本機能でグラフを一括で作成することができず、マクロを組む必要があります。しかし、マクロを組んだとしてもExcel自体の動作が重くなってしまい、強制終了してしまう場合も多々あります。PCのスペックによりますが、体感20個くらいが限界かなと思います。その点、Pythonでは100個でも問題なく作成できます。ただ、Pythonにも難しいところがあり、データの入れ替え、グラフの種類、色や配置などのデザインなどは設定が煩雑でExcelのほうが圧倒的に使い易いです。
このあたりを踏まえて、目的に応じた手段を選んでいただければと思います。
2.データの準備
まず、今回どのような形式でグラフを作成するかといいますと「大量のデータから一部の区間を抜粋したグラフ」を大量に作成していきたいと思います。ですので必要なデータは、
- グラフで表したいデータのCSV
- 抽出する区間とタイトルのCSV
になります。今回の例では、潮位観測所(伊勢湾、尾鷲、潮岬)の2007年~2022年の20分ごとの潮位データが「グラフで表したいデータ」となり、期間内で起きた擾乱を「抽出する区間とタイトル」としています。下の画像を参考にしてください。
- 番号:整理番号(3が始めになっている意味は特にないです)
- 日時:日付(CSVなのでシリアル値になっています)
- 伊勢湾~潮岬:それぞれの潮位の値
- 期間番号:整理番号
- 始点、終点:それぞれの期間の始点と終点の番号(グラフ用データの「番号」に対応しています)
- タイトル:グラフのタイトル(最終的にグラフに表示されます)
3.グラフ作成のコード
下記にグラフ作成のコードを記載いたします。データ参照箇所や列の指定などは適宜調整してください。
import csv
import pandas as pd
import matplotlib.pyplot as plt
import datetime
from matplotlib.dates import DateFormatter
#基本はこっち
%matplotlib inline
#出力されるグラフが真っ白な場合こっちを使う
#%matplotlib notebook
path_dcsv = r'【グラフ用データ.csv保存先のパス】\グラフ用データ.csv'
df_dcsv = pd.read_csv(path_dcsv,encoding = "shift-jis")
#シリアル値を日付へ変更
df_dcsv2 = df_dcsv.copy()
df_dcsv2['日時'] = pd.to_datetime(df_dcsv2['日時'], unit='D', origin='1899/12/30')
path_tcsv = r'【グラフタイトル.csv保存先のパス】\グラフタイトル.csv'
df_tcsv = pd.read_csv(path_tcsv,encoding = "shift-jis")
#保存先のパスを指定
savegraph_path = r'【出力したい保存先のパス】'
#整理番号を参照して作成するグラフの個数を判別
df_tcsv_i = df_tcsv.tail(1)
i = df_tcsv_i.iloc[0, 0]
i = i+1
for count in range(1,i):
df_tcsv_g = df_tcsv[df_tcsv["期間番号"] == count]
B_No = df_tcsv_g.iloc[0, 1]
E_No = df_tcsv_g.iloc[0, 2]
title = df_tcsv_g.iloc[0, 3]
data_x = df_dcsv2.iloc[B_No:E_No, 1]
idata_y = df_dcsv2.iloc[B_No:E_No, 2]
odata_y = df_dcsv2.iloc[B_No:E_No, 3]
sdata_y = df_dcsv2.iloc[B_No:E_No, 4]
fig, ax = plt.subplots()
ax.set_ylabel('m')
ax.set_title(title)
ax.plot(data_x,idata_y,color="blue", label="isewan")
ax.plot(data_x,odata_y,color="green", label="owase")
ax.plot(data_x,sdata_y,color="red", label="sionomisaki")
ax.legend(loc=0)
plt.annotate(f'Max: {idata_y.max()}', xy=(data_x[idata_y.idxmax()], idata_y.max()), xytext=(10, -10), textcoords='offset points', arrowprops=dict(arrowstyle='->', color="blue"), color="deepskyblue")
plt.annotate(f'Max: {odata_y.max()}', xy=(data_x[odata_y.idxmax()], odata_y.max()), xytext=(10, -10), textcoords='offset points', arrowprops=dict(arrowstyle='->', color="green"), color="springgreen")
plt.annotate(f'Max: {sdata_y.max()}', xy=(data_x[sdata_y.idxmax()], sdata_y.max()), xytext=(10, -10), textcoords='offset points', arrowprops=dict(arrowstyle='->', color="red"), color="hotpink")
date_fmt = DateFormatter('%Y/%m/%d')
ax.xaxis.set_major_formatter(date_fmt)
plt.xticks(rotation=45)#x軸のラベルのを45°傾ける
plt.show()
graphname = savegraph_path + "\\" + title + ".png"
plt.savefig ( graphname,bbox_inches='tight' )
出力されたものは以下になります。
今回の例では、92個のグラフを10秒ほどで作成できました。
4.補足
グラフを出力する際に、Python上ではグラフが表示されるのですが、出力されたグラフが真っ白の場合があります。明確な原因はわからないのですが、解決方法としては下記のコードを部分を変更することで治る場合があります。
#基本はこっち
%matplotlib inline
#出力されるグラフが真っ白な場合こっちを使う
%matplotlib notebook
出力するデータの形式ですが、下記のものに対応しています。
- emf
- eps
- jpeg
- jpg
- png
- ps
- raw
- rgba
- svg
- svgz
- tif
- tiff
コードの下記の箇所を変更することで、出力フォーマットを変更できます。
#「.png」を出力したいフォーマットに変更
graphname = savegraph_path + "\\" + title + ".png"
以上になります。
コメント