0
大きなプロジェクトの一環として、Pyqt5に埋め込まれたmatplotlibのグラフを更新しています。私は散点に注釈を追加して削除するonpickイベントを持っています。下のような方法で私のプロットを更新した後、onPickフィーチャは2回登録されます。正しく削除されていないものがあります。私は、私の問題を修正するだろう、図のほかに私が何を明らかにするのだろうと思っていた。matplotlib onPickイベントを2回登録する
単純な例の問題を強調:
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
class plot(QWidget):
def __init__(self):
super().__init__()
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.Layout = QVBoxLayout()
self.xarray = [1,2,3,4,5,6]
self.yarray = [6,7,5,4,2,1]
update_btn = QPushButton("Update Plot", self)
self.Layout.addWidget(update_btn, 1)
update_btn.clicked.connect(self.updateplot)
self.createplot()
self.setLayout(self.Layout)
def updateplot(self):
self.xarray = [6,7,5,3,2,1]
self.figure.clear()
self.createplot()
def createplot(self):
ax = self.figure.add_subplot(1,1,1)
ax.grid()
val = self.displayval(ax)
self.plot = ax.plot(self.xarray, self.yarray,'o', marker = 'o', c= 'b', picker = 5)[0]
self.Layout.addWidget(self.canvas, 2)
self.canvas.draw()
def displayval(self, ax):
def onPick(event):
print("connecting")
plot = event.artist
xval = plot.get_xdata()
yval = plot.get_ydata()
ind = event.ind
if xval[ind].size > 1 or yval[ind].size > 1: return
xy = (xval[ind][0], yval[ind][0])
ann = ax.annotate('(%f , %f)' % xy, xy= xy)
self.figure.canvas.draw()
self.figure.canvas.mpl_connect('pick_event', onPick)
return onPick
if __name__ == '__main__':
appl = QApplication(sys.argv)
main = plot()
main.show()
sys.exit(appl.exec_())
注:私は、しかし、これは私のプログラムでデータを正しくレンダリングされません
ax.set_xaxis()
ようなもので、軸の値を更新しようとしているため、代替的な答えが好ましい。
プロットを更新するたびに、新しいpick_eventが登録されると思います。したがって、一度更新するとonPickは2回呼び出されます.2回更新すると3回呼び出されます。更新機能に依存せず、一度だけ登録する必要があります。 – ImportanceOfBeingErnest
私は@ImportanceOfBeingErnestに同意します。 'figure.clear()'の直後や 'displayval()'の中で接続する前のように、プロットを消去するときにシグナル/スロットを切断する必要があります。 – bnaecker
@bnacker 'displayval()'でシグナル/イベントキューをクリアするのは、回避策としては良いアイデアです。私はそれをどうやって行うのか分かりますか?しかし、私はこれをしないで、問題を解決する理由は、キャンバス上に2つのアクションを登録しています。 –