Pythonによるグラフ描画
1. 目的
オブジェクト指向プログラミングの代表的な Python を学習し、Python を用いたグラフ描画技術を習得する。
2. 理論
2.1 Matplotlib
Matplotlibとは、Pythonで使えるグラフ描画ライブラリである。散布図やヒストグラムなど基礎的なグラフだけでなく、多様なグラフを少ない手順で描画できる。公式サイトに多くのグラフ例がある。
https://matplotlib.org/stable/gallery/index.html
3. 実験方法
3.1 csvファイルのアップロード
LMSで配布したsample.csv
とA0001.CSV
を、Azure 上のサーバーにアップロードする。
SFTPでのアップロード方法は以下を参照。
サーバで新たに作業用ディレクトリを作り、カレントディレクトリを移す。
mkdir work20220419
cd work20220419
このディレクトリに2つのファイルをアップロードする。
3.2 電圧-電流グラフの描画
sample.csv
の中身は次のようになっている。
V[V], I[mA]
0, 0.00
1, 10.47
2, 20.64
3, 30.49
4, 41.88
5, 52.36
6, 61.08
7, 69.10
8, 81.92
9, 87.95
10, 99.47
これをPythonに取り込む。
Pythonプログラムを書くためのテキストファイルを作成する。
touch samplegraph.py
これをnano(他のエディタでも可)で編集する。
nano samplegraph.py
以下のプログラムをファイルに書き込む。
import numpy as np
import matplotlib.pyplot as plt
FNM = "sample.csv"
data=np.loadtxt(FNM, delimiter=',', skiprows=1)
V = data[:, 0]
I = data[:, 1]
plt.plot(V, I)
plt.show()
細かく区切って説明する。まず、必要なライブラリをインポートする。
import numpy as np
import matplotlib.pyplot as plt
次に、np.loadtxt()
関数でテキストファイルを読み込む。
FNM = "sample.csv"
data=np.loadtxt(FNM, delimiter=',', skiprows=1)
Tip
np.loadtxt()
のドキュメント
https://numpy.org/doc/stable/reference/generated/numpy.loadtxt.html
dataは10行2列の配列であり、1列目に電圧V, 2列めに電流Iが入っている。
V = data[:, 0]
I = data[:, 1]
このデータをプロットする。
plt.plot(V, I)
plt.show()
このプログラムを保存し、nanoを終了してターミナルに戻る。
プログラムを実行する。
python3 samplegraph.py
プロットは表示されたが、実験のレポートとして体裁が悪い。
- 縦軸、横軸の単位がない
- 目盛りは内向きのほうがよい
- プロットではなく折れ線グラフ
- 理論線があるとよい
- 凡例がない
以上の問題を解決する。
nanoでプログラムを開き、以下の命令を適切な位置に追記する。
縦軸、横軸の単位をつける
plt.xlabel("Voltage [V]")
plt.ylabel("Amplitude [mA]")
目盛りを内向きに
plt.rcParams['xtick.direction'] = "in"
plt.rcParams['ytick.direction'] = "in"
プロットを点にする
plt.plot(V, I)
を、以下の命令に置き換える。
plt.plot(V, I, "x")
Tip
3つめの引数の"x"
はマーカーの種類を表している。マーカーには多くの種類がある。
https://matplotlib.org/stable/api/markers_api.html
理論線をつける
今回は、I[mA] = V[V] * 10 が理論値となる。
以下の命令を適切な位置に追記する。
I_theo = V * 10
plt.plot(V, I_theo, "-")
凡例をつける
理論線と実測値が両方出てどちらがどちらかわからなくなったため、凡例をつける。
それぞれのplt.plot()
を、以下の命令に置き換える。
plt.plot(V, I, "x", label="measured")
plt.plot(V, I_theo, "-", label="theory")
また、plt.show()
のすぐ前に以下の命令を追記する。
plt.legend()
これで実行すると、レポートとして提出するのに適切なグラフが描画できる。
課題
体裁を整えたグラフをLMSの課題1に提出する。
3.3 ディジタルオシロスコープのグラフ描画
ディジタルオシロスコープの出力したA0001.CSV
の先頭の数行を見ると、次のようになっている。見やすくするため表形式で表示している。
Format | 1.0B | ||||
Memory Length | 10000 | Memory Length | 10000 | Memory Length | 10000 |
IntpDistance | 0 | IntpDistance | 0 | IntpDistance | 0 |
Trigger Address | 4999 | Trigger Address | 4999 | Trigger Address | 4999 |
Trigger Level | 0.00E+00 | Trigger Level | 0.00E+00 | Trigger Level | 0.00E+00 |
Source | CH1 | Source | CH2 | Source | Math |
Vertical Units | V | Vertical Units | V | Vertical Units | V |
Vertical Units Div | 0 | Vertical Units Div | 0 | Vertical Units Div | 0 |
Vertical Units Extend Div | 16 | Vertical Units Extend Div | 16 | Vertical Units Extend Div | 16 |
Label | Label | Label | Probe Type | ||
Probe Ratio | 1.00E+01 | Probe Ratio | 1.00E+01 | Probe Ratio | 1.00E+00 |
Vertical Scale | 2.00E+00 | Vertical Scale | 2.00E+00 | Vertical Scale | 2.00E+00 |
Vertical Position | 0.00E+00 | Vertical Position | 0.00E+00 | Vertical Position | 0.00E+00 |
Horizontal Units | S | Horizontal Units | S | Horizontal Units | S |
Horizontal Scale | 2.00E-04 | Horizontal Scale | 2.00E-04 | Horizontal Scale | 2.00E-04 |
Horizontal Position | 0.00E+00 | Horizontal Position | 0.00E+00 | Horizontal Position | 0.00E+00 |
Horizontal Mode | Main | Horizontal Mode | Main | Horizontal Mode | Main |
SincET Mode | Real Time | SincET Mode | Real Time | SincET Mode | Real Time |
Sampling Period | 2.00E-07 | Sampling Period | 2.00E-07 | Sampling Period | 2.00E-07 |
Horizontal Old Scale | 2.00E-04 | Horizontal Old Scale | 2.00E-04 | Horizontal Old Scale | 2.00E-04 |
Horizontal Old Position | 0.00E+00 | Horizontal Old Position | 0.00E+00 | Horizontal Old Position | 0.00E+00 |
Firmware | V1.14 | Firmware | V1.14 | Firmware | V1.14 |
Mode | Detail | Mode | Detail | Mode | Detail |
Waveform Data | Waveform Data | Waveform Data | |||
-1.00E-03 | -0.4 | -1.00E-03 | -2.64 | -1.00E-03 | 2.24 |
-1.00E-03 | -0.32 | -1.00E-03 | -2.72 | -1.00E-03 | 2.4 |
-1.00E-03 | -0.32 | -1.00E-03 | -2.72 | -1.00E-03 | 2.4 |
-9.99E-04 | -0.32 | -9.99E-04 | -2.72 | -9.99E-04 | 2.4 |
このcsvファイルをグラフにする。
pythonプログラムを書くためのファイルを新たに作成し、編集する。
touch oscillograph.py
nano oscillograph.py
先頭の方にはグラフ描画に必要ないデータが多数ある。
また、下の方のデータを見ても、0, 2, 4列目は時間を示しており、全く同じ内容である(最初の列は0列目であることに注意)。まずはこれを削除する。
以下のプログラムの、np.loadtxt()
関数の引数を追加し、必要のないデータを読み込まないようにせよ。
行については25
行目までは読み込まず、列については[0, 1, 3, 5]
列だけ使う。
import numpy as np
import matplotlib.pyplot as plt
FNM = "A0001.CSV"
data=np.loadtxt(FNM, delimiter=',')
- numpy.loadtxt(fname, delimiter=None, skiprows=0, usecols=None)
- Load data from a text file.
- Parameters:
fname
: File, filename.delimiter
: The string used to separate values.skiprows
: Skip the first skiprows lines.usecols
: Which columns to read, with 0 being the first.
Tip
usecols
はリストで複数指定できる。
data
の先頭はこのようになった。列は左から、time, CH1, CH2, CH3のデータを示している。
-1.00E-03 | -0.4 | -2.64 | 2.24 |
-1.00E-03 | -0.32 | -2.72 | 2.4 |
-1.00E-03 | -0.32 | -2.72 | 2.4 |
-9.99E-04 | -0.32 | -2.72 | 2.4 |
-9.99E-04 | -0.32 | -2.72 | 2.4 |
-9.99E-04 | -0.32 | -2.64 | 2.32 |
-9.99E-04 | -0.32 | -2.72 | 2.4 |
-9.99E-04 | -0.32 | -2.64 | 2.32 |
-9.98E-04 | -0.32 | -2.72 | 2.4 |
-9.98E-04 | -0.32 | -2.72 | 2.4 |
このデータをグラフにする。 0列目は時間、1列目はCH1、2列目はCH2、3列目はCH3を表している。
time = data[:, 0]
CH1 = data[:, 1]
CH2 = data[:, 2]
CH3 = data[:, 3]
3つのグラフを描きたいため、以下のように追記する。
plt.plot(time, CH1)
plt.plot(time, CH2)
plt.plot(time, CH3)
plt.show()
ここまででnanoを閉じ、pythonプログラムを実行すると、グラフが出る。
これをさらに見やすくするため、上で行ったようなプログラムを記述する。
課題
オシロスコープのグラフの体裁を整え、LMSの課題2に提出する。理論線は必要ない。
参考文献
Ubuntu manuals accessed on 10.13.2021
Microsoft Documentation accessed on 10.13.2021
NumPy v1.21 Manual accessed on 10.20.2021