之前我在CSDN发布了上述问题,现在整理各位大佬的回答于下文。再次感谢各位大佬帮我解答这个问题。
首先是利用空间曲面+指定中心的渐变色反应4个维度信息,xyz的值代表前3维度,颜色代表第四维度,效果如下:
下文代码中的颜色映射可以自己编写,由于我想以某一指定坐标为中心进行颜色渐变所以设中心为(x,y,z),设样本点为(x0,y0,z0),则颜色映射函数应为:
可以自定义映射函数colorMap():来为曲面(我这里是水平面和竖直面)的每个色块投射不同的色彩(色彩来源于设定好的色板plt.get_cmap('rainbow_r'))
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = plt.axes(projection='3d')
# 设置坐标轴名字
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
# 制作数据,用于画网格和平面,这里选5,可以设置更小的网格
x = np.linspace(-2, 2, 5)
X, Y = np.meshgrid(x, x)
# 网格的线条长度,通过记录线条端点坐标得到
lineLength = [-2, 2]
num = len(x)
# 用于画格子的函数
def line(point): return [point, point]
# 用于画面的函数,画水平和垂直的面,需要平面偏移量,把平面打成格子
def fun(x, y, offset):
z = 0 * x * y + offset
return z
# 颜色映射函数,自定义所画平面每个色块的颜色映射方式,我随意设置了映射函数,返回值不能覆盖全色板,用偏移量0.3调整最佳观看个映射范围
def colorMap(C):
return C / np.max(C) - 0.3
for i in range(num):
for j in range(num):
# 画线条组成格子
ax.plot3D(line(x[i]), line(x[j]), lineLength, c='black')
ax.plot3D(line(x[i]), lineLength, line(x[j]), c='black')
ax.plot3D(lineLength, line(x[i]), line(x[j]), c='black')
for i in range(num):
# 画平面组成格子以及设定色板
cmap = plt.get_cmap('rainbow_r')
Z = fun(X, Y, x[i])
# 自定义渐变中心center
center = [2, 2, -2]
# 计算中心距离,用于画水平面的色板映射
C = np.sqrt((X - center[0]) ** 2 + (Y - center[1]) ** 2 + (Z - center[2]) ** 2)
ax.plot_surface(X, Y, Z, alpha=0.8, cmap=cmap, facecolors=cmap(colorMap(C)))
# 由于画竖直面的反转了水平面的XYZ位置,所以渐变中心也应该反转
centerT = [2, -2, 2]
C = np.sqrt((X - centerT[0]) ** 2 + (Y - centerT[1]) ** 2 + (Z - centerT[2]) ** 2)
ax.plot_surface(X, Z, Y, alpha=0.5, cmap=cmap, facecolors=cmap(colorMap(C)))
# 注释色条
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文字体设置-黑体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
m = plt.cm.ScalarMappable(cmap=cmap)
cb = plt.colorbar(m)
cb.ax.set_title('myBar')
plt.title("以(%.2f,%.2f,%.2f)为渐变中心的图" % (center[0], center[1], center[2]))
plt.show()
然后是散点版本。这里就不做多的解释了,用法同上文效果如下:
import numpy as np
import matplotlib.pyplot as plt
# 生成数据
x = np.linspace(-2, 2, 5)
y = np.linspace(-2, 2, 5)
z = np.linspace(-2, 2, 5)
X, Y, Z = np.meshgrid(x, y, z, indexing='ij')
center = [0, 0, 2]
# 指定色板
cmap = plt.get_cmap('rainbow_r')
C = np.sqrt((X-center[0])**2 + (Y-center[1])**2 + (Z-center[2])**2) # 指定颜色的维度
# 绘制散点图
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.scatter(X, Y, Z, c=C, cmap=cmap)
plt.colorbar(surf)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文字体设置-黑体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.title("以(%.2f,%.2f,%.2f)为渐变中心的图" % (center[0], center[1], center[2]))
plt.show()
再次感谢各位大佬对我发布的问题的悉心指导。由于个人水平有限,不能将各位解答者的全部内容精华整理,感兴趣的伙伴可以自行查看我发布的原问题。我发布的原问题链接如下:https://ask.csdn.net/questions/7896502