如何在动画中放置文本



我正试图将文本放在matplotlib动画中。(希望情节之外,但我还不担心)

我试着遵循这个解决方案,但是我的代码有点复杂,因为它不是每次只给出一行。这是我的代码

import math
import argparse
import os
import json
import sys
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation ,FFMpegWriter

line_x=[ 0,1,2,3,4,5,6,7,8,9,10,11,12  ]
line1_y=[ 3,5,7,9,11,19,23,26,29,31,37,40,45  ]
line2_y=[0,2,5,7,10,10,8,5,3,2,1,3,5]
line3_y=[39,38,32,29,26,22,19,13,10,8,7,6,3]
set_lines=[line1_y,line2_y,line3_y]
n_lineas=[1,2,3,1,3,2,3,1,3,2,1,2]
show=True
thecolors=['blue','red','violet']
thelegends=['unus','duo','tres']
print(sys.argv)
if len(sys.argv)==2 and sys.argv[1]=='movie':
show=False

def get_n(thelist,c):
while(c>=len(thelist)):
c-len(thelist)
return thelist[c]

class Update:
def __init__(self,ax,limit_x):
self.ax = ax
self.lx=limit_x
if limit_x!=0:
self.ax.set_xlim(0,limit_x)
self.ax.set_ylim(0,45)
self.ax.set_aspect('equal')
self.ax.grid(True)
self.lines=()
self.counter=0
self.text=self.ax.text(0,0,'')
def __call__(self, frame):
print("Frame: ",frame)
lines=[]
self.ax.cla()
self.ax.set_xlim(0,self.lx)
self.ax.set_ylim(0,45)
self.ax.grid(True)
self.ax.set_xlabel("Y (meters)")
self.ax.set_ylabel("X (meters)")
n_lines_this_time=get_n(n_lineas,self.counter)
self.counter+=1
print(n_lines_this_time,"lines this time")
for myline in range(n_lines_this_time):
#line,=self.ax.plot([],[],'.-',color=gt_color,label=legend)
line,=self.ax.plot([],[],'.-',color=thecolors[myline],label=thelegends[myline])
x = []
y = []
for v in range(13):
x.append(line_x[v])
y.append(set_lines[myline][v])
line.set_xdata(x)
line.set_ydata(y)
lines.append(line)
plt.legend()
self.lines=tuple(lines)
self.text.set_text("Frame "+str(frame))
self.text.set_position((0,0))
#return self.lines,self.text  #<---HERE this does not work!!!
return self.lines

def init(self):
print("Init")
line,=self.ax.plot([],[])
self.ax.grid(True)
self.ax.set_xlabel("Y (meters)")
self.ax.set_ylabel("X (meters)")
self.text.set_text('')
self.text.set_position((0,0))
return line,self.text,
#return line,

fig, ax = plt.subplots(1, 1,figsize=(10,10))
plt.gcf().canvas.mpl_connect(
'key_release_event',
lambda event: [exit(0) if event.key == 'escape' else None])
plt.xlabel("Y (meters)") 
plt.ylabel("X (meters)")
plt.legend()
ug_i = Update(ax,13)
anim = FuncAnimation(fig, ug_i,init_func=ug_i.init, frames=10, interval=1000, blit=True,repeat=False)
if not show:  
writervideo = FFMpegWriter(fps=1)
anim.save('whatever.mp4', writer=writervideo)
print('done')
plt.close()
else:
#plt.legend()
plt.show()

在当前状态下,文本不显示(当然),但当我试图返回它(如上面的注释("HERE")所标记的)时,它崩溃了,给我错误

Traceback (most recent call last):
File "/home/kansai/miniconda3/envs/roscv/lib/python3.7/site-packages/matplotlib/backend_bases.py", line 1194, in _on_timer
ret = func(*args, **kwargs)
File "/home/kansai/miniconda3/envs/roscv/lib/python3.7/site-packages/matplotlib/animation.py", line 1442, in _step
still_going = Animation._step(self, *args)
File "/home/kansai/miniconda3/envs/roscv/lib/python3.7/site-packages/matplotlib/animation.py", line 1173, in _step
self._draw_next_frame(framedata, self._blit)
File "/home/kansai/miniconda3/envs/roscv/lib/python3.7/site-packages/matplotlib/animation.py", line 1192, in _draw_next_frame
self._draw_frame(framedata)
File "/home/kansai/miniconda3/envs/roscv/lib/python3.7/site-packages/matplotlib/animation.py", line 1748, in _draw_frame
key=lambda x: x.get_zorder())
File "/home/kansai/miniconda3/envs/roscv/lib/python3.7/site-packages/matplotlib/animation.py", line 1748, in <lambda>
key=lambda x: x.get_zorder())
AttributeError: 'tuple' object has no attribute 'get_zorder'
Aborted (core dumped)

什么是失败的,我如何显示文本?(如果在剧情之外更好)

取消注释代码行后,我没有得到任何错误,但是文本不可见。所以,不是使用ax.text,而是使用fig.text:现在文本在绘图区域外可见。

import math
import argparse
import os
import json
import sys
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation ,FFMpegWriter

line_x=[ 0,1,2,3,4,5,6,7,8,9,10,11,12  ]
line1_y=[ 3,5,7,9,11,19,23,26,29,31,37,40,45  ]
line2_y=[0,2,5,7,10,10,8,5,3,2,1,3,5]
line3_y=[39,38,32,29,26,22,19,13,10,8,7,6,3]
set_lines=[line1_y,line2_y,line3_y]
n_lineas=[1,2,3,1,3,2,3,1,3,2,1,2]
show=True
thecolors=['blue','red','violet']
thelegends=['unus','duo','tres']
# print(sys.argv)
# if len(sys.argv)==2 and sys.argv[1]=='movie':
#     show=False

def get_n(thelist,c):
while(c>=len(thelist)):
c-len(thelist)
return thelist[c]

class Update:
def __init__(self,fig,ax,limit_x):
self.ax = ax
self.lx=limit_x
if limit_x!=0:
self.ax.set_xlim(0,limit_x)
self.ax.set_ylim(0,45)
self.ax.set_aspect('equal')
self.ax.grid(True)
self.lines=()
self.counter=0
self.text=fig.text(0.15,0.5,'')
def __call__(self, frame):
print("Frame: ",frame)
lines=[]
self.ax.cla()
self.ax.set_xlim(0,self.lx)
self.ax.set_ylim(0,45)
self.ax.grid(True)
self.ax.set_xlabel("Y (meters)")
self.ax.set_ylabel("X (meters)")
n_lines_this_time=get_n(n_lineas,self.counter)
self.counter+=1
print(n_lines_this_time,"lines this time")
for myline in range(n_lines_this_time):
#line,=self.ax.plot([],[],'.-',color=gt_color,label=legend)
line,=self.ax.plot([],[],'.-',color=thecolors[myline],label=thelegends[myline])
x = []
y = []
for v in range(13):
x.append(line_x[v])
y.append(set_lines[myline][v])
line.set_xdata(x)
line.set_ydata(y)
lines.append(line)
plt.legend()
self.lines=tuple(lines)
self.text.set_text("Frame "+str(frame))
return self.lines,self.text  #<---HERE this does not work!!!
return self.lines

def init(self):
print("Init")
line,=self.ax.plot([],[])
self.ax.grid(True)
self.ax.set_xlabel("Y (meters)")
self.ax.set_ylabel("X (meters)")
self.text.set_text('')
return line,self.text,
#return line,

fig, ax = plt.subplots(1, 1)
plt.gcf().canvas.mpl_connect(
'key_release_event',
lambda event: [exit(0) if event.key == 'escape' else None])
plt.xlabel("Y (meters)") 
plt.ylabel("X (meters)")
plt.legend()
ug_i = Update(fig,ax,13)
anim = FuncAnimation(fig, ug_i,init_func=ug_i.init, frames=10, interval=1000, blit=True,repeat=False)
if not show:  
writervideo = FFMpegWriter(fps=1)
anim.save('whatever.mp4', writer=writervideo)
print('done')
plt.close()
else:
#plt.legend()
plt.show()

最新更新