LoginSignup
2
4

More than 3 years have passed since last update.

実験系でもPythonで効率化したい(3)PandasでExcelみたいなことをしたい

Last updated at Posted at 2019-12-09

動機

  • (1)を見てください

環境

  • Windows10
  • Anaconda(3.x)
  • (2)でpySerialをconda installしました

目標

  • わたしの環境でのマニュアル操作の自動化を例として、自動化方法を示す

方法

pandasというPythonで使える、Excelのような表操作に適したパッケージがあります。これとmatplotlibというグラフを簡単にきれいに描画できるパッケージを用いて「自動で取得した電圧値をグラフ化する」の例を提示します。

空間に電流が広範囲に、一方向に流れているときに、空間より小さいマトを使って電流を測定するとします。マトを電流に対して垂直に少しずつ横切らせ、ステップごとの電流を記録するとき、その「移動の制御」と「電流の測定」をpyserialから制御します。移動の制御はシグマ光機SHOT102、電流の測定はADVANTEST社のR6441シリーズを用いています。
2019-12-09_19.57.13.png

Cell1

import serial
import time
import pandas as pd
import matplotlib.pyplot as plt

serialはpyserialを使う、timeはシリアル通信のインターバル時間を作る、pandasはdataframeを使う、matplotlib.pyplotはグラフの描画のために使います。

Cell2

## 定数指定 
MAX = 42000
COMpulse = "COM9"
COMampere = "COM10"
bitRate = 9600

pyserialで用いる定数を指定します。

Cell3

## 変数初期化 
pulse = 0
ampere_list = []
pulse_list = []
ampere_average_list =[]

使用する変数を初期化します。

Cell4(省略可)

## 奥原点移動(初期化)
ser = serial.Serial(COMpulse, bitRate, timeout=0.1)
ser.write(b"H:2-\r\n")
time.sleep(0.1)
print(ser.read_all())
ser.close()

動作確認と計測原点に移ります。

Cell5

pulseは0-42000の値を取り、1パルスあたり3μm移動します。(実際は2パルスあたり6μm動きますが、コマンドはこのように記述するようです)。各positionでの電流の値を5回サンプリングし、平均してその点での値とします。平均する回数は任意です。光学台を最後まで動かし終わったら、電流と位置の値のリストをdataframeとしてくっつけて、pulse値を実際の長さに変換し、matplotlibで描画する。という流れになっています。(ついでにdataframeをcsvに出しています。)

## 測定開始
while 1:
    if pulse >= MAX:
        ## 位置がMAXまで来ている場合while文を終了
        break
    ## 現在位置の情報を記録
    pulse_list.append(pulse/2) #pulseは何故か2倍で指定して命令するので2で割っている
    ## 電流を測定する(5回とって平均したものをその位置での値とする)
    for i in range(5):
        ser = serial.Serial(COMampere,bitRate,timeout=0.1)
        time.sleep(0.5)
        ser.write(b"MD?\r\n")
        time.sleep(0.5)
        tmp = ser.read_all()
        ampere = float(tmp.split()[1])
        ampere_average_list.append(ampere)
        ser.close()
    ## 電流とpulse(位置)をlistに追加
    ampere_list.append(sum(ampere_average_list)/len(ampere_average_list))
    ampere_average_list = [] #リストを初期化

    ## 光学台を動かす
    pulse += 1000
    position = "A:2+P"+str(pulse)+"\r\n" # コマンドを文字列の結合で作る
    ser = serial.Serial(COMpulse,bitRate,timeout=0.1)
    ser.write(bytes(position, 'UTF-8'))
    time.sleep(0.5)
    ser.write(b"G:\r\n")
    ser.close()


## リストをdataframeに変える
print(ampere_list)
print(pulse_list)
df = pd.DataFrame({'ampere(A)':ampere_list,'pulse':pulse_list})
## pulse値を長さに変える
def pulseToMilliMeter(pulse):
    return pulse*0.006
df["position(mm)"] = df["pulse"].map(pulseToMilliMeter) # Excelの一括関数適用のようなことができる
df.to_csv('./csv/hoge/result.csv',index=False)
## matplotlibを用いてグラフを描画する
plt.figure()
df.plot(x='position(mm)',y='ampere(A)')
plt.savefig('./img/sample.png')
plt.close('all')

おわりに

以上で効率化できたとします。実際Enterを押すだけなので、かなりシンプルになりましたし、再現性も高まります。他にも効率化できるネタができたら、続きを書きます。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4