Python 无法调用canvas.show()

Python 无法调用canvas.show(),python,python-3.x,matplotlib,tkinter,Python,Python 3.x,Matplotlib,Tkinter,错误: # GUI imports from tkinter import * # Graph imports import matplotlib.pyplot as plt import matplotlib from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg from matplotlib.figure import Figure import matplotlib

错误:

# GUI imports
from tkinter import *

# Graph imports
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style

# Time imports
import time

def animate(i):
    a.clear()
    a.plot(data)

data = []

# GUI Set-Up
ROOT = Tk()
ROOT.attributes("-fullscreen", True)
matplotlib.use("TkAgg")
style.use('ggplot')
f = Frame(ROOT)
fig = Figure(figsize=(12, 7), dpi=100)

a = fig.add_subplot(221)
a.set_title("Data")

canvas = FigureCanvasTkAgg(fig)
canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=True)
canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=True)
canvas.show()

Frame.pack(f)

LOOP_ACTIVE = True
ROOT.config(cursor="none")

ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()

for x in range(0, 10):
    data.append(x)
    ROOT.update()
    time.sleep(1)
/usr/bin/python3.5/root/pycharm项目/Capstone2/main.py 回溯(最近一次呼叫最后一次): 文件“/root/PycharmProjects/Capstone2/main.py”,第62行,在 canvas.show() 文件“/usr/lib/python3/dist packages/matplotlib/backends/backend_tkagg.py”,第353行,在绘图中 self.\u master.update\u idletasks() AttributeError:“非类型”对象没有“更新\u idletasks”属性 进程已完成,退出代码为1

相关代码:

# GUI imports
from tkinter import *

# Graph imports
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style

# Time imports
import time

def animate(i):
    a.clear()
    a.plot(data)

data = []

# GUI Set-Up
ROOT = Tk()
ROOT.attributes("-fullscreen", True)
matplotlib.use("TkAgg")
style.use('ggplot')
f = Frame(ROOT)
fig = Figure(figsize=(12, 7), dpi=100)

a = fig.add_subplot(221)
a.set_title("Data")

canvas = FigureCanvasTkAgg(fig)
canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=True)
canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=True)
canvas.show()

Frame.pack(f)

LOOP_ACTIVE = True
ROOT.config(cursor="none")

ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()

for x in range(0, 10):
    data.append(x)
    ROOT.update()
    time.sleep(1)
我的理解:

# GUI imports
from tkinter import *

# Graph imports
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style

# Time imports
import time

def animate(i):
    a.clear()
    a.plot(data)

data = []

# GUI Set-Up
ROOT = Tk()
ROOT.attributes("-fullscreen", True)
matplotlib.use("TkAgg")
style.use('ggplot')
f = Frame(ROOT)
fig = Figure(figsize=(12, 7), dpi=100)

a = fig.add_subplot(221)
a.set_title("Data")

canvas = FigureCanvasTkAgg(fig)
canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=True)
canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=True)
canvas.show()

Frame.pack(f)

LOOP_ACTIVE = True
ROOT.config(cursor="none")

ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()

for x in range(0, 10):
    data.append(x)
    ROOT.update()
    time.sleep(1)
每秒钟应添加一个以上的数据点。每秒钟,绘图都应该更新以反映这一点

我的想法:

# GUI imports
from tkinter import *

# Graph imports
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style

# Time imports
import time

def animate(i):
    a.clear()
    a.plot(data)

data = []

# GUI Set-Up
ROOT = Tk()
ROOT.attributes("-fullscreen", True)
matplotlib.use("TkAgg")
style.use('ggplot')
f = Frame(ROOT)
fig = Figure(figsize=(12, 7), dpi=100)

a = fig.add_subplot(221)
a.set_title("Data")

canvas = FigureCanvasTkAgg(fig)
canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=True)
canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=True)
canvas.show()

Frame.pack(f)

LOOP_ACTIVE = True
ROOT.config(cursor="none")

ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()

for x in range(0, 10):
    data.append(x)
    ROOT.update()
    time.sleep(1)
  • 从一些谷歌搜索中可以看出,AttributeError会弹出,因为我试图调用canvas.show和canvas,但我认为我的行“canvas=FigureCanvasTkAgg(fig)”是正确的,早期的行如“canvas.get_tk_widget().pack(side=BOTTOM,fill=BOTH,expand=True)”不会导致错误
  • 如果我省略了“canvas.show()”,那么稍后会出现错误“Tkinter回调中的异常”
  • 如果我修改代码使canvas=FigureCanvasTkAgg(fig,master=ROOT)与我找到的一些示例相匹配,则不会发生错误,但动画不会做任何事情。我找不到关于FigureCanvasTkAgg的任何文档,只是一些示例,所以我不太确定修改这一行是做什么的
  • 在这里可以看到完整的代码(警告:这太恶心了):

    我基于的代码如下所示:


    我不确定我错在哪里。如果您有任何建议,我将不胜感激。

    代码的某些部分对我来说并不清楚:使用了
    canvas.show()
    (它甚至不应该存在)和
    plt.show()
    (考虑到您根本没有创建任何pyplot图形,这是没有意义的)

    鉴于在大多数示例中使用了
    canvas=FigureCanvasTkAgg(图,master=ROOT)
    ,我不知道为什么不使用它

    文件末尾的循环似乎没有什么用处。而是使用动画循环来更改数据

    最后,您忘记实际启动程序,即
    ROOT.mainloop()


    你能提供一个例子吗?我已经更新了我的帖子,包括了我能提供的最好的最小的、完整的和可验证的例子。谢谢你的建议,我使用canvas.show()来学习我的教程。我不应该包括plt.show(),我只是盲目地跟随一些在线示例。ROOT.mainloop()是一种我不喜欢使用的阻塞方法。我希望能够定期调用ROOT.update(),并实现相同的功能。谢谢你的帮助,明天我就可以测试你的补丁了,希望我能在我的程序中实现它们。你能链接到教程吗?(正如建议的那样,你应该提供你所使用的资源。)我想这不是真的很旧,就是一个糟糕的选择;但人们不可能不看到它就知道。在任何情况下,如果出于某种原因,可以使用canvas.draw();在本例中,它完全不是必需的。如果您不调用
    ROOT.mainloop()
    ,您将有两个确保实现自己的事件循环。这将与接下来的任何代码竞争。对于
    FuncAnimation
    的使用,我强烈建议您通过
    mainloop
    启动tk事件循环,否则您会遇到像这里一样的麻烦。我在文章末尾链接了教程,在我漫无边际的解释下隐藏了我试图避免使用ROOT.mainloop()的原因这是因为在我的实际程序中,我正在运行一个while循环,该循环以串行方式获取数据,然后我需要绘制该数据,同时还要执行许多与GUI无关的其他任务。如果我使用mainloop,我不知道如何在不破坏和重新绘制窗口的情况下获取数据和做我需要做的事情。我会从不同的角度来看待这一点。考虑任何GUI需要一个事件循环,在某个点启动这个事件循环,而不是手动运行它是有意义的。如果接下来需要另一个循环,可以在事件循环中运行此循环(通常通过计时器),也可以在其他线程中运行。