2011-02-06 7 views
11

Sto cercando di creare un grafico di superficie tridimensionale per l'espressione: z = y^2/x, per x nell'intervallo [-2,2] e y nell'intervallo [-1.4,1.4]. Voglio anche che i valori z siano compresi tra -4 e 4.Python/matplotlib mplot3d- come si imposta un valore massimo per l'asse z?

Il problema è che quando visualizzo il surfaceplot finito, i valori dell'asse z non si fermano a [-4,4].

Quindi la mia domanda è come posso "rimuovere" il valore dell'asse z che va oltre l'intervallo [-4,4] dal grafico finito?

Il mio codice è:

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

fig = plt.figure() 
ax = fig.gca(projection="3d") 

x = np.arange(-2.0,2.0,0.1,float)  # x in interval [-2,2] 
y = np.arange(-1.4,1.4,0.1,float)  # y in interval [-1.4,1.4] 
x,y = np.meshgrid(x,y) 
z = (y**2/x)       # z = y^2/x 

ax.plot_surface(x, y, z,rstride=1, cstride=1, linewidth=0.25) 

ax.set_zlim3d(-4, 4)     # viewrange for z-axis should be [-4,4] 
ax.set_ylim3d(-2, 2)     # viewrange for y-axis should be [-2,2] 
ax.set_xlim3d(-2, 2)     # viewrange for x-axis should be [-2,2] 
plt.show() 

risposta

1

clipping i dati saranno raggiungere questo obiettivo, ma non è molto carina.

z[z>4]= np.nan 
z[z<-4]= np.nan 
+0

non c'è un modo migliore per fare questo? In qualche modo "tagliare" i valori z al di fuori del range di [-4,4] durante la visualizzazione del grafico? – user605243

+0

@ user605243: in linea di principio, dovresti essere in grado di utilizzare un masked_array, come è possibile con i grafici 2D. In pratica non sembra funzionare (anche se i cambiamenti necessari in axes3d.py per farlo sembrare non troppo scoraggiante). Purtroppo non sono riuscito a far funzionare il trucco np.nan neanche con un sacco di " CGPathCloseSubpath: nessun punto corrente. " errori. – DSM

9

Ho lo stesso problema e non ho ancora trovato nulla di meglio che ritagliare i miei dati. Purtroppo nel mio caso sono legato a matplotlib 1.2.1. Ma nel caso in cui sia possibile eseguire l'aggiornamento alla versione 1.3.0, si potrebbe avere una soluzione: sembra che ci sia un nuovo gruppo di API relativo agli intervalli degli assi. In particolare, potresti essere interessato da "set_zlim".

Modifica 1: consente di migrare il mio ambiente per utilizzare matplotlib 1.3.0; set_zlim funzionato come un fascino :)

Il codice follwing lavorato per me (Tra l'altro sto facendo funzionare questo su OSX, io non sono sicuro che questo ha un impatto?):

# ---------------------------------------------------------------------------- 
# Make a 3d plot according to data passed as arguments 
def Plot3DMap(self, LabelX, XRange, LabelY, YRange, LabelZ, data3d) : 
    fig = plt.figure() 
    ax = fig.add_subplot(111, projection="3d") 
    xs, ys = np.meshgrid(XRange, YRange) 
    surf = ax.plot_surface(xs, ys, data3d) 
    ax.set_xlabel(LabelX) 
    ax.set_ylabel(LabelY) 
    ax.set_zlabel(LabelZ) 
    ax.set_zlim(0, 100) 
    plt.show() 
+1

Puoi confermare che set_zlim funziona per te? Sto usando 1.3.1 e quando ho 'set_zlim' o' set_zlim3d' limita solo gli assi ma in realtà non ritaglia i dati. – KobeJohn

+1

Puoi spiegare come usare set_zlim? – Jonny

+0

@Jonny: http://matplotlib.org/mpl_toolkits/mplot3d/api.html#mpl_toolkits.mplot3d.axes3d.Axes3D.set_zlim – TocToc

Problemi correlati