You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于2D输入间距绘制带颜色的3D函数及排障

问题与解决方案

需求描述

定义三个数组:

v1=np.linspace(1,100)
v2=np.linspace(1,100)
v3=np.linspace(1,100)   

有函数 f = (v1 + v2*10)/v3,需要实现两个目标:

  1. 在以v1、v2、v3为坐标轴的3D图中绘制该函数,根据函数值为曲面/点集着色;
  2. 用嵌套循环遍历输入向量的所有值,逐点构建函数(之前尝试循环时报错)。

此外,尝试了一段代码绘制3D曲面,但最终只显示线条,代码如下:

import mpl_toolkits.mplot3d.axes3d as axes3d
import sympy
from sympy import symbols, Function

# Parameters I use in the function
L = 132
alpha = 45*math.pi/180
beta = 0


s,t = symbols('s,t')
z = Function('z')(s,t)
figure = plt.figure(figsize=(8,8))
ax = figure.add_subplot(1, 1, 1, projection='3d')

# experiment with various range of data in x and y
x1 = np.linspace(-40,-40,100)  
y1 = np.linspace(-40,40,100)
x,y = np.meshgrid(x1,y1)

# My function Z
c1=math.cos(beta)**2
c2=math.cos(alpha)**2
s1=math.sin(alpha)**2
den = math.sqrt((c1*c2)+s1)
z=L*((math.cos(beta)/den)-1)+(s*(math.sin(alpha)))+(t*(1-math.cos(alpha)))


ax.plot_surface(x,y,z,cmap='rainbow')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.show()

问题代码分析

这段代码存在两个核心问题:

  1. x1 = np.linspace(-40,-40,100) 生成的是全为-40的数组,meshgrid后x是无变化的100x100矩阵,x轴没有跨度,自然只能画出线条;
  2. 错误混用SymPy符号变量与NumPy数值数组:s、t是SymPy符号,未替换为x、y的数值,导致z是符号表达式而非数值矩阵,plot_surface无法识别。

正确实现方法

1. 3D曲面绘图的最佳方式

无需使用SymPy,直接用NumPy数值计算结合Matplotlib的3D绘图即可,核心是生成有跨度的网格矩阵,确保所有运算为数值运算。

修正你尝试的代码(实现曲面绘制)

import numpy as np
import matplotlib.pyplot as plt
import math

# 参数定义
L = 132
alpha = 45 * math.pi / 180
beta = 0

# 生成有跨度的x、y轴线性空间
x1 = np.linspace(-40, 40, 100)  
y1 = np.linspace(-40, 40, 100)
x, y = np.meshgrid(x1, y1)

# 计算z的数值矩阵(直接用x、y替代符号变量)
c1 = math.cos(beta)**2
c2 = math.cos(alpha)**2
s1 = math.sin(alpha)**2
den = math.sqrt((c1 * c2) + s1)
z = L * ((math.cos(beta)/den) - 1) + (x * math.sin(alpha)) + (y * (1 - math.cos(alpha)))

# 绘制3D曲面
figure = plt.figure(figsize=(8,8))
ax = figure.add_subplot(1, 1, 1, projection='3d')
ax.plot_surface(x, y, z, cmap='rainbow')

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.show()

针对初始函数 f=(v1+v2*10)/v3 的3D可视化

如果要以v1、v2、v3为坐标轴,用f值着色,可以绘制三维散点图:

import numpy as np
import matplotlib.pyplot as plt

# 生成三个轴的取值数组
v1 = np.linspace(1, 100, 20)
v2 = np.linspace(1, 100, 20)
v3 = np.linspace(1, 100, 20)

# 构建三维网格
x, y, z = np.meshgrid(v1, v2, v3)

# 计算函数值
f = (x + y*10)/z

# 绘制带颜色映射的三维散点图
fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111, projection='3d')
scatter = ax.scatter(x, y, z, c=f, cmap='rainbow')

ax.set_xlabel('v1')
ax.set_ylabel('v2')
ax.set_zlabel('v3')
plt.colorbar(scatter, label='f=(v1+v2*10)/v3')
plt.show()

2. 嵌套循环逐点构建函数

如果不想用NumPy的向量化运算,可用嵌套循环逐点计算函数值,核心是初始化对应维度的结果数组,再遍历索引计算。

三维网格逐点计算

import numpy as np
import matplotlib.pyplot as plt

v1 = np.linspace(1, 100, 20)
v2 = np.linspace(1, 100, 20)
v3 = np.linspace(1, 100, 20)

# 初始化与三维网格同维度的结果数组
f_values = np.zeros((len(v1), len(v2), len(v3)))

# 三层嵌套循环遍历所有组合
for i in range(len(v1)):
    for j in range(len(v2)):
        for k in range(len(v3)):
            f_values[i,j,k] = (v1[i] + v2[j]*10)/v3[k]

# 可视化结果
fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111, projection='3d')
x, y, z = np.meshgrid(v1, v2, v3)
scatter = ax.scatter(x, y, z, c=f_values.flatten(), cmap='rainbow')

ax.set_xlabel('v1')
ax.set_ylabel('v2')
ax.set_zlabel('v3')
plt.colorbar(scatter, label='f=(v1+v2*10)/v3')
plt.show()

二维曲面逐点计算(固定v3值)

import numpy as np
import matplotlib.pyplot as plt

v1 = np.linspace(1, 100, 100)
v2 = np.linspace(1, 100, 100)
v3 = 50  # 固定v3的取值

# 初始化二维结果数组
z_values = np.zeros((len(v1), len(v2)))

# 两层嵌套循环计算每个点的函数值
for i in range(len(v1)):
    for j in range(len(v2)):
        z_values[i,j] = (v1[i] + v2[j]*10)/v3

# 绘制3D曲面
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(111, projection='3d')
x, y = np.meshgrid(v1, v2)
ax.plot_surface(x, y, z_values, cmap='rainbow')

ax.set_xlabel('v1')
ax.set_ylabel('v2')
ax.set_zlabel('f=(v1+v2*10)/v3')
plt.show()

内容的提问来源于stack exchange,提问作者stefano massardi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 19:51:02