Home > Enterprise >  How to collect the axis object of the last mouse click in matplotlib canvas drawn with pyqt5?
How to collect the axis object of the last mouse click in matplotlib canvas drawn with pyqt5?

Time:04-14

I have an interactive window and I need to know which subplot was selected during the interaction. When I was using matplotlib alone, I could use plt.connect('button_press_event', myMethod). But with pyqt5, I am importing FigureCanvasQTAgg and there is a reference to the figure itself but not an equivalent of pyplot. So, I am unable to create that reference.

Minimal reproducible example:

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas, NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt
from matplotlib.widgets import SpanSelector
import numpy as np

# list to store the axis last used with a mouseclick
currAx = []


# detect the currently modified axis
def onClick(event):
    if event.inaxes:
        currAx[:] = [event.inaxes]


class MyWidget(QWidget):
    def __init__(self):
        super().__init__()

        self.canvas = FigureCanvas(plt.Figure())
        self.axis = self.canvas.figure.subplots(3)
        for i, ax in enumerate(self.axis):
            t = np.linspace(-i, i   1, 100)
            ax.plot(t, np.sin(2 * np.pi * t))
        self.listOfSpans = [SpanSelector(
            ax,
            self.onselect,
            "horizontal"
        )
            for ax in self.axis]
        plt.connect('button_press_event', onClick)
        # need an equivalent of ^^ to find the axis interacted with
        self.init_ui()

    def init_ui(self):
        layout = QVBoxLayout()
        toolbar = NavigationToolbar(self.canvas, self)
        layout.addWidget(toolbar)
        layout.addWidget(self.canvas)
        self.setLayout(layout)
        self.show()

    def onselect(self, xmin, xmax):
        if xmin == xmax:
            return
        # identify the axis interacted and do something with that information
        for ax, span in zip(self.axis, self.listOfSpans):
            if ax == currAx[0]:
                print(ax)
        print(xmin, xmax)
        self.canvas.draw()


def run():
    app = QApplication([])
    mw = MyWidget()
    app.exec_()


if __name__ == '__main__':
    run()

CodePudding user response:

Apparently, there is a method for connecting canvas as well - canvas.mpl_connect('button_press_event', onclick).

Link to the explanation: https://matplotlib.org/stable/users/explain/event_handling.html

Found the link to the explanation in this link :Control the mouse click event with a subplot rather than a figure in matplotlib.

  • Related