Pythonを使ってグラフを作成しよう
なんでなの?
今までExcelで実験レポートのグラフを作成していたが,体裁を整えるのが億劫だし,見た目ダサい
MATLABはライセンス高い
じゃあPythonかーという流れ.
この文章の目的
- 使用するPythonファイルがブラックボックス化しないように(忘れっぽいから) おぼえがきとして使う.
- 実験レポートを作成するときのディレクトリ構造がちょっと複雑になるから,それをまとめておく.
この方のコードを参考にした.🔗Qiita 学生実験用のグラフ作成術
ディレクトリ構造について
第○○回実験
├─配布資料.pdf
├─完成したレポート.pdf
├─測定データ.xlsx
├─tex
│ ├out
│ ├report.tex
│ ├figure_data1.pdf
│ ├figure_data2.pdf
│
│# ここ!
├py-pdf-figure
│ ├data1.csv
│ ├data2.csv
│ ├py_data1.py
│ ├py_data2.py
以下のコードは上の図で言うところのpy_data1.pyである.
コードの説明
とりあえず全体
データは同じディレクトリにCSVを置く.列が同じ成分となるようにする
以下はデータをプロットして散布図を作成して,近似曲線(直線)をかくコード
#Step0. ライブラリのインポート
import numpy as np
from matplotlib import pyplot as plt
from scipy import optimize
import japanize_matplotlib
#Step1. 実験データの読み込み
data1 = np.loadtxt("data1.csv", dtype = "float", delimiter = ",")
data1 = data1.T
x1 = data1[0]
y1 = data1[1]
#Step2. 理論式でフィッティング
def f(x, a, b):
return a * x + b
popt1, pcov1 = optimize.curve_fit(f, x1, y1)
#Step3. 目盛りの場所と向きの設定
plt.rcParams['font.size'] = 14
plt.rcParams['xtick.direction'] = 'in'
plt.rcParams['ytick.direction'] = 'in'
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.xaxis.set_ticks_position('both')
ax1.yaxis.set_ticks_position('both')
plt.tick_params(length = 5)
#Step4. 軸ラベルの設定
ax1.set_xlabel(r"電流$I/\rm{\mu A}$")
ax1.set_ylabel(r"電圧$V/\rm{mV}$")
#Step5. 実験データのプロット
plt.scatter(x1, y1, color = "k", label = "実験値", marker = ",")
#Step6. フィッティングした函数のプロット
xk = np.arange(min(x1), max(x1), 0.01)
plt.plot(xk, f(xk, popt1[0], popt1[1]), color = "k", label = "近似曲線")
#Step7. 凡例の付加
plt.legend()
#Step8. 画像の保存と表示
plt.savefig("out.png", bbox_inches = "tight", dpi = 350)
plt.savefig("out.pdf", bbox_inches = "tight")
plt.show()
plt.close()
各パーツごと
Step1
#Step1. 実験データの読み込み
data1 = np.loadtxt("data1.csv", dtype = "float", delimiter = ",")
data1 = data1.T
x1 = data1[0]
y1 = data1[1]
CSVが縦に同じ成分だから,転置してリストで扱いやすくしている.
Step2
#Step2. 理論式でフィッティング
def f(x, a, b):
return a * x + b
popt1, pcov1 = optimize.curve_fit(f, x1, y1)
optimize.curve_fitでフィッティングしている.
実験によってaとbを出力するようにしてもいいかも.
2次近似や指数関数近似もできるよ.
指数関数近似のときは
def func(x, a):
y = a * np.exp(x)
return y
こんな感じ(できるかまだ確かめてない2025-11-06時点)
Step3
#Step3. 目盛りの場所と向きの設定
plt.rcParams['font.size'] = 14
plt.rcParams['xtick.direction'] = 'in'
plt.rcParams['ytick.direction'] = 'in'
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.xaxis.set_ticks_position('both')
ax1.yaxis.set_ticks_position('both')
plt.tick_params(length = 5)
特に言うことない.
Step4
#Step4. 軸ラベルの設定
ax1.set_xlabel(r"電流$I/\rm{\mu A}$")
ax1.set_ylabel(r"電圧$V/\rm{mV}$")
ここで軸の名前を表示. イタリック体とローマン体の使い分け楽にできる.
Step5
#Step5. 実験データのプロット
plt.scatter(x1, y1, color = "k", label = "実験値", marker = ",")
color = "k"プロットする色(kは黒)label = "実験値"凡例の名前marker = ","プロットする図形(,は四角)
Step6
#Step6. フィッティングした函数のプロット
xk = np.arange(min(x1), max(x1), 0.01)
plt.plot(xk, f(xk, popt1[0], popt1[1]), color = "k", label = "近似曲線")
color = "k"函数の色(kは黒)label = "近似曲線"凡例の名前
Step7
#Step7. 凡例の付加
plt.legend()
凡例つけてる
Step8
#Step8. 画像の保存と表示
plt.savefig("out.png", bbox_inches = "tight", dpi = 350)
plt.savefig("out.pdf", bbox_inches = "tight")
plt.show()
plt.close()
画像をout.png,out.pdfとして出力.主に使うのはpdfやからpngのところは消してもいいね.
散布図に2つのデータをプロットしたいとき
以下のように変更を加えるとうまくいく.
「ここ!」ってかいてあるところが変更を加えたとこ.
#Step0. ライブラリのインポート
import numpy as np
from matplotlib import pyplot as plt
from scipy import optimize
import japanize_matplotlib
#Step1. 実験データの読み込み
data1 = np.loadtxt("data1.csv", dtype = "float", delimiter = ",")
## ここ!
data2 = np.loadtxt("data2.csv", dtype = "float", delimiter = ",")
data1 = data1.T
## ここ!
data2 = data2.T
x1 = data1[0]
y1 = data1[1]
## ここ!
x2 = data2[0]
y2 = data2[1]
#Step2. 理論式でフィッティング
def f(x, a, b):
return a / x + b
popt1, pcov1 = optimize.curve_fit(f, x1, y1)
## ここ!
popt2, pcov2= optimize.curve_fit(f, x2, y2)
#Step3. 目盛りの場所と向きの設定
plt.rcParams['font.size'] = 14
plt.rcParams['xtick.direction'] = 'in'
plt.rcParams['ytick.direction'] = 'in'
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.xaxis.set_ticks_position('both')
ax1.yaxis.set_ticks_position('both')
plt.tick_params(length = 5)
#Step4. 軸ラベルの設定
ax1.set_xlabel(r"体積$V/\rm{cc}$")
ax1.set_ylabel(r"圧力$p/\rm{kPa}$")
#Step5. 実験データのプロット
plt.scatter(x1, y1, color = "b", label = "実験値", marker = ",", zorder=3)
#Step6. フィッティングした函数のプロット
xk = np.arange(min(min(x1), min(x2)), max(max(x1), max(x2)), 0.01)
plt.plot(xk, f(xk, popt1[0], popt1[1]), color = "b", label = "近似曲線", zorder=2)
## ここ!
plt.plot(xk, f(xk, popt2[0], popt2[1]), color = "r", label = "理論値", zorder=1)
#Step7. 凡例の付加
plt.legend()
#Step8. 画像の保存と表示
plt.savefig("out.png", bbox_inches = "tight", dpi = 350)
plt.savefig("out.pdf", bbox_inches = "tight")
plt.show()
plt.close()