使用 matplotlib surface_plot 和 facecolors 的意外恒定颜色

unexpected constant color using matplotlib surface_plot and facecolors

我正在球体表面绘制一个函数。为了测试我的代码,我简单地绘制了球坐标 phi 除以 pi。我得到

出乎意料的是,一半的球体颜色相同,而另一半的颜色不正确(在 phi=pi 时,我应该得到 1,而不是 2)。如果我将数据数组除以 2,问题就会消失。有人可以向我解释发生了什么吗?

这是我使用的代码:

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

# prepare the sphere surface
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
phi = np.linspace(0,2*np.pi, 50)
theta = np.linspace(0, np.pi, 25)
x=np.outer(np.cos(phi), np.sin(theta))
y=np.outer(np.sin(phi), np.sin(theta))
z=np.outer(np.ones(np.size(phi)), np.cos(theta))

# prepare function to plot
PHI=np.outer(phi,np.ones(np.size(theta)))
THETA=np.outer(np.ones(np.size(phi)),theta)
data = PHI/np.pi

# plot
surface=ax.plot_surface(x, y, z, cstride=1, rstride=1, 
                        facecolors=cm.jet(data),cmap=plt.get_cmap('jet'))

# add colorbar
m = cm.ScalarMappable(cmap=surface.cmap,norm=surface.norm)
m.set_array(data)
plt.colorbar(m)
plt.show()

代码有点乱。

  • 指定 facecolors 时,没有理由提供颜色图,因为不需要从颜色图中检索面部颜色。
  • 颜色图的范围从 0 到 1。您的数据范围从 0 到 2。因此一半的面部颜色是相同的。因此,您首先需要将数据标准化为 (0,1) 范围,例如使用 Normalize 实例,然后您可以应用颜色图。

    norm = plt.Normalize(vmin=data.min(), vmax=data.max()) 
    surface=ax.plot_surface(x, y, z, cstride=1, rstride=1, 
                            facecolors=cm.jet(norm(data)))
    
  • 对于颜色条,您应该使用与绘图本身相同的颜色图和相同的标准化。

    m = cm.ScalarMappable(cmap=cm.jet,norm=norm)
    m.set_array(data)
    

完整代码:

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

# prepare the sphere surface
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
phi = np.linspace(0,2*np.pi, 50)
theta = np.linspace(0, np.pi, 25)
x=np.outer(np.cos(phi), np.sin(theta))
y=np.outer(np.sin(phi), np.sin(theta))
z=np.outer(np.ones(np.size(phi)), np.cos(theta))

# prepare function to plot
PHI=np.outer(phi,np.ones(np.size(theta)))
THETA=np.outer(np.ones(np.size(phi)),theta)
data = PHI/np.pi

# plot
norm = plt.Normalize(vmin=data.min(), vmax=data.max()) 
surface=ax.plot_surface(x, y, z, cstride=1, rstride=1, 
                        facecolors=cm.jet(norm(data)))

# add colorbar
m = cm.ScalarMappable(cmap=cm.jet,norm=norm)
m.set_array(data)
plt.colorbar(m)
plt.show()