使用matplotlib绘制点很慢

时间:2014-02-16 20:36:37

标签: python matplotlib interactive

在我的代码中,我有一个draggablepoint类,它定义了一个可以交互式拖动的点。因此,界面基本上选择一个draggablepoint,清除现有的点并将其绘制在图上。我希望在点击按钮后立即在图上显示该点,但是,显示该点需要时间。 有没有更快的方法来编写matplotlib零件代码?谢谢!

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.widgets import Button
from random import randint
import math
class Interface:

    def __init__(self, points):
        self.points = points
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111)
        self.run_button = Button(plt.axes([0.75, 0.6, 0.1, 0.04]), 'Draw', color='g', hovercolor='0.75')
        self.circles = []
        self.has_circle = False
        self.draggables = []

    def go(self):
        self.run_button.on_clicked(self.run)


    def run(self, event):
        '''remove point from the figure first'''
        if self.has_circle:
            self.circle.remove() 
        did = randint(0, len(self.points)-1)
        self.has_circle = True
        self.circle = patches.Circle(self.points[did], 0.02, fc='b', alpha=0.5, picker=True)
        self.ax.add_patch(self.circle)
        dr = DraggablePoint(self.circle)
        dr.connect()
        self.draggables.append(dr)

class DraggablePoint:
    lock = None #only one can be animated at a time
    def __init__(self, point):
        self.point = point
        self.press = None
        self.background = None
        self.ax = self.point.figure.add_subplot(111)

    def connect(self):
        'connect to all the events we need'
        self.cidpress = self.point.figure.canvas.mpl_connect('button_press_event', self.on_press)
        self.cidrelease = self.point.figure.canvas.mpl_connect('button_release_event', self.on_release)
        self.cidmotion = self.point.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)

    def on_press(self, event):
        if event.inaxes != self.point.axes: return
        if DraggablePoint.lock is not None: return
        contains = self.point.contains(event)[0]
        if not contains: return
        self.press = (self.point.center), event.xdata, event.ydata
        DraggablePoint.lock = self    
        # draw everything but the selected rectangle and store the pixel buffer
        canvas = self.point.figure.canvas
        axes = self.point.axes
        self.point.set_animated(True)
        canvas.draw()
        self.background = canvas.copy_from_bbox(self.point.axes.bbox)
        # now redraw just the rectangle
        axes.draw_artist(self.point)
        # and blit just the redrawn area
        canvas.blit(axes.bbox)

    def on_motion(self, event):
        if DraggablePoint.lock is not self: return
        if event.inaxes != self.point.axes: return
        if event.xdata < event.ydata / math.sqrt(3): return
        if event.xdata > (event.ydata - math.sqrt(3))/(-math.sqrt(3)): return
        self.point.center, xpress, ypress = self.press
        dx = event.xdata - xpress
        dy = event.ydata - ypress
        self.point.center = (self.point.center[0]+dx, self.point.center[1]+dy)
        canvas = self.point.figure.canvas
        axes = self.point.axes
        # restore the background region
        canvas.restore_region(self.background)
        # redraw just the current rectangle
        axes.draw_artist(self.point)
        # blit just the redrawn area
        canvas.blit(axes.bbox)

    def on_release(self, event):
        'on release we reset the press data'
        if DraggablePoint.lock is not self:return
        self.press = None
        DraggablePoint.lock = None
        # turn off the rect animation property and reset the background
        self.point.set_animated(False)
        self.background = None
        # redraw the full figure
        self.point.figure.canvas.draw()

    def disconnect(self):
        'disconnect all the stored connection ids'
        self.point.figure.canvas.mpl_disconnect(self.cidpress)
        self.point.figure.canvas.mpl_disconnect(self.cidrelease)
        self.point.figure.canvas.mpl_disconnect(self.cidmotion)

if __name__ == '__main__':
    points = [(0.5,0.4), (0.2, 0.3), (0.4, 0.8), (0.8, 0.9)]
    interface = Interface(points)
    interface.go()
    plt.show()

1 个答案:

答案 0 :(得分:1)

self.fig.canvas.draw()功能的末尾添加run

出现这一点很慢,因为在离开按钮之前不会强制更新。