Picker不会在嵌入式pyside对话框中的matplotlib中选择补丁对象

时间:2012-04-24 19:10:34

标签: python matplotlib pyqt4 pyside

我在PySide中遇到嵌入式matplotlib的问题。当我尝试 选择窗口上的一个对象看起来我只能选择 subplot因为我收到了错误

AttributeError: 'AxesSubplot' object has no attribute 'get_xdata'

当我尝试在行

中的画布上捕获Line2D类的实例时
if isinstance(event.artist, Line2D)

我只能捕获AxesSubplot对象,而不是Line2D(也不是矩形,也不是文本)

感谢任何帮助, 理查德

class navDialog(QtGui.QDialog, Ui_mplDialog):
    def __init__(self, parent=None):
        super(navDialog, self).__init__(parent)
        # Basic preparation for an embedded matplotlib
        self.setupUi(self)
        fig = Figure(figsize=(600,600), dpi=72, facecolor=(1,1,1),edgecolor=(1,1,1))
        #fig.set_picker(picker)

        self.canvas = FigureCanvas(fig)
        self.verticalLayout.addWidget(self.canvas)

        ax = fig.add_subplot(111, xlim=(0, 10), ylim=(0, 10),axisbg='0.3', picker = True)
        ax.set_title('Click on the points', picker=True)
        fig.set_frameon(False)
        #fig.set_alpha(self, alpha)

        self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                  QtGui.QSizePolicy.Expanding)
        self.canvas.updateGeometry()


        self.navigation_toolbar = NavigationToolbar(self.canvas, self)
        self.verticalLayout.addWidget(self.navigation_toolbar, 0)

        #self.canvas.mpl_connect('button_press_event', self.on_pick)
        self.canvas.mpl_connect('pick_event', self.on_pick)

        # Specific content
        from matplotlib.collections import PatchCollection
        from matplotlib.projections.polar import PolarAxes
        import matplotlib.path as mpath
        import matplotlib.patches as mpatches
        import matplotlib.lines as mlines


        fig = plt.figure(figsize=(5,5))
        ax = plt.axes([0,0,1,1])
        patches = []

        # add entities on a circle
        es = session.query(Entity).all()
        vpuInFocus =session.query(Entity).filter(Entity.entity_in_focus == True) \
                                        .filter(Entity.entity_class_id== 1).one()
        esQty = len(es) - 1
        center = [5,5]

        theta = 2*3.14 / esQty
        arc = 0
        rad = 3
        pos = []
        # Entity in focus
        ePatch = mpatches.Circle(center, 0.3, ec='r', color='0.7',picker=True)
        patches.append(ePatch)
        ax.text(center[0], center[1], vpuInFocus.name, ha="center",family=font, size=14)

        for e in es:
            if e.Id is not vpuInFocus.Id:
                eX = center[0] + np.sin(arc) * rad
                eY = center[1] + np.cos(arc) * rad
                pos.append([e.name, eX , eY])
                # patch form can depend on the entityclass !!!
                ePatch = mpatches.Circle([eX, eY], 0.3, ec='r',color='0.7', picker=True)
                patches.append(ePatch)
                ax.text(eX, eY, e.name, ha="center", family=font,size=14)

                line = matplotlib.lines.Line2D([center[0], eX],[center[1], eY], picker=True)  # [x1, x2], [y1, y2]
                line.set_color('1.0')
                patches.append(line)

                arc = arc + theta


        collection = PatchCollection(patches, cmap=matplotlib.cm.jet,alpha=0.4)
        ax.add_collection(collection)

    def onclick(self, event):
        print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
            event.button, event.x, event.y, event.xdata, event.ydata)

    def on_pick(self, event):
        if isinstance(event.artist, Line2D):
            thisline = event.artist
            xdata = thisline.get_xdata()
            ydata = thisline.get_ydata()
            ind = event.ind
            print 'onpick1 line:', zip(npy.take(xdata, ind),npy.take(ydata, ind))
        elif isinstance(event.artist, Rectangle):
            patch = event.artist
            print 'onpick1 patch:', patch.get_path()
        elif isinstance(event.artist, Text):
            text = event.artist
            print 'onpick1 text:', text.get_text()
        mouseevent = event.mouseevent
        msg = "X is: " + str(mouseevent.xdata) + "\nY is: " +str(mouseevent.ydata)
        print msg

因此无法挑选补丁!以下代码对我来说很好。

class mplDialog(QtGui.QDialog, Ui_mplDialog):
  def __init__(self, parent=None):
    super(mplDialog, self).__init__(parent)


    # Basic preparation for an embedded matplotlib
    self.setupUi(self)

    # Context menu on system2 in focus button
    self.setContextMenuPolicy(Qt.CustomContextMenu)
    self.customContextMenuRequested.connect(self.ctxMenu)

    fig = Figure(figsize=(600,600), dpi=72, facecolor=(1,1,1), edgecolor=(0,0,0))

    self.canvas = FigureCanvas(fig)
    self.verticalLayout.addWidget(self.canvas)           

    self.axes = fig.add_subplot(111)        
    self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding,
                               QtGui.QSizePolicy.Expanding)
    self.canvas.updateGeometry()
    self.navigation_toolbar = NavigationToolbar(self.canvas, self)
    self.verticalLayout.addWidget(self.navigation_toolbar, 0)

    # Specific content
    self.axes.plot([1,2,3,4,5,6,7,8,9],[50, 67, 74, 57, 57, 57, 75, 64, 96], picker=True)
    self.axes.scatter(2, 80, marker='o', picker=True)

    # Add patches (which can't be picked!)
    from matplotlib.collections import PatchCollection
    import matplotlib.patches as mpatches
    font = "sans-serif"
    patches = []
    ePatch = mpatches.Circle([5,70], ec='r', color='r', picker=True)
    patches.append(ePatch) 
    ePatch = mpatches.Rectangle([7,60], 3, 10,  ec='r', color='0.7', picker=True)
    self.axes.text(7,60, "Rect name", picker=True)
    patches.append(ePatch)   
    collection = PatchCollection(patches, cmap=matplotlib.cm.jet, alpha=0.4)
    self.axes.add_collection(collection)

    self.canvas.mpl_connect('pick_event', self.onpick1)  

def onpick1(self, event):
    #print event.artist
    if isinstance(event.artist, Line2D):
        thisline = event.artist
        xdata = thisline.get_xdata()
        ydata = thisline.get_ydata()
        ind = event.ind
        print 'onpick1 line:', zip(np.take(xdata, ind), np.take(ydata, ind))
    elif isinstance(event.artist, Rectangle):  # For bar plots
        patch = event.artist
        print 'onpick1 patch:', patch.get_path()
    elif isinstance(event.artist, Text):
        text = event.artist
        print 'onpick1 text:', text.get_text(), "Obj", text
    else:   # For scatter plots
        patch = event.artist
        print 'onpick1 Circle:' #patch.get_path()

0 个答案:

没有答案