2013-06-25 5 views
7

Ich habe eine 3D-Plot-Oberfläche aus einer Datei erstellt und ich versuche, die Handlung zu animieren. Ich habe die Beispiele in der Matplotlib-Webseite und andere Beispiele in SO gelesen, und beachten Sie, dass ich eine Update-Funktion erstellen muss, um die Werte in der Datei durchlaufen und erstellen Sie dann ein matplotlib.animation Objekt, aber ich verstehe nicht, wie es geht .Wie man 3d plot_surface in Matplotlib animiert

Ich würde mich sehr freuen, wenn mir jemand die Syntax der Update-Funktion erklären könnte und wie man sie im matplotlib.animation Objekt verwenden könnte.

Meine Daten sind ein mehrdimensionales Array mit 498 Zeilen und für jede Zeile habe ich ein Array mit 64x128 Werten. Die Daten sind wie folgt organisiert:

Daten sind eine Zeitreihe von einer Kraftmessplatte und jede der 500 Linien ist ein Rahmen, was bedeutet, dass dieser Versuch 10 Sekunden dauert. Für jeden Frame habe ich ein Array mit 64x128 Werten.

Dies ist mein Code bis jetzt:

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() 

Antwort

2

Dies ist möglicherweise nicht der optimale Weg, aber ich fand die Dokumentation/Beispiele zu nicht ausreichend.

Was ich verwendet habe, ist die folgende Lösung: Verwenden Sie animation.FuncAnimation, um eine Funktion aufzurufen. In dieser Funktion löschen und neu zeichnen, wie folgt:

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,