From 909e2241a7209f6d6608a5c975afc68080ad3e22 Mon Sep 17 00:00:00 2001 From: Marcel Paffrath Date: Thu, 8 Jun 2017 14:09:01 +0200 Subject: [PATCH] [change] working version of pyqtgraph for dataPlot, WIP: fill not working on versions lower 0.9.9 --- QtPyLoT.py | 119 +++++++++++++++++++++++++++---------- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 98 ++++++++++++++---------------- 3 files changed, 135 insertions(+), 84 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index b653bfe8..b47bbbd2 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -1009,10 +1009,7 @@ class MainWindow(QMainWindow): return self.dataPlot @staticmethod - def getWFID(gui_event): - - ycoord = gui_event.ydata - + def getWFID(ycoord): try: statID = int(round(ycoord)) except TypeError as e: @@ -1199,10 +1196,13 @@ class MainWindow(QMainWindow): Connect signals refering to WF-Dataplot (select station, tutor_user, scrolling) ''' if self.pg: - pass + self.connect_pg() else: self.connect_mpl() + def connect_pg(self): + self.poS_id = self.dataPlot.plotWidget.scene().sigMouseClicked.connect(self.pickOnStation) + def connect_mpl(self): if not self.poS_id: self.poS_id = self.dataPlot.mpl_connect('button_press_event', @@ -1220,10 +1220,14 @@ class MainWindow(QMainWindow): Disconnect all signals refering to WF-Dataplot (select station, tutor_user, scrolling) ''' if self.pg: - pass + self.disconnect_pg() else: self.disconnect_mpl() + def disconnect_pg(self): + if self.poS_id: + self.dataPlot.plotWidget.scene().sigMouseClicked.disconnect(self.poS_id) + def disconnect_mpl(self): if self.poS_id: self.dataPlot.mpl_disconnect(self.poS_id) @@ -1236,6 +1240,8 @@ class MainWindow(QMainWindow): self.scroll_id = None def finishWaveformDataPlot(self): + if pg: + self.getPlotWidget().updateWidget() self.connectWFplotEvents() self.loadlocationaction.setEnabled(True) self.auto_tune.setEnabled(True) @@ -1260,7 +1266,7 @@ class MainWindow(QMainWindow): def clearWaveformDataPlot(self): self.disconnectWFplotEvents() if self.pg: - self.dataPlot.plotitem.clear() + self.dataPlot.plotWidgetitem.clear() else: self.dataPlot.getAxes().cla() self.loadlocationaction.setEnabled(False) @@ -1313,6 +1319,8 @@ class MainWindow(QMainWindow): #self._max_xlims = self.dataPlot.getXLims() def adjustPlotHeight(self): + if self.pg: + return height_need = len(self.data.getWFData())*self.height_factor plotWidget = self.getPlotWidget() if self.tabs.widget(0).frameSize().height() < height_need: @@ -1408,7 +1416,9 @@ class MainWindow(QMainWindow): return self.seismicPhase def getStationName(self, wfID): - return self.getPlotWidget().getPlotDict()[wfID][0] + plot_dict = self.getPlotWidget().getPlotDict() + if wfID in plot_dict.keys(): + return plot_dict[wfID][0] def alterPhase(self): pass @@ -1455,14 +1465,25 @@ class MainWindow(QMainWindow): self.dataPlot.draw() def pickOnStation(self, gui_event): - if not gui_event.button == 1: - return - - wfID = self.getWFID(gui_event) + if self.pg: + if not gui_event.button() == 1: + return + else: + if not gui_event.button == 1: + return + + if self.pg: + ycoord = self.dataPlot.plotWidget.getPlotItem().vb.mapSceneToView(gui_event.scenePos()).y() + else: + ycoord = gui_event.ydata + + wfID = self.getWFID(ycoord) if wfID is None: return station = self.getStationName(wfID) + if not station: + return self.update_status('picking on station {0}'.format(station)) data = self.get_data().getWFData() pickDlg = PickDlg(self, parameter=self._inputs, @@ -1629,12 +1650,23 @@ class MainWindow(QMainWindow): plotID = self.getStationID(station) if plotID is None: return - ax = self.getPlotWidget().axes + if pg: + pw = self.getPlotWidget().plotWidget + else: + ax = self.getPlotWidget().axes ylims = np.array([-.5, +.5]) + plotID - phase_col = { - 'P': ('c', 'c--', 'b-', 'bv', 'b^', 'b'), - 'S': ('m', 'm--', 'r-', 'rv', 'r^', 'r') - } + if pg: + dashed = QtCore.Qt.DashLine + dotted = QtCore.Qt.DotLine + phase_col = { + 'P': (pg.mkPen('c'), pg.mkPen((0, 255, 255, 100), style=dashed), pg.mkPen('b', style=dashed), pg.mkPen('b', style=dotted)), + 'S': (pg.mkPen('m'), pg.mkPen((255, 0, 255, 100), style=dashed), pg.mkPen('r', style=dashed), pg.mkPen('r', style=dotted)) + } + else: + phase_col = { + 'P': ('c', 'c--', 'b-', 'bv', 'b^', 'b'), + 'S': ('m', 'm--', 'r-', 'rv', 'r^', 'r') + } stat_picks = self.getPicks(type=picktype)[station] @@ -1655,22 +1687,47 @@ class MainWindow(QMainWindow): if not spe and epp and lpp: spe = symmetrize_error(mpp - epp, lpp - mpp) - if picktype == 'manual': - if picks['epp'] and picks['lpp']: - ax.fill_between([epp, lpp], ylims[0], ylims[1], - alpha=.25, color=colors[0], label='EPP, LPP') - if spe: - ax.plot([mpp - spe, mpp - spe], ylims, colors[1], label='{}-SPE'.format(phase)) - ax.plot([mpp + spe, mpp + spe], ylims, colors[1]) - ax.plot([mpp, mpp], ylims, colors[2], label='{}-Pick'.format(phase)) + if pg: + if picktype == 'manual': + if picks['epp'] and picks['lpp']: + pw.plot([epp, epp], ylims, + alpha=.25, pen=colors[0], name='EPP') + pw.plot([lpp, lpp], ylims, + alpha=.25, pen=colors[0], name='LPP') + if spe: + spe_l = pg.PlotDataItem([mpp - spe, mpp - spe], ylims, pen=colors[1], name='{}-SPE'.format(phase)) + spe_r = pg.PlotDataItem([mpp + spe, mpp + spe], ylims, pen=colors[1]) + pw.addItem(spe_l) + pw.addItem(spe_r) + try: + fill = pg.FillBetweenItem(spe_l, spe_r, brush=colors[1].brush()) + fb = pw.addItem(fill) + except: + print('Could not create fill for SPE.') + pw.plot([mpp, mpp], ylims, pen=colors[2], name='{}-Pick'.format(phase)) + else: + pw.plot([mpp, mpp], ylims, pen=colors[0], name='{}-Pick (NO PICKERROR)'.format(phase)) + elif picktype == 'auto': + pw.plot([mpp, mpp], ylims, pen=colors[3]) else: - ax.plot([mpp, mpp], ylims, colors[6], label='{}-Pick (NO PICKERROR)'.format(phase)) - elif picktype == 'auto': - ax.plot(mpp, ylims[1], colors[3], - mpp, ylims[0], colors[4]) - ax.vlines(mpp, ylims[0], ylims[1], colors[5], linestyles='dotted') + raise TypeError('Unknown picktype {0}'.format(picktype)) else: - raise TypeError('Unknown picktype {0}'.format(picktype)) + if picktype == 'manual': + if picks['epp'] and picks['lpp']: + ax.fill_between([epp, lpp], ylims[0], ylims[1], + alpha=.25, color=colors[0], label='EPP, LPP') + if spe: + ax.plot([mpp - spe, mpp - spe], ylims, colors[1], label='{}-SPE'.format(phase)) + ax.plot([mpp + spe, mpp + spe], ylims, colors[1]) + ax.plot([mpp, mpp], ylims, colors[2], label='{}-Pick'.format(phase)) + else: + ax.plot([mpp, mpp], ylims, colors[6], label='{}-Pick (NO PICKERROR)'.format(phase)) + elif picktype == 'auto': + ax.plot(mpp, ylims[1], colors[3], + mpp, ylims[0], colors[4]) + ax.vlines(mpp, ylims[0], ylims[1], colors[5], linestyles='dotted') + else: + raise TypeError('Unknown picktype {0}'.format(picktype)) def locate_event(self): """ diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index b603f317..47c1eedd 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -be8035-dirty +a071-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 68b637dd..c0b285eb 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -414,26 +414,23 @@ class WaveformWidgetPG(QtGui.QWidget): # create plot self.main_layout = QtGui.QVBoxLayout() self.setLayout(self.main_layout) - #self.win = pg.GraphicsWindow(title="Window") - self.plot = pg.PlotWidget(title=title) - self.main_layout.addWidget(self.plot) - #self.plot = self.win.addPlot(title=title) - self.plot.setMouseEnabled(False, False) - self.plot.showGrid(x=False, y=True, alpha=0.2) - # update labels of the entire widget - #self.updateWidget(xlabel, ylabel, title) + self.plotWidget = pg.PlotWidget(title=title, autoDownsample=True) + self.main_layout.addWidget(self.plotWidget) + #self.plotWidget.setMouseEnabled(False, False) + self.plotWidget.showGrid(x=False, y=True, alpha=0.2) + self._proxy = pg.SignalProxy(self.plotWidget.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved) + def reinitMoveProxy(self): self.vLine = pg.InfiniteLine(angle=90, movable=False) self.hLine = pg.InfiniteLine(angle=0, movable=False) - self.plot.addItem(self.vLine, ignoreBounds=True) - self.plot.addItem(self.hLine, ignoreBounds=True) - self._proxy = pg.SignalProxy(self.plot.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved) - + self.plotWidget.addItem(self.vLine, ignoreBounds=True) + self.plotWidget.addItem(self.hLine, ignoreBounds=True) + def mouseMoved(self, evt): pos = evt[0] ## using signal proxy turns original arguments into a tuple - if self.plot.sceneBoundingRect().contains(pos): - mousePoint = self.plot.getPlotItem().vb.mapSceneToView(pos) - index = int(mousePoint.x()) + if self.plotWidget.sceneBoundingRect().contains(pos): + mousePoint = self.plotWidget.getPlotItem().vb.mapSceneToView(pos) + # index = int(mousePoint.x()) # if index > 0 and index < len(data1): # label.setText("x=%0.1f, y1=%0.1f, y2=%0.1f" % (mousePoint.x(), data1[index], data2[index])) self.vLine.setPos(mousePoint.x()) @@ -457,7 +454,8 @@ class WaveformWidgetPG(QtGui.QWidget): def plotWFData(self, wfdata, title=None, zoomx=None, zoomy=None, noiselevel=None, scaleddata=False, mapping=True, component='*', nth_sample=1, iniPick=None): - #self.getAxes().cla() + self.title = title + self.plotWidget.getPlotItem().clear() self.clearPlotDict() wfstart, wfend = full_range(wfdata) nmax = 0 @@ -501,10 +499,10 @@ class WaveformWidgetPG(QtGui.QWidget): trace.normalize(np.max(np.abs(trace.data)) * 2) times = [time for index, time in enumerate(time_ax) if not index%nth_sample] data = [datum + n for index, datum in enumerate(trace.data) if not index%nth_sample] - self.plot.plot(times, data, pen=(0, 0, 0)) + self.plotWidget.plot(times, data, pen=(0, 0, 0)) if noiselevel is not None: for level in noiselevel: - self.plot.plot([time_ax[0], time_ax[-1]], + self.plotWidget.plot([time_ax[0], time_ax[-1]], [level, level], pen=(0, 0, 0)) # if iniPick: # ax = self.getAxes() @@ -512,16 +510,12 @@ class WaveformWidgetPG(QtGui.QWidget): # colors='m', linestyles='dashed', # linewidth=2) self.setPlotDict(n, (station, channel, network)) - xlabel = 'seconds since {0}'.format(wfstart) - ylabel = '' - #self.updateWidget(xlabel, ylabel, title) - # self.setXLims([0, wfend - wfstart]) - # self.setYLims([-0.5, nmax + 0.5]) - # if zoomx is not None: - # self.setXLims(zoomx) - # if zoomy is not None: - # self.setYLims(zoomy) - # self.draw() + self.reinitMoveProxy() + self.xlabel = 'seconds since {0}'.format(wfstart) + self.ylabel = '' + self.setXLims([0, wfend - wfstart]) + self.setYLims([-0.5, nmax + 0.5]) + self.draw() # def getAxes(self): # return self.axes @@ -532,41 +526,41 @@ class WaveformWidgetPG(QtGui.QWidget): # def getYLims(self): # return self.getAxes().get_ylim() - # def setXLims(self, lims): - # self.getAxes().set_xlim(lims) + def setXLims(self, lims): + vb = self.plotWidget.getPlotItem().getViewBox() + vb.setXRange(lims[0], lims[1], padding=0) - # def setYLims(self, lims): - # self.getAxes().set_ylim(lims) + def setYLims(self, lims): + vb = self.plotWidget.getPlotItem().getViewBox() + vb.setYRange(lims[0], lims[1], padding=0) def setYTickLabels(self, pos, labels): ticks = zip(pos, labels) - leftAx = self.plot.getPlotItem().axes['left']['item'] + minorTicks = [(0, 0) for item in labels] # leftAx.tickLength = 5 # leftAx.orientation = 'right' - leftAx.setTicks([ticks, []]) + self.getAxItem('left').setTicks([ticks, minorTicks]) - # def updateXLabel(self, text): - # self.getAxes().set_xlabel(text) - # self.draw() + def updateXLabel(self, text): + self.getAxItem('bottom').setLabel(text) + self.draw() - # def updateYLabel(self, text): - # self.getAxes().set_ylabel(text) - # self.draw() + def updateYLabel(self, text): + self.getAxItem('left').setLabel(text) + self.draw() - # def updateTitle(self, text): - # self.getAxes().set_title(text) - # self.draw() + def getAxItem(self, position): + return self.plotWidget.getPlotItem().axes[position]['item'] - # def updateWidget(self, xlabel, ylabel, title): - # self.updateXLabel(xlabel) - # self.updateYLabel(ylabel) - # self.updateTitle(title) + def updateTitle(self, text): + self.plotWidget.getPlotItem().setTitle(text) + self.draw() + + def updateWidget(self):#, xlabel, ylabel, title): + self.updateXLabel(self.xlabel) + self.updateYLabel(self.ylabel) + self.updateTitle(self.title) - # def insertLabel(self, pos, text): - # pos = pos / max(self.getAxes().ylim) - # axann = self.getAxes().annotate(text, xy=(.03, pos), - # xycoords='axes fraction') - # axann.set_bbox(dict(facecolor='lightgrey', alpha=.6)) def draw(self): pass