2013-06-25 28 views
7

Tôi đã tạo một bề mặt lô 3D từ một tệp và tôi đang cố gắng tạo hiệu ứng cho cốt truyện. Tôi đã đọc các ví dụ trong trang web matplotlib và các ví dụ khác trong SO, và lưu ý rằng tôi cần tạo một hàm cập nhật để lặp qua các giá trị trong tệp và sau đó tạo đối tượng matplotlib.animation nhưng tôi không hiểu cách thực hiện .Làm thế nào để animate 3d plot_surface trong matplotlib

Tôi sẽ đánh giá rất cao nếu ai đó có thể giải thích cho tôi cú pháp của hàm cập nhật và cách sử dụng nó trong đối tượng matplotlib.animation.

Dữ liệu của tôi là mảng đa chiều với 498 dòng và cho mỗi dòng tôi có một mảng có giá trị 64x128. Dữ liệu được sắp xếp theo cách sau:

Dữ liệu là chuỗi thời gian từ một đĩa lực và mỗi một trong 500 dòng là một khung, nghĩa là thử nghiệm này kéo dài 10 giây. Đối với mỗi khung tôi có một mảng khác với giá trị 64x128.

Đây là mã của tôi cho đến bây giờ:

from mpl_toolkits.mplot3d import * 
import matplotlib.pyplot as plt 
import numpy as np 
from random import random, seed 
from matplotlib import cm 
from mpl_toolkits.mplot3d import axes3d 
import matplotlib.animation as animation 

source_path = "c:\\Projecto\\" 
destination_path = "c:\\Projecto\\EntirePlate\\" 
#fid = np.loadtxt(source_path + "rolloff_xls.txt",dtype=str) 

fid_MP = open(source_path + "101mp - Entire plate roll off.xls","Ur") 
lines_MP = fid_MP.readlines() 
fid_MP.close() 

values_MP = [] 

for i in lines_MP: 
     if i[0].isdigit(): 
      values_MP.append(i) 

values = np.loadtxt(values_MP,dtype=float) 

new_values_MP =[] 

for i in range(0,(len(values_MP)/64)): 
    for j in range(0,64): 
     new_values_MP.append([[i],[j],values[j]]) 

new_values_MP = np.asarray(new_values_MP) 

fig = plt.figure() 
ax = fig.gca(projection='3d')    # to work in 3d 
plt.hold(True) 

x_surf = np.arange(0,128)    # generate a mesh 
y_surf = np.arange(0,64) 
x_surf, y_surf = np.meshgrid(x_surf, y_surf) 
z_surf = [] 

for i in range(0,64): 
    # print(new_values[i]) 
    z_surf.append(np.asarray(new_values_MP[i][2])) # ex. function, which depends on x and y 

z_surf = np.asarray(z_surf).reshape([64,128]) 

ax.plot_surface(x_surf, y_surf, z_surf, rstride=2, cstride=2 ,cmap=cm.jet) # plot a 3d surface plot 

ax.set_xlabel('Medio Lateral - Axis') 
ax.set_ylabel('Anterior Posterior - Axis') 
ax.set_zlabel('Pressure (P)') 

def update(x_values, y_values, z_values): 
    for i in range(0,len(values_MP)/64): 
     x_surf = x_values 
     y_surf = y_values 
     z_surf.set_data(new_values_MP[i,2]) 
    return z_surf 

ani = animation.FuncAnimation(fig, update, frames=xrange(len(values_MP)/64), 
           interval=50, blit=False) 
plt.show() 

Trả lời

2

Đây có thể không phải là cách tối ưu, nhưng tôi thấy các tài liệu hướng dẫn/ví dụ không đủ quá.

Điều tôi đã giải thích là giải pháp sau: sử dụng hoạt ảnh.FuncAnimation để gọi hàm. Trong chức năng đó rõ ràng và vẽ lại, như vậy:

from __future__ import division 
from matplotlib import cm 
from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
import mpl_toolkits.mplot3d.axes3d as p3 
import matplotlib.animation as animation 
import numpy as np 

plot_args = {'rstride': 1, 'cstride': 1, 'cmap': 
      cm.bwr, 'linewidth': 0.01, 'antialiased': True, 'color': 'w', 
      'shade': True} 

soln = np.zeros((size, size)) 
midpoint = size // 2 
soln[midpoint, midpoint] = 1 

#first frame 
X = range(size) 
Y = range(size) 
X, Y = np.meshgrid(X, Y) 
plot = ax.plot_surface(X, Y, soln, **plot_args) 
pam_ani = animation.FuncAnimation(fig, data_gen, fargs=(soln, plot), 
           interval=30, blit=False) 

def data_gen(framenumber, soln, plot): 
    #change soln variable for the next frame 
    ... 
    ax.clear() 
    plot = ax.plot_surface(X, Y, soln, **plot_args) 
    return plot, 
Các vấn đề liên quan