如何使用 python matplotlib 与另一个代码并行运行动画?
Posted
技术标签:
【中文标题】如何使用 python matplotlib 与另一个代码并行运行动画?【英文标题】:How to run animation in parallel with another code with python matplotlib? 【发布时间】:2022-01-14 19:30:09 【问题描述】:接下来的代码是用matplotlib.FuncAnimation
制作动画def animate(i):
x_val = changing_list
y_val = another_changing_list
plt.cla()
plt.scatter(x_val, y_val)
ani = animation.FuncAnimation(plt.gcf(), animate, interval =1000)
plt.show()
我想知道的是如何使用这样的循环同时运行该动画:
for value in values_list:
changing_list.append(value)
结果是一个动画,立即显示 changeing_list 列表中的新值。
如果有任何帮助,我将不胜感激!
【问题讨论】:
对我来说太难了,看看:***.com/questions/18791722/… 只是为了澄清(我是新手)同时意味着你想在两个不同的线程中运行绘图和循环,并将数据从一个线程传输到另一个线程? pypi.org/project/stream-engine StreamEngine 是 matplotlib Animation 类的扩展,使用户能够轻松绘制实时流数据。 找到matplotlib.org/3.1.0/gallery/misc/multiprocess_sgskip.html 【参考方案1】:不确定你的时代要求什么,很确定不是最好的方法:
尝试 1:
import time
from threading import Thread, Event, Lock
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from random import randint
changing_list = []
another_changing_list = []
values_list = [randint(0,i) for i in range(1,99)]
a = list(zip(changing_list, another_changing_list))
leng_start = len(changing_list)
lock = Lock()
evt = Event()
def loop_thread(values_list, changing_list, another_changing_list):
global a
t = 2
while True:
for value in values_list:
if not evt.is_set():
# print('is not set')
pass
if evt.is_set():
print('is set')
break
lock.acquire()
changing_list.append(values_list[randint(0,len(values_list)-1)])
another_changing_list.append(values_list[randint(0,len(values_list)-1)])
a = list(zip(changing_list, another_changing_list))
lock.release()
time.sleep((t))
# print(a)
# sys.stdout.flush()
break
print('exit thread')
def init_animate():
pass
cnt = 0
pippo = None
def animate(j):
global pippo
global cnt
global leng_start
global a
global changing_list
global another_changing_list
if len(changing_list) != leng_start:
leng_start = len(changing_list)
if pippo:
pippo.remove()
# print('leng_start : after ', leng_start, ' chan :' ,len(changing_list))
if (cnt % 2) == 0:
col = 'red'
else:
col = 'blue'
cnt += 1
pippo = axe.scatter(changing_list,another_changing_list, color = col)
# print(a[-1][0], a[-1][1],'len a ; ', len(a), ' j : ',j)
fig = plt.figure()
axe = fig.add_subplot(111)
thread_1 = Thread(target=loop_thread, args=(values_list, changing_list, another_changing_list))
thread_1.start()
animat = animation.FuncAnimation(fig, animate, init_func=init_animate,
interval=1000, repeat = False)
plt.show()
evt.set()
print('plt.show() closed')
尝试 2 尝试在不使用 animation.FuncAnimation
的情况下制作动画,每个散点都在一个循环中,但很容易不同步,只是在点数达到 4 或 5 后才计数:
import gc
import time
from threading import Thread, Event, Lock
import matplotlib.pyplot as plt
from random import randint
# changing_list = [1,2,3]
# another_changing_list = [8,7,99]
gc.collect()
changing_list = []
another_changing_list = []
values_list = [randint(0,i) for i in range(1,99)]
a = list(zip(changing_list, another_changing_list))
lock = Lock()
lock2 = Lock()
evt = Event()
evt2 = Event()
pippo = None
def plotting_thread(fig, axe):
global a
global pippo
global changing_list
global another_changing_list
leng_start = len(changing_list)
# print('leng_start :', leng_start)
cnt = 0
while True:
lock.acquire()
time.sleep(0.5)
if not evt.is_set():
# print('is not set')
# print('leng_start before if : ', leng_start)
if len(changing_list) != leng_start:
leng_start = len(changing_list)
# print('leng_start : after ', leng_start, ' chan :' ,len(changing_list))
if (cnt % 2) == 0:
col = 'red'
else:
col = 'blue'
cnt += 1
# print(col)
axe.clear()
for i in range(len(changing_list)-1):
time.sleep(1)
axe.scatter( changing_list[i], another_changing_list[i], color=col)
fig.canvas.draw_idle()
# plt.draw() ### works too ?
if evt.is_set():
print('is set plotting')
break
lock.release()
def loop_thread(values_list):
global a
global changing_list
global another_changing_list
while True:
t = 2
time.sleep((t))
lock2.acquire()
if not evt2.is_set():
# print('is not set')
changing_list.append(values_list[randint(0,len(values_list)-1)])
another_changing_list.append(values_list[randint(0,len(values_list)-1)])
a = list(zip(changing_list, another_changing_list))
if evt2.is_set():
print('is set loop_thread')
break
# print(a)
# print(changing_list)
# print(another_changing_list)
lock2.release()
print('exit thread')
fig = plt.figure() # the figure will be reused later
axe = fig.add_subplot(111)
thread_1 = Thread(target=loop_thread, args=((values_list,)))
thread_2 = Thread(target=plotting_thread, args=(fig, axe))
thread_1.start()
thread_2.start()
plt.show()
evt.set()
evt2.set()
print('plt.show() closed')
已编辑:上面的代码可以正常使用:
t = 2
while True:
t +=1
time.sleep((t))
lock2.acquire()
在loop_thread
中这样每次迭代动画有更多的时间来完成
在某处读到animation.FuncAnimation
必须在主线程中。无法使用 animation.FuncAnimation
将其置于 while 循环中以将每个系列从“add+1 element to serie”循环中动画化。
【讨论】:
以上是关于如何使用 python matplotlib 与另一个代码并行运行动画?的主要内容,如果未能解决你的问题,请参考以下文章
如何在ubuntu上使用pip为python3升级matplotlib?