Python tkinter中的两个动画同时出现
我想让两个动画同时工作 这是我的密码:Python tkinter中的两个动画同时出现,python,animation,tkinter,Python,Animation,Tkinter,我想让两个动画同时工作 这是我的密码: import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import matplotlib.animation as animation import tkinter as tk f = plt.figure(figsize=(6, 2), dpi=100) f1 = plt.figure(figsize=(4, 2),
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.animation as animation
import tkinter as tk
f = plt.figure(figsize=(6, 2), dpi=100)
f1 = plt.figure(figsize=(4, 2), dpi=100)
def animate(i):
a = f.add_subplot(111)
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [3, 5, 2, 7, 3, 5, 4, 6, 2, 2]
a.plot(x, y)
def animate1(j):
a1 = f1.add_subplot(111)
x1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y1 = [6, 1, 4, 9, 4, 2, 5, 1, 2, 4]
a1.plot(x1, y1)
class Figure(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.config(background='blue')
canvas = FigureCanvasTkAgg(f, self)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
class Figure1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.config(background='blue')
canvas = FigureCanvasTkAgg(f1, self)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
class Calculator(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, *kwargs)
tk.Tk.wm_title(self, 'Beam calculator')
container = tk.Frame(self)
container.pack(side='top', fill='both', expand=True)
bfig = Figure(container, controller=self)
bfig.grid(row=0, column=0, sticky="nsew")
bfig1 = Figure(container, controller=self)
bfig1.grid(row=1, column=0, sticky="nsew")
if __name__ == '__main__':
app = Calculator()
app.geometry('1280x720')
ani = animation.FuncAnimation(f, animate, interval=1000)
ani1 = animation.FuncAnimation(f1, animate1, interval=1000)
app.mainloop()
但只有第二个数字出现
我发现了以下主题:
但是我不知道如何使它正常工作。有三件小事妨碍了代码的工作:
bfig1=Figure(容器,控制器=self)
更改为bfig1=Figure1(容器,控制器=self)
。否则,画布永远不会附着到图f1
*kwargs
应该是**kwargs
在tk.tk.\uuuu_uuinit_uuu(self,*args,*kwargs)
行中。
请参见*args
和**kwargs
的含义您还可以使用许多其他更改来改进代码 一个大问题是
a=f.add_子图(111)
不应放在animate
函数中。这将在图形中创建一个轴对象a
,即f
。通常每个图有一个轴和一个图形。(请参见。)由于为动画的每个帧调用一次animate
,因此您不希望为每个帧创建新的轴。下面的代码建议如何在全局范围内定义一次a
另一个主要的编程原则是首字母缩写 虽然一开始复制代码可能很容易,但从长远来看,它会使维护变得更容易 更难修改代码。例如,假设您决定要添加 将一些代码添加到
图
类中。因为您有两个几乎相同的图
类,您可能必须向图
和图1
添加相同的代码。及
如果您以后发现该代码中存在错误,则必须修复这两个代码中的错误
地方也一样。因为每一次编辑都需要完成,所以您的生产力会减半
两次。如果您忘记在某个地方执行此操作,则会引入另一个bug
您可以通过泛化动画
和图形
使您的代码更加枯燥,以便
可以删除动画1
和图1
。你所需要做的就是添加一个额外的参数
到函数(例如,行
和f
)来概括代码并允许代码
重新使用(请参阅下面的代码以了解我的意思。)
使用带编号的变量名几乎总是一个坏主意。 通常应使用
列表
或dict
代替编号变量。
由于编号变量名通常以相同的方式使用,
(即对x1
执行此操作,对x2
执行相同操作,对x3
执行相同操作,等等。)
使用带编号的变量会导致代码重复,这与DRY原则背道而驰。
如果使用列表来收集一个对象中的所有数字变量,则可以使用循环一次处理所有数字变量:
for x in xs:
do_something(x)
性能提示:在动画中可能出现的数千次调用
plt.plot
plt会使程序明显变慢。每次调用都会生成新的Line2D
对象,这些对象需要在动画的每一帧中重新渲染。为了获得更好的性能,请反复使用相同的Line2D
对象,只需更改Line2D
对象内的ydata即可使matplotlib呈现不同的行:
line.set_ydata(y)
line.set_ydata(y)
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.animation as animation
import matplotlib.figure as mplfig
import tkinter as tk
def animate(i, line):
y = np.random.randint(10, size=len(x))
line.set_ydata(y)
return [line]
class Figure(tk.Frame):
def __init__(self, parent, controller, f):
tk.Frame.__init__(self, parent)
self.controller = controller
canvas = FigureCanvasTkAgg(f, self)
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
canvas.draw()
class Calculator(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.wm_title('Beam calculator')
container = tk.Frame(self)
container.pack(side='top', fill='both', expand=True)
for i, f in enumerate(figs):
bfig = Figure(container, controller=self, f=f)
bfig.grid(row=i, column=0, sticky="nsew")
# give the rows equal weight so they are allotted equal size
container.grid_rowconfigure(i, weight=1)
# you need to give at least one row and one column a positive weight
# https://stackoverflow.com/a/36507919/190597 (Bryan Oakley)
container.grid_columnconfigure(0, weight=1)
if __name__ == '__main__':
figs = [mplfig.Figure(figsize=(6, 2), dpi=100),
mplfig.Figure(figsize=(4, 2), dpi=100)]
axs = [f.add_subplot(111) for f in figs]
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ys = [[3, 5, 2, 7, 3, 5, 4, 6, 2, 2],
[6, 1, 4, 9, 4, 2, 5, 1, 2, 4]]
lines = [ax.plot(x, ys[i])[0] for i, ax in enumerate(axs)]
for ax in axs:
ax.set_ylim([0, 10])
app = Calculator()
app.geometry('1280x720')
anis = [animation.FuncAnimation(f, animate, interval=1000, fargs=[line])
for f, line in zip(figs,lines)]
app.mainloop()