如何在Python中为3d球体的各个部分着色

时间:2016-04-14 05:24:29

标签: python numpy matplotlib 3d

我使用Mathplotlib使用下面的代码在python中创建了一个3d球体图

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()

情节图片: -

enter image description here

我想为每个单独的盒子上色不同的颜色。我曾尝试使用颜色贴图,但我只能根据z值更改颜色。

任何建议都将不胜感激。我愿意使用其他工具或语言来完成这项任务,但我需要使用相同大小的方框。

2 个答案:

答案 0 :(得分:1)

除了注释中给出的链接外,还可以直接将变量映射到色彩映射表。检查适合解决方案的示例:

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()

,这个特别糟糕的例子导致了这个:

enter image description here

答案 1 :(得分:1)

@ Armatita的解决方案非常优雅,特别是如果你有一个映射功能。我赞成它:)。  任意形状的另一种解决方案可以使用Poly3DCollection完成。现在您可以导入实际数据,并且表面可以在空间中进行仲裁,并且不必连接。

为了比较,我使用相同的球体。我根据您的评论编辑了答案,将颜色指定为两个角度的函数。

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()

enter image description here