Python独習!

習得したPython知識をペイフォワード

Pythonでグラフのプロットとプロットの間の値を読み取る

実験で〇〇を測定したけど測定間隔が粗かった。データとデータの間にある値が欲しんだけど…
interpolateのスプライン補間でデータ数を増やす。※あくまでもデータの“補間”ですのでその意味をちゃんと理解してご使用ください。

解説

スプライン補間の詳細はググってもらうとして、interpolateの使い方は以下のサイトが非常にわかりやすかった。応用例は↓↓のサンプルプログラムを参照してほしい。
org-technology.com

サンプルプログラム

エクセルからデータを読み込んで、任意の「横軸の値」を与えるとそれに対応するデータを返すというプログラム。
元データは以下のようにエクセルで表形式で保存してあるとする。A列が横軸データ、B列が縦軸データとなっている。見てのとおりデータ数は26個。

元データ(エクセルシート)

これをデータ数1000個でスプライン補間すると以下の青線グラフになる。赤線は元データのグラフ。

python-spline-スプライン補間
スプライン補間結果

ここで、例えば課題のレポートに横軸が10.5における測定値が必要だったことが後からわかったとする。元データには存在しないので再測定するか…もしくは、スプライン補間したデータを求めるか。サンプルプログラムでは44行目、48行目のようにすることでスプライン補間結果から値を得ている。

x=10.5に対応するyは205.713です


ソースコード

# 37_SplineCurve_001.py
# python 3.8.1
# openpyxl 3.0.3
# coding: utf-8

import numpy as np
from scipy import interpolate
from matplotlib import pyplot as plt
import openpyxl


def read_excel(wb_path):
    col_A = []
    col_B = []
    
    wb = openpyxl.load_workbook(wb_path)
    sheet_list = wb.sheetnames
    sheet = wb[sheet_list[0]]
    
    num_data = sheet.max_row

    for i in range(1, num_data+1):
        cell = sheet.cell(row=i, column=1)
        col_A.append(cell.value)

        cell = sheet.cell(row=i, column=2)
        col_B.append(cell.value)

    return col_A, col_B


def interpolate_spline(data_x, data_y, xoi):
    data_x_min = min(data_x)
    data_x_max = max(data_x)

    interpolated_func = interpolate.interp1d(data_x, data_y, kind="quadratic")
    corr_data_x = np.linspace(data_x_min, data_x_max, 1000)
    corr_data_y = interpolated_func(corr_data_x)

#    plt.plot(data_x, data_y,"r")
#    plt.plot(corr_data_x, corr_data_y)
#    plt.show()

    return interpolated_func(xoi)

if __name__ == '__main__':

    xoi = 10.5  #欲しいy値に対応するx値 (X of Interest) 
        
    wb_path = 'OriginalData.xlsx'
    x, y = read_excel(wb_path)
    yoi = interpolate_spline(x, y, xoi)  #欲しいy値を求める (Y of Interest)
    print("x={}に対応するyは{:.3f}です".format(xoi, yoi))


/* -----codeの行番号----- */