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):
source to share
No one has answered this question yet
Check out similar questions: