我正在尝试 - 并且成功 - 使用Canvas
中的tkinter
对象创建简单的绘图。我试图尽可能多地使用与Python3一起安装的工具。 Matplotlib和其他人都很棒,但是对于我试图保持较小的东西来说,它们是非常大的安装。
根据硬件设备的输入,每0.5秒更新一次图。删除前128个点,绘制当前的128个点。有关屏幕截图,请参阅我的most recent blog post。我已经使用canvas.create_oval()
成功创建了这些图,但是当我运行它时,我听到我的PC风扇稍微增加了一点(我让它们处于激进的热配置文件中)并意识到我使用了15%的CPU ,这似乎很奇怪。
运行cProfile后,我发现canvas.create_oval()
的累积时间比我预期的要多。
在tkinter画布上阅读了一些关于优化的内容之后(除了'使用别的东西之外没有其他内容),我发现了一个帖子,建议可以使用一个点并使用canvas.create_images()
而不是canvas.create_oval()
。我试过了,create_image()
的时间有点少,但仍然非常重要。
为了完整起见,我将包含代码片段。请注意,此方法是名为Plot4Q
的类的一部分,该类是tk.Canvas
的子类:
def plot_point(self, point, point_format=None, fill='green', tag='data_point'):
x, y = point
x /= self.x_per_pixel
y /= self.y_per_pixel
x_screen, y_screen = self.to_screen_coords(x, y)
if fill == 'blue':
self.plot.create_image((x_screen, y_screen), image=self.blue_dot, tag=tag)
else:
self.plot.create_image((x_screen, y_screen), image=self.green_dot, tag=tag)
我是一个分析newb,因此包含该分析器的部分输出是谨慎的。我按照&time;' cumtime'排序并强调了相关方法。
update_plots
来电scatter
scatter
来电plot_point
(上图)请注意,scatter
占总运行时间的11.6%。
是否有更有效的方法在画布上创建点(并删除它们,虽然在tkinter中不需要很长时间)?
如果没有,是否有更有效的方法来创建绘图并将其嵌入到tkinter界面中?
我对使用不同的库有点开放,但我想保持它小而快。我曾经认为tk画布会小巧而快速,因为它在具有现代PC功率的十分之一的机器上运行良好。
在下面运行了一个有用的答案(Brian Oakley)后,我更新了结果。
为了解释一下更新的代码,我再次使用椭圆(我喜欢颜色控制)。我检查标签是否存在。如果它不存在,则在指定的点创建新的椭圆。如果标记确实存在,则计算新坐标并调用move
函数。
def plot_point(self, point, fill='green', tag='data_point'):
if not fill:
fill = self.DEFAULT_LINE_COLOR
point_width = 2
# find the location of the point on the canvas
x, y = point
x /= self.x_per_pixel
y /= self.y_per_pixel
x_screen, y_screen = self.to_screen_coords(x, y)
x0 = x_screen - point_width
y0 = y_screen - point_width
x1 = x_screen + point_width
y1 = y_screen + point_width
# if the tag exists, then move the point, else create the point
point_ids = self.plot.find_withtag(tag)
if point_ids != ():
point_id = point_ids[0]
location = self.plot.coords(point_id)
current_x = location[0]
current_y = location[1]
move_x = x_screen - current_x
move_y = y_screen - current_y
self.plot.move(point_id, move_x, move_y)
else:
point = self.plot.create_oval(x0,
y0,
x1,
y1,
outline=fill,
fill=fill,
tag=tag)
改善幅度不大,分别为10.4%和11.6%。
答案 0 :(得分:2)
创建许多项时(更具体地说,创建新的对象ID时)画布存在性能问题。删除对象没有帮助,问题在于不断增加的对象ID,它们永远不会被重用。这个问题通常不会出现,直到你有成千上万的项目。如果你创造256 /秒,你将在一两分钟内开始遇到这个问题。
如果您在屏幕外创建一次128个对象,然后只需移动它们而不是破坏并重新创建它们,就可以完全消除这种开销。