来自计算矩阵的 3D 表面动画 [英] Animation of a 3D surface from calculated matrices

查看:37
本文介绍了来自计算矩阵的 3D 表面动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对由 Jacobi 迭代方法生成的 3D 表面进行动画处理,每次迭代后都会生成一个矩阵 UF 并将其存储在列表中 UFK 我能够自己绘制每次迭代,但我想创建一个动画来平滑地显示从凹面到平面的演变和收敛.谢谢.

I'm trying to animate a 3D surface generated out of Jacobi iterative method, after each iteration a matrix UF is generated and stored in a list UFK i was able to plot each iteration by it self but i want to create an animation that shows the evolution and convergence from concave to flat surface smoothly. Thank you.

import numpy as np 
import pandas as pd
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import matplotlib.animation as animation
%matplotlib notebook

Nx = 15        
Ny = 15         
tol = 1e-3      
err = 1        
k = 0         

Uy0 = 200*np.ones((1,Nx)) # Boundry condition at y=0 # lower boundry
UNy = 200*np.ones((1,Nx)) # Boundry condition at y=Ny # Upper boundary
Ux0 = 200*np.ones(Ny) # Boundry condition at x=0 # left boundry 
UNx = 200*np.ones(Ny) # Boundry condition at x=Nx # Right boundary 
# initial the whole matrix: the value at the interior nodes 
U = np.zeros((Ny,Nx))
#Adding boundry conditions to the matrix 
U[0] = UNy
U[Ny-1] = Uy0
U[:,Nx-1] = UNx
U[:,0]= Ux0
# Iterate Jacobi method  
UFK=[]
UFK.append(U.copy())
NFK=[]
UF=U.copy()

while True:
    k=k+1 
    for i in range (1,Nx-1):
        for j in range (1,Ny-1):
            UF[j,i] = (UF[j+1,i]+UF[j,i+1]+UF[j-1,i]+UF[j,i-1])*0.25 #the matrix i want to plot after each iteration 
    UFK.append(UF.copy())
    H = UFK[-1]-UFK[-2]
    N = np.linalg.norm(H)
    NFK.append(N)
    if N <= tol:
        break

def data(t,UFK,surf):
    for t in range(0,k-1):
        L = UFK[t]
        ax.clear()
        surf = ax.plot_surface(XX, YY, L, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
    return surf

fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(0, Nx)
Y = np.arange(0, Ny)
XX,YY = np.meshgrid(X, Y)
surf = ax.plot_surface(XX, YY, UFK[0],rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
ax.set_zlim(0, 200)
ax.zaxis.set_major_locator(LinearLocator(10))
fig.colorbar(surf, shrink=0.5, aspect=10)
ax.set_xlabel('X nodes - Axis')
ax.set_ylabel('Y nodes - Axis')
ax.set_zlabel('Value')



ani = animation.FuncAnimation(fig, data, fargs=(UFK,surf), interval=10, repeat=True )
plt.show()

推荐答案

首先,animation.FuncAnimation 的调用必须发生在 plt.show() 之前.

First of all the call to animation.FuncAnimation must happen before plt.show().

其次,您不需要为动画函数提供参数 UFK,surf.

Second, you do not need to give the arguments UFK,surf to the animating function.

第三,data 中的循环为每个动画步骤运行,因此您最终会得到相同的图.摆脱那个循环.

Third, the loop inside data is running for each animation step, therefore you would end up with identical plots at the end. Get rid of that loop.

第四,将动画限制为已计算的矩阵数.

Fourth, restrict the animation to the number of matrices you have calculated.

这是一个工作代码:

import numpy as np 
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator
import matplotlib.animation as animation


Nx = 15        
Ny = 15         
tol = 1e-3      
err = 1        
k = 0         

Uy0 = 200*np.ones((1,Nx)) # Boundry condition at y=0 # lower boundry
UNy = 200*np.ones((1,Nx)) # Boundry condition at y=Ny # Upper boundary
Ux0 = 200*np.ones(Ny) # Boundry condition at x=0 # left boundry 
UNx = 200*np.ones(Ny) # Boundry condition at x=Nx # Right boundary 
# initial the whole matrix: the value at the interior nodes 
U = np.zeros((Ny,Nx))
#Adding boundry conditions to the matrix 
U[0] = UNy
U[Ny-1] = Uy0
U[:,Nx-1] = UNx
U[:,0]= Ux0
# Iterate Jacobi method  
UFK=[]
UFK.append(U.copy())
NFK=[]
UF=U.copy()

while True:
    k=k+1 
    for i in range (1,Nx-1):
        for j in range (1,Ny-1):
            UF[j,i] = (UF[j+1,i]+UF[j,i+1]+UF[j-1,i]+UF[j,i-1])*0.25 #the matrix i want to plot after each iteration 
    UFK.append(UF.copy())
    H = UFK[-1]-UFK[-2]
    N = np.linalg.norm(H)
    NFK.append(N)
    if N <= tol:
        break

def data(t):
    # remove for loop here
    L = UFK[t]
    ax.clear()
    surf = ax.plot_surface(XX, YY, L, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
    ax.set_zlim([0,200]) # set zlim to be always the same for every frame


fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(0, Nx)
Y = np.arange(0, Ny)
XX,YY = np.meshgrid(X, Y)
surf = ax.plot_surface(XX, YY, UFK[0],rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
ax.set_zlim(0, 200)
ax.zaxis.set_major_locator(LinearLocator(10))
fig.colorbar(surf, shrink=0.5, aspect=10)
ax.set_xlabel('X nodes - Axis')
ax.set_ylabel('Y nodes - Axis')
ax.set_zlabel('Value')

ani = animation.FuncAnimation(fig, data, len(UFK), interval=50, repeat=True )
plt.show()

这篇关于来自计算矩阵的 3D 表面动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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