I am trying to switch from MATLAB to python but now I have some issues that I cannot solve by myself. I did a GUI in pyqt designed with Qt designer (to analyze some neurons), all visualizations are done in a matplotlib widget for Qt (it is included in pythonxy) but now I need some tools like in MATLAB for interactive selections (not only on image but also on a plot) that work with matplotlib integrated in Qt GUI:
I found this http://matplotlib.org/users/event_handling.html please, don't tell me that I must implement the above tools by myself with this python module xD
And I found this http://www.pyqtgraph.org/ but it isn't integrated with matplotlib and the final render is not so nice like in matplotlib.
Is there a good interactive selection tools for pyqt? On Google, I cannot find anything useful but I cannot believe that there aren't good interactive tools for python... if so I will switch back to MATLAB.
Thanks for any help
OK, I have implemented by myself imline for matplotlib integrated in Qt GUI... now, imrect and so on are simple to implement. If someone needs imrect and so on, I will update the code. Below it is my code for 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With