2012-10-24 16 views
14

Sto creando un paio di grafici PDF con matplotlib che è composto da 400 sottotrame. Ognuno ha solo 5 punti dati. Ci vogliono 420 s su un buon computer per salvare 5 foto pdf. C'è un modo per ottimizzare il codice o è normale per matplotlib?matplotlib molto lento. È normale?

porzione di codice per il tracciato:

plot_cnt = 1 
for k in np.arange(K_min, K_max + 1): 
    for l in np.arange(L_min, L_max + 1): 
     ax = plt.subplot(grid[0], grid[1], plot_cnt) 
     plot_cnt += 1 
     plt.setp(ax, 'frame_on', False) 
     ax.set_ylim([-0.1, 1.1]) 
     ax.set_xlabel('K={},L={}'.format(k, l), size=3) 
     ax.set_xlim([-0.1, 4.1]) 
     ax.set_xticks([]) 
     ax.set_yticks([]) 
     ax.grid('off') 
     ax.plot(np.arange(5), (data['S1']['Azimuth'][:, k - 1, l + offset_l] + \ 
       data['S1']['Delta Speed'][:, k - 1, l + offset_l] + \ 
       data['S1']['Speed'][:, k - 1, l + offset_l])/3, 
       'r-o', ms=1, mew=0, mfc='r') 
     ax.plot(np.arange(5), data['S2'][case][:, k - 1, l + offset_l], 
       'b-o', ms=1, mew=0, mfc='b') 
plt.savefig(os.path.join(os.getcwd(), 'plot-average.pdf')) 
plt.clf() 
print 'Final plot created.' 

Immagine finale: enter image description here

+3

400 sottotrame sembra molto per me. Anche se non si dispone di molti dati, Matplotlib potrebbe non essere ottimizzato per visualizzare questo tipo di griglie. – Simon

+1

@Simon, è possibile tracciare usando un'unica grande sottotrama? Quindi ogni cinque dovrebbe essere collegato. Qualche idea? – rowman

+0

Non ho l'ambiente giusto per eseguire i test, ma ci sono alcune cose che puoi fare. Il primo passo è eseguire il profiler sul tuo codice (vedi [qui] (http://stackoverflow.com/questions/582336/how-can-you-profile-a-python-script) per maggiori informazioni). Con questo, è possibile individuare dove viene trascorso il tempo. Le due cose che potresti provare è trovare qualche risorsa da rilasciare ad ogni passo, o creare i diagrammi in diversi processi usando [multiprocessing] (http://docs.python.org/library/multiprocessing.html). Se trovo il tempo, proverò a farlo, ma in questa fase non posso garantire nulla – Simon

risposta

20

costruzione fuori di ciò che @rowman Detto questo, si può fare tutto questo in un'assi (come si disattivano tutte le zecche eccetera). Qualcosa di simile:

K_max = 20 
K_min = 0 
L_max = 20 
L_min = 0 
ax = plt.subplot(111) 
x_offset = 7 # tune these 
y_offset = 7 # tune these 
plt.setp(ax, 'frame_on', False) 
ax.set_ylim([0, (K_max-K_min +1)*y_offset ]) 
ax.set_xlim([0, (L_max - L_min+1)*x_offset]) 
ax.set_xticks([]) 
ax.set_yticks([]) 
ax.grid('off') 



for k in np.arange(K_min, K_max + 1): 
    for l in np.arange(L_min, L_max + 1): 
     ax.plot(np.arange(5) + l*x_offset, 5+rand(5) + k*y_offset, 
       'r-o', ms=1, mew=0, mfc='r') 
     ax.plot(np.arange(5) + l*x_offset, 3+rand(5) + k*y_offset, 
       'b-o', ms=1, mew=0, mfc='b') 
     ax.annotate('K={},L={}'.format(k, l), (2.5+ (k)*x_offset,l*y_offset), size=3,ha='center') 
plt.savefig(os.path.join(os.getcwd(), 'plot-average.pdf')) 

print 'Final plot created.' 

Corse in circa un secondo o due. Penso che tutto il tempo sia dedicato all'impostazione dell'oggetto axes che è piuttosto complesso internamente. output with fake data

+0

Molto bello. Per pura curiosità, può essere utilizzata anche la tecnica menzionata [qui] (http://www.scipy.org/Cookbook/Matplotlib/Animations)? Basta usare la riga 'set_ydata'. Dovrebbe trovare un metodo per copiare gli oggetti ax. – rowman

+0

@rowman puoi essere più specifico su quale metodo a quel link? Se volessi creare 400 figure separate, 'set_ydata' sarebbe utile, ma non vedo immediatamente che sarebbe utile in questo caso. – tacaswell

+0

Per le applicazioni GUI, creo una linea e aggiorna Y solo per essere veloce invece di ridisegnare l'intera figura ogni volta. In questo caso, stavo pensando invece di creare 400 figure, copiare un oggetto 400 volte, aggiornare Y e la posizione dell'asse della figura. Potrebbe richiedere lo stesso tempo però. – rowman