我正在尝试以 3D 方式绘制多种阻尼类型的振动放大系数。为了让那些不知道它是什么的人简化一下,基本上,你有 3 个变量:
我的直觉告诉我应该用 (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()
我有点被困在试图绘制这个,所以如果你有任何建议,我会很高兴。
如果您使用
numpy
,则不要使用 math
模块。 Numpy 作为内置的所有数学函数,但它们在 numpy 数组上的工作效果要好得多。我们可以借助网格计算所有 b、d 值的 nu。
网格网格可以接受 2 个 1D 数组,并返回 2 个 2D 数组,使得数组中的每个索引对应于原始 1D 数组中唯一的一对元素。
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()
此外,3D 绘图往往会阻碍查看所有数据(因为尖峰隐藏了其后面的东西)。我会推荐 pcolormesh 或轮廓图。在后一种情况下,最后 6 行变为:
plt.contourf(B, D, nu)
plt.colorbar()
plt.xlabel('b')
plt.ylabel('d')
plt.show()
这应该有效: 我不是 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)
您需要首先创建一个
matplotlib figure
。
fig = plt.figure()
ax = Axes3D(fig)
ax.plot(b, d, nu)
plt.show()
此外,所有变量的大小都应该相同。因此,您的变量
d
应该是与其他变量长度相同的数组。
如果将变量
d
转换为长度为 0.1
的 510
数组,你会得到以下结果。
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)]
d = 0.1
for beta in b:
nu.append( math.sqrt(1+(2*d*beta)**2)/ math.sqrt((1-beta**2)**2+(2*d*beta)**2))
#turned d into array of length 510 with 0.1 for each value
d = np.ones(510)*0.1
fig = plt.figure()
ax = Axes3D(fig)
ax.plot(b, d, nu)
plt.show()
你得到:
这是 MalteHerrmann 的答案,但没有
for
循环。
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.6, 0.1) # changed a bit the interval
nu = np.zeros( (b.size, d.size) )
for i in range (len(d)):
for j in range (len(b)):
nu[i,j] = math.sqrt( 1 + (2*d[i]*b[j])**2 ) / math.sqrt( (1-b[j]**2)**2 + (2*d[i]*b[j])**2)
X, Y = np.meshgrid(d, b)
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
ax.plot_surface(X, Y, nu)