Matplotlib: перетащить и бросить
Я создал FigureCanvas
который позволяет перетаскивать на всех Text
экземпляров. Это отлично работает для текста внутри осей, но для текста вне осей (таких как метки осей), когда текст выбирается, он оставляет за собой "след" текста, куда бы вы его ни перемещали. Как только мышь отпущена, след исчезает, и текст находится в желаемых местах, но я пытаюсь понять, почему это произошло (и почему это произошло бы вне осей, но не внутри?)
Кстати, это происходит только в том случае, если я пытаюсь ввести "блиц" для производительности. Так что я предполагаю, что совершаю какую-то ошибку в блинте.
Код для функции перетаскивания ниже. Есть идеи?
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_()
Снимок экрана: проблема в действии (вы можете увидеть "след", оставленный позади при перемещении вне осей вверху слева):