2010-11-15 11 views
5

Snippet:Fare Matplotlib correre più veloce

ax = Axes3D(self.fig) 

u = np.linspace(0, 2 * np.pi, 100) 
v = np.linspace(0, np.pi, 100) 

x = self.prop * np.outer(np.cos(u), np.sin(v)) 
y = self.prop * np.outer(np.sin(u), np.sin(v)) 
z = self.prop * np.outer(np.ones(np.size(u)), np.cos(v)) 

t = ax.plot_surface(x, y, z, rstride=6, cstride=6,color='lightgreen',linewidth=0) 
self.canvas.draw() 

È possibile che questo frammento rappresenta graficamente una sfera in Tkinter usando matplotlib. Ho riscontrato che i valori più elevati di rstride e cstride consentono al grafico di ottenere prestazioni leggermente migliori. Tuttavia, danno alla sfera una strana forma a coste. Mi chiedevo quali altre cose potessero essere modificate nel codice sopra riportato per migliorare le prestazioni.

risposta

13

In realtà, il problema è più all'interno plot_surface. Ci sono molte cose che possono essere fatte per migliorarlo. Per esempio, l'ombreggiatura prende un sacco di tempo e solo cambiando una sola riga:

colors = [color * (0.5 + norm(v) * 0.5) for v in shade] 

a

colors = np.outer(0.5+norm(shade)*0.5,color) 

all'interno di una delle funzioni utilizzate da plot_surface, ho ottenuto una riduzione di circa il 28% in il runtime complessivo. Perché? La funzione norm (beh, tipo di classe) è impostata per la vettorizzazione, ma non è stata utilizzata in questo modo. So che ci sono molte cose simili all'interno di queste funzioni che non sono molto ottimali. Modifica delle due linee:

for rs in np.arange(0, rows-1, rstride): 
    for cs in np.arange(0, cols-1, cstride): 

a

for rs in xrange(0,rows-1,rstride): 
    for cs in xrange(0,cols-1,cstride): 

nella funzione plot_surface si dà un altro sostanziale miglioramento - ora siamo in calo del 33% rispetto al tempo di esecuzione originale.

Da quello che ho visto, il codice non è stato scritto per l'efficienza tanto da farlo funzionare da quello che posso dire - ci sono molti posti in cui le cose potrebbero essere fatte per essere più vettorializzate usando Numpy e non lo sono. Temo che ciò che è veramente necessario sia qualche ottimizzazione delle funzioni matplotlib.

+0

Queste sembrano davvero ottime correzioni su quale file è la funzione plot_surface in? – rectangletangle

+0

Si trova nel file mpl_toolkits/mplot3d/axes3d.py. La seconda modifica è in realtà in "trama_superficie". La prima modifica è all'interno di una funzione chiamata '_shade_colors' che chiama' plot_surface'. Sto lavorando per inviare queste modifiche alla fonte. –

+0

Wow, ecco alcune cose davvero buone! Grazie – rectangletangle

1

A questo punto è il pacchetto di visualizzazione che ha il collo di bottiglia. Il numero di punti è definito e costante.

Provare se l'utilizzo di psyco può accelerarlo (è solo a 32 bit).