なんでなの?

今まで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()