Python Matplotlib:拖放和布点

Python Matplotlib:拖放和布点,python,matplotlib,blit,Python,Matplotlib,Blit,我已经创建了一个FigureCanvas,它允许在所有文本实例上进行拖放。这对于轴内的文本非常有效,但对于轴外的文本(如s轴标签),在拾取文本时,无论您移动文本的何处,都会留下一条“轨迹”。 释放鼠标后,轨迹消失,文本处于所需位置,但我试图理解为什么会发生这种情况(以及为什么会发生在轴外,而不是轴内?) 顺便说一句,这只有在我尝试引入“闪电”来提高性能时才会发生。所以我想我在布告中犯了一些错误 拖放功能的代码如下所示。有什么想法吗 import logging import sys from m

我已经创建了一个
FigureCanvas
,它允许在所有
文本
实例上进行拖放。这对于轴内的文本非常有效,但对于轴外的文本(如s轴标签),在拾取文本时,无论您移动文本的何处,都会留下一条“轨迹”。 释放鼠标后,轨迹消失,文本处于所需位置,但我试图理解为什么会发生这种情况(以及为什么会发生在轴外,而不是轴内?)

顺便说一句,这只有在我尝试引入“闪电”来提高性能时才会发生。所以我想我在布告中犯了一些错误

拖放功能的代码如下所示。有什么想法吗

import logging
import sys
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from PySide import QtGui
logger = logging.getLogger('colorpicker_example')
logger.setLevel(logging.DEBUG)

class JFigureCanvas(FigureCanvas):
    def __init__(self):
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)

        self._draggedArtist = None

        self.mpl_connect("pick_event", self.pck_event)
        self.mpl_connect("motion_notify_event", self.motion_event)
        self.mpl_connect("button_release_event", self.release_event)

    def pck_event(self, event):
        """ Pick event handler for text objects. If a pick event occurs, grab the artist and position."""
        if isinstance(event.artist, text.Text):
            self._draggedArtist = event.artist   

            #Get the x y position and transform it to display coords   
            x, y = self._draggedArtist.get_transform().transform_point(
                            (self._draggedArtist._x, self._draggedArtist._y))  
            self.startPos = (x, y, event.mouseevent.x, event.mouseevent.y)

            # draw everythin but the selected text and store the pixel buffer
            self._draggedArtist.set_animated(True)
            self.draw()
            self.background = self.copy_from_bbox(self.figure.bbox)

            # redraw the text
            self.figure.draw_artist(self._draggedArtist)

            # blit the redrawn area
            self.blit(self.figure.bbox)

    def motion_event(self, event):
        """ Motion event handler. If there is an artist stored, moved it with the mouse and redraw"""
        if self._draggedArtist:
            x0, y0, xpress, ypress = self.startPos
            dx = event.x - xpress
            dy = event.y - ypress
            canvasLoc = (x0 + dx, y0 + dy)
            newPos = self._draggedArtist.get_transform().inverted().transform_point(canvasLoc)
            self._draggedArtist.set_position(newPos)

            # Restore the background
            self.restore_region(self.background)

            #redraw the text
            self.figure.draw_artist(self._draggedArtist)

            # blit the redrawn area 
            self.blit(self.figure.bbox)

    def release_event(self, event):
        " If the mouse is released, release any artist"
        if self._draggedArtist:
            self._draggedArtist.set_animated(False)
        self.background = None
        self._draggedArtist = None
        self.draw()

class MainWindow(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        chart = JFigureCanvas()

        # Put some text in the axes
        chart.axes.text(0.5, 0.5, "Test", picker = True)

        self.setCentralWidget(chart)

if __name__ == '__main__':

    logging.basicConfig()
    app = QtGui.QApplication(sys.argv)
    main = MainWindow()
    main.show()
    app.exec_()
实际问题的屏幕截图(在左上角的轴外移动时,您可以看到后面留下的“轨迹”):


您是在子类化什么
FigureCanvas
?您使用的是什么后端?如果你能把它变成一个可运行的例子,那会很有帮助。+1用于获得一个可运行的例子。没有什么事情会马上就错了(从散文中我猜是用错了bbox,但看起来是对的)。如果这在不久的将来还没有解决,你能在gh上为此创建一个问题吗(闻起来像是一个在轴外闪烁的bug)。一个天真的猜测是,在抓取blit背景之前,只需使用
set_visible(False)
手动隐藏文本。动画的框架在下面做了很多事情,里面可能有一个微妙的bug…我添加了代码使它可以运行。我将尝试set\u visible使用
set\u visible
尝试各种组合。我所能做的就是让文本在拖动时消失,在释放鼠标时重新显示,这并不理想。