Pythonによるグラフ描画

1. 目的

オブジェクト指向プログラミングの代表的な Python を学習し、Python を用いたグラフ描画技術を習得する。

2. 理論

2.1 Matplotlib

Matplotlibとは、Pythonで使えるグラフ描画ライブラリである。散布図やヒストグラムなど基礎的なグラフだけでなく、多様なグラフを少ない手順で描画できる。公式サイトに多くのグラフ例がある。

https://matplotlib.org/stable/gallery/index.html

3. 実験方法

3.1 csvファイルのアップロード

LMSで配布したsample.csvA0001.CSVを、Azure 上のサーバーにアップロードする。

SFTPでのアップロード方法は以下を参照。

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)

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