如何使用matplotlib使用动画更新打印标题?

2024-04-19 14:00:23 发布

您现在位置:Python中文网/ 问答频道 /正文

低于我的密码。为什么标题不更新每一个记号?我读到这个: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 在@eyllansec应答之后,我编辑了这段代码:

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,

现在文本可以正常工作,但是箭头更新不是“流动的”(它会出现并使每个更新都消失)。


Tags: importtruedatatitlematplotlibdefasupdate
1条回答
网友
1楼 · 发布于 2024-04-19 14:00:23

FuncAnimation中使用blit=True时会出现问题。这将存储背景,并且只更新update函数返回的艺术家。但是,恢复的背景将覆盖标题,因为它在轴之外。

可能的解决方案是:

  1. 把标题放在轴里面。
  2. 不要使用blitting
  3. 也可以使用ArtistAnimation而不是FuncAnimation。但我还没有测试过。

请注意,在更新函数中使用plt.draw或类似的方法(如其他答案中所建议的)是没有意义的,因为它破坏了使用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()

enter image description here

注意,我稍微更改了角度设置,因为arrow的角度必须是弧度而不是度数。

2。不使用blitting(blit=False

你可以决定不使用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()

enter image description here

相关问题 更多 >