Matplotlib中disk-cyclide坐标参数化曲面绘图报错求助
问题描述
尝试绘制采用disk-cyclide坐标参数化的曲面,参数化函数及Lambda函数如图所示。运行代码时出现错误提示“Z必须是二维数组”,但该曲面由三个变量参数化,请问如何调整以满足绘图要求?
size = 250 psi = np.linspace(0, 2*np.pi, size) mu = np.linspace(0,K, size) nu = np.linspace(0, Kl, size) Mu, Nu, Psi = np.meshgrid(mu, nu, psi) k = 0.963 kl = 0.270 K = sp.special.ellipk(k) Kl = sp.special.ellipk(kl) Lambda = 1 - (sp.special.ellipj(Mu,k)[2]**2)*(sp.special.ellipj(Nu,kl)[0]) x = (1/Lambda)*(sp.special.ellipj(Mu,k)[1])*(sp.special.ellipj(Nu,kl)[1])*np.cos(Psi) y = (a/Lambda)*(sp.special.ellipj(Mu,k)[1])*(sp.special.ellipj(Nu,kl)[1])*np.sin(Psi) z = (a/Lambda)*(sp.special.ellipj(Mu,k)[0])*(sp.special.ellipj(Mu,k)[2])*(sp.special.ellipj(Nu,kl)[0])*(sp.special.ellipj(Nu,kl)[2]) fig = plt.figure() ax = fig.gca(projection = '3d') ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap="hot") plt.show()
解决方案
问题根源
plot_surface仅接受二维数组作为输入,但你通过meshgrid(mu, nu, psi)生成了三维数组(三个参数维度),这是核心矛盾。disk-cyclide本质是二维曲面,属于2维流形,只需要两个独立参数,三个参数中必然存在依赖关系,或是你误解了参数化逻辑。
调整步骤
修正参数维度:保留两个独立参数,比如固定第三个参数为某个值,或选择其中两个参数生成二维网格。
示例:将mu和psi作为独立参数,固定nu为中间值:# 生成二维网格:mu和psi size = 250 psi = np.linspace(0, 2*np.pi, size) mu = np.linspace(0, K, size) Mu, Psi = np.meshgrid(mu, psi) # 固定nu为Kl/2,也可替换为其他值或遍历多个值生成曲面族 Nu = np.full_like(Mu, Kl/2)修复未定义变量:代码中
y和z用到的a未定义,需补充赋值(比如a = 1.0)。确保输出为二维数组:重新计算
x、y、z,确认最终结果是二维数组后,再传入plot_surface。
完整修正示例代码
import numpy as np import scipy.special as sp import matplotlib.pyplot as plt # 补充未定义的参数a a = 1.0 k = 0.963 kl = 0.270 # 先计算椭圆积分,避免未定义问题 K = sp.ellipk(k) Kl = sp.ellipk(kl) size = 250 # 选择两个独立参数:mu和psi psi = np.linspace(0, 2*np.pi, size) mu = np.linspace(0, K, size) Mu, Psi = np.meshgrid(mu, psi) # 固定nu为中间值 Nu = np.full_like(Mu, Kl/2) # 计算Lambda与坐标 Lambda = 1 - (sp.ellipj(Mu, k)[2]**2) * (sp.ellipj(Nu, kl)[0]) x = (1/Lambda) * sp.ellipj(Mu, k)[1] * sp.ellipj(Nu, kl)[1] * np.cos(Psi) y = (a/Lambda) * sp.ellipj(Mu, k)[1] * sp.ellipj(Nu, kl)[1] * np.sin(Psi) z = (a/Lambda) * sp.ellipj(Mu, k)[0] * sp.ellipj(Mu, k)[2] * sp.ellipj(Nu, kl)[0] * sp.ellipj(Nu, kl)[2] fig = plt.figure() ax = fig.gca(projection='3d') ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap="hot") plt.show()
曲面族绘制说明
如果disk-cyclide的参数化确实需要三个参数,说明它是带参数的曲面族,此时需要遍历第三个参数,绘制多个曲面:
# 遍历nu的多个值,绘制曲面族 nu_values = np.linspace(0, Kl, 5) for nu_val in nu_values: Nu = np.full_like(Mu, nu_val) # 重复计算坐标并绘制 Lambda = 1 - (sp.ellipj(Mu, k)[2]**2) * (sp.ellipj(Nu, kl)[0]) x = (1/Lambda) * sp.ellipj(Mu, k)[1] * sp.ellipj(Nu, kl)[1] * np.cos(Psi) y = (a/Lambda) * sp.ellipj(Mu, k)[1] * sp.ellipj(Nu, kl)[1] * np.sin(Psi) z = (a/Lambda) * sp.ellipj(Mu, k)[0] * sp.ellipj(Mu, k)[2] * sp.ellipj(Nu, kl)[0] * sp.ellipj(Nu, kl)[2] ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap="hot", alpha=0.6)
内容的提问来源于stack exchange,提问作者João Renato
相关产品推荐
相关产品推荐

