2012-01-23 19 views
13

Correlato a this question, voglio un grafico a dispersione 3D con i colori prescritti per ciascun punto. L'esempio pubblicato nella domanda funziona sul mio sistema, ma dopo il primo ridisegno (ad esempio dopo aver salvato o ruotando l'immagine) il colore sembra essere perso, cioè tutti i punti sono disegnati in blu con le solite informazioni di profondità. Si prega di consultare l'esempio modificato di seguito.Colore dispersione 3D Matplotlib perso dopo il ridisegno

Il mio sistema è Python 2.6.7 con matplotlib 1.1.0 installato da macports su mac 10.8.0. Io uso il backend MacOSX.

Qualcuno sa come aggirare questo problema?

import numpy as np 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 

# Create Map 
cm = plt.get_cmap("RdYlGn") 

x = np.random.rand(30) 
y = np.random.rand(30) 
z = np.random.rand(30) 

col = np.arange(30) 

fig = plt.figure() 
ax3D = fig.add_subplot(111, projection='3d') 
ax3D.scatter(x, y, z, s=30, c=col, marker='o', cmap=cm) 

plt.savefig('image1.png') 
plt.savefig('image2.png') 

Qui ci sono le due immagini, ottengo: First image Second image

+0

Hm, lo stesso su Windows. Se commento la riga 'col = np.arange (30) ', entrambi i grafici risultano identici. Non posso spiegare perché però. 'pyplot' è un modulo stateful e non penso sia saggio aprire una nuova figura senza chiudere quella vecchia. Se mantieni sempre una sola figura aperta, penso che tali effetti potrebbero essere prevenuti. –

+0

Ho appena notato che il codice utilizza effettivamente due cifre. Questa non era la causa del problema, però. Ho rimosso la prima cifra dal codice di esempio e il problema persiste. Grazie per aver sottolineato che il problema esiste anche su Windows. Mi sembra che questa sia una specie di bug. –

+0

Proprio come una nota per i futuri visitatori, questo sembra essere risolto in MatPlotLib 1.2.0 :) – Poik

risposta

11

Non è chiaro il motivo per cui questo sta accadendo, e certamente è un bug. Qui fornisco un trucco per ottenere il risultato desiderato, anche se non è come automatico come si vorrebbe.

Per qualche motivo, lo Patch3DCollection che rappresenta i punti di dispersione non viene aggiornato dopo il primo rendering. Questo aggiornamento è essenziale, perché è dove sono impostati colori univoci per ogni patch di raccolta. Per forzare la reinizializzazione, è possibile utilizzare il metodo changed nel metodo Patch3DCollection (in realtà un metodo ScalarMappable) e questo solo documenta che una modifica è stata completata. Quando viene disegnata la figura, controlla se è avvenuto un aggiornamento e quindi ridefinisce i colori. In caso contrario, questo processo viene saltato.

Per forzare questo aggiornamento a verificarsi automaticamente, si vorrebbe farlo in ogni evento "draw". Per fare ciò, è necessario register a method utilizzando il metodo mpl_connect (consultare l'esercitazione collegata).

Questo esempio mostra come il salvataggio della figura due volte preserva la mappatura dei colori, ma se rimuovi il commento dalla riga plt.show(), funzionerà comunque (a rotazione, ad esempio).

import numpy as np 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 

# Create Map 
cm = plt.get_cmap("RdYlGn") 

# added a seed so consistant plotting of points 
np.random.seed(101) 
x = np.random.rand(30) 
y = np.random.rand(30) 
z = np.random.rand(30) 

col = np.arange(30) 

fig = plt.figure() 
#ax = fig.add_subplot(111) 
#scatCollection = ax.scatter(x,y, 
ax3D = fig.add_subplot(111, projection='3d') 
# keep track of the Patch3DCollection: 
scatCollection = ax3D.scatter(x, y, z, s=30, 
          c=col, 
          marker='o', 
          cmap=cm 
          ) 
def forceUpdate(event): 
    global scatCollection 
    scatCollection.changed() 

fig.canvas.mpl_connect('draw_event',forceUpdate) 

#plt.show() 

plt.savefig('image1.png') 

plt.savefig('image2.png') 

Idealmente non dovrebbe essere richiesto per fare questo, e il globale scatCollection dovrebbe essere letta utilizzando altri metodi (sto lavorando a fare questo). Ma questo funziona per ora ...

Problemi correlati