Matplotlib: Drag n Drop and blitting

I created FigureCanvas

one that allows you to drag and drop all instances Text

. This is great for text within axes, but for text outside of the axes (such s-axis labels), when the text is collated, it leaves a trail of text wherever you move it. As soon as the mouse is released, the trail disappears and the text is in the desired positions, but I'm trying to figure out why this will happen (and why it will happen outside the axes but not inside?)

BTW this only happens if I try to type "blitting" for performance. So I guess I am wrong about blitting.

The code for the drag n function is below. Any ideas?

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_()

      

Screenshot of the problem in action (you can see the "footprint" left when moving outside the axes in the upper left corner):

Blitting problem

+3


source to share





All Articles