анимированные подзаговоры с использованием matplotlib и информационного текста с текущими значениями

Я пытаюсь объединить примеры из здесь и здесь. info_text не работает, не обновляется. Я получаю сообщение об ошибке:

AttributeError: 'list' object has no attribute 'set_animated'

Кто-нибудь знает, почему? Вот мой код:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from pprint import pprint

total_subplots = 2
# initialize the data arrays 
#xdata, y1data, y2data = [], [], []
signals =list()
for i in range(0, total_subplots):
    signals.append([])  # [[],[]] 
xdata = list()
ax = list()
lines = list()
info_text = list()

colors=['blue', 'red']


def data_gen():

    t_max = 1000.0
    t = 0
    dt = 0.05

    y = [''] * total_subplots

    while t < t_max:

        t += dt
        y[0] = np.sin(2*np.pi*t) * np.exp(-t/10.)
        y[1] = np.cos(2*np.pi*t) * np.exp(-t/10.)
        # adapted the data generator to yield both sin and cos
        yield t, y


def run(data):
    # update the data
    t, y = data

    xdata.append(t)

    for i in range(0, total_subplots):
        signals[i].append(y[i])

    # axis limits checking. Same as before, just for both axes
    for i in range(len(ax)):
        xmin, xmax = ax[i].get_xlim()
        if t >= xmax:
            ax[i].set_xlim(xmin, 2*xmax)
            ax[i].figure.canvas.draw()

    # update the data of both line objects
    for i in range(len(lines)):
        lines[i].set_data(xdata, signals[i])
        text = 'Time = %.1f s \nValue = %.1f'%(t, y[i])        
        info_text[i].set_text(text)    

    return lines, info_text


# Initialize
# create a figure with two subplots
#fig, (ax1, ax2) = plt.subplots(2,1)
fig = plt.figure()
for i in range(0, total_subplots):
    axis = fig.add_subplot(2, 1, (i+1))
    ax.append(axis) 

    # intialize two line objects (one in each axes)
    line, = ax[i].plot([], [], lw=2, color=colors[i])
    lines.append(line)

    # the same axes initalizations as before (just now we do it for both of them)
    ax[i].set_ylim(-1.1, 1.1)
    ax[i].set_xlim(0, 5)
    ax[i].grid()


    text = ax[i].text(0.05, 0.9, '', transform=ax[i].transAxes)
    info_text.append(text)

# Run
ani = animation.FuncAnimation(fig, run, 
                              data_gen,
                              interval=10,
                              blit=True,
                              repeat=False)

plt.show()

person ioaniatr    schedule 22.11.2018    source источник


Ответы (1)


Я думаю, вы имеете в виду вернуть итерацию художников для анимации. Тем не менее, это должен быть один единственный итеративный объект. Например.

return lines + info_text
person ImportanceOfBeingErnest    schedule 22.11.2018
comment
Оно работает!! Спасибо!! Но как на самом деле сделать его итерируемым таким образом? - person ioaniatr; 23.11.2018
comment
Списки итерабельны в python. - person ImportanceOfBeingErnest; 23.11.2018
comment
Я видел, что на самом деле он объединяет 2 списка в один и выглядит так: [<matplotlib.lines.Line2D object>, <matplotlib.lines.Line2D object>,<matplotlib.text.Text object>, <matplotlib.text.Text object>], но подумал, что должно быть так: [<matplotlib.lines.Line2D object>, <matplotlib.text.Text object>, <matplotlib.lines.Line2D object>,<matplotlib.text.Text object>] - person ioaniatr; 23.11.2018
comment
Какая разница? - person ImportanceOfBeingErnest; 23.11.2018
comment
Может быть, это помещает неправильный info_text в неправильный график. У каждого графика есть свои info_text. - person ioaniatr; 23.11.2018
comment
Но вы хотите показывать все информационные_тексты в каждом кадре анимации, верно? - person ImportanceOfBeingErnest; 23.11.2018