예제 #1
0
    def _refresh_mpl_widget(self):
        """ Create the mpl widget and update the underlying control.

        """
        # Delete the old widgets in the layout, it's just shenanigans
        # to try to reuse the old widgets when the figure changes.
        widget = self.widget
        layout = widget.layout()
        while layout.count():
            layout_item = layout.takeAt(0)
            layout_item.widget().deleteLater()

        # Create the new figure and toolbar widgets. It seems that key
        # events will not be processed without an mpl figure manager.
        # However, a figure manager will create a new toplevel window,
        # which is certainly not desired in this case. This appears to
        # be a limitation of matplotlib. The canvas is manually set to
        # visible, or QVBoxLayout will ignore it for size hinting.
        figure = self.declaration.figure
        if figure:
            canvas = FigureCanvasQTAgg(figure)
            canvas.setParent(widget)
            canvas.setFocusPolicy(Qt.ClickFocus)
            canvas.setVisible(True)
            toolbar = NavigationToolbar2QTAgg(canvas, widget)
            toolbar.setVisible(self.declaration.toolbar_visible)
            layout.addWidget(toolbar)
            layout.addWidget(canvas)
예제 #2
0
    def _refresh_mpl_widget(self):
        """ Create the mpl widget and update the underlying control.

        """
        # Delete the old widgets in the layout, it's just shenanigans
        # to try to reuse the old widgets when the figure changes.
        widget = self.widget
        layout = widget.layout()
        while layout.count():
            layout_item = layout.takeAt(0)
            layout_item.widget().deleteLater()

        # Create the new figure and toolbar widgets. It seems that key
        # events will not be processed without an mpl figure manager.
        # However, a figure manager will create a new toplevel window,
        # which is certainly not desired in this case. This appears to
        # be a limitation of matplotlib. The canvas is manually set to
        # visible, or QVBoxLayout will ignore it for size hinting.
        figure = self.declaration.figure
        if figure:
            canvas = FigureCanvasQTAgg(figure)
            canvas.setParent(widget)
            canvas.setFocusPolicy(Qt.ClickFocus)
            canvas.setVisible(True)
            toolbar = NavigationToolbar2QT(canvas, widget)
            toolbar.setVisible(self.declaration.toolbar_visible)
            layout.addWidget(toolbar)
            layout.addWidget(canvas)
예제 #3
0
class GraphViewer(Graphics):
    signalShowTitle = QtCore.pyqtSignal(str)
    signalGraphUpdate = pyqtSignal()
    waitEvent = threading.Event()
    signalPrint = pyqtSignal()
    signalPrintEnd = threading.Event()


    def __init__(self, parent = None):
        Graphics.__init__(self,parent)
        self.parent = parent
        self.create_main_frame()



    def create_main_frame(self):

          self.canvas =  FigureCanvas(self.fig)
          self.canvas2 =  FigureCanvas(self.fig2)
          self.canvas.setParent(self.parent.ui.frame)
          self.canvas.setFocusPolicy(Qt.StrongFocus)
          self.canvas.setFocus()
    #
          self.mpl_toolbar = CustomToolbar(self.canvas, self.parent.ui.mpl,self)
          self.canvas.mpl_connect('pick_event',self.onPick)
          self.canvas.mpl_connect('key_press_event', self.on_key_press)
    #
          self.vbox = QVBoxLayout()
          self.vbox.addWidget(self.canvas)  # the matplotlib canvas
          self.vbox.addWidget(self.canvas2)  # the matplotlib canvas
          self.vbox.addWidget(self.mpl_toolbar)
          self.parent.ui.frame.setLayout(self.vbox)
    #
    # #
          self.fig.clear()
    #
          self.genPlotPage()
          self.genTextPage()
          self.canvas.setVisible(True)
          self.canvas2.setVisible(False)
          self.canvas.setFocusPolicy(Qt.StrongFocus)
          self.canvas.setFocus()
          self.page = 1
          self.signalGraphUpdate.emit()

    def genImage(self):
        self.fig.savefig('../WorkingDir/Page1.png', format='png')
class ThumbnailPlotter(QWidget):
    def __init__(self, title="Time domain preview"):
        QWidget.__init__(self)

        plt.close()
        plt.clf()

        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.figure.patch.set_facecolor('none')

        self.ax = self.figure.add_subplot(111)
        self.figure.subplots_adjust(left=0, right=0.99, top=0.99, bottom=0.01)

        self.main_vbox = QVBoxLayout()
        self.main_vbox.addWidget(QLabel("<h3>" + title + "</h3>"))
        self.main_vbox.addWidget(self.canvas)
        self.canvas.setVisible(False)
        self.setLayout(self.main_vbox)

        self.movie = QMovie("ajax-loader.gif")
        self.process_label = QLabel()
        self.process_label.setMovie(self.movie)
        self.movie.start()

        self.main_hbox = QHBoxLayout()
        self.main_vbox.addLayout(self.main_hbox)
        self.main_hbox.addStretch()
        self.main_hbox.addWidget(self.process_label)
        self.main_hbox.addStretch()
        self.process_label.setVisible(False)

        self.sizepolicy = QSizePolicy(QSizePolicy.Policy.Expanding,
                                      QSizePolicy.Policy.Fixed)
        self.setSizePolicy(self.sizepolicy)

        self.main_vbox.setContentsMargins(0, 0, 0, 0)
        self.main_vbox.setAlignment(Qt.AlignTop)
        self.setLoading()

    def setLoading(self):
        self.canvas.setVisible(False)
        self.process_label.setVisible(True)

    def draw(self, y):
        self.canvas.setVisible(True)
        self.process_label.setVisible(False)
        self.ax.clear()
        self.ax.plot(y)
        self.ax.set_xticklabels([])
        self.ax.set_yticklabels([])
        self.canvas.draw()

    def sizeHint(self, *args, **kwargs):
        return QSize(100, 150)
class ThumbnailPlotter(QWidget):
    
    def __init__(self, title="Time domain preview"):
        QWidget.__init__(self)
      
        plt.close() 
        plt.clf()
        
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.figure.patch.set_facecolor('none')

        self.ax = self.figure.add_subplot(111)
        self.figure.subplots_adjust(left=0, right=0.99, top=0.99, bottom=0.01)

        self.main_vbox = QVBoxLayout()
        self.main_vbox.addWidget(QLabel("<h3>"+title+"</h3>"))
        self.main_vbox.addWidget(self.canvas)
        self.canvas.setVisible(False)
        self.setLayout(self.main_vbox)
        
        self.movie = QMovie("ajax-loader.gif")
        self.process_label = QLabel()
        self.process_label.setMovie(self.movie)
        self.movie.start()
        
        self.main_hbox = QHBoxLayout()
        self.main_vbox.addLayout(self.main_hbox)
        self.main_hbox.addStretch()
        self.main_hbox.addWidget(self.process_label)
        self.main_hbox.addStretch()
        self.process_label.setVisible(False)
        
        self.sizepolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
        self.setSizePolicy(self.sizepolicy)
        
        self.main_vbox.setContentsMargins(0, 0, 0, 0)
        self.main_vbox.setAlignment(Qt.AlignTop)
        self.setLoading()
        
    def setLoading(self):
        self.canvas.setVisible(False)
        self.process_label.setVisible(True)
    
    def draw(self, y):
        self.canvas.setVisible(True)
        self.process_label.setVisible(False)
        self.ax.clear()
        self.ax.plot(y)
        self.ax.set_xticklabels([])
        self.ax.set_yticklabels([])
        self.canvas.draw()
        
    def sizeHint(self, *args, **kwargs):
        return QSize(100, 150)
예제 #6
0
class MiniMap(QtGui.QWidget):
    """Shows the entire signal and allows the user to navigate through it.

    Provides an scrollable selector over the entire signal.

    Attributes:
        xmin: Selector lower limit (measured in h-axis units).
        xmax: Selector upper limit (measured in h-axis units).
        step: Selector length (measured in h-axis units).
    """
    def __init__(self, parent, ax, record=None):
        super(MiniMap, self).__init__(parent)
        self.ax = ax

        self.xmin = 0.0
        self.xmax = 0.0
        self.step = 10.0
        self.xrange = np.array([])

        self.minimapFig = plt.figure()
        self.minimapFig.set_figheight(0.75)
        self.minimapFig.add_axes((0, 0, 1, 1))
        self.minimapCanvas = FigureCanvas(self.minimapFig)
        self.minimapCanvas.setFixedHeight(64)
        self.minimapSelector = self.minimapFig.axes[0].axvspan(0,
                                                               self.step,
                                                               color='gray',
                                                               alpha=0.5,
                                                               animated=True)
        self.minimapSelection = self.minimapFig.axes[0].axvspan(
            0, self.step, color='LightCoral', alpha=0.5, animated=True)
        self.minimapSelection.set_visible(False)
        self.minimapBackground = []
        self.minimapSize = (self.minimapFig.bbox.width,
                            self.minimapFig.bbox.height)

        self.press_selector = None
        self.playback_marker = None
        self.minimapCanvas.mpl_connect('button_press_event', self.onpress)
        self.minimapCanvas.mpl_connect('button_release_event', self.onrelease)
        self.minimapCanvas.mpl_connect('motion_notify_event', self.onmove)

        # Animation related attrs.
        self.background = None
        self.animated = False

        # Set the layout
        self.layout = QtGui.QVBoxLayout(self)
        self.layout.addWidget(self.minimapCanvas)

        # Animation related attributes
        self.parentViewer = parent

        # Set Markers dict
        self.markers = {}

        self.record = None
        if record is not None:
            self.set_record(record)

    def set_record(self, record, step):
        self.record = record
        self.step = step
        self.xrange = np.linspace(0,
                                  len(self.record.signal) / self.record.fs,
                                  num=len(self.record.signal),
                                  endpoint=False)
        self.xmin = self.xrange[0]
        self.xmax = self.xrange[-1]
        self.markers = {}

        ax = self.minimapFig.axes[0]
        ax.lines = []
        formatter = FuncFormatter(
            lambda x, pos: str(datetime.timedelta(seconds=x)))
        ax.xaxis.set_major_formatter(formatter)
        ax.grid(True, which='both')
        # Set dataseries to plot
        xmin = self.xmin * self.record.fs
        xmax = self.xmax * self.record.fs
        pixel_width = np.ceil(self.minimapFig.get_figwidth() *
                              self.minimapFig.get_dpi())
        x_data, y_data = plotting.reduce_data(self.xrange, self.record.signal,
                                              pixel_width, xmin, xmax)
        # self._plot_data.set_xdata(x_data)
        # self._plot_data.set_ydata(y_data)
        ax.plot(x_data, y_data, color='black', rasterized=True)
        ax.set_xlim(self.xmin, self.xmax)
        plotting.adjust_axes_height(ax)
        # Set the playback marker
        self.playback_marker = PlayBackMarker(self.minimapFig, self)
        self.playback_marker.markers[0].set_animated(True)
        # Draw canvas
        self.minimapCanvas.draw()
        self.minimapBackground = self.minimapCanvas.copy_from_bbox(
            self.minimapFig.bbox)
        self.draw_animate()

    def onpress(self, event):
        self.press_selector = event
        xdata = round(self.get_xdata(event), 2)
        xmin = round(xdata - (self.step / 2.0), 2)
        xmax = round(xdata + (self.step / 2.0), 2)
        self.parentViewer._set_animated(True)
        self.set_selector_limits(xmin, xmax)

    def onrelease(self, event):
        self.press_selector = None

        # Finish parent animation
        self.parentViewer._set_animated(False)

    def onmove(self, event):
        if self.press_selector is not None:
            xdata = round(self.get_xdata(event), 2)
            xmin = round(xdata - (self.step / 2.0), 2)
            xmax = round(xdata + (self.step / 2.0), 2)
            self.set_selector_limits(xmin, xmax)

    def get_xdata(self, event):
        inv = self.minimapFig.axes[0].transData.inverted()
        xdata, _ = inv.transform((event.x, event.y))
        return xdata

    def set_selector_limits(self, xmin, xmax):
        step = xmax - xmin
        if step >= self.xmax - self.xmin:
            xleft = self.xmin
            xright = self.xmax
        if xmin < self.xmin:
            xleft = self.xmin
            xright = self.step
        elif xmax > self.xmax:
            xleft = self.xmax - step
            xright = self.xmax
        else:
            xleft = xmin
            xright = xmax
        if (xleft, xright) != (self.minimapSelector.xy[1, 0],
                               self.minimapSelector.xy[2, 0]):
            self.step = step
            self.minimapSelector.xy[:2, 0] = xleft
            self.minimapSelector.xy[2:4, 0] = xright
            self.ax.set_xlim(xleft, xright)
            self.draw_animate()
        else:
            self.parentViewer.draw()

    def get_selector_limits(self):
        return self.minimapSelector.xy[0, 0], self.minimapSelector.xy[2, 0]

    def draw(self):
        self.draw_animate()

    def draw_animate(self):
        size = self.minimapFig.bbox.width, self.minimapFig.bbox.height
        if size != self.minimapSize:
            self.minimapSize = size
            self.minimapCanvas.draw()
            self.minimapBackground = self.minimapCanvas.copy_from_bbox(
                self.minimapFig.bbox)
        self.minimapCanvas.restore_region(self.minimapBackground)
        self.minimapFig.draw_artist(self.minimapSelection)
        self.minimapFig.draw_artist(self.minimapSelector)
        self.minimapFig.draw_artist(self.playback_marker.markers[0])
        for marker in self.markers.values():
            self.minimapFig.draw_artist(marker)
        self.minimapCanvas.blit(self.minimapFig.bbox)

    def set_visible(self, value):
        self.minimapCanvas.setVisible(value)

    def get_visible(self):
        return self.minimapCanvas.isVisible()

    def set_selection_limits(self, xleft, xright):
        self.minimapSelection.xy[:2, 0] = xleft
        self.minimapSelection.xy[2:4, 0] = xright
        self.draw_animate()

    def set_selection_visible(self, value):
        self.minimapSelection.set_visible(value)
        self.draw_animate()

    def create_marker(self, key, position, **kwargs):
        if self.xmin <= position <= self.xmax:
            marker = self.minimapFig.axes[0].axvline(position, animated=True)
            self.markers[key] = marker
            self.markers[key].set(**kwargs)

    def set_marker_position(self, key, value):
        marker = self.markers.get(key)
        if marker is not None:
            if self.xmin <= value <= self.xmax:
                marker.set_xdata(value)

    def set_marker(self, key, **kwargs):
        marker = self.markers.get(key)
        if marker is not None:
            kwargs.pop(
                "animated", None
            )  # marker's animated property must be always true to be drawn properly
            marker.set(**kwargs)

    def delete_marker(self, key):
        marker = self.markers.get(key)
        if marker is not None:
            self.minimapFig.axes[0].lines.remove(marker)
            self.markers.pop(key)
class PluginDialog(QDialog):

    def __init__(self, iface, parent=None, flags=Qt.WindowFlags()):
        QDialog.__init__(self, parent, flags)
        uic.loadUi(UI_PATH, self)

        self.iface = iface
        self.input_layer = None
        self.raster_layer = None
        self.roughness_layer = None
        #add channel info
        self.channel_info = None

        # self.name_box.setExpression('')
        # self.station_box.setExpression('')
        self.delta_box.setExpression('0.1')
        self.connection_box.setExpression("'standard'")
        self.type_box.setExpression("'river'")
        self.initial_box.setExpression('0.5')
        self.point_bc_enabled_box.setExpression('False')
        self.point_bc_stationary_box.setExpression('True')
        self.point_bc_value_box.setExpression('0')
        self.lateral_bc_enabled_box.setExpression('False')
        self.lateral_bc_stationary_box.setExpression('True')
        self.lateral_bc_value_box.setExpression('0')
        self.overflow_left_enabled_box.setExpression('True')
        self.overflow_left_poleni_box.setExpression('0.577')
        self.overflow_right_enabled_box.setExpression('True')
        self.overflow_right_poleni_box.setExpression('0.577')
        self.localbridgeheight_box.setExpression('1.5')
        self.bridgebodyheight_box.setExpression('4.0')

        self.groupBox_bridge.setCollapsed(True)
        self.mGroupBox_6.setCollapsed(True)
        self.mGroupBox.setCollapsed(True)
        self.mGroupBox_4.setCollapsed(True)
        self.mGroupBox_3.setCollapsed(True)
        self.mGroupBox_2.setCollapsed(True)
        self.groupBox_main.setCollapsed(True)
        self.mGroupBox_4.setCollapsed(False)

        #set DGM layer
        self.raster_layer_box.setFilters(QgsMapLayerProxyModel.RasterLayer)
        self.raster_layer_box.layerChanged.connect(self.setRasterLayer)
        self.raster_band_box.setEnabled(False)

        self.method_box.addItem('nearest neighbor (downscaling/upscaling)')
        self.method_box.addItem('bi-linear (downscaling)')
        self.method_box.addItem('bi-cubic (downscaling)')

        #set roughness layer
        self.roughness_layer_box.setFilters(QgsMapLayerProxyModel.RasterLayer)
        self.roughness_layer_box.layerChanged.connect(self.setRoughnessLayer)
        self.roughness_layer_box.setLayer(None)

        #set channel layer
        self.comboBox_main.setFilters(QgsMapLayerProxyModel.PolygonLayer)
        self.comboBox_main.layerChanged.connect(self.setChannelLayer)
        self.comboBox_main.setLayer(None)

        self.browse_button.clicked.connect(self.onBrowseButtonClicked)
        self.HelpButton.clicked.connect(self.Help)
        self.iface.currentLayerChanged.connect(self.setInputLayer)

        #############################################
        #autostationing button function
        def autoclicked(state):
            if state > 0:
                self.profileid_box.setEnabled(True)
                self.station_box.setEnabled(False)
                self.preview_button.setDisabled(True)
            else:
                self.profileid_box.setEnabled(False)
                self.station_box.setEnabled(True)
                self.preview_button.setDisabled(False)

        self.profileid_box.setEnabled(False)
        self.autostation_box.stateChanged.connect(autoclicked)
        #############################################  
        
        if PREVIEW_ENABLED:
            self.figure = Figure(figsize=(10, 4), dpi=100)
            self.axes = self.figure.add_subplot(111)
            self.axes.set_xlabel('Stationing')
            self.axes.set_ylabel('Elevation [m+NHN]')
            self.figure.tight_layout()
            self.canvas = Canvas(self.figure)
            self.canvas.setParent(self)
            self.canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
            self.layout().addWidget(self.canvas)
            self.canvas.setVisible(False)
            self.cursor = None
            self.preview_button.toggled.connect(self.canvas.setVisible)
            self.preview_button.toggled.connect(self.update_button.setEnabled)
            self.update_button.clicked.connect(self.updateLongitudinalPreview)
        else:
            self.preview_button.setDisabled(True)
            self.figure = None
            self.axes = None
            self.canvas = None
            self.cursor = None

        self.setInputLayer(self.iface.activeLayer())
        self.setRasterLayer(self.raster_layer_box.currentLayer())


    def __del__(self):
        #self.iface.currentLayerChanged.disconnect(self.setInputLayer)
        print('Done')

    def Help(self):
        webbrowser.open("https://promaides.myjetbrains.com/youtrack/articles/PMDP-A-45/1D-River-Profile-Export")

    def onBrowseButtonClicked(self):
        current_filename = self.filename_edit.text()
        new_filename, __ = QFileDialog.getSaveFileName(self.iface.mainWindow(), '1D-River Profile Export', current_filename)
        if new_filename != '':
            self.filename_edit.setText(new_filename)
            self.filename_edit.editingFinished.emit()

    def setInputLayer(self, layer):
        """
        """
        if not layer:
            self.input_layer = None
            self.input_label.setText(u'<i>No layer selected.<br>'
                                     u'Please select a polyline layer.</i>')
        else:
            layer_name = layer.name()
            if layer.type() == QgsMapLayer.VectorLayer:
                if layer.geometryType() == QgsWkbTypes.LineGeometry:
                    self.input_layer = layer
                    if layer.selectedFeatureCount():
                        self.input_label.setText(u'<i>Input layer is "{}" with {} selected feature(s).</i>'
                                                 .format(layer_name, layer.selectedFeatureCount()))
                    else:
                        self.input_label.setText(u'<i>Input layer is "{}" with {} feature(s).</i>'
                                                 .format(layer_name, layer.featureCount()))

                else:
                    self.input_layer = None
                    self.input_label.setText(u'<i>Selected layer "{}" is not a polyline layer.<br>'
                                             u'Please select a polyline layer.</i>'
                                             .format(layer_name))
            else:
                self.input_layer = None
                self.input_label.setText(u'<i>Selected layer "{}" is not a vector layer.<br>'
                                         u'Please select a polyline layer.</i>'
                                         .format(layer_name))

        self.name_box.setLayer(self.input_layer)
        self.station_box.setLayer(self.input_layer)
        self.delta_box.setLayer(self.input_layer)
        self.connection_box.setLayer(self.input_layer)
        self.type_box.setLayer(self.input_layer)
        self.initial_box.setLayer(self.input_layer)
        self.profileid_box.setLayer(self.input_layer)
        self.point_bc_enabled_box.setLayer(self.input_layer)
        self.point_bc_stationary_box.setLayer(self.input_layer)
        self.point_bc_value_box.setLayer(self.input_layer)
        self.lateral_bc_enabled_box.setLayer(self.input_layer)
        self.lateral_bc_stationary_box.setLayer(self.input_layer)
        self.lateral_bc_value_box.setLayer(self.input_layer)
        self.overflow_left_enabled_box.setLayer(self.input_layer)
        self.overflow_left_poleni_box.setLayer(self.input_layer)
        self.overflow_right_enabled_box.setLayer(self.input_layer)
        self.overflow_right_poleni_box.setLayer(self.input_layer)
        self.localbridgeheight_box.setLayer(self.input_layer)
        self.bridgebodyheight_box.setLayer(self.input_layer)


        self.updateButtonBox()


    def setRasterLayer(self, layer):
        self.raster_layer = layer
        if layer:
            self.raster_band_box.setEnabled(True)
            self.raster_band_box.setRange(1, layer.bandCount())
        else:
            self.raster_band_box.setEnabled(False)

        self.updateButtonBox()      

    def setRoughnessLayer(self, layer):
        self.roughness_layer = layer
        if layer:
            self.roughness_band_box.setEnabled(True)
            self.roughness_band_box.setRange(1, layer.bandCount())
        else:
            self.roughness_band_box.setEnabled(False)

    def setChannelLayer(self, layer):
            self.channel_info = layer

    def updateButtonBox(self):
        if self.input_layer and self.raster_layer:
            self.button_box.button(QDialogButtonBox.Ok).setEnabled(True)
        else:
            self.button_box.button(QDialogButtonBox.Ok).setEnabled(False)

    def updateLongitudinalPreview(self):
        if not PREVIEW_ENABLED:
            self.iface.messageBar().pushCritical(
                'River Profile Export',
                'Preview is disabled since Python module "matplotlib" is not installed!'
            )
            return
        
        flip_directions = self.flip_directions_box.isChecked()
        addfullriver = self.fullriver_box.isChecked()
        autostation = self.autostation_box.isChecked()
        abs_init = self.abs_init_box.isChecked()
        adjust_elevation = self.adjust_elevation_box.isChecked()
        
        input_layer = self.input_layer
        if not input_layer:
            return

        if input_layer.selectedFeatureCount():
            selected = True
            features = input_layer.selectedFeatures()
        else:
            selected = False
            features = input_layer.getFeatures()

        stations, ok = QgsVectorLayerUtils.getValues(input_layer, self.station_box.expression(), selected)
        if not autostation:
            if not ok:
                self.iface.messageBar().pushCritical(
                    'River Profile Export',
                    'Invalid expression for stations!'
                )
                return

        init_values, ok = QgsVectorLayerUtils.getValues(input_layer, self.initial_box.expression(), selected)
        if not ok:
            self.iface.messageBar().pushCritical(
                'River Profile Export',
                'Invalid expression for initial condition!'
            )
            return


        dem_layer = self.raster_layer
        dem_band = self.raster_band_box.value()
        dem_method = self.method_box.currentText()
        dem_nan = self.nan_box.value()
        dem_interpol = RasterInterpolator(dem_layer, dem_band, 10, 10, dem_method, dem_nan)

        base, left, right, h = [], [], [], []

        # iterate over profiles and extract base elevation,
        # left and right bank elevation, and init value
        for i, f in enumerate(features):

           # line = f.geometry().asPolyline()
            line = []
            buff = f.geometry()
            for p in buff.vertices():
                line.append(p)

            if flip_directions:
                line = list(reversed(line))

            z = [dem_interpol(QgsPointXY(p)) for p in line]

            if adjust_elevation:
                if z[0] <= z[1]:
                    z[0] = z[1] + 0.01
                if z[-1] <= z[-2]:
                    z[-1] = z[-2] + 0.01

            i_min = np.argmin(z)
            # minimum profile elevation
            z_min = z[int(i_min)]

            base.append(z_min)
            left.append(z[0])
            right.append(z[-1])

            init_value = float(init_values[i])
            # init values are absolute values
            if not abs_init:
                init_value += z_min

            h.append(init_value)

        s, base, left, right, h = list(zip(*sorted(zip(stations, base, left, right, h))))

        self.axes.cla()
        self.axes.plot(s, base, 'k', lw=1.5, label='base')
        self.axes.plot(s, left, 'r', lw=1.0, label='left bank')
        self.axes.plot(s, right, 'g', lw=1.0, label='right bank')
        self.axes.plot(s, h, 'b--', lw=0.5, label='init. h')
        self.axes.legend()
        self.axes.set_xticks(s)
        self.axes.set_xticklabels(list(map(str, s)), rotation=90, fontdict=dict(fontsize=9))
        self.axes.set_xlabel('Stationing')
        self.axes.set_ylabel('Elevation [m+NHN]')
        self.figure.tight_layout()
        self.cursor = Cursor(self.axes, useblit=True, color='0.5', linewidth=0.5)
        self.canvas.draw()
예제 #8
0
class StreamViewerWidget(QtGui.QWidget):
    """Shows the entire signal and allows the user to navigate through it.

    Provides an scrollable selector over the entire signal.

    Attributes:
        xmin: Selector lower limit (measured in h-axis units).
        xmax: Selector upper limit (measured in h-axis units).
        step: Selector length (measured in h-axis units).
    """

    trace_selected = QtCore.Signal(int)
    selection_made = QtCore.Signal(bool)

    def __init__(self, parent, stream=None):
        super(StreamViewerWidget, self).__init__(parent)

        self.fig = plt.figure()
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Expanding,
                                                    QtGui.QSizePolicy.Policy.Expanding))
        self.canvas.setMinimumHeight(320)
        self.canvas.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.canvas.setFocus()
        self.graphArea = QtGui.QScrollArea(self)
        self.graphArea.setWidget(self.canvas)
        self.graphArea.setWidgetResizable(True)
        self.graphArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        # Set the layout
        self.layout = QtGui.QVBoxLayout(self)
        self.layout.addWidget(self.graphArea)

        # Animation related attrs.
        self.background = []
        self.animated = False
        self.size = (self.fig.bbox.width, self.fig.bbox.height)

        # Set TracePlot list
        self.trace_plots = []

        self.stream = None
        if stream is not None:
            self.set_stream(stream)

        # Event handling
        self.visible_axes = []
        self._selected_traces = set()
        self.shift_pressed = False
        self.press_selector = None
        self.fig.canvas.mpl_connect('motion_notify_event', self.on_move)
        self.fig.canvas.mpl_connect('button_press_event', self.on_press)
        self.fig.canvas.mpl_connect('key_press_event', self.on_key_press)
        self.fig.canvas.mpl_connect('key_release_event', self.on_key_release)

    @property
    def selected_traces(self):
        if self.stream is not None:
            return [self.stream.traces[i] for i in self._selected_traces]
        return []

    def on_move(self, event):
        axes_selected = False
        for i, axes in enumerate(self.fig.axes):
            if axes.get_visible():
                ymin, ymax = axes.get_position().ymin, axes.get_position().ymax
                xmin, xmax = axes.get_position().xmin, axes.get_position().xmax
                xfig, yfig = self._event_to_fig_coords(event)
                if ymin <= yfig <= ymax and xmin <= xfig <= xmax:
                    self.canvas.setToolTip(self.stream.traces[i].name)
                    axes_selected = True
                    break
        if not axes_selected:
            self.canvas.setToolTip("")

    def on_key_press(self, event):
        if event.key == 'control':
            self.shift_pressed = True

    def on_key_release(self, event):
        self.shift_pressed = False

    def on_press(self, event):
        trace_selected = False
        if event.button == 1:# and event.dblclick:
            for i, ax in enumerate(self.fig.axes):
                if ax.get_visible():
                    ymin, ymax = ax.get_position().ymin, ax.get_position().ymax
                    xmin, xmax = ax.get_position().xmin, ax.get_position().xmax
                    xfig, yfig = self._event_to_fig_coords(event)
                    if ymin <= yfig <= ymax and xmin <= xfig <= xmax:
                        trace_selected = True
                        if self.shift_pressed:
                            if self._selected_traces:
                                self.trace_selected.emit(i)
                                self.selection_made.emit(True)
                            self._selected_traces.add(i)
                        else:
                            self.trace_selected.emit(i)
                            self.selection_made.emit(True)
                            self._selected_traces = {i}
                        break
            # if the user clicked out of any trace (and he's not using shift), then deselect all
            if not trace_selected and not self.shift_pressed:
                self._selected_traces = set()
                self.selection_made.emit(False)
            # Now update selection status on plots
            for i, plot in enumerate(self.trace_plots):
                plot.set_selected(i in self._selected_traces)
            self.draw()

    def _event_to_fig_coords(self, event):
        inv = self.fig.transFigure.inverted()
        return inv.transform((event.x, event.y))

    def set_stream(self, stream):
        self.stream = stream
        self._selected_traces = set()
        # Clear canvas
        for plot in self.trace_plots:
            plot.remove()
        self.trace_plots = []
        # Plot stream traces
        for i, trace in enumerate(self.stream.traces):
            self.trace_plots.append(TracePlot(self, trace, fig_nrows=len(stream), ax_pos=i + 1))
        # Draw canvas
        self.subplots_adjust()
        self.canvas.draw()
        self.background = self.canvas.copy_from_bbox(self.fig.bbox)
        self.draw()

    def refresh_stream_data(self):
        for plot in self.trace_plots:
            plot.update_data()

    def draw(self):
        self.canvas.draw()
        #self.draw_animate()

    def draw_animate(self):
        size = self.fig.bbox.width, self.fig.bbox.height
        if size != self.size:
            self.size = size
            self.canvas.draw()
            self.background = self.canvas.copy_from_bbox(self.fig.bbox)
        self.canvas.restore_region(self.background)
        for artist in self._get_animated_artists():
            if artist.get_visible():
                ax = artist.get_axes()
                if ax is not None:
                    if artist.get_axes().get_visible():
                        self.fig.draw_artist(artist)
                else:
                    self.fig.draw_artist(artist)
        self.canvas.blit(self.fig.bbox)

    def _get_animated_artists(self):
        artists = []
        for ax in self.fig.axes:
            artists.extend(ax.images)
            artists.extend(ax.lines)
            artists.append(ax.xaxis)
            artists.append(ax.yaxis)
            artists.extend(ax.patches)
            artists.extend(ax.spines.values())
        for artist in artists:
            if artist.get_animated():
                yield artist

    def set_visible(self, value):
        self.canvas.setVisible(value)

    def get_visible(self):
        return self.canvas.isVisible()

    def remove_trace(self, idx):
        self.trace_plots.pop(idx).remove()

    def subplots_adjust(self):
        visible_subplots = [ax for ax in self.fig.get_axes() if ax.get_visible()]
        for i, ax in enumerate(visible_subplots):
            correct_geometry = (len(visible_subplots), 1, i + 1)
            if correct_geometry != ax.get_geometry():
                ax.change_geometry(len(visible_subplots), 1, i + 1)
        # Adjust space between subplots
        self.fig.subplots_adjust(left=0.02, right=0.98, bottom=0.02,
                                 top=0.98, hspace=0.05)

    def showEvent(self, event):
        self.draw()

    def resizeEvent(self, event):
        self.draw()

    def update_markers(self):
        for plot in self.trace_plots:
            plot.update_markers()
        self.draw()

    def visualize_stream_range(self, start_trace=None, end_trace=None):
        for i, ax in enumerate(self.fig.axes):
            ax.set_visible(start_trace <= i < end_trace)
        self.subplots_adjust()
        self.canvas.draw()
예제 #9
0
class AppForm(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setWindowTitle('Web Log Analysis')

        self.create_menu()
        self.create_main_frame()
        self.create_status_bar()

        #self.on_draw()

    def save_plot(self):
        file_choices = "PNG (*.png)|*.png"
        
        path = unicode(QFileDialog.getSaveFileName(self, 
                        'Save file', '', 
                        file_choices))
        if path:
            self.canvas.print_figure(path, dpi=self.dpi)
            self.statusBar().showMessage('Saved to %s' % path, 2000)
    
    def on_about(self):
        msg = """ 
					* All the fields of packets are displayed in table
					* These packets can be filtered out
						Filtering is done on the basis of IP and request method.
						syntax is:
							IP==82.28.27.27
							METHOD==GET   or   METHOD==POST
		
					* Colour coding scheme is used for displaying packets
						For ex: RED :- Status code is 4xx or 5xx
					* After clicking on each packet, All the information about packet is displayed 
					* There is toolbar and Menubar. Various options are present there.
					* After pressing graph menu, graph is displayed.
						Graph is plotted Number of bytes in MB/Number of days in may
        """
        QMessageBox.about(self, "About the demo", msg.strip())
    
    def on_pick(self, event):
        # The event received here is of the type
        # matplotlib.backend_bases.PickEvent
        #
        # It carries lots of information, of which we're using
        # only a small amount here.
        # 
        box_points = event.artist.get_bbox().get_points()
        msg = "You've clicked on a bar with coords:\n %s" % box_points
        
        QMessageBox.information(self, "Click!", msg)
    
    def on_draw(self):

		if(len(self.data)!=0):
			print self.data[0][3]
			print self.data[0][9]
			d = {}
			print len(self.data) 
			i = 0
			for a in self.data:
				st = a[3]
				got_date = st[:2]
				if str(a[9]) == '-':
					print "Do nothing"
				else:
					got_date = int(got_date)  
					s = d.keys()
					if got_date in s:
						print got_date," : ",d[got_date]
						d[got_date] = int(d[got_date]) + int(a[9])
					else:
						d[got_date] = int(a[9])
		    			print d[got_date]
		    	
		    
		   
			print d
			x = d.keys()
			y = d.values()
			for i in range(0,len(y)):
				y[i] = float(y[i])/ 1000000.0
			print x
			print y
		    # clear the axes and redraw the plot anew
		    #
			self.axes.clear()        
			self.axes.grid(True)
		    
			self.axes.set_xlabel('Date of month')
			self.axes.set_ylabel('Size of data sent in MB')                
		    
			self.axes.bar(
		        left=x, 
		        height=y, 
		        width=20.00 / 100.0, 
		        align='center', 
		        alpha=0.44,
		        picker=10)
		    
			self.canvas.draw()


    def myapply(self):
		expression = self.textbox.displayText()
		print "Expression in filter is "+expression
		if expression == "":
			tablemodel = MyTableModel(self, self.tabledata, self.header)
			self.tableview.setModel(tablemodel)
			self.tableview.resizeColumnsToContents()   	 	
			hh = self.tableview.horizontalHeader()
			hh.setStretchLastSection(True)				
		elif expression[:4] == "IP==":
			IP_addr = expression[4:]
			temp = []
			for a in self.tabledata:
			
				if a[0] == IP_addr:
					temp.append(a)
					
			if len(temp) == 0:
				QMessageBox.about(self, "Ooopps", "IP enterred is either wrong or there isn't entry for this IP.")		
			else:		
				tablemodel = MyTableModel(self, temp, self.header)
				self.tableview.setModel(tablemodel) 
				self.tableview.resizeColumnsToContents()   	 	
				hh = self.tableview.horizontalHeader()
				hh.setStretchLastSection(True)
		elif expression[:8] == "METHOD==":
			method = expression[8:]
			temp = []
			for a in self.tabledata:
				if a[2] == method:
					temp.append(a)
					
			if len(temp) == 0:
				QMessageBox.about(self, "Ooopps", "METHOD enterred is either wrong or there isn't entry for this.")		
			else:		
				tablemodel = MyTableModel(self, temp, self.header)
				self.tableview.setModel(tablemodel) 
				self.tableview.resizeColumnsToContents()   	 	
				hh = self.tableview.horizontalHeader()
				hh.setStretchLastSection(True)
		
		else:
			if len(self.tabledata) == 0:
				QMessageBox.about(self, "Ooopps", "Table is empty")		
			else:
				QMessageBox.about(self, "Ooopps", "Check your enterred expression!!")        		
    def up(self):
    	print "Up"
    	
    def myrefresh(self):
    	print "refresh"	
    	
    def down(self):
    	print "down"    
        
    def show_graph(self):
		self.tableview.setVisible(False)
		self.list.setVisible(False)
		print "graph" 
		self.canvas.setVisible(True)
		self.mpl_toolbar.setVisible(True)
		self.on_draw()

    def show_table(self):
		self.canvas.setVisible(False)
		self.mpl_toolbar.setVisible(False)
		print "show_table"
		self.tableview.setVisible(True)
		self.list.setVisible(True)

    
    def myopen(self):
		print "open" 

		self.tabledata = []
		self.data = []
		filename = QFileDialog.getOpenFileName(self, 'Open File', '/')
		print filename
		
		f = open(filename,'r+')

		for line in f:
			matchObj = re.match( r'(.*?) (.*?) (.*?) \[(.*?) (.*?)\] "(.*?) (.*?) (.*?)" (.*?) (.*?) "(.*?)" "(.*)"', line, re.M|re.I)
			if matchObj:
				a = (matchObj.group(1),matchObj.group(4),matchObj.group(6),matchObj.group(9),matchObj.group(10),matchObj.group(7))      
				self.tabledata.append(a)
				b = (matchObj.group(1),matchObj.group(2),matchObj.group(3),matchObj.group(4),matchObj.group(5),matchObj.group(6),matchObj.group(7),matchObj.group(8),matchObj.group(9),matchObj.group(10),matchObj.group(11),matchObj.group(12))
				self.data.append(b)
        
		tablemodel = MyTableModel(self, self.tabledata, self.header)
		self.tableview.setModel(tablemodel)
		self.tableview.resizeColumnsToContents()   	 	
		hh = self.tableview.horizontalHeader()
		hh.setStretchLastSection(True)		
		
		self.btn.setEnabled(True)

    	
    def myclose(self):
    	print "close"
    	self.close()    
    		
    def viewclicked(self,index):
		row = index.row()
		self.list.clear()
		self.list.addItem(QListWidgetItem("Ip address         "+self.data[row][0]))	 
		self.list.addItem(QListWidgetItem("User-identifier    "+self.data[row][1]))
		self.list.addItem(QListWidgetItem("Frank              "+self.data[row][2]))
		self.list.addItem(QListWidgetItem("Date and Time      "+self.data[row][3]))
		self.list.addItem(QListWidgetItem("Request Method     "+self.data[row][5]))
		self.list.addItem(QListWidgetItem("URL                "+self.data[row][6]))
		self.list.addItem(QListWidgetItem("Http version       "+self.data[row][7]))
		self.list.addItem(QListWidgetItem("Status             "+self.data[row][8]))
		self.list.addItem(QListWidgetItem("Bytes sent         "+self.data[row][9]))
		self.list.addItem(QListWidgetItem("Web page referred  "+self.data[row][10]))
		self.list.addItem(QListWidgetItem("Browser information"+self.data[row][11]))
    		    		    
    def create_main_frame(self):
		self.main_frame = QWidget()

		self.data = []

		exitAction = QtGui.QAction(QtGui.QIcon('exit24.png'), 'Exit', self)
		exitAction.setShortcut('Ctrl+Q')
		exitAction.setStatusTip('Exit application')
		exitAction.triggered.connect(self.myclose)

		openAction = QtGui.QAction(QtGui.QIcon('open24.jpeg'), 'Open', self)
		openAction.setShortcut('Ctrl+O')
		openAction.setStatusTip('Open File')
		openAction.triggered.connect(self.myopen)
		
		tableAction = QtGui.QAction(QtGui.QIcon('table24.png'), 'Table', self)
		tableAction.setShortcut('Ctrl+T')
		tableAction.setStatusTip('Table View')
		tableAction.triggered.connect(self.show_table)

		graphAction = QtGui.QAction(QtGui.QIcon('graph24.png'), 'Graph', self)
		graphAction.setShortcut('Ctrl+G')
		graphAction.setStatusTip('Graphical View')
		graphAction.triggered.connect(self.show_graph)

		refreshAction = QtGui.QAction(QtGui.QIcon('refresh24.gif'), 'Refresh', self)
		refreshAction.setStatusTip('Refresh')
		refreshAction.triggered.connect(self.myrefresh)

		upAction = QtGui.QAction(QtGui.QIcon('up24.gif'), 'Up', self)
		upAction.setStatusTip('Up')
		upAction.triggered.connect(self.up)

		downAction = QtGui.QAction(QtGui.QIcon('down24.gif'), 'Down', self)
		downAction.setStatusTip('Down')
		downAction.triggered.connect(self.down)

		self.dpi = 150
		self.fig = Figure((5.0, 4.0), dpi=self.dpi)
		self.canvas = FigureCanvas(self.fig)
		self.canvas.setParent(self.main_frame)
		
		self.axes = self.fig.add_subplot(111)
        
		self.canvas.mpl_connect('pick_event', self.on_pick)
        
		self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame)

		self.canvas.move(280,80)		
		self.mpl_toolbar.move(280,80)
		self.canvas.setVisible(False)
		self.mpl_toolbar.setVisible(False)
                
		toolbar = self.addToolBar('Exit')

		toolbar.setStyleSheet('QToolBar{spacing:10px;}')
		toolbar.addAction(openAction)
		toolbar.addSeparator()
		toolbar.addAction(tableAction)
		toolbar.addAction(graphAction)
		toolbar.addSeparator()		
		toolbar.addAction(refreshAction)
		toolbar.addAction(upAction)
		toolbar.addAction(downAction)
		toolbar.addSeparator()
		toolbar.addAction(exitAction)
		 
		self.textbox = QtGui.QLineEdit(self)
		self.textbox.resize(280,35)
		self.textbox.move(10, 70)

		self.btn = QPushButton('Apply', self)
		self.btn.setToolTip('Click to apply expression')
		self.btn.resize(self.btn.sizeHint())	
		self.btn.move(300, 73)		
		self.btn.clicked.connect(self.myapply)
		self.btn.setEnabled(False)

		self.tabledata = [()]

		self.header = ["  IP address  ","  Date and time  ","  Request Method  ","  Status code  ","  Number of bytes  ","  URL  "]
		
		tablemodel = MyTableModel(self, self.tabledata, self.header)
		self.tableview = QTableView(self)
		self.tableview.setModel(tablemodel)
		
		self.tableview.move(10, 130)
		screen = QtGui.QDesktopWidget().screenGeometry()
		self.tableview.resize((screen.width())-100, ((screen.height())/7)*3)
        # set font
		font = QFont("Arial Black", 10)
		self.tableview.setFont(font)
        # set column width to fit contents (set font first!)
		#self.tableview.resizeColumnsToContents()
		self.tableview.setShowGrid(False)
		self.tableview.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
		self.tableview.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
		self.tableview.setStyleSheet('background-color:rgb(180, 250, 140);')
		self.tableview.clicked.connect(self.viewclicked)
		
		#hh = self.tableview.horizontalHeader()
		#hh.setStretchLastSection(True)        
		# set row height
		
		nrows = len(self.tabledata)
		for row in xrange(nrows):
			self.tableview.setRowHeight(row, 24)		
			
		vh = self.tableview.verticalHeader()
		vh.setVisible(False)
        
		screen = QtGui.QDesktopWidget().screenGeometry()
		self.list = QListWidget(self)
		self.list.move(10 , 150 + ((screen.height())/7)*3)
		self.list.resize((screen.width())-100, ((screen.height())/4))

		self.showMaximized()
		self.setCentralWidget(self.canvas)
    
    def create_status_bar(self):
        self.status_text = QLabel("Ready")
        self.statusBar().addWidget(self.status_text, 1)
        
    def create_menu(self):        
        self.file_menu = self.menuBar().addMenu("&File")
        
        load_file_action = self.create_action("&Save plot",
            shortcut="Ctrl+S", slot=self.save_plot, 
            tip="Save the plot")
        quit_action = self.create_action("&Quit", slot=self.close, 
            shortcut="Ctrl+Q", tip="Close the application")
        
        self.add_actions(self.file_menu, 
            (load_file_action, None, quit_action))
        
        self.help_menu = self.menuBar().addMenu("&Help")
        about_action = self.create_action("&About", 
            shortcut='F1', slot=self.on_about, 
            tip='About the demo')
        
        self.add_actions(self.help_menu, (about_action,))

    def add_actions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def create_action(  self, text, slot=None, shortcut=None, 
                        icon=None, tip=None, checkable=False, 
                        signal="triggered()"):
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % icon))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            self.connect(action, SIGNAL(signal), slot)
        if checkable:
            action.setCheckable(True)
        return action
예제 #10
0
class StreamViewerWidget(QtGui.QWidget):
    """Shows the entire signal and allows the user to navigate through it.

    Provides an scrollable selector over the entire signal.

    Attributes:
        xmin: Selector lower limit (measured in h-axis units).
        xmax: Selector upper limit (measured in h-axis units).
        step: Selector length (measured in h-axis units).
    """

    trace_selected = QtCore.Signal(int)
    selection_made = QtCore.Signal(bool)

    def __init__(self, parent, stream=None):
        super(StreamViewerWidget, self).__init__(parent)

        self.fig = plt.figure()
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setSizePolicy(
            QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Expanding,
                              QtGui.QSizePolicy.Policy.Expanding))
        self.canvas.setMinimumHeight(320)
        self.canvas.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.canvas.setFocus()
        self.graphArea = QtGui.QScrollArea(self)
        self.graphArea.setWidget(self.canvas)
        self.graphArea.setWidgetResizable(True)
        self.graphArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        # Set the layout
        self.layout = QtGui.QVBoxLayout(self)
        self.layout.addWidget(self.graphArea)

        # Animation related attrs.
        self.background = []
        self.animated = False
        self.size = (self.fig.bbox.width, self.fig.bbox.height)

        # Set TracePlot list
        self.trace_plots = []

        self.stream = None
        if stream is not None:
            self.set_stream(stream)

        # Event handling
        self.visible_axes = []
        self._selected_traces = set()
        self.shift_pressed = False
        self.press_selector = None
        self.fig.canvas.mpl_connect('motion_notify_event', self.on_move)
        self.fig.canvas.mpl_connect('button_press_event', self.on_press)
        self.fig.canvas.mpl_connect('key_press_event', self.on_key_press)
        self.fig.canvas.mpl_connect('key_release_event', self.on_key_release)

    @property
    def selected_traces(self):
        if self.stream is not None:
            return [self.stream.traces[i] for i in self._selected_traces]
        return []

    def on_move(self, event):
        axes_selected = False
        for i, axes in enumerate(self.fig.axes):
            if axes.get_visible():
                ymin, ymax = axes.get_position().ymin, axes.get_position().ymax
                xmin, xmax = axes.get_position().xmin, axes.get_position().xmax
                xfig, yfig = self._event_to_fig_coords(event)
                if ymin <= yfig <= ymax and xmin <= xfig <= xmax:
                    self.canvas.setToolTip(self.stream.traces[i].name)
                    axes_selected = True
                    break
        if not axes_selected:
            self.canvas.setToolTip("")

    def on_key_press(self, event):
        if event.key == 'control':
            self.shift_pressed = True

    def on_key_release(self, event):
        self.shift_pressed = False

    def on_press(self, event):
        trace_selected = False
        if event.button == 1:  # and event.dblclick:
            for i, ax in enumerate(self.fig.axes):
                if ax.get_visible():
                    ymin, ymax = ax.get_position().ymin, ax.get_position().ymax
                    xmin, xmax = ax.get_position().xmin, ax.get_position().xmax
                    xfig, yfig = self._event_to_fig_coords(event)
                    if ymin <= yfig <= ymax and xmin <= xfig <= xmax:
                        trace_selected = True
                        if self.shift_pressed:
                            if self._selected_traces:
                                self.trace_selected.emit(i)
                                self.selection_made.emit(True)
                            self._selected_traces.add(i)
                        else:
                            self.trace_selected.emit(i)
                            self.selection_made.emit(True)
                            self._selected_traces = {i}
                        break
            # if the user clicked out of any trace (and he's not using shift), then deselect all
            if not trace_selected and not self.shift_pressed:
                self._selected_traces = set()
                self.selection_made.emit(False)
            # Now update selection status on plots
            for i, plot in enumerate(self.trace_plots):
                plot.set_selected(i in self._selected_traces)
            self.draw()

    def _event_to_fig_coords(self, event):
        inv = self.fig.transFigure.inverted()
        return inv.transform((event.x, event.y))

    def set_stream(self, stream):
        self.stream = stream
        self._selected_traces = set()
        # Clear canvas
        for plot in self.trace_plots:
            plot.remove()
        self.trace_plots = []
        # Plot stream traces
        for i, trace in enumerate(self.stream.traces):
            self.trace_plots.append(
                TracePlot(self, trace, fig_nrows=len(stream), ax_pos=i + 1))
        # Draw canvas
        self.subplots_adjust()
        self.canvas.draw()
        self.background = self.canvas.copy_from_bbox(self.fig.bbox)
        self.draw()

    def refresh_stream_data(self):
        for plot in self.trace_plots:
            plot.update_data()

    def draw(self):
        self.canvas.draw()
        #self.draw_animate()

    def draw_animate(self):
        size = self.fig.bbox.width, self.fig.bbox.height
        if size != self.size:
            self.size = size
            self.canvas.draw()
            self.background = self.canvas.copy_from_bbox(self.fig.bbox)
        self.canvas.restore_region(self.background)
        for artist in self._get_animated_artists():
            if artist.get_visible():
                ax = artist.get_axes()
                if ax is not None:
                    if artist.get_axes().get_visible():
                        self.fig.draw_artist(artist)
                else:
                    self.fig.draw_artist(artist)
        self.canvas.blit(self.fig.bbox)

    def _get_animated_artists(self):
        artists = []
        for ax in self.fig.axes:
            artists.extend(ax.images)
            artists.extend(ax.lines)
            artists.append(ax.xaxis)
            artists.append(ax.yaxis)
            artists.extend(ax.patches)
            artists.extend(ax.spines.values())
        for artist in artists:
            if artist.get_animated():
                yield artist

    def set_visible(self, value):
        self.canvas.setVisible(value)

    def get_visible(self):
        return self.canvas.isVisible()

    def remove_trace(self, idx):
        self.trace_plots.pop(idx).remove()

    def subplots_adjust(self):
        visible_subplots = [
            ax for ax in self.fig.get_axes() if ax.get_visible()
        ]
        for i, ax in enumerate(visible_subplots):
            correct_geometry = (len(visible_subplots), 1, i + 1)
            if correct_geometry != ax.get_geometry():
                ax.change_geometry(len(visible_subplots), 1, i + 1)
        # Adjust space between subplots
        self.fig.subplots_adjust(left=0.02,
                                 right=0.98,
                                 bottom=0.02,
                                 top=0.98,
                                 hspace=0.05)

    def showEvent(self, event):
        self.draw()

    def resizeEvent(self, event):
        self.draw()

    def update_markers(self):
        for plot in self.trace_plots:
            plot.update_markers()
        self.draw()

    def visualize_stream_range(self, start_trace=None, end_trace=None):
        for i, ax in enumerate(self.fig.axes):
            ax.set_visible(start_trace <= i < end_trace)
        self.subplots_adjust()
        self.canvas.draw()
예제 #11
0
class MiniMap(QtGui.QWidget):
    """Shows the entire signal and allows the user to navigate through it.

    Provides an scrollable selector over the entire signal.

    Attributes:
        xmin: Selector lower limit (measured in h-axis units).
        xmax: Selector upper limit (measured in h-axis units).
        step: Selector length (measured in h-axis units).
    """

    def __init__(self, parent, ax, record=None):
        super(MiniMap, self).__init__(parent)
        self.ax = ax

        self.xmin = 0.0
        self.xmax = 0.0
        self.step = 10.0
        self.xrange = np.array([])

        self.minimapFig = plt.figure()
        self.minimapFig.set_figheight(0.75)
        self.minimapFig.add_axes((0, 0, 1, 1))
        self.minimapCanvas = FigureCanvas(self.minimapFig)
        self.minimapCanvas.setFixedHeight(64)
        self.minimapSelector = self.minimapFig.axes[0].axvspan(0, self.step,
                                                               color='gray',
                                                               alpha=0.5,
                                                               animated=True)
        self.minimapSelection = self.minimapFig.axes[0].axvspan(0, self.step,
                                                                color='LightCoral',
                                                                alpha = 0.5,
                                                                animated=True)
        self.minimapSelection.set_visible(False)
        self.minimapBackground = []
        self.minimapSize = (self.minimapFig.bbox.width,
                            self.minimapFig.bbox.height)

        self.press_selector = None
        self.playback_marker = None
        self.minimapCanvas.mpl_connect('button_press_event', self.onpress)
        self.minimapCanvas.mpl_connect('button_release_event', self.onrelease)
        self.minimapCanvas.mpl_connect('motion_notify_event', self.onmove)

        # Animation related attrs.
        self.background = None
        self.animated = False

        # Set the layout
        self.layout = QtGui.QVBoxLayout(self)
        self.layout.addWidget(self.minimapCanvas)

        # Animation related attributes
        self.parentViewer = parent

        # Set Markers dict
        self.markers = {}

        self.record = None
        if record is not None:
            self.set_record(record)

    def set_record(self, record, step):
        self.record = record
        self.step = step
        self.xrange = np.linspace(0, len(self.record.signal) / self.record.fs,
                                  num=len(self.record.signal), endpoint=False)
        self.xmin = self.xrange[0]
        self.xmax = self.xrange[-1]
        self.markers = {}

        ax = self.minimapFig.axes[0]
        ax.lines = []
        formatter = FuncFormatter(lambda x, pos: str(datetime.timedelta(seconds=x)))
        ax.xaxis.set_major_formatter(formatter)
        ax.grid(True, which='both')
        # Set dataseries to plot
        xmin = self.xmin * self.record.fs
        xmax = self.xmax * self.record.fs
        pixel_width = np.ceil(self.minimapFig.get_figwidth() * self.minimapFig.get_dpi())
        x_data, y_data = plotting.reduce_data(self.xrange, self.record.signal, pixel_width, xmin, xmax)
        # self._plot_data.set_xdata(x_data)
        # self._plot_data.set_ydata(y_data)
        ax.plot(x_data, y_data, color='black', rasterized=True)
        ax.set_xlim(self.xmin, self.xmax)
        plotting.adjust_axes_height(ax)
        # Set the playback marker
        self.playback_marker = PlayBackMarker(self.minimapFig, self)
        self.playback_marker.markers[0].set_animated(True)
        # Draw canvas
        self.minimapCanvas.draw()
        self.minimapBackground = self.minimapCanvas.copy_from_bbox(self.minimapFig.bbox)
        self.draw_animate()

    def onpress(self, event):
        self.press_selector = event
        xdata = round(self.get_xdata(event), 2)
        xmin = round(xdata - (self.step / 2.0), 2)
        xmax = round(xdata + (self.step / 2.0), 2)
        self.parentViewer._set_animated(True)
        self.set_selector_limits(xmin, xmax)

    def onrelease(self, event):
        self.press_selector = None

        # Finish parent animation
        self.parentViewer._set_animated(False)

    def onmove(self, event):
        if self.press_selector is not None:
            xdata = round(self.get_xdata(event), 2)
            xmin = round(xdata - (self.step / 2.0), 2)
            xmax = round(xdata + (self.step / 2.0), 2)
            self.set_selector_limits(xmin, xmax)

    def get_xdata(self, event):
        inv = self.minimapFig.axes[0].transData.inverted()
        xdata, _ = inv.transform((event.x, event.y))
        return xdata

    def set_selector_limits(self, xmin, xmax):
        step = xmax - xmin
        if step >= self.xmax - self.xmin:
            xleft = self.xmin
            xright = self.xmax
        if xmin < self.xmin:
            xleft = self.xmin
            xright = self.step
        elif xmax > self.xmax:
            xleft = self.xmax - step
            xright = self.xmax
        else:
            xleft = xmin
            xright = xmax
        if (xleft, xright) != (self.minimapSelector.xy[1, 0], self.minimapSelector.xy[2, 0]):
            self.step = step
            self.minimapSelector.xy[:2, 0] = xleft
            self.minimapSelector.xy[2:4, 0] = xright
            self.ax.set_xlim(xleft, xright)
            self.draw_animate()
        else:
            self.parentViewer.draw()

    def get_selector_limits(self):
        return self.minimapSelector.xy[0, 0], self.minimapSelector.xy[2, 0]

    def draw(self):
        self.draw_animate()

    def draw_animate(self):
        size = self.minimapFig.bbox.width, self.minimapFig.bbox.height
        if size != self.minimapSize:
            self.minimapSize = size
            self.minimapCanvas.draw()
            self.minimapBackground = self.minimapCanvas.copy_from_bbox(self.minimapFig.bbox)
        self.minimapCanvas.restore_region(self.minimapBackground)
        self.minimapFig.draw_artist(self.minimapSelection)
        self.minimapFig.draw_artist(self.minimapSelector)
        self.minimapFig.draw_artist(self.playback_marker.markers[0])
        for marker in self.markers.values():
            self.minimapFig.draw_artist(marker)
        self.minimapCanvas.blit(self.minimapFig.bbox)

    def set_visible(self, value):
        self.minimapCanvas.setVisible(value)

    def get_visible(self):
        return self.minimapCanvas.isVisible()

    def set_selection_limits(self, xleft, xright):
        self.minimapSelection.xy[:2, 0] = xleft
        self.minimapSelection.xy[2:4, 0] = xright
        self.draw_animate()

    def set_selection_visible(self, value):
        self.minimapSelection.set_visible(value)
        self.draw_animate()

    def create_marker(self, key, position, **kwargs):
        if self.xmin <= position <= self.xmax:
            marker = self.minimapFig.axes[0].axvline(position, animated=True)
            self.markers[key] = marker
            self.markers[key].set(**kwargs)

    def set_marker_position(self, key, value):
        marker = self.markers.get(key)
        if marker is not None:
            if self.xmin <= value <= self.xmax:
                marker.set_xdata(value)

    def set_marker(self, key, **kwargs):
        marker = self.markers.get(key)
        if marker is not None:
            kwargs.pop("animated", None)  # marker's animated property must be always true to be drawn properly
            marker.set(**kwargs)

    def delete_marker(self, key):
        marker = self.markers.get(key)
        if marker is not None:
            self.minimapFig.axes[0].lines.remove(marker)
            self.markers.pop(key)