如何使用动画使用matplotlib更新剧情标题? [英] How to update plot title with matplotlib using animation?

查看:76
本文介绍了如何使用动画使用matplotlib更新剧情标题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的代码下面.为什么标题不会每隔一滴就更新一次?我读了这篇文章:带有blit的Matplotlib动画-如何更新绘图标题?,但没有用.

Below my code. Why doesn't title updates every tick? I read this: Matplotlib animation with blit -- how to update plot title? but it wasn't useful.

#! /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回答后,我编辑这段代码:

EDIT n. 1 After @eyllanesc answer, I edit this piece of code:

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,

现在文本可以正常工作,但是箭头更新不是流畅"的(每次更新都会出现和消失).

Now text works correctly, but the arrow updating is not "fluid" (it appeares and disappeares every update).

推荐答案

FuncAnimation中使用blit=True时出现问题.这将存储背景,并且仅更新更新功能返回的艺术家.但是,还原的背景将覆盖标题,因为它位于轴外.

The problem arises when using blit=True in the FuncAnimation. This will store the background and only update the artists returned by the update function. However, the restored background will overwrite the title, since it is outside the axes.

可能的解决方案是:

  1. 将标题放在轴内.
  2. 不要发短信
  3. 可能也可以使用ArtistAnimation代替FuncAnimation.但是我还没有测试.
  1. Put the title inside the axes.
  2. Don't use blitting
  3. Possibly using an ArtistAnimation instead of a FuncAnimation would work as well. But I haven't tested it.

请注意,在更新功能内部使用plt.draw或类似功能(如在其他答案中所建议的)是没有意义的,因为它会破坏使用blitting的所有优势,并使动画比不使用blitting的情况更慢.

Note that using plt.draw or similar inside the updating function (as proposed in other answers) does not make sense, since it destroys all the advatages of using blitting and makes the animation even slower than in the case of not using blitting.

您可以使用位于轴内的title = ax.text(..)代替轴外的标题.可以为每次迭代title.set_text("..")更新此文本,然后必须由更新功能(return arr1, title,)返回该文本.

Instead of a title outside the axes, you may use a title = ax.text(..) positionned inside the axes. This text can be updated for each iteration title.set_text("..") and must then be returned by the updating function (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的角度必须为辐射度而不是度数.

Note that I slightly changed the angle setting, since it the angle for arrow must be in radiants instead of degrees.

您可以决定不使用blitting,这在对动画速度的要求不是很高的情况下才有意义.不使用blitting可以在轴外使用普通标题.但是,在这种情况下,您需要在每次迭代中都删除美术师(否则,最终会在绘图中出现很多箭头).

You may decide not to use blitting, which makes sense when the requirements on the speed of the animation are not so high. Not using blitting allows to use a normal title outside the axes. However, in this case you would need to remove the artist for each iteration (otherwise one would end up with a lot of arrows in the plot).

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()

这篇关于如何使用动画使用matplotlib更新剧情标题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆