本記事では「【Matplotlib】Pythonデータ取得ツールを複数グラフに対応してみた」についてアウトプットします。
以前PythonでMatplotlibを使ったデータ解析補助ツールについてアウトプットしました。
以前は1ファイル中に1つのグラフ情報しかなかったのでそのままでよかったのですが、最近は1ファイル中に複数グラフ入っているデータを扱うことが出てきたので、改造して対応してみました。
改造内容としては、1つの画面中に複数個のグラフを出力して、頂点をマーキングして座標を取得するというもの。
グラフをクリックするのを複数窓に対応させたところがポイントです。
(データから1つ分のグラフ情報だけ抽出してやればよくない?とか言わない!)
ツールに搭載したい機能
- 任意のデータファイルを選択する
- 折れ線グラフとして表示する
- クリックして任意の座標のマーキング
- マーキングした部分の座標の読み取り
- 左クリックと右クリックの打ち分け
- 複数窓でグラフを表示(New!!)
- クリックを複数窓に対応(New!!)
環境
- OS:Mac
- 使用環境:Python3.7、VS Code
- 使用ライブラリ:numpy、pandas、matplotlib、tkinter
実際に書いたコード
import matplotlib
matplotlib.use('Qt4Agg')
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tkinter import filedialog
typ = [('CSVファイル', '*.csv')]
dir = '/Users/◯◯/△△/' #任意のファイルを指定
file = filedialog.askopenfilename(filetypes = typ, initialdir = dir)
data = pd.read_csv(file)
x1 = data['X1']
y1 = data['Y1']
x2 = data['X2'] #追加部分
y2 = data['X2'] #追加部分
#グラフの描画
fig = plt.figure()
ax1 = fig.add_subplot(2, 1, 1)
ax2 = fig.add_subplot(2, 1, 2) #追加部分
ax1.plot(x1, y1)
ax1.set_title('xy1')
ax2.plot(x2, y2) #追加部分
ax2.set_title('xy2') #追加部分
#クリックで座標に印をつける
def oncpaint(event):
if event.button==3:
if event.inaxes == ax1:
ind = np.searchsorted(x1,event.xdata)
ax1.plot([x1[ind]],[y1[ind]], ".", color="red")
fig.canvas.draw()
print('x1= %f y1= %f' %(x1[ind], y1[ind]))
elif event.inaxes == ax2: #追加部分
ind = np.searchsorted(x2,event.xdata)
ax2.plot([x2[ind]],[y2[ind]], ".", color="red")
fig.canvas.draw()
print('x2= %f y2= %f' %(x2[ind], y2[ind]))
#グラフのウィンドウのサイズを設定
fig.set_size_inches(18, 9) #追加部分
cid = fig.canvas.mpl_connect('button_press_event', oncpaint)
plt.show()
複数グラフに対応したポイント
クリックして認識するところの部分(下記)の、数字をグラフに対応する数字に変更するだけです。
if event.inaxes == ax1:
ind = np.searchsorted(x1,event.xdata)
ax1.plot([x1[ind]],[y1[ind]], ".", color="red")
fig.canvas.draw()
print('x1= %f y1= %f' %(x1[ind], y1[ind]))
elif event.inaxes == ax2:
ind = np.searchsorted(x2,event.xdata)
ax2.plot([x2[ind]],[y2[ind]], ".", color="red")
fig.canvas.draw()
print('x2= %f y2= %f' %(x2[ind], y2[ind]))
グラフが増えたらその分だけelifの部分を数字を変えて追加していくだけでさらに多くのグラフに対応することができます。
その時はもちろん
ax3 = fig.add_subplot(3, 1, 3)
というようにグラフの表示領域も増やしていく必要があるので注意ですね。
このツールの使用方法
データの準備
今回は、得られるデータが横軸X、縦軸Yになるので、サンプルとして下記のようなCSV形式のファイルを用意します。
X1、Y1、X2、Y2という感じで複数軸の情報が入っています。
使い方
基本的には前回記事で紹介したように、
- 任意のデータファイルを選択
- グラフの表示
- クリックで座標のマーキングと読み取り
- 解析に使用する
という流れはそのままです。
前回は窓一つだったのが、複数窓になることでたくさんのデータに対応できるようになりました。
赤い点がクリックして印をつけたところです。ここの座標が出力されます。
1つ1つやっていくよりまとめて処理したほうが早いですからね。
出力結果もこんな感じでx1 = ◯、y1 = ◯、x2 = ◯、y2 = ◯という感じで出力できます。
果たしてこの方法の需要が自分以外にあるのかどうかとっても疑問なところはありますが、やりたいことはとりあえずできました!
改良するべき欠点
今回改造したツールの欠点。
それは、あらかじめ設定したデータ数を下回るとエラーを起こすということです。
あと、設定したデータ数を上回ると上回った分は表示されないこと。
現状、データを吐き出す時にある一定数で吐き出すようなデータの取得をしているので、あまり問題無いけれど、やむを得ないときはコード中のxとyを増やしたり減らしたりして対応しています。
なんとかその都度書き変えずに柔軟に対応できるような設定にできたらいいなと思いつつ…
(多分必要に迫られない限りはやらない気がしますが←)
まとめ
以上、「【Matplotlib】Pythonデータ取得ツールを複数グラフに対応してみた」についてのアウトプットでした。
以前作ったツールを改造してみたよ。というものですが、自分で作ることができたり、必要に応じて改造していけたりするのは便利だし、できることが徐々に増えていくのがとても楽しいですね。
他にもscipyというライブラリを使って頂点自動認識みたいなのもやってみたのでいつかアウトプットしていきたいです。
プログラミングは自分の可能性とか世界を広げてくれるツールの一つだと思うので、もっと作りたいと思ったものを作れるように頑張っていきます!
参考にさせてもらったページ
・python/matplotlibの図上にてクリックで座標値を取得したりキーボード入力値を取得したりする
・matplotlibで描いたグラフ上の座標を取得する方法
この場を借りてお礼申し上げます。
コメント