質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

684閲覧

キャンバス上をマウスでクリックし点を追加、2個以上の点をスプライン補完したい

takes.it.easy

総合スコア19

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/06/29 14:46

前提・実現したいこと

matplotlibのキャンバス上をマウスでクリックすると点が追加されます。追加された点のx座標とy座標を用いてスプライン補完を行い、リアルタイムで点と点を結びたいです。

発生している問題・エラーメッセージ

ValueError: at least 2 breakpoints are needed

該当のソースコード

Python

1import matplotlib.pyplot as plt 2import numpy as np 3from scipy import interpolate 4 5def main(): 6 fig = plt.figure() 7 ClickAddPoints(fig).show() 8 9class ClickAddPoints: 10 def __init__(self, fig): 11 self.fig = fig 12 self.ax1 = fig.add_axes([0.1,0.1,0.8,0.8]) 13 self.xy = [] 14 self.points = self.ax1.scatter([], [], s=200, color='red', picker=10) 15 self.spline = interpolate.Akima1DInterpolator([],[]) 16 self.ax1.figure.canvas.mpl_connect('button_press_event', self.on_click) 17 18 def on_click(self, event): 19 if event.inaxes is not self.ax1: 20 return 21 self.xy.append([event.xdata, event.ydata]) 22 self.points.set_offsets(self.xy) 23 self.ax1.draw_artist(self.points) 24 self.ax1.figure.canvas.blit(self.ax1.bbox) 25 num = (len(self.xy)) 26 print(num) 27 if num > 2 : 28 self.spline.set_offsets(self.xy) 29 self.X = np.linspace(event.xdata[0], event.xdata[-1], num=100, endpoint=True) 30 self.Y = self.f(self.X) 31 plt.plot(self.X, self.Y) 32 else: 33 return 34 35 def show(self): 36 self.ax1.set_xticks(np.linspace(0, 4, 5)) 37 self.ax1.set_yticks(np.linspace(0, 4, 5)) 38 self.ax1.set_aspect('equal') 39 plt.show() 40 41main()

試したこと

プログラミング初心者です。書籍を読み調べたりしましたが有効な方法が見つかりません。このサイトの使用も初めてなので情報が至らなかったり、失礼があるかもしれませんがご了承ください。よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

patapi

2020/06/29 17:41 編集

質問中のソースですが、スプライン補完曲線を返すfの実体がどこにも定義されていないのに、呼び出しているため、そもそも動かない気がします。 self.spline~以降の部分を修正して関数として切り出す必要があるのではないでしょうか。
takes.it.easy

2020/06/30 02:49

つまりスプライン補完曲線を計算するための関数が必要ということでよろしいでしょうか?
patapi

2020/06/30 03:36

スプライン補完曲線を計算するための関数について、参考として回答欄にコードを記載しました。ご参照ください。
guest

回答1

0

ベストアンサー

元ソースをできる限り活かすとすれば以下のようになるでしょうか。

import matplotlib.pyplot as plt import numpy as np from scipy import interpolate def main(): fig = plt.figure() ClickAddPoints(fig).show() class ClickAddPoints: def __init__(self, fig): self.fig = fig self.ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) self.xy = [] self.points = self.ax1.scatter([], [], s=10, color='red', picker=100) self.ax1.figure.canvas.mpl_connect('button_press_event', self.on_click) def on_click(self, event): # 前の線をクリアする場合は下の行をコメントアウトする。 # plt.cla() if event.inaxes is not self.ax1: return # クリックしたx座標が過去のプロットのx座標と重複している場合返る。 if event.xdata in [t[0] for t in self.xy]: return self.xy.append([event.xdata, event.ydata]) self.points.set_offsets(self.xy) self.ax1.draw_artist(self.points) self.ax1.figure.canvas.blit(self.ax1.bbox) if len(self.xy) > 2: # x座標でソート self.xy.sort() xx = [t[0] for t in self.xy] yy = [t[1] for t in self.xy] x1, y1 = self.calc_spline(xx, yy, 100) plt.plot(x1, y1) self.show() else: return def calc_spline(self, x, y, point): ''' スプライン曲線を演算する。 ''' f = interpolate.Akima1DInterpolator(x, y) x1 = np.linspace(x[0], x[-1], num=point, endpoint=True) y1 = f(x1) return x1, y1 def show(self): self.ax1.set_xticks(np.linspace(0, 4, 5)) self.ax1.set_yticks(np.linspace(0, 4, 5)) self.ax1.set_aspect('equal') plt.show() main()

投稿2020/06/29 17:25

編集2020/06/29 17:28
patapi

総合スコア820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takes.it.easy

2020/06/30 03:39

示していただいたコードをそのまま実行すると、4つ目(あるいは3つ目)の点を追加したところで、それまでの点が2重になるように出現し、スプライン補完がなされません。原因は何でしょうか。
takes.it.easy

2020/06/30 04:22

すみません。補完されていました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問