Matplotlib:关联画布单击事件到最近的轴

时间:2017-04-25 22:10:22

标签: python matplotlib

有没有办法将画布上的点击但在绘图轴之外与最近的点击轴相关联?我有一个带有x个子图的画布,我试图找出鼠标点击附近最近的子图。最终,这将帮助我创建一个缩放矩形,允许用户放大所选子图的区域(导航工具栏只放大一个子图)。

#import os
#os.environ['QT_API'] = 'pyside'

from PyQt4 import QtGui, QtCore
import sys
import matplotlib

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
from matplotlib.figure                  import Figure
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar

import numpy as np

class Canvas(FigureCanvasQTAgg):

    def __init__(self, parent=None):
        self.figure = Figure()
        super(Canvas, self).__init__(self.figure)

        self.ax1 = self.figure.add_subplot(1,1,1)
        self.figure.subplots_adjust(left = 0.05, bottom = 0.02, right = 0.98, top = 0.99)
        self.setMinimumWidth(1000)
        self.ax1.plot([1,2,3])
        self.draw()

    def add_subplot(self, data=[]):
        rows = len(self.figure.axes) + 1
        for index, axes in enumerate(self.figure.axes, start=1):
            axes.change_geometry(rows, 1, index)

        ax = self.figure.add_subplot(rows, 1, index+1)
        x = np.arange(1000,1)
        y = np.arange(1000,1)
        ax.step(x,y)
        ax.patch.set_facecolor('None')
        self.figure.set_figheight(self.figure.get_figheight()*self.figScalingfactor)

    def figScaling(self, numSubplot):
        self.figScalingfactor = round(1.1729*pow(numSubplot, -0.028),3)


class Window(QtGui.QMainWindow):

    def __init__(self):
        super(Window, self).__init__()

        self.showMaximized()
        self.widget = QtGui.QWidget()
        self.setCentralWidget(self.widget)
        self.widget.setLayout(QtGui.QVBoxLayout())
        self.widget.layout().setContentsMargins(0,0,0,0)
        self.widget.layout().setSpacing(5)

        self.canvas = Canvas(self)
        self.scroll = QtGui.QScrollArea(self.widget)
        self.scroll.setWidget(self.canvas)
        self.scroll.setWidgetResizable(False)
        self.nav = NavigationToolbar(self.canvas, self.widget)
        self.numSubplots = 30
        self.canvas.figScaling(self.numSubplots)

        for x in range(self.numSubplots):
            self.canvas.add_subplot()
            self.canvas.adjustSize()
        self.canvas.draw_idle()
        self.widget.layout().addWidget(self.nav)
        self.widget.layout().addWidget(self.scroll)

        self.showVline = False
        self.hoveringLine = None

        self.canvas.mpl_connect("scroll_event", self.scrolling)
        self.canvas.mpl_connect("button_press_event", self.onClick)
        self.canvas.mpl_connect("motion_notify_event", self.onMove)

    def scrolling(self, event):
        val = self.scroll.verticalScrollBar().value()
        if event.button =="down":
            self.scroll.verticalScrollBar().setValue(val+100)
        else:
            self.scroll.verticalScrollBar().setValue(val-100)

    def onClick(self, event):
        if event.dblclick and self.showVline == False:
            self.background = self.canvas.copy_from_bbox(self.canvas.figure.bbox)
            self.showVline = True
            self.hoveringLine  = self.canvas.ax1.axvline(x=event.xdata, ymin=-1.2*self.numSubplots, ymax=1.2,
                                                         lw=2, zorder=0, clip_on=False)
        elif event.dblclick and self.showVline:
            self.showVline = False
            self.hoveringLine = None
            self.canvas.ax1.axvline(x=event.xdata, ymin=-1.2*self.numSubplots, ymax=1.2,
                                                         lw=2, zorder=0, clip_on=False)
            self.canvas.draw()
        else:
            print(event.xdata)
            print(event.ydata)


    def onMove(self, event):
        if (self.showVline):
            self.canvas.restore_region(self.background)
            self.hoveringLine.set_xdata(event.xdata)
            self.canvas.ax1.draw_artist(self.hoveringLine)
            self.canvas.blit(self.canvas.figure.bbox)


def main():
    app = QtGui.QApplication(sys.argv)
    app.aboutToQuit.connect(app.deleteLater)
    GUI = Window()
    GUI.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

0 个答案:

没有答案