Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tkinter画布创建图像并创建椭圆优化 背景_Python_Python 3.x_Plot_Tkinter_Tkinter Canvas - Fatal编程技术网

Python Tkinter画布创建图像并创建椭圆优化 背景

Python Tkinter画布创建图像并创建椭圆优化 背景,python,python-3.x,plot,tkinter,tkinter-canvas,Python,Python 3.x,Plot,Tkinter,Tkinter Canvas,我正在尝试并成功地使用tkinter中的Canvas对象创建一个简单的绘图。我正在尽可能多地使用Python3安装的工具。Matplotlib和其他软件都很不错,但它们的安装量相当大,我正试图将其缩小一点 根据硬件设备的输入,每0.5s更新一次绘图。将删除之前的128个点,并绘制当前的128个点。请参见我的屏幕截图。我已经使用canvas.create_oval()成功地创建了绘图,但是当我运行它时,我听到我的电脑风扇有点加速(我有一个激进的热配置),并意识到我使用了15%的CPU,这似乎很奇怪

我正在尝试并成功地使用
tkinter
中的
Canvas
对象创建一个简单的绘图。我正在尽可能多地使用Python3安装的工具。Matplotlib和其他软件都很不错,但它们的安装量相当大,我正试图将其缩小一点

根据硬件设备的输入,每0.5s更新一次绘图。将删除之前的128个点,并绘制当前的128个点。请参见我的屏幕截图。我已经使用canvas.create_oval()成功地创建了绘图,但是当我运行它时,我听到我的电脑风扇有点加速(我有一个激进的热配置),并意识到我使用了15%的CPU,这似乎很奇怪

问题 在运行cProfile之后,我发现
canvas.create_oval()
花费的累积时间比我预期的要多

在阅读了一些关于tkinter画布优化的内容后(除了“使用其他东西”之外,没有太多内容),我发现了一篇帖子,其中建议可以使用一个点的图像,并使用
画布。create_images()
而不是
画布。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)
简介 我是一个分析新手,所以谨慎的做法是包含该分析程序的部分输出。我已按“cumtime”排序,并强调了相关方法

  • update\u绘图
    calls
    scatter
  • 分散
    调用
    绘图点
    (如上)
请注意,
scatter
占用了总运行时间的11.6%

问题 有没有更有效的方法在画布上创建点(并删除点,尽管在tkinter中这不会花费很长时间)

如果没有,是否有更有效的方法创建绘图并将其嵌入tkinter接口

我对使用不同的库有点开放,但我想保持它的小型化和快速化。我原以为tk canvas会小而快,因为它在功率只有现代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%。

当创建许多项时(更具体地说,当创建新对象ID时),画布会出现性能问题。删除对象没有帮助,问题在于不断增加的对象ID永远不会被重用。这个问题通常不会出现,直到你有10的数以千计的项目。如果您创建的是256/秒,您将在一两分钟内开始遇到该问题


如果您一次在屏幕外创建128个对象,然后简单地移动它们,而不是销毁和重新创建它们,则可以完全消除此开销

好的,我来试一试。我可能要花一两天的时间才能恢复,但这很有道理,应该不难。当我得到结果时,我会写封信。谢谢你抽出时间!你的建议确实有帮助——10.4%对11.6%——但我必须说我在寻找更多的东西。我已经用更多的信息更新了我的问题。再次感谢@轻微混淆:看起来你仍然在做大量的工作来绘制每个像素。对我来说,
find_with tag
似乎没用——只要在启动时创建它们,就可以避免调用。如果你每半秒钟打128次电话,那似乎是不必要的开销。我想如果你把计算和作图分开,你就能更幸运地找出问题所在。计算所有点,而不进行任何绘制和纵断面。然后,简单地绘制128个点和轮廓。使用
find_with tag
可以在同一画布上绘制(和删除)多组数据,并用标记对每组数据进行寻址。这允许我同时显示和删除多组数据,这在这个应用程序中非常有用。我意识到我在解释文档中没有很好地阐述这一点,所以我理解其中的困惑。我会按照你的建议去做。再次感谢@好吧,这是有道理的。