在我的代码下面。为什么每个滴答都没有标题更新?我读到了这个:Matplotlib animation with blit -- how to update plot title?但它没有用。
#! /usr/bin/python3
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time
import random as rr
plt.rc('grid', color='#397939', linewidth=1, linestyle='-')
plt.rc('xtick', labelsize=10)
plt.rc('ytick', labelsize=5)
width, height = matplotlib.rcParams['figure.figsize']
size = min(width, height)
fig = plt.figure(figsize=(size, size))
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True, facecolor='#cfd98c')
ax.set_rmax(20.0)
plt.grid(True)
plt.title("")
def data_gen(t=0):
tw = 0
phase = 0
ctn = 0
while True:
ctn += 1
if ctn == 1000:
phase=round(rr.uniform(0,180),0)
tw = round(rr.uniform(0,20),0)
ctn = 0
yield tw, phase
def update(data):
tw, phase = data
print(data)
ax.set_title("|TW| = {}, Angle: {}°".format(tw, phase))
arr1 = plt.arrow(phase, 0, 0, tw, alpha = 0.5, width = 0.080,
edgecolor = 'red', facecolor = 'red', lw = 2, zorder = 5)
return arr1,
ani = animation.FuncAnimation(fig, update, data_gen, interval=100, blit=True, repeat=False)
plt.show()
编辑n。 1 在@eyllanesc回答之后,我编辑了这段代码:
def data_gen(t=0):
tw = 10
phase = 0
ctn = 0
while True:
if phase < 2*180:
phase += 1
else:
phase=0
yield tw, phase
def update(data):
tw, phase = data
angolo = phase /180 * np.pi
print("|TW| = {}, Angle = {}°".format(tw,phase))
ax.set_title("|TW| = {}, Angle: {}°".format(tw, phase))
arr1 = plt.arrow(angolo, 0, 0, tw, alpha = 0.5, width = 0.080, edgecolor = 'red', facecolor = 'red', lw = 2, zorder = 5)
plt.draw()
return arr1,
现在文字工作正常,但箭头更新不是&#34;流畅&#34; (它出现并消失每次更新)。
答案 0 :(得分:9)
在blit=True
中使用FuncAnimation
时出现问题。这将存储背景并仅更新由更新功能返回的艺术家。但是,恢复后的背景将覆盖标题,因为它位于轴外。
可能的解决方案是:
ArtistAnimation
代替FuncAnimation
也可以。但我还没有测试过它。请注意,在更新功能中使用plt.draw
或类似内容(如在其他答案中所提议的)是没有意义的,因为它破坏了使用blitting的所有优点并且使动画甚至比不使用blitting时更慢使用blitting。
blit=True
)您可以在轴内使用title = ax.text(..)
,而不是轴外的标题。可以为每次迭代title.set_text("..")
更新此文本,然后必须由更新函数(return arr1, title,
)返回。
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
plt.rc('grid', color='#397939', linewidth=1, linestyle='-')
plt.rc('xtick', labelsize=10)
plt.rc('ytick', labelsize=5)
width, height = matplotlib.rcParams['figure.figsize']
size = min(width, height)
fig = plt.figure(figsize=(size, size))
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True, facecolor='#cfd98c')
ax.set_rmax(20.0)
plt.grid(True)
title = ax.text(0.5,0.85, "", bbox={'facecolor':'w', 'alpha':0.5, 'pad':5},
transform=ax.transAxes, ha="center")
def data_gen(t=0):
tw = 10
phase = 0
while True:
if phase < 2*180:
phase += 2
else:
phase=0
yield tw, phase
def update(data):
tw, phase = data
title.set_text(u"|TW| = {}, Angle: {}°".format(tw, phase))
arr1 = ax.arrow(np.deg2rad(phase), 0, 0, tw, alpha = 0.5, width = 0.080,
edgecolor = 'red', facecolor = 'red', lw = 2, zorder = 5)
return arr1,title,
ani = animation.FuncAnimation(fig, update, data_gen, interval=100, blit=True, repeat=False)
plt.show()
请注意,我稍微改变了角度设置,因为arrow
的角度必须是辐射而不是度。
blit=False
)你可能决定不使用blitting,这对动画速度的要求不那么高是有意义的。不使用blitting允许使用轴外的普通标题。但是,在这种情况下,您需要为每次迭代删除艺术家(否则最终会在图中出现很多箭头)。
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
plt.rc('grid', color='#397939', linewidth=1, linestyle='-')
plt.rc('xtick', labelsize=10)
plt.rc('ytick', labelsize=5)
width, height = matplotlib.rcParams['figure.figsize']
size = min(width, height)
fig = plt.figure(figsize=(size, size))
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True, facecolor='#cfd98c')
ax.set_rmax(20.0)
plt.grid(True)
def data_gen(t=0):
tw = 10
phase = 0
while True:
if phase < 2*180:
phase += 2
else:
phase=0
yield tw, phase
arr1 = [None]
def update(data):
tw, phase = data
ax.set_title(u"|TW| = {}, Angle: {}°".format(tw, phase))
if arr1[0]: arr1[0].remove()
arr1[0] = ax.arrow(np.deg2rad(phase), 0, 0, tw, alpha = 0.5, width = 0.080,
edgecolor = 'red', facecolor = 'red', lw = 2, zorder = 5)
ani = animation.FuncAnimation(fig, update, data_gen, interval=100, blit=False, repeat=False)
plt.show()