2013-02-25 26 views
3

我想从MATLAB切换到Python,但现在我有一些我自己无法解决的问题。我在用Qt设计器设计的pyqt中做了一个GUI(用于分析一些神经元),所有的可视化都是在一个用于Qt的matplotlib小部件中完成的(它包含在pythonxy中),但现在我需要一些类似于MATLAB的工具来进行交互选择图像,而且还取决于图)与matplotlib的工作集成在Qt的GUI:像Python中的Python交互式选择工具

  • imline
  • impoly
  • imellipse
  • imfreehand
  • imrect(不PyQt的GUI imrect for python)工作;
  • ginput(我可以直接在myMatplotlibWidget.figure.ginput()上调用ginput,当我在matplotlib库的matplotlib \ blocking_input.py文件中注释self.fig.show()命令后)。

我发现这个http://matplotlib.org/users/event_handling.html请不要告诉我,我必须通过自己对这个Python模块的xD

落实上述工具和我发现这http://www.pyqtgraph.org/,但它不与matplotlib和集成最终的渲染在matplotlib中不太好。

pyqt是否有很好的互动选择工具?在谷歌上,我找不到任何有用的东西,但我不相信没有好的python交互工具...如果是的话,我将切换回MATLAB。

感谢所有帮助

+2

鉴于你使用Qt来制作你的GUI,使用Qt的工具来构建你所需要的。 (例如'QRubberBand'等)。对于matplotlib有这样的东西,但是如果你将它嵌入到Qt中,使用gui中性的matplotlib小部件没有任何意义。 – 2013-02-25 01:39:52

+0

我是Qt和python中的新成员,我仅在Qt中使用matplotlib小部件,因为它非常接近MATLAB绘图,直方图,干,imshow工具。无论如何,我会尝试自己编写pyqt中需要的交互式工具:) QRubberBand类对我来说似乎是一个很好的起点;有没有关于Qt类的其他建议来实现一些交互式工具(主要是画线,矩形,多边形等)? – opensw 2013-02-25 11:09:27

回答

2

OK,我已经通过自己实现imline为matplotlib集成在Qt的图形用户界面...现在,不正确等很容易实现。如果有人需要正确的等等,我会更新代码。下面是我的代码imline:

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 

import time 
import matplotlib as mpl 
import matplotlib.pyplot as plt 

import numpy as np 
import scipy.optimize as opt 


class Imline(QObject): 
    ''' 
    Plot interactive line 
    ''' 

    def __init__(self, plt, image = None, scale = 1, *args, **kwargs): 
     ''' 
     Initialize imline 
     ''' 
     super(Imline, self).__init__(None) 

     # set plot   
     self.__plt = plt 
     self.scale = scale   

     # initialize start and end points   
     self.startX = None 
     self.startY = None 
     self.endX = None 
     self.endY = None 

     # initialize line2d   
     self.__line2d = None 
     self.mask = None 

     # store information to generate mask 
     if(image is not None):   
      height, width = image.shape 

     else: 
      height = None 
      width = None    

     self.__width = width 
     self.__height = height 

     # set signals and slots   
     self.__c1 = self.__plt.figure.canvas.mpl_connect('button_press_event', self.__mousePressEvent) 
     self.__c2 = self.__plt.figure.canvas.mpl_connect('motion_notify_event', self.__mouseMoveEvent) 
     self.__c3 = self.__plt.figure.canvas.mpl_connect('button_release_event', self.__mouseReleaseEvent)  

     self.imlineEventFinished = SIGNAL('imlineEventFinished')   


    def __mousePressEvent(self, event): 
     ''' 
     Starting point 
     ''' 

     # get xy data   
     xdata = event.xdata 
     ydata = event.ydata 

     # check if mouse is outside the figure   
     if((xdata is None) | (ydata is None) | (self.startX is not None) | (self.startY is not None) | (self.endX is not None) | (self.endY is not None)): 
      return  

     # start point   
     self.startX = xdata 
     self.startY = ydata 


    def __mouseMoveEvent(self, event): 
     ''' 
     Draw interactive line 
     ''' 

     # get xy data   
     xdata = event.xdata 
     ydata = event.ydata 

     # check if mouse is outside the figure   
     if((xdata is None) | (ydata is None) | (self.startX is None) | (self.startY is None) | (self.endX is not None) | (self.endY is not None)): 
      return  

     # remove line   
     if(self.__line2d is not None): 
      self.__line2d[0].remove() 

     # set x, t 
     x = [self.startX, xdata] 
     y = [self.startY, ydata]   

     # plot line 
     self.__plt.axes.hold(True) 
     xlim = self.__plt.axes.get_xlim() 
     ylim = self.__plt.axes.get_ylim() 
     self.__line2d = self.__plt.axes.plot(x, y, color = [1, 0, 0]) 
     self.__plt.axes.set_xlim(xlim) 
     self.__plt.axes.set_ylim(ylim) 

     # update plot   
     self.__plt.draw() 
     self.__plt.show() 


    def __mouseReleaseEvent(self, event): 
     ''' 
     End point 
     '''  

     # get xy data   
     xdata = event.xdata 
     ydata = event.ydata 

     # check if mouse is outside the figure   
     if((xdata is None) | (ydata is None) | (self.endX is not None) | (self.endY is not None)): 
      return    

     # remove line   
     if(self.__line2d is not None): 
      self.__line2d[0].remove() 

     self.endX = xdata 
     self.endY = ydata 

     P = np.polyfit([self.startX, self.endX], [self.startY, self.endY],1) 
     self.__m = P[0] 
     self.__q = P[1] 

     # update plot   
     self.__plt.draw() 
     self.__plt.show() 

     # disconnect the vents   
     self.__plt.figure.canvas.mpl_disconnect(self.__c1) 
     self.__plt.figure.canvas.mpl_disconnect(self.__c2) 
     self.__plt.figure.canvas.mpl_disconnect(self.__c3) 

     # emit SIGNAL   
     self.emit(SIGNAL('imlineEventFinished')) 


    def createMask(self): 
     ''' 
     Create mask from painted line 
     ''' 

     # check height width   
     if((self.__height is None) | (self.__width is None)): 
      return None 

     # initialize mask   
     mask = np.zeros((self.__height, self.__width))   

     # get m q   
     m = self.__m 
     q = self.__q   

     print m, q 

     # get points   
     startX = np.int(self.startX) 
     startY = np.int(self.startY) 
     endX = np.int(self.endX) 
     endY = np.int(self.endY) 

     # ensure startX < endX 
     tempStartX = startX 
     if(startX > endX): 
      startX = endX 
      endX = tempStartX 

     # ensure startY < endY 
     tempStartY = startY 
     if(startY > endY): 
      startY = endY 
      endY = tempStartY 

     # save points 
     self.startX = startX 
     self.endX = endX 
     self.startY = startY 
     self.endY = endY 

     # intialize data   
     xData = np.arange(startX, endX) 
     yData = np.arange(startY, endY) 

     # scan on x   
     for x in xData: 
      row = round(m*x + q) 
      if(row < startY): 
       row = startY 
      if(row > endY): 
       row = endY 
      mask[row, x] = 1 

     # scan on y 
     for y in yData: 
      col = round((y - q)/m) 
      if(col < startX): 
       col = startX 
      if(col > endX): 
       col = endX 
      mask[y, col] = 1 

     # get boolean mask   
     mask = mask == 1   

     # return boolean mask 
     return mask 
+1

我认为这是互联网上用Python实现类似imline行为的最佳资源。您能否详细说明如何使用它(提供MWE)? – Ralph 2014-05-11 14:37:55

+0

MWE,也许指针将它扩展到'impoly',请! – 2016-11-16 20:10:53