如何设置相对于图形半径的颜色图?
我该如何封闭圆柱体的端部(侧面,而不是顶部和底部)?
我的脚本:
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from math import sin, cos, pi
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
h, w = 60,30
znew = np.random.randint(low=90, high=110, size=(60,30))
theta = np.linspace(0,2*pi, h)
Z = np.linspace(0,1,w)
Z,theta = np.meshgrid(Z, theta)
R = 1
X = (R*np.cos(theta))*znew
Y = (R*np.sin(theta))*znew
ax1 = ax.plot_surface(X,Y,Z,linewidth = 0, cmap="coolwarm",
vmin= 80,vmax=130, shade = True, alpha = 0.75)
fig.colorbar(ax1, shrink=0.9, aspect=5)
plt.show()
答案 0 :(得分:0)
首先,您需要使用map
的{{3}}关键字参数来绘制具有任意(非基于plot_surface
的颜色)的表面。您必须为每个点传递四个显式的RGBA颜色,这意味着我们需要在每个点上使用由半径指定的键来采样一个颜色图对象。最后,这将破坏所得表面的可映射属性,因此我们将必须通过手动告诉颜色条使用半径来颜色来构造颜色条:
Z
请注意,我已将半径更改为平滑的值,以减少混乱的结果。 import numpy as np
from matplotlib import pyplot as plt
import matplotlib.cm as cm
from matplotlib.colors import Normalize
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
h, w = 60,30
#znew = np.random.randint(low=90, high=110, size=(h,w))
theta = np.linspace(0,2*np.pi, h)
Z = np.linspace(0,1,w)
Z,theta = np.meshgrid(Z, theta)
znew = 100 + 10*np.cos(theta/2)*np.cos(2*Z*np.pi)
R = 1
X = (R*np.cos(theta))*znew
Y = (R*np.sin(theta))*znew
true_radius = np.sqrt(X**2 + Y**2)
norm = Normalize()
colors = norm(true_radius) # auto-adjust true radius into [0,1] for color mapping
cmap = cm.get_cmap("coolwarm")
ax.plot_surface(X, Y, Z, linewidth=0, facecolors=cmap(colors), shade=True, alpha=0.75)
# the surface is not mappable, we need to handle the colorbar manually
mappable = cm.ScalarMappable(cmap=cmap)
mappable.set_array(colors)
fig.colorbar(mappable, shrink=0.9, aspect=5)
plt.show()
Arary包含数据单位的实际半径,归一化后的数据半径为true_radius
(本质上为colors
)。
结果:
最后,请注意,我生成的半径使圆柱体无法无缝关闭。这模仿了您的随机示例输入。只要在colors = (true_radius - true_radius.min())/true_radius.ptp()
中半径不是2π周期,您就无法执行 操作。这与可视化无关,这是几何。