must - python plot 3d data
Cómo coloreo secciones individuales de una esfera 3d en Python (2)
Además del enlace proporcionado en los comentarios, es posible asignar directamente una variable al mapa de colores. Verifica tu ejemplo adaptado con una solución:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
fig = plt.figure()
ax = fig.add_subplot(111, projection=''3d'')
u = np.linspace(0,2*np.pi, 32)
v = np.linspace(0, np.pi, 16)
x = 10 * np.outer(np.cos(u), np.sin(v))
y = 10 * np.outer(np.sin(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))
C = np.cos(x)
ax.plot_surface(x, y, z, facecolors = cm.jet(C), rstride=4, cstride=4) # Look how I gave a variable to the facecolors.
plt.show()
, este particularmente mal ejemplo resulta en esto:
He creado una trama en 3D de una esfera en python usando Mathplotlib usando el siguiente código
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
fig = plt.figure()
ax = fig.add_subplot(111, projection=''3d'')
u = np.linspace(0,2*np.pi, 32)
v = np.linspace(0, np.pi, 16)
x = 10 * np.outer(np.cos(u), np.sin(v))
y = 10 * np.outer(np.sin(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))
ax.plot_surface(x, y, z, rstride=4, cstride=4, color=''b'')
plt.show()
Imagen de la trama: -
Me gustaría colorear cada caja individual con un color diferente. Intenté usar un mapa de colores, pero solo pude cambiar el color en función del valor z con esto.
Cualquier sugerencia sería muy apreciada. Estoy abierto a usar otras herramientas o idiomas para realizar esta tarea, pero necesito que las cajas sean del mismo tamaño.
La solución de @Armatita es muy elegante, especialmente si tiene una función de mapeo. Lo voté arriba :). Otra solución para formas arbitrarias se puede hacer con Poly3DCollection
. Ahora podría importar datos reales y las superficies podrían arbitray en el espacio y no tendrían que conectarse.
Para comparar, sin embargo, utilicé la misma esfera. Edité la respuesta para asignar el color en función de los dos ángulos según sus comentarios a continuación.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import numpy as np
fig = plt.figure()
ax = fig.gca(projection=''3d'')
r=1 # radius of sphere
phi = np.linspace(0,360, 12)/180.0*np.pi
theta = np.linspace(-90,90,7)/180.0*np.pi
# make up some function like OP (original poster) suggested:
# numerical value in the range of 20-40.
vars=[]
for i in range(len(phi)-1):
for j in range(len(theta)-1):
vars.append( (i*j* - i +j)/25+40) # min at 20, max at 40
# set colors as function of data in vars
# less than 25 as red, from 25-35 as yellow
# and anything greater than 35 as green. –
cols=[]
for var in vars:
if var <25:
col=''r''
elif 25<=var<=35:
col=''y''
else:
col=''g''
cols.append(col)
verts2 = []
for i in range(len(phi)-1):
for j in range(len(theta)-1):
cp0= r*np.cos(phi[i])
cp1= r*np.cos(phi[i+1])
sp0= r*np.sin(phi[i])
sp1= r*np.sin(phi[i+1])
ct0= np.cos(theta[j])
ct1= np.cos(theta[j+1])
st0= r*np.sin(theta[j])
st1= r*np.sin(theta[j+1])
verts=[]
verts.append((cp0*ct0, sp0*ct0, st0))
verts.append((cp1*ct0, sp1*ct0, st0))
verts.append((cp1*ct1, sp1*ct1, st1))
verts.append((cp0*ct1, sp0*ct1, st1))
verts2.append(verts )
poly3= Poly3DCollection(verts2 ,facecolor= cols)
poly3.set_alpha(0.9)
ax.add_collection3d(poly3)
ax.set_xlabel(''X'')
ax.set_xlim3d(-1, 1)
ax.set_ylabel(''Y'')
ax.set_ylim3d(-1, 1)
ax.set_zlabel(''Z'')
ax.set_zlim3d(-1, 1)
plt.show()