Как превратить этот сюжет в анимацию? У меня есть сюжет, но я бы хотел как-нибудь превратить его в анимацию - PullRequest
0 голосов
/ 07 мая 2020

Последние несколько ночей я боролся, как превратить мои волны на графике в какую-то анимацию после каждого временного шага или после каждого шага x. Как я могу изменить и написать код, чтобы моя программа как-то анимировалась каждый раз на шаге волны. Я очень новичок в python и программировании и никогда раньше не использовал анимационную часть matplotlib.

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




T = 20.0 # t
X = 10.0 # x

n = 300
m = 300

#positions of time and space, xp= x position accross grid, tp = t position accross grid
tp = T / (n - 1)
xp = X / (m - 1)

C = 0.5

U = np.zeros((n, m))

# Set the initial values for each x position
for i in range(0, n):
    U[i, 0] = np.exp(- (i * xp - 2.5) ** 2)


for i in range(1, n): # across x
    for j in range(1, m): # across t
        U[i, j] = (xp * U[i, j - 1] + C * tp * U[i - 1, j]) / (xp + C * tp) # equation for new distribution value

fig = plt.figure(1)

#gives time position instead of time step
tn = np.zeros((m, 1))
for j in range(0, m):
    tn[j] = j * tp

#gives x position instead of x step
xn = np.zeros((n, 1))
for j in range(0, n):
    xn[j] = j * xp

for i in [0, 50, 100, 150, 200, 250, 299 ]: # selects which position of time 
    label = 't = ' + str(tn[i][0]) # lables legend
    subfig = fig.add_subplot(1, 1, 1)
    subfig.plot(xn, U[:, i], label=label)
    subfig.legend()
    subfig.grid(True)
    print(tn)

# Save Image
plt.xlabel('x: position')
plt.ylabel('u: u(x, t)')
plt.title(r'$\frac{\partial u}{\partial t} + C \frac{\partial u}{\partial x} = 0$')

plt.savefig('transport-equation')`

1 Ответ

1 голос
/ 07 мая 2020

plt - сложный пакет, к которому нужно привыкнуть. В общем, графикой нелегко управлять, и plt старается быть как можно более простой, но при этом обеспечивая максимальную гибкость. В общем, когда вы используете plt, существует множество глобальных переменных, которые автоматически генерируются, обновляются, очищаются и обрабатываются за вас. Когда вы используете "plt.xlabel", вы действительно применяете это к определенной оси в определенной фигуре, которая автоматически определяется для вас. Если вам нужен больший контроль в plt и / или вы хотите сделать что-то сложное, например анимацию, вам нужно сделать свои глобальные переменные явными.

#Create xn and U. 

import matplotlib.pyplot as plt

figure = plt.figure()                     #This is the window that pops open. 
axis   = figure.add_subplot(1,1,1)        #This is a graph/grid.  
axis.grid(True)                           #Add a grid to the axis. 
label  = 't = ' + str(tn[i][0])
plots  = axis.plot(xn,U[:,0],label=label) #These are the plots of data with X and Y. 

Массивы X и Y могут генерировать более одного графика за раз, следовательно, графики представляют собой список с одним элементом в нем. Чтобы понять, как это работает, вы можете буквально манипулировать данными в реальном времени и наблюдать за их изменением в окне plt.

figure.show()
plots[0].set_ydata(U[:,10])
plots[0].set_ydata(U[:,-1])
# Close the window when done. 

Чтобы создать анимацию, нам нужно указать plt, что нужно применить анимацию к данной фигуре. plt затем попытается обновить цифру и все, что к ней прикреплено. Если у вас уже открыто окно, анимация все равно будет применена и работать, но вы также сохраните все, что изначально было построено на рисунке (поэтому мы должны закрыть окно и перекодировать анимацию). plt НЕ следует соглашению о том, что выполнение одной строки за раз аналогично выполнению всех строк одновременно. plt ведет себя по-разному до и после открытия окна.

#Create xn and U. 

import matplotlib.pyplot as plt

figure = plt.figure()
axis   = figure.add_subplot(1,1,1)
axis.grid(True)
label  = 't = ' + str(tn[i][0])
plots  = axis.plot(xn,U[:,0],label=label)

def animate_function(frame):       
    frame %= 300                   #frame is an integer that counts from 0. 
    plots[0].set_ydata(U[:,frame]) #Change which globals you want. 
    return plots                   #Return the changed items so plt knows. 

#Tell plt to apply this animation function to your figure. 
#Tell plt to wait approximately 10ms per frame. 
#Tell plt to only update pixels that actually change (called blit). 
#Save to a global variable so plt doesn't get upset at you. 
ani    = animation.FuncAnimation(figure,animate_function,interval=10,blit=True)

#Now open the window and show the figure. 
figure.show()
...