Matplotlib中用于面颜色的归一化颜色图

5

首先,我正在尝试在matplotlib中绘制球面调和函数,就像在mayavi中看到的一样:http://docs.enthought.com/mayavi/mayavi/auto/example_spherical_harmonics.html

以下是我的进展:

import matplotlib.pyplot as plt
from matplotlib import cm, colors
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from scipy import special

# Create a sphere
r = 3
pi = np.pi
cos = np.cos
sin = np.sin
phi, theta = np.mgrid[0:pi:50j, 0:2*pi:50j]


x = r * sin(phi) * cos(theta)
y = r * sin(phi) * sin(theta)
z = r * cos(phi)

colorfunction=special.sph_harm(3,4,theta,phi).real

norm=colors.Normalize(vmin = np.min(colorfunction), vmax = np.max(colorfunction), clip = False)
print colorfunction



fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z)
ax.plot_surface(
    x, y, z,  rstride=1, cstride=1, norm=norm, cmap=cm.jet, facecolors=cm.jet(colorfunction))
plt.show()

这里的想法是使用colorfunction根据球面谐波来给球体表面着色。然而,这个函数的输出是一个带有负数的数组。我需要做的是将这个数组“归一化”,使它与matplotlib的颜色映射良好地配合使用。然而,与Color matplotlib plot_surface command with surface gradient中的答案不同,那里的答案仅通过除以最大元素来进行粗略的归一化,我有负元素,所以那种方法行不通。我最好使用matplotlib.colors.Normalize,但它在facecolors上不起作用。
我知道规范应用于cmap=cm.jet,因为如果我完全删除facecolors参数,我会得到一个新的颜色映射,它按照我的norm函数的要求运作。
这是我的问题的关键所在,我不能让我的归一化颜色映射应用于我的facecolors。有什么想法吗? 这是上述代码当前生成的图。正如你所看到的,负值被完全切断,信息丢失了,因为颜色映射的范围比实际值要大得多(所以一切看起来都是蓝色)。
1个回答

8
也许这太琐碎了,但是:
ax.plot_surface(x, y, z,  rstride=1, cstride=1, facecolors=cm.jet(norm(colorfunction)))

这个函数是对colorfunction进行归一化处理。只需定义以下归一化函数即可:
norm = colors.Normalize()

这将自动将输入值缩放在0到1之间。
结果: enter image description here 看起来,cmapnorm关键字适用于使用Z数据对表面进行着色的情况,因此它们在这里没有用处。

1
我建议在这里使用其中一种分歧颜色地图。 - tacaswell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接