2015-11-12 54 views
3

我正試圖通過允許用戶鼠標單擊位置來使用'ginput'來測量matplotlib圖中的距離。我可以在matplotlib圖中獨立執行此操作,但在嘗試將圖設置到matplotlib畫布上並將其嵌入到PyQt4小部件中時遇到了問題。下面是我的代碼,其中大部分來自matplotlib示例。我的解決方案是單擊一組位置,並將(x,y)座標傳遞給'dist_calc'函數以獲取距離。在嵌入式matplotlib中使用ginput PyQt4中的數字

import sys 
from PyQt4 import QtGui 
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas 
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar 
import matplotlib.pyplot as plt 
from matplotlib.figure import Figure 
import random 
import numpy as np 

class Window(QtGui.QWidget): 
def __init__(self, parent=None): 
    super(Window, self).__init__(parent) 
    self.fig = Figure((6.5, 5.0), tight_layout=True) 
    self.ax = self.fig.add_subplot(111) 
    self.canvas = FigureCanvas(self.fig) 
    self.toolbar = NavigationToolbar(self.canvas, self) 

    self.button = QtGui.QPushButton('Plot') 
    self.button.clicked.connect(self.plot) 

    self.ndist = QtGui.QPushButton('Measure') 
    self.ndist.clicked.connect(self.draw_line) 

    self.toolbar.addWidget(self.button) 
    self.toolbar.addWidget(self.ndist) 
    self.fig.tight_layout() 
    layout = QtGui.QVBoxLayout() 
    layout.addWidget(self.toolbar) 
    layout.addWidget(self.canvas) 
    self.setLayout(layout) 

def plot(self): 
    data = [random.random() for i in range(20)] 
    self.ax.hold(False)       
    self.ax.plot(data, '*-')      
    self.canvas.draw()      

def draw_line(self): 
    self.xy = plt.ginput(0) 
    x = [p[0] for p in self.xy] 
    y = [p[1] for p in self.xy] 
    self.ax.plot(x,y) 
    self.ax.figure.canvas.draw() 
    self.get_dist(x, y) 

def get_dist(self, xpts, ypts): 
    npts = len(xpts) 
    distArr = [] 
    for i in range(npts-1): 
     apt = [xpts[i], ypts[i]] 
     bpt = [xpts[i+1], ypts[i+1]] 
     dist =self.calc_dist(apt,bpt) 
     distArr.append(dist) 

    tdist = np.sum(distArr) 
    print(tdist) 

def calc_dist(self,apt, bpt): 
    apt = np.asarray(apt) 
    dist = np.sum((apt - bpt)**2) 
    dist = np.sqrt(dist) 
    return dist 

if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    main = Window() 
    main.show() 
    sys.exit(app.exec_()) 

回答

0

根據this comment通過的鉛Matplotlib開發者,您必須進口pyplot當你在Qt中嵌入Matplotlib之一。 Pyplot設置了自己的gui,mainloop和canvas,這會干擾Qt事件循環。

更改線路self.xy = plt.ginput(0)self.xy = self.fig.ginput(0)沒有幫助,但給了一個精闢的錯誤:

AttributeError: 'FigureCanvasQTAgg' object has no attribute 'manager' 
Figure.show works only for figures managed by pyplot, normally created by pyplot.figure(). 

總之,我不認爲這是可能的。 ginput是一個阻塞函數,似乎只能用於Matplotlib事件循環。恐怕你將不得不使用Matplotlib mouse events來構建你想要的功能,而在嵌入到PyQt中時,會做。只要確保不要使用pyplot!

編輯:我只記得,也許LassoSelector是你所需要的。

相關問題