Esempio n. 1
0
    def __init__(self, parent):
        super(MplWidget, self).__init__(parent)
        # Create the mpl figure and subplot (white bg, 100 dots-per-inch).
        # Construct the canvas with the figure:
        self.plt_lim = [] # define variable for x,y plot limits

        if cmp_version("matplotlib", "2.2.0") >= 0:
            self.fig = Figure(constrained_layout=True)
        else:
            self.fig = Figure()

        self.canvas = FigureCanvas(self.fig)
        self.canvas.setSizePolicy(QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)

        # Needed for mouse modifiers (x,y, <CTRL>, ...):
        #    Key press events in general are not processed unless you
        #    "activate the focus of Qt onto your mpl canvas"
        # http://stackoverflow.com/questions/22043549/matplotlib-and-qt-mouse-press-event-key-is-always-none
        self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus )
        self.canvas.setFocus()

        self.canvas.updateGeometry()

        # Create a custom navigation toolbar, tied to the canvas and
        # initialize toolbar settings
        #
        self.mplToolbar = MplToolbar(self.canvas, self)
        self.mplToolbar.zoom_locked = False
        self.mplToolbar.cursor_enabled = False
        #self.mplToolbar.enable_plot(state = True)
        self.mplToolbar.sig_tx.connect(self.process_signals)
        layHToolbar = QHBoxLayout()
        layHToolbar.addWidget(self.mplToolbar, 1, QtCore.Qt.AlignLeft)
        layHToolbar.addStretch(1)

        #=============================================
        # Main plot widget layout
        #=============================================
        self.layVMainMpl = QVBoxLayout()
        self.layVMainMpl.addLayout(layHToolbar)
        self.layVMainMpl.addWidget(self.canvas)

        self.setLayout(self.layVMainMpl)
Esempio n. 2
0
class MplWidget(QWidget):
    """
    Construct a subwidget consisting of a Matplotlib canvas and a subclassed
    NavigationToolbar.
    """

    def __init__(self, parent):
        super(MplWidget, self).__init__(parent)
        # Create the mpl figure and subplot (white bg, 100 dots-per-inch).
        # Construct the canvas with the figure:
        self.plt_lim = [] # define variable for x,y plot limits

        if cmp_version("matplotlib", "2.2.0") >= 0:
            self.fig = Figure(constrained_layout=True)
        else:
            self.fig = Figure()

        self.canvas = FigureCanvas(self.fig)
        self.canvas.setSizePolicy(QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)

        # Needed for mouse modifiers (x,y, <CTRL>, ...):
        #    Key press events in general are not processed unless you
        #    "activate the focus of Qt onto your mpl canvas"
        # http://stackoverflow.com/questions/22043549/matplotlib-and-qt-mouse-press-event-key-is-always-none
        self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus )
        self.canvas.setFocus()

        self.canvas.updateGeometry()

        # Create a custom navigation toolbar, tied to the canvas and
        # initialize toolbar settings
        #
        self.mplToolbar = MplToolbar(self.canvas, self)
        self.mplToolbar.zoom_locked = False
        self.mplToolbar.cursor_enabled = False
        #self.mplToolbar.enable_plot(state = True)
        self.mplToolbar.sig_tx.connect(self.process_signals)
        layHToolbar = QHBoxLayout()
        layHToolbar.addWidget(self.mplToolbar, 1, QtCore.Qt.AlignLeft)
        layHToolbar.addStretch(1)

        #=============================================
        # Main plot widget layout
        #=============================================
        self.layVMainMpl = QVBoxLayout()
        self.layVMainMpl.addLayout(layHToolbar)
        self.layVMainMpl.addWidget(self.canvas)

        self.setLayout(self.layVMainMpl)

#------------------------------------------------------------------------------
    @pyqtSlot(object)
    def process_signals(self, dict_sig):
        """
        Process sig
        """
#        if 'enabled' in dict_sig:
#            self.clear_disabled_figure(dict_sig['enabled'])
#        else:
        pass

#------------------------------------------------------------------------------
    def save_limits(self):
        """
        Save x- and y-limits of all axes in self.limits when zoom is unlocked
        """
        if not self.mplToolbar.zoom_locked:
            for ax in self.fig.axes:
                self.limits = ax.axis() # save old limits

#------------------------------------------------------------------------------
    def redraw(self):
        """
        Redraw the figure with new properties (grid, linewidth)
        """
        # only execute when at least one axis exists -> tight_layout crashes otherwise
        if self.fig.axes:
            self.mplToolbar.cycle_draw_grid(cycle=False, axes=self.fig.axes)
            for ax in self.fig.axes:

                if self.mplToolbar.zoom_locked:
                    ax.axis(self.limits) # restore old limits
                else:
                    self.limits = ax.axis() # save old limits

#            try:
#                # tight_layout() crashes with small figure sizes
#               self.fig.tight_layout(pad = 0.1)
#            except(ValueError, np.linalg.linalg.LinAlgError):
#                logger.debug("error in tight_layout")
        self.canvas.draw() # now (re-)draw the figure

#------------------------------------------------------------------------------
#    def clear_disabled_figure(self, enabled):
#        """
#        Clear the figure when it is disabled in the mplToolbar
#        """
#        if not enabled:
#            self.fig.clf()
#            self.pltCanv.draw()
#        else:
#            self.redraw()

#------------------------------------------------------------------------------
    def plt_full_view(self):
        """
        Zoom to full extent of data if axes is set to "navigationable"
        by the navigation toolbar
        """
        #Add current view limits to view history to enable "back to previous view"
        self.mplToolbar.push_current()
        for ax in self.fig.axes:
            if ax.get_navigate():
                ax.autoscale()
        self.redraw()
#------------------------------------------------------------------------------
    def get_full_extent(self, ax, pad=0.0):
        """
        Get the full extent of axes system `ax`, including axes labels, tick labels
        and titles.

        Needed for inset plot in H(f)
        """
        #http://stackoverflow.com/questions/14712665/matplotlib-subplot-background-axes-face-labels-colour-or-figure-axes-coor
        # For text objects, we need to draw the figure first, otherwise the extents
        # are undefined.
        self.canvas.draw()
        items = ax.get_xticklabels() + ax.get_yticklabels()
        items += [ax, ax.title, ax.xaxis.label, ax.yaxis.label]
        bbox = Bbox.union([item.get_window_extent() for item in items])
        return bbox.expanded(1.0 + pad, 1.0 + pad)

#------------------------------------------------------------------------------
    def toggle_cursor(self):
        """
        Toggle the tracking cursor
        """
        if MPL_CURS:
            self.mplToolbar.cursor_enabled = not self.mplToolbar.cursor_enabled
            if self.mplToolbar.cursor_enabled:
                if hasattr(self, "cursors"): # dangling references to old cursors?
                    for i in range(len(self.cursors)):
                        self.cursors[i].remove()         # yes, remove them!
                self.cursors = []
                for ax in self.fig.axes:
                    if ax.__class__.__name__ in {"AxesSubplot", "Axes3DSubplot"}:
                        self.cursors.append(mplcursors.cursor(ax, hover=True))
            else:
                for i in range(len(self.cursors)):
                    self.cursors[i].remove()