如何在python中3D绘制2个变量的函数?

Bru*_*lva 5 python 3d data-visualization matplotlib

我正在尝试 3D 绘制多种类型阻尼的振动放大系数。为了让那些不知道它是什么的人简化它,基本上,你有 3 个变量:

  • beta,它在 0 和无限之间变化,但我想以 0.2 的间隔将它从 0 可视化到 3。
  • 阻尼比 d 在 0 和无穷大之间变化,但我想以 0.1 的间隔从 0 到 1 绘制它。
  • 最后是nu,这是一个根据之前的两个变量而变化的函数。

二维函数,y 是 nu,x 是 beta

我的直觉说我应该用 (X,Y,Z) = (beta, d, nu) 来绘制它,但我才刚刚开始使用这个库,而且我对 python 有点陌生,我只是在需要的时候使用它可视化或计算课堂上的问题。我尝试为 beta 和 d 创建 2 个数组,但我不知道我应该为 nu 创建数组,因为它取决于两者。

这是我到现在为止的一段代码:

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


nu = []
b = [0.1 + i / 100 for i in range(0, 510)]
damp = [0.1 + i/10 for i in range(0,510)]

for d in damp:
    nu_new = []
    nu.append(nu_new)
    for beta in b:
        nu_new.append( math.sqrt(1+(2*d*beta)**2)/ math.sqrt((1-beta**2)**2+(2*d*beta)**2))

fig = plt.figure()
ax = Axes3D(fig)
ax.plot(b, d, nu)
plt.show()
Run Code Online (Sandbox Code Playgroud)

我有点卡住了试图绘制这个,所以如果你有任何建议,我会很高兴。

小智 6

如果您正在使用numpy,则不要使用该math模块。Numpy 作为内置的所有数学函数,但它们在 numpy 数组上工作得更好。我们可以在网格的帮助下计算所有 b、d 值的 nu。

网格网格可以采用 2 个一维数组,并返回 2 个二维数组,这样数组中的每个索引都对应于原始一维数组中唯一的一对元素。

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

b = np.arange(0.2, 3.2, 0.2)
d = np.arange(0.1, 1.0, 0.1)

B, D = np.meshgrid(b, d)
nu = np.sqrt( 1 + (2*D*B)**2 ) / np.sqrt( (1-B**2)**2 + (2*D*B)**2)

fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(B, D, nu)
plt.xlabel('b')
plt.ylabel('d')
plt.show()
Run Code Online (Sandbox Code Playgroud)

这产生: 在此处输入图片说明

此外,3D 绘图往往会阻止查看所有数据(因为尖峰隐藏了其背后的东西)。我会推荐一个 pcolormesh 或一个轮廓图。在后一种情况下,最后 6 行变为:

plt.contourf(B, D, nu)
plt.colorbar()
plt.xlabel('b')
plt.ylabel('d')
plt.show()
Run Code Online (Sandbox Code Playgroud)

它产生: 在此处输入图片说明


Mal*_*ann 3

这应该可行:我不是Python专家,尤其是两个for循环可能非常不Python,但它完成了工作。

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

b = np.arange(0.2, 3.2, 0.2)
d = np.arange(0.1, 1.0, 0.1)
nu = np.zeros( (b.size, d.size) )
counter_y = 0

for deta in d:
    counter_x = 0
    for beta in b:
        nu[counter_x, counter_y] = math.sqrt( 1 + (2*deta*beta)**2 ) / math.sqrt( (1-beta**2)**2 + (2*deta*beta)**2)
        counter_x += 1
    counter_y += 1

X, Y = np.meshgrid(d, b)

fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
ax.plot_surface(X, Y, nu)
Run Code Online (Sandbox Code Playgroud)