プロットをデータに

プロット画像をデータに自動で変換する PlotDigitizerWebPlotDigitizer のようなツールもあるが,自前でやってみる。

plt.ginput() を使う。これは最後に開いた図上でクリックした座標のリストを返す。Jupyter Notebook 等ではうまくいかない。

import matplotlib.pyplot as plt
import numpy as np

img = plt.imread("filename.png") # 画像を読む
print(img.shape)                 # サイズを確認
plt.figure(figsize=[20, 10])     # できるだけ大きくする
plt.imshow(img)                  # 画像を表示

x1, x2, y1, y2 = 250, 500, 0, 2.5 # 既知の2点の座標

# 上の2点を各3回ずつクリックして中央値をとる
a1, b1 = np.median(plt.ginput(3, timeout=0), axis=0)
a2, b2 = np.median(plt.ginput(3, timeout=0), axis=0)

# プロット点を順に1回ずつクリック
# 右クリック(Ctrl-クリック)で一つ前を削除
# 中クリック(Alt-クリック)で終了
p = plt.ginput(-1, timeout=0)

def conv(t, t1, t2, u1, u2):
    return (u2 - u1) * (t - t1) / (t2 - t1) + u1

# CSV出力
with open("filename.csv", "w") as f:
    print("x,y", file=f)
    for x, y in p:
        x = conv(x, a1, a2, x1, x2)
        y = conv(y, b1, b2, y1, y2)
        print(f"{x:.3f},{y:.3f}", file=f) # 小数第3位まで