Координаты imshow графического интерфейса matplotlib

Я делаю графический интерфейс, используя pyqt4, который содержит изображение, отображаемое imshow matplotlib с использованием массива 2d. Если бы я отобразил это с помощью pyplot, в окне отобразились бы координаты x, y курсора, если я наведу указатель мыши на изображение. Однако это, похоже, исчезло, когда я встроил imshow в графический интерфейс pyqt. Есть ли способ заставить событие мыши вызывать некоторую функцию, которая возвращает эти координаты x, y (или, что еще лучше, индексы этого массива 2d) точки, над которой находится мышь?

EDIT: я нашел документацию для wx, но до сих пор не знаю, как это сделать для своего графического интерфейса. wxcursor_demo

Если это поможет, вот как я встраиваю сюжет imshow. Сначала я создаю базовый класс холста, затем на его основе создаю класс для imshow:

class Canvas(FigureCanvas):
    def __init__(self, parent = None, width = 5, height = 5, dpi = 100, projection = None):
        self.fig = Figure(figsize = (width, height), dpi = dpi)
        if projection:
            self.axes = Axes3D(self.fig)
        else:
            self.axes = self.fig.add_subplot(111)

        self.axes.tick_params(axis = 'both', which = 'major', labelsize = 8)
        self.axes.tick_params(axis = 'both', which = 'minor', labelsize = 8)
        self.compute_initial_figure()
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def compute_initial_figure(self):
        pass

class TopView(Canvas):
    def __init__(self, *args, **kwargs):
        Canvas.__init__(self, *args, **kwargs)
        self.divider = make_axes_locatable(self.axes)
        self.cax = self.divider.append_axes("bottom", size = "5%", pad = 0.2)

    def compute_initial_figure(self):
        self.top = self.axes.imshow(zarr, interpolation = 'none', extent = [xmin, xmax, ymin, ymax], origin = 'lower')
        self.top.set_cmap('nipy_spectral')
        self.top.set_clim(vmin = pltMin, vmax = pltMax)

Затем в главном окне я создаю объект и размещаю его в макете сетки:

tv = TopView(self.main_widget, width = 4, height = 3, dpi = 100)
self.g.addWidget(tv, 1, 2, 3, 1)

person Ethan Neidhart    schedule 14.05.2015    source источник


Ответы (1)


Matplotlib использует свое собственное событие, поэтому они не зависят от наборов инструментов пользовательского интерфейса (wx-windows, Qt и т. д.). Поэтому wxcursor_demo легко адаптируется к Qt, как и в вашем случае.

Сначала добавьте следующую строку в конструктор вашего класса Canvas

self.mpl_connect('motion_notify_event', self.mouse_moved)

Это будет вызывать метод mouse_moved каждый раз, когда мышь находится в движении.

В методе mouse_moved вы можете генерировать сигнал Qt, который подключен к виджету, который знает, как отображать координаты мыши. Что-то вроде этого:

def mouse_moved(self, mouse_event):
    if mouse_event.inaxes:
        x, y = mouse_event.xdata, mouse_event.ydata
        self.mouse_moved_signal.emit(x,y)

Конечно, вам также придется определить mouse_moved_signal в конструкторе Canvas. Обратите внимание, что параметр mouse_event является событием Matplotlib, а не событие Qt.

Я рекомендую вам прочитать главу о событиях в документации Matplotlib, чтобы понять, что такое возможно.

person titusjan    schedule 14.05.2015