class PlotWidget(QtGui.QWidget): """This class represents the plot view for plotting graphs. :returns: an instance of *PlotWidget* """ def __init__(self,): QtGui.QWidget.__init__(self) self.figure = Figure(facecolor=(1, 1, 1), tight_layout=True) self.ax = self.figure.add_subplot(111) # Canvas self.canvas = FigureCanvas(self.figure) self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) self.canvas.updateGeometry() # Navigation self.navi_toolbar = NavigationToolbar(self.canvas, self) self.navi_toolbar.setOrientation(QtCore.Qt.Vertical) # Fixed with, otherwise navigation bar resize arbitrary self.navi_toolbar.setFixedWidth(40) self.vbl = QtGui.QHBoxLayout() self.vbl.addWidget(self.navi_toolbar) self.vbl.addWidget(self.canvas) self.setLayout(self.vbl) def plot(self, x_data_1, y_data_1, x_data_2, y_data_2): """Plot given data on *PlotWidget*. :param x_data_1: X-axis data for plot 1 :type x_data_1: array_like :param y_data_1: Y-axis data for plot 1 :type y_data_1: array_like :param x_data_2: X-axis data for plot 2 :type x_data_2: array_like :param y_data_2: Y-axis data for plot 2 :type y_data_2: array_like """ self.ax.clear() self.ax.grid(True) self.ax.plot(x_data_1, y_data_1, 'b^', label='Input Data') self.ax.plot(x_data_2, y_data_2, 'b-', label='Fitted Data') self.ax.legend() self.canvas.draw()
class PlotWidget(QtGui.QWidget): """This class represents the plot view for plotting graphs. :returns: an instance of *PlotWidget* """ def __init__(self): QtGui.QWidget.__init__(self) self.figure = Figure(facecolor=(1, 1, 1), tight_layout=True) self.ax = self.figure.add_subplot(111) # Canvas self.canvas = FigureCanvas(self.figure) self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) self.canvas.updateGeometry() # Navigation self.navi_toolbar = NavigationToolbar(self.canvas, self) self.navi_toolbar.setOrientation(QtCore.Qt.Vertical) # Fixed with, otherwise navigation bar resize arbitrary self.navi_toolbar.setFixedWidth(40) self.vbl = QtGui.QHBoxLayout() self.vbl.addWidget(self.navi_toolbar) self.vbl.addWidget(self.canvas) self.setLayout(self.vbl) def plot(self, x_data_1, y_data_1, x_data_2, y_data_2): """Plot given data on *PlotWidget*. :param x_data_1: X-axis data for plot 1 :type x_data_1: array_like :param y_data_1: Y-axis data for plot 1 :type y_data_1: array_like :param x_data_2: X-axis data for plot 2 :type x_data_2: array_like :param y_data_2: Y-axis data for plot 2 :type y_data_2: array_like """ self.ax.clear() self.ax.grid(True) self.ax.plot(x_data_1, y_data_1, 'b^', label='Input Data') self.ax.plot(x_data_2, y_data_2, 'b-', label='Fitted Data') self.ax.legend() self.canvas.draw()
def init_plots(self): """ Initialize plots used in plugin """ self.plot_dock = QtGui.QDockWidget('TSTools Plots', self.iface.mainWindow()) self.plot_dock.setObjectName('TSTools Plots') settings.plot_dirty = [] for plot in plots.plots: self.plots.append(plot(self.iface)) settings.plot_dirty.append(False) self.plot_tabs = QtGui.QTabWidget(self.plot_dock) @QtCore.pyqtSlot(int) def tab_changed(idx): """ Updates current tab index & re-plots if needed """ settings.plot_current = idx if settings.plot_dirty[idx]: self.plots[idx].plot() settings.plot_dirty[idx] = False self.plot_tabs.currentChanged.connect(tab_changed) for plot in self.plots: widget = QtGui.QWidget() layout = QtGui.QHBoxLayout() nav = NavigationToolbar(plot, widget, coordinates=False) nav.setOrientation(QtCore.Qt.Vertical) nav.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) plot.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) layout.addWidget(nav) layout.addWidget(plot) widget.setLayout(layout) self.plot_tabs.addTab(widget, plot.__str__()) self.plot_dock.setWidget(self.plot_tabs) self.iface.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.plot_dock)
def init_plots(self): """ Initialize plots used in plugin """ self.plot_dock = QtGui.QDockWidget('TSTools Plots', self.iface.mainWindow()) self.plot_dock.setObjectName('TSTools Plots') settings.plot_dirty = [] for plot in plots.plots: self.plots.append(plot(self.iface)) settings.plot_dirty.append(False) self.plot_tabs = QtGui.QTabWidget(self.plot_dock) @QtCore.pyqtSlot(int) def tab_changed(idx): """ Updates current tab index & re-plots if needed """ settings.plot_current = idx if settings.plot_dirty[idx]: self.plots[idx].plot() settings.plot_dirty[idx] = False self.plot_tabs.currentChanged.connect(tab_changed) for plot in self.plots: widget = QtGui.QWidget() layout = QtGui.QHBoxLayout() nav = NavigationToolbar(plot, widget, coordinates=False) nav.setOrientation(QtCore.Qt.Vertical) nav.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) plot.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) layout.addWidget(nav) layout.addWidget(plot) widget.setLayout(layout) self.plot_tabs.addTab(widget, plot.__str__()) self.plot_dock.setWidget(self.plot_tabs) self.iface.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.plot_dock)
class MPL_Widget(QtGui.QWidget): def __init__(self, parent = None, enableAutoScale = False, enableCSV = False, enableEdit = False, doublePlot = False, layoutDir = 'h'): QtGui.QWidget.__init__(self, parent) if doublePlot: self.canvas = DoubleMyMplCanvas() else: self.canvas = MyMplCanvas() self.toolbar = NavigationToolbar(self.canvas, self.canvas) self.iconSize = QtCore.QSize(15,15) self.toolbar.setIconSize(self.iconSize) self.installEventFilter(EventFilter(self)) if layoutDir == 'v': self.toolbar.setOrientation(QtCore.Qt.Vertical) self.layout = QtGui.QHBoxLayout() elif layoutDir == 'h': self.layout = QtGui.QVBoxLayout() # self.layout.addWidget(self.canvas) # self.layout.addWidget(self.toolbar) self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas) self.setLayout(self.layout) ###############ZOOM CONTROLS ################ #This function has been disabled because of the special autoscaling requried for a custom program #FIX THIS if enableAutoScale: print "Enable AutoScale" #self.enableAutoScale() self.span = SpanSelector(self.canvas.ax, self.onselect, 'horizontal', minspan =0.01, useblit=True, rectprops=dict(alpha=0.5, facecolor='#C6DEFF') ) self.hZoom = False self.span.visible = False self.localYMax = 0 self.canvas.mpl_connect('button_press_event', self.onclick) ###########SAVING FIGURE TO CLIPBOARD########## self.cb = None #will be used for the clipboard self.tempPath = getHomeDir() self.tempPath = os.path.join(self.tempPath,'tempMPL.png') # self.mpl2ClipAction = QtGui.QAction("Save to Clipboard", self) # self.mpl2ClipAction.setShortcut("Ctrl+C") # self.addAction(self.mpl2ClipAction) # QtCore.QObject.connect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) if enableEdit: self.enableEdit() self.lineDict = None self.addLegend = False #######SAVING FIGURE DATA############################ if enableCSV: self.enableCSV() ########### HELPER FUNCTIONS ######################### # def focusOutEvent(self, event): # print "Focus Out" def focusEvent(self, event): self.enableAutoScale() self.enableZoom() self.enableClip() self.enableCSV() #print "Focus In %s"%self.canvas.plotTitle def lossFocusEvent(self, event): self.disableAutoScale() self.disableZoom() self.disableClip() self.disableCSV() #print "Focus Out %s"%self.canvas.plotTitle def enableClip(self): self.mpl2ClipAction = QtGui.QAction("Save to Clipboard", self) self.mpl2ClipAction.setShortcut("Ctrl+C") self.addAction(self.mpl2ClipAction) QtCore.QObject.connect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) def disableClip(self): QtCore.QObject.disconnect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) self.removeAction(self.mpl2ClipAction) def enableEdit(self): self.editAction = QtGui.QAction("Edit Line Properties", self) self.editAction.setShortcut("Ctrl+Alt+E") self.addAction(self.editAction) QtCore.QObject.connect(self.editAction,QtCore.SIGNAL("triggered()"), self.editPlotProperties) def disableEdit(self): if self.editAction: QtCore.QObject.disconnect(self.editAction,QtCore.SIGNAL("triggered()"), self.editPlotProperties) self.removeAction(self.editAction) def enableZoom(self): self.Zoom = QtGui.QAction("Zoom", self) self.Zoom.setShortcut("Ctrl+Z") self.addAction(self.Zoom) QtCore.QObject.connect(self.Zoom,QtCore.SIGNAL("triggered()"), self.ZoomToggle) def disableZoom(self): if self.Zoom != None: QtCore.QObject.disconnect(self.Zoom,QtCore.SIGNAL("triggered()"), self.ZoomToggle) self.removeAction(self.Zoom) def disableAutoScale(self): if self.actionAutoScale != None: QtCore.QObject.disconnect(self.actionAutoScale,QtCore.SIGNAL("triggered()"), self.autoscale_plot) self.removeAction(self.actionAutoScale) def enableAutoScale(self): self.actionAutoScale = QtGui.QAction("AutoScale", self)#self.MainWindow) self.actionAutoScale.setShortcut("Ctrl+A") self.addAction(self.actionAutoScale) QtCore.QObject.connect(self.actionAutoScale,QtCore.SIGNAL("triggered()"), self.autoscale_plot) def enableCSV(self): self.saveCSVAction = QtGui.QAction("Save to CSV", self) self.saveCSVAction.setShortcut("Ctrl+Alt+S") self.addAction(self.saveCSVAction) QtCore.QObject.connect(self.saveCSVAction,QtCore.SIGNAL("triggered()"), self.save2CSV) def disableCSV(self): QtCore.QObject.disconnect(self.saveCSVAction,QtCore.SIGNAL("triggered()"), self.save2CSV) self.removeAction(self.saveCSVAction) def setLineDict(self): self.lineDict = {} lineList = self.canvas.ax.get_lines() if lineList > 0: for line in lineList: self.lineDict[line.get_label()]=line def editPlotProperties(self): print "Edit Enabled" self.setLineDict() # if len(self.lineDict) > 0: curAx = self.canvas.ax if POD(self.lineDict, curAx = curAx, parent = self).exec_(): if self.addLegend: curAx.legend(borderaxespad = 0.03, axespad=0.25) self.canvas.format_labels() self.canvas.draw() else: print "Cancel" def ZoomToggle(self): #self.toolbar.zoom() #this implements the classic zoom if self.hZoom: self.hZoom = False self.span.visible = False else: self.hZoom = True self.span.visible = True def autoscale_plot(self): #self.toolbar.home() #implements the classic return to home self.canvas.ax.autoscale_view(tight = False, scalex=True, scaley=True) self.canvas.draw() self.emit(QtCore.SIGNAL("autoScaleAxis(bool)"),True) def onclick(self, event): #sets up the maximum Y level to be displayed after the zoom. #if not set then it maxes to the largest point in the data #not necessarily the local max if event.ydata != None: self.localYMax = int(event.ydata) def onselect(self, xmin, xmax): #print xmin, xmax if self.hZoom: self.canvas.ax.set_ylim(ymax = self.localYMax) self.canvas.ax.set_xlim(xmin, xmax) self.canvas.draw() def save2CSV(self): path = self.SFDialog() if path != None: try: lines = self.canvas.ax.get_lines() data2write = [] for line in lines: data2write.append(line.get_data()[0]) data2write.append(line.get_data()[1]) print data2write data2write = N.array(data2write) data2write.dtype = N.float32 N.savetxt(str(path), N.transpose(data2write), delimiter = ',', fmt='%.4f') except: try: #this is for the case where the data may not be in float format? N.savetxt(str(path), N.transpose(data2write), delimiter = ',') except: print 'Error saving figure data' errorMsg = "Sorry: %s\n\n:%s\n"%(sys.exc_type, sys.exc_value) print errorMsg def SFDialog(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Select File to Save", "", "csv Files (*.csv)") if not fileName.isEmpty(): print fileName return fileName else: return None def mpl2Clip(self): try: self.canvas.fig.savefig(self.tempPath) tempImg = QtGui.QImage(self.tempPath) self.cb = QtGui.QApplication.clipboard() self.cb.setImage(tempImg) except: print 'Error copying figure to clipboard' errorMsg = "Sorry: %s\n\n:%s\n"%(sys.exc_type, sys.exc_value) print errorMsg
class MPL_Widget(QtGui.QWidget): def __init__(self, parent = None, enableAutoScale = False, enableCSV = False, enableEdit = False, doublePlot = False, layoutDir = 'h'): QtGui.QWidget.__init__(self, parent) if doublePlot: self.canvas = DoubleMyMplCanvas() else: self.canvas = MyMplCanvas() self.toolbar = NavigationToolbar(self.canvas, self.canvas) self.iconSize = QtCore.QSize(15,15) self.toolbar.setIconSize(self.iconSize) self.installEventFilter(EventFilter(self)) if layoutDir == 'v': self.toolbar.setOrientation(QtCore.Qt.Vertical) self.layout = QtGui.QHBoxLayout() elif layoutDir == 'h': self.layout = QtGui.QVBoxLayout() # self.layout.addWidget(self.canvas) # self.layout.addWidget(self.toolbar) self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas) self.setLayout(self.layout) ###############ZOOM CONTROLS ################ #This function has been disabled because of the special autoscaling requried for a custom program #FIX THIS if enableAutoScale: print "Enable AutoScale" #self.enableAutoScale() self.span = SpanSelector(self.canvas.ax, self.onselect, 'horizontal', minspan =0.01, useblit=True, rectprops=dict(alpha=0.5, facecolor='#C6DEFF') ) self.hZoom = False self.span.visible = False self.localYMax = 0 self.canvas.mpl_connect('button_press_event', self.onclick) ###########SAVING FIGURE TO CLIPBOARD########## self.cb = None #will be used for the clipboard self.tempPath = getHomeDir() self.tempPath = os.path.join(self.tempPath,'tempMPL.png') # self.mpl2ClipAction = QtGui.QAction("Save to Clipboard", self) # self.mpl2ClipAction.setShortcut("Ctrl+C") # self.addAction(self.mpl2ClipAction) # QtCore.QObject.connect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) if enableEdit: self.enableEdit() self.lineDict = None self.addLegend = False #######SAVING FIGURE DATA############################ if enableCSV: self.enableCSV() ########### HELPER FUNCTIONS ######################### # def focusOutEvent(self, event): # print "Focus Out" def focusEvent(self, event): self.enableAutoScale() self.enableZoom() self.enableClip() self.enableCSV() #print "Focus In %s"%self.canvas.plotTitle def lossFocusEvent(self, event): self.disableAutoScale() self.disableZoom() self.disableClip() self.disableCSV() #print "Focus Out %s"%self.canvas.plotTitle def enableClip(self): self.mpl2ClipAction = QtGui.QAction("Save to Clipboard", self) self.mpl2ClipAction.setShortcut("Ctrl+C") self.addAction(self.mpl2ClipAction) QtCore.QObject.connect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) def disableClip(self): QtCore.QObject.disconnect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) self.removeAction(self.mpl2ClipAction) def enableEdit(self): self.editAction = QtGui.QAction("Edit Line Properties", self) self.editAction.setShortcut("Ctrl+Alt+E") self.addAction(self.editAction) QtCore.QObject.connect(self.editAction,QtCore.SIGNAL("triggered()"), self.editPlotProperties) def disableEdit(self): if self.editAction: QtCore.QObject.disconnect(self.editAction,QtCore.SIGNAL("triggered()"), self.editPlotProperties) self.removeAction(self.editAction) def enableZoom(self): self.Zoom = QtGui.QAction("Zoom", self) self.Zoom.setShortcut("Ctrl+Z") self.addAction(self.Zoom) QtCore.QObject.connect(self.Zoom,QtCore.SIGNAL("triggered()"), self.ZoomToggle) def disableZoom(self): if self.Zoom != None: QtCore.QObject.disconnect(self.Zoom,QtCore.SIGNAL("triggered()"), self.ZoomToggle) self.removeAction(self.Zoom) def disableAutoScale(self): if self.actionAutoScale != None: QtCore.QObject.disconnect(self.actionAutoScale,QtCore.SIGNAL("triggered()"), self.autoscale_plot) self.removeAction(self.actionAutoScale) def enableAutoScale(self): self.actionAutoScale = QtGui.QAction("AutoScale", self)#self.MainWindow) self.actionAutoScale.setShortcut("Ctrl+A") self.addAction(self.actionAutoScale) QtCore.QObject.connect(self.actionAutoScale,QtCore.SIGNAL("triggered()"), self.autoscale_plot) def enableCSV(self): self.saveCSVAction = QtGui.QAction("Save to CSV", self) self.saveCSVAction.setShortcut("Ctrl+Alt+S") self.addAction(self.saveCSVAction) QtCore.QObject.connect(self.saveCSVAction,QtCore.SIGNAL("triggered()"), self.save2CSV) def disableCSV(self): QtCore.QObject.disconnect(self.saveCSVAction,QtCore.SIGNAL("triggered()"), self.save2CSV) self.removeAction(self.saveCSVAction) def setLineDict(self): self.lineDict = {} lineList = self.canvas.ax.get_lines() if lineList > 0: for line in lineList: self.lineDict[line.get_label()]=line def editPlotProperties(self): print "Edit Enabled" self.setLineDict() # if len(self.lineDict) > 0: curAx = self.canvas.ax if POD(self.lineDict, curAx = curAx, parent = self).exec_(): if self.addLegend: curAx.legend(borderaxespad = 0.03, axespad=0.25) self.canvas.format_labels() self.canvas.draw() else: print "Cancel" def ZoomToggle(self): #self.toolbar.zoom() #this implements the classic zoom if self.hZoom: self.hZoom = False self.span.visible = False else: self.hZoom = True self.span.visible = True def autoscale_plot(self): #self.toolbar.home() #implements the classic return to home self.canvas.ax.autoscale_view(tight = False, scalex=True, scaley=True) self.canvas.draw() self.emit(QtCore.SIGNAL("autoScaleAxis(bool)"),True) def onclick(self, event): #sets up the maximum Y level to be displayed after the zoom. #if not set then it maxes to the largest point in the data #not necessarily the local max if event.ydata != None: self.localYMax = int(event.ydata) def onselect(self, xmin, xmax): #print xmin, xmax if self.hZoom: self.canvas.ax.set_ylim(ymax = self.localYMax) self.canvas.ax.set_xlim(xmin, xmax) self.canvas.draw() def save2CSV(self): path = self.SFDialog() if path != None: try: lines = self.canvas.ax.get_lines() data2write = [] for line in lines: data2write.append(line.get_data()[0]) data2write.append(line.get_data()[1]) print data2write data2write = N.array(data2write) data2write.dtype = N.float32 N.savetxt(str(path), N.transpose(data2write), delimiter = ',', fmt='%.4f') except: try: #this is for the case where the data may not be in float format? N.savetxt(str(path), N.transpose(data2write), delimiter = ',') except: print 'Error saving figure data' errorMsg = "Sorry: %s\n\n:%s\n"%(sys.exc_type, sys.exc_value) print errorMsg def SFDialog(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Select File to Save", "", "csv Files (*.csv)") if not fileName.isEmpty(): print fileName return fileName else: return None def mpl2Clip(self): try: self.canvas.fig.savefig(self.tempPath) tempImg = QtGui.QImage(self.tempPath) self.cb = QtGui.QApplication.clipboard() self.cb.setImage(tempImg) except: print 'Error copying figure to clipboard' errorMsg = "Sorry: %s\n\n:%s\n"%(sys.exc_type, sys.exc_value) print errorMsg
class MPL_Widget(QtGui.QWidget): def __init__(self, parent=None, enableAutoScale=True, enableCSV=False, enableEdit=True, doublePlot=False, layoutDir='h'): QtGui.QWidget.__init__(self, parent) if doublePlot: self.canvas = DoubleMyMplCanvas() else: self.canvas = MyMplCanvas() self.toolbar = NavigationToolbar(self.canvas, self.canvas) # self.toolbar.hide() self.installEventFilter(EventFilter(self)) if layoutDir == 'v': self.toolbar.setOrientation(QtCore.Qt.Vertical) self.layout = QtGui.QHBoxLayout() elif layoutDir == 'h': self.layout = QtGui.QVBoxLayout() # self.layout.addWidget(self.canvas) # self.layout.addWidget(self.toolbar) self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas) self.setLayout(self.layout) ########################## self.dataLabels = None ###########SAVING FIGURE TO CLIPBOARD########## self.cb = None #will be used for the clipboard self.tempPath = getHomeDir() self.tempPath = os.path.join(self.tempPath, 'tempMPL.png') if enableEdit: self.enableEdit() self.lineDict = None self.addLegend = False self.x = None #used for picker self.y = None #######SAVING FIGURE DATA############################ if enableCSV: self.enableCSV() ########### HELPER FUNCTIONS ######################### self.clearPlotAction = QtGui.QAction("Clear Plot", self) self.addAction(self.clearPlotAction) QtCore.QObject.connect(self, QtCore.SIGNAL("triggered()"), self.clearPlot) # def focusOutEvent(self, event): # print "Focus Out" def clearPlot(self): print "Clear Plot" self.canvas.ax.cla() self.canvas.format_labels() self.canvas.draw() # def __initContextMenus__(self): # self.clearPlotAction = QtGui.QAction("Clear Plot", self) # self.addAction(self.clearPlotAction) # QtCore.QObject.connect(self, QtCore.SIGNAL("triggered()"), self.clearPlot) # # self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) # self.connect(self, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.plotTabContext) # def plotTabContext(self, point): # '''Create a menu for mainTabWidget''' # plotCT_menu = QtGui.QMenu("Menu", self) # plotCT_menu.addAction(self.Zoom) # plotCT_menu.addAction(self.actionAutoScale) # plotCT_menu.addSeparator() # plotCT_menu.addAction(self.clearPlotAction) # plotCT_menu.exec_(self.mapToGlobal(point)) def focusEvent(self, event): self.enableAutoScale() self.enableZoom() self.enableClip() # self.enableCSV() #print "Focus In %s"%self.canvas.plotTitle def lossFocusEvent(self, event): self.disableAutoScale() self.disableZoom() self.disableClip() # self.disableCSV() #print "Focus Out %s"%self.canvas.plotTitle def enableClip(self): self.mpl2ClipAction = QtGui.QAction("Save to Clipboard", self) self.mpl2ClipAction.setShortcut("Ctrl+C") self.addAction(self.mpl2ClipAction) QtCore.QObject.connect(self.mpl2ClipAction, QtCore.SIGNAL("triggered()"), self.mpl2Clip) def disableClip(self): QtCore.QObject.disconnect(self.mpl2ClipAction, QtCore.SIGNAL("triggered()"), self.mpl2Clip) self.removeAction(self.mpl2ClipAction) def enableEdit(self): self.editAction = QtGui.QAction("Edit Line Properties", self) self.editAction.setShortcut("Ctrl+Alt+E") self.addAction(self.editAction) QtCore.QObject.connect(self.editAction, QtCore.SIGNAL("triggered()"), self.editPlotProperties) def disableEdit(self): if self.editAction: QtCore.QObject.disconnect(self.editAction, QtCore.SIGNAL("triggered()"), self.editPlotProperties) self.removeAction(self.editAction) def enableZoom(self): self.Zoom = QtGui.QAction("Zoom", self) self.Zoom.setShortcut("Ctrl+Z") self.addAction(self.Zoom) QtCore.QObject.connect(self.Zoom, QtCore.SIGNAL("triggered()"), self.ZoomToggle) def disableZoom(self): if self.Zoom != None: QtCore.QObject.disconnect(self.Zoom, QtCore.SIGNAL("triggered()"), self.ZoomToggle) self.removeAction(self.Zoom) def disableAutoScale(self): if self.actionAutoScale != None: QtCore.QObject.disconnect(self.actionAutoScale, QtCore.SIGNAL("triggered()"), self.autoscale_plot) self.removeAction(self.actionAutoScale) def enableAutoScale(self): self.actionAutoScale = QtGui.QAction("AutoScale", self) #self.MainWindow) self.actionAutoScale.setShortcut("Ctrl+A") self.addAction(self.actionAutoScale) QtCore.QObject.connect(self.actionAutoScale, QtCore.SIGNAL("triggered()"), self.autoscale_plot) def enableCSV(self): self.saveCSVAction = QtGui.QAction("Save to CSV", self) self.saveCSVAction.setShortcut("Ctrl+Alt+S") self.addAction(self.saveCSVAction) QtCore.QObject.connect(self.saveCSVAction, QtCore.SIGNAL("triggered()"), self.save2CSV) def disableCSV(self): QtCore.QObject.disconnect(self.saveCSVAction, QtCore.SIGNAL("triggered()"), self.save2CSV) self.removeAction(self.saveCSVAction) def setLineDict(self): self.lineDict = {} lineList = self.canvas.ax.get_lines() if lineList > 0: for line in lineList: self.lineDict[line.get_label()] = line def editPlotProperties(self): print "Edit Enabled" self.setLineDict() # if len(self.lineDict) > 0: curAx = self.canvas.ax if POD(self.lineDict, curAx=curAx, parent=self).exec_(): if self.addLegend: curAx.legend(borderaxespad=0.03, axespad=0.25) self.canvas.format_labels() self.canvas.draw() else: print "Cancel" def ZoomToggle(self): self.toolbar.zoom() #this implements the classic zoom # if self.hZoom: # self.hZoom = False # self.span.visible = False # else: # self.hZoom = True # self.span.visible = True def autoscale_plot(self): self.toolbar.home() #implements the classic return to home # self.canvas.ax.autoscale_view(tight = False, scalex=True, scaley=True) # self.canvas.draw() # self.emit(QtCore.SIGNAL("autoScaleAxis(bool)"),True) # def onclick(self, event): # #sets up the maximum Y level to be displayed after the zoom. # #if not set then it maxes to the largest point in the data # #not necessarily the local max # if event.ydata != None: # self.localYMax = int(event.ydata) # # def onselect(self, xmin, xmax): # #print xmin, xmax # if self.hZoom: # self.canvas.ax.set_ylim(ymax = self.localYMax) # self.canvas.ax.set_xlim(xmin, xmax) # self.canvas.draw() def save2CSV(self): path = self.SFDialog() if path != None: try: lines = self.canvas.ax.get_lines() data2write = [] for line in lines: data2write.append(line.get_data()[0]) data2write.append(line.get_data()[1]) print data2write data2write = N.array(data2write) data2write.dtype = N.float32 N.savetxt(str(path), N.transpose(data2write), delimiter=',', fmt='%.4f') except: try: #this is for the case where the data may not be in float format? N.savetxt(str(path), N.transpose(data2write), delimiter=',') except: print 'Error saving figure data' errorMsg = "Sorry: %s\n\n:%s\n" % (sys.exc_type, sys.exc_value) print errorMsg def SFDialog(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Select File to Save", "", "csv Files (*.csv)") if not fileName.isEmpty(): print fileName return fileName else: return None def removePicker(self): try: self.handleA.remove() except: print "" def setData(self, x, y): if x != None: self.x = x if y != None: self.y = y def addPicker(self): '''Sets up the plot variables used for interaction''' self.handleA, = self.canvas.ax.plot([0], [0], 'o',\ ms=8, alpha=.5, color='yellow', visible=True, label = '_nolegend_') self.is_hZoom = False self.canvas.mpl_connect('pick_event', self.OnPickPlot) def OnPickPlot(self, event): self.pickIndex = event.ind[0] try: self.textHandle.remove() except: pass self.curText = event.artist.get_label() if self.x != None and self.y != None: #I'd rather do the following ALWAYS but it seems difficult to do in terms of keeping track of which arrays were plotted when multiple plots are present paramVal = N.take(self.y, [self.pickIndex]) self.handleA.set_data(N.take(self.x, [self.pickIndex]), [paramVal]) else: paramVal = event.mouseevent.ydata self.handleA.set_data([event.mouseevent.xdata], [paramVal]) showText = '%s: %s' % (self.dataLabels[self.pickIndex], paramVal[0]) # showText = '%s: %s'%self.dataLabels[self.pickIndex] self.textHandle = self.canvas.ax.text(0.03, 0.95, showText, fontsize=9,\ bbox=dict(facecolor='yellow', alpha=0.1),\ transform=self.canvas.ax.transAxes, va='top') self.handleA.set_visible(True) self.canvas.draw() def mpl2Clip(self): try: self.canvas.fig.savefig(self.tempPath) tempImg = QtGui.QImage(self.tempPath) self.cb = QtGui.QApplication.clipboard() self.cb.setImage(tempImg) except: print 'Error copying figure to clipboard' errorMsg = "Sorry: %s\n\n:%s\n" % (sys.exc_type, sys.exc_value) print errorMsg
class MPL_Widget(QtGui.QWidget): def __init__(self, parent = None, enableAutoScale = True, enableCSV = False, enableEdit = True, doublePlot = False, layoutDir = 'h'): QtGui.QWidget.__init__(self, parent) if doublePlot: self.canvas = DoubleMyMplCanvas() else: self.canvas = MyMplCanvas() self.toolbar = NavigationToolbar(self.canvas, self.canvas) # self.toolbar.hide() self.installEventFilter(EventFilter(self)) if layoutDir == 'v': self.toolbar.setOrientation(QtCore.Qt.Vertical) self.layout = QtGui.QHBoxLayout() elif layoutDir == 'h': self.layout = QtGui.QVBoxLayout() # self.layout.addWidget(self.canvas) # self.layout.addWidget(self.toolbar) self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas) self.setLayout(self.layout) ########################## self.dataLabels = None ###########SAVING FIGURE TO CLIPBOARD########## self.cb = None #will be used for the clipboard self.tempPath = getHomeDir() self.tempPath = os.path.join(self.tempPath,'tempMPL.png') if enableEdit: self.enableEdit() self.lineDict = None self.addLegend = False self.x = None#used for picker self.y = None #######SAVING FIGURE DATA############################ if enableCSV: self.enableCSV() ########### HELPER FUNCTIONS ######################### self.clearPlotAction = QtGui.QAction("Clear Plot", self) self.addAction(self.clearPlotAction) QtCore.QObject.connect(self, QtCore.SIGNAL("triggered()"), self.clearPlot) # def focusOutEvent(self, event): # print "Focus Out" def clearPlot(self): print "Clear Plot" self.canvas.ax.cla() self.canvas.format_labels() self.canvas.draw() # def __initContextMenus__(self): # self.clearPlotAction = QtGui.QAction("Clear Plot", self) # self.addAction(self.clearPlotAction) # QtCore.QObject.connect(self, QtCore.SIGNAL("triggered()"), self.clearPlot) # # self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) # self.connect(self, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.plotTabContext) # def plotTabContext(self, point): # '''Create a menu for mainTabWidget''' # plotCT_menu = QtGui.QMenu("Menu", self) # plotCT_menu.addAction(self.Zoom) # plotCT_menu.addAction(self.actionAutoScale) # plotCT_menu.addSeparator() # plotCT_menu.addAction(self.clearPlotAction) # plotCT_menu.exec_(self.mapToGlobal(point)) def focusEvent(self, event): self.enableAutoScale() self.enableZoom() self.enableClip() # self.enableCSV() #print "Focus In %s"%self.canvas.plotTitle def lossFocusEvent(self, event): self.disableAutoScale() self.disableZoom() self.disableClip() # self.disableCSV() #print "Focus Out %s"%self.canvas.plotTitle def enableClip(self): self.mpl2ClipAction = QtGui.QAction("Save to Clipboard", self) self.mpl2ClipAction.setShortcut("Ctrl+C") self.addAction(self.mpl2ClipAction) QtCore.QObject.connect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) def disableClip(self): QtCore.QObject.disconnect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) self.removeAction(self.mpl2ClipAction) def enableEdit(self): self.editAction = QtGui.QAction("Edit Line Properties", self) self.editAction.setShortcut("Ctrl+Alt+E") self.addAction(self.editAction) QtCore.QObject.connect(self.editAction,QtCore.SIGNAL("triggered()"), self.editPlotProperties) def disableEdit(self): if self.editAction: QtCore.QObject.disconnect(self.editAction,QtCore.SIGNAL("triggered()"), self.editPlotProperties) self.removeAction(self.editAction) def enableZoom(self): self.Zoom = QtGui.QAction("Zoom", self) self.Zoom.setShortcut("Ctrl+Z") self.addAction(self.Zoom) QtCore.QObject.connect(self.Zoom, QtCore.SIGNAL("triggered()"), self.ZoomToggle) def disableZoom(self): if self.Zoom != None: QtCore.QObject.disconnect(self.Zoom,QtCore.SIGNAL("triggered()"), self.ZoomToggle) self.removeAction(self.Zoom) def disableAutoScale(self): if self.actionAutoScale != None: QtCore.QObject.disconnect(self.actionAutoScale,QtCore.SIGNAL("triggered()"), self.autoscale_plot) self.removeAction(self.actionAutoScale) def enableAutoScale(self): self.actionAutoScale = QtGui.QAction("AutoScale", self)#self.MainWindow) self.actionAutoScale.setShortcut("Ctrl+A") self.addAction(self.actionAutoScale) QtCore.QObject.connect(self.actionAutoScale,QtCore.SIGNAL("triggered()"), self.autoscale_plot) def enableCSV(self): self.saveCSVAction = QtGui.QAction("Save to CSV", self) self.saveCSVAction.setShortcut("Ctrl+Alt+S") self.addAction(self.saveCSVAction) QtCore.QObject.connect(self.saveCSVAction,QtCore.SIGNAL("triggered()"), self.save2CSV) def disableCSV(self): QtCore.QObject.disconnect(self.saveCSVAction,QtCore.SIGNAL("triggered()"), self.save2CSV) self.removeAction(self.saveCSVAction) def setLineDict(self): self.lineDict = {} lineList = self.canvas.ax.get_lines() if lineList > 0: for line in lineList: self.lineDict[line.get_label()]=line def editPlotProperties(self): print "Edit Enabled" self.setLineDict() # if len(self.lineDict) > 0: curAx = self.canvas.ax if POD(self.lineDict, curAx = curAx, parent = self).exec_(): if self.addLegend: curAx.legend(borderaxespad = 0.03, axespad=0.25) self.canvas.format_labels() self.canvas.draw() else: print "Cancel" def ZoomToggle(self): self.toolbar.zoom() #this implements the classic zoom # if self.hZoom: # self.hZoom = False # self.span.visible = False # else: # self.hZoom = True # self.span.visible = True def autoscale_plot(self): self.toolbar.home() #implements the classic return to home # self.canvas.ax.autoscale_view(tight = False, scalex=True, scaley=True) # self.canvas.draw() # self.emit(QtCore.SIGNAL("autoScaleAxis(bool)"),True) # def onclick(self, event): # #sets up the maximum Y level to be displayed after the zoom. # #if not set then it maxes to the largest point in the data # #not necessarily the local max # if event.ydata != None: # self.localYMax = int(event.ydata) # # def onselect(self, xmin, xmax): # #print xmin, xmax # if self.hZoom: # self.canvas.ax.set_ylim(ymax = self.localYMax) # self.canvas.ax.set_xlim(xmin, xmax) # self.canvas.draw() def save2CSV(self): path = self.SFDialog() if path != None: try: lines = self.canvas.ax.get_lines() data2write = [] for line in lines: data2write.append(line.get_data()[0]) data2write.append(line.get_data()[1]) print data2write data2write = N.array(data2write) data2write.dtype = N.float32 N.savetxt(str(path), N.transpose(data2write), delimiter = ',', fmt='%.4f') except: try: #this is for the case where the data may not be in float format? N.savetxt(str(path), N.transpose(data2write), delimiter = ',') except: print 'Error saving figure data' errorMsg = "Sorry: %s\n\n:%s\n"%(sys.exc_type, sys.exc_value) print errorMsg def SFDialog(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Select File to Save", "", "csv Files (*.csv)") if not fileName.isEmpty(): print fileName return fileName else: return None def removePicker(self): try: self.handleA.remove() except: print "" def setData(self, x, y): if x != None: self.x = x if y != None: self.y = y def addPicker(self): '''Sets up the plot variables used for interaction''' self.handleA, = self.canvas.ax.plot([0], [0], 'o',\ ms=8, alpha=.5, color='yellow', visible=True, label = '_nolegend_') self.is_hZoom = False self.canvas.mpl_connect('pick_event', self.OnPickPlot) def OnPickPlot(self, event): self.pickIndex = event.ind[0] try: self.textHandle.remove() except: pass self.curText = event.artist.get_label() if self.x != None and self.y != None: #I'd rather do the following ALWAYS but it seems difficult to do in terms of keeping track of which arrays were plotted when multiple plots are present paramVal = N.take(self.y, [self.pickIndex]) self.handleA.set_data(N.take(self.x, [self.pickIndex]), [paramVal]) else: paramVal = event.mouseevent.ydata self.handleA.set_data([event.mouseevent.xdata], [paramVal]) showText = '%s: %s'%(self.dataLabels[self.pickIndex],paramVal[0]) # showText = '%s: %s'%self.dataLabels[self.pickIndex] self.textHandle = self.canvas.ax.text(0.03, 0.95, showText, fontsize=9,\ bbox=dict(facecolor='yellow', alpha=0.1),\ transform=self.canvas.ax.transAxes, va='top') self.handleA.set_visible(True) self.canvas.draw() def mpl2Clip(self): try: self.canvas.fig.savefig(self.tempPath) tempImg = QtGui.QImage(self.tempPath) self.cb = QtGui.QApplication.clipboard() self.cb.setImage(tempImg) except: print 'Error copying figure to clipboard' errorMsg = "Sorry: %s\n\n:%s\n"%(sys.exc_type, sys.exc_value) print errorMsg