Matplotlib 干涉图奇怪的图案
Matplotlib interference figure strange pattern
我正在尝试制作这样的 interference figure 动画:
不同的是,上图显示的是随时间变化的干涉图,因此相长干涉点和相消干涉点保持不变。相反,我试图制作一个动画,其中我改变了两个源的频率,使它们固定在 space.
这是我的代码:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
source = 0.5
sources = [-source, source]
axlim = max(sources)*2 + 1
N = 1000
x = np.linspace(-axlim, axlim, N)
y = np.linspace(-axlim, axlim, N)
X, Y = np.meshgrid(x, y)
fig = plt.figure()
def update(f):
plt.gca().cla()
C1 = np.sin(2*np.pi*f*((X - sources[0])**2 + Y**2))
C2 = np.sin(2*np.pi*f*((X - sources[1])**2 + Y**2))
Z = C1 + C2
plt.contour(X, Y, Z)
plt.plot(sources, [0, 0], 'ro')
plt.gca().set_aspect('equal')
plt.axis('off')
ani = FuncAnimation(fig = fig, func = update, frames = 11, interval = 100)
plt.show()
问题是奇怪的图案出现在最后几帧中:
那些图案不是物理的(它们不符合物理定律),所以我的代码一定有错误。我找不到哪里,但我认为问题出在 matplotlib contour
函数中:我怀疑它引入了一种别名...
问题出在您对 C1
和 C2
的定义中:您将正弦函数应用于 x 和 y 距离的平方和,而没有应用平方根。你应该使用:
C1 = np.sin(2*np.pi*f*np.sqrt((X - sources[0])**2 + Y**2))
C2 = np.sin(2*np.pi*f*np.sqrt((X - sources[1])**2 + Y**2))
contour
绘图方法没有问题,但是,我建议您将其替换为contourf
,或者更好的是imshow
。原因是 contour
在您的字段具有相同值的地方绘制线条,使绘图的其余部分为空。相反,contourf
或 imshow
用您选择的颜色图填充空白 space,这样您可以更好地显示您的字段并避免模棱两可的白色 space。
请参阅此代码以供参考:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.animation import FuncAnimation
source = 0.5
sources = [-source, source]
axlim = max(sources)*2 + 1
N = 1000
x = np.linspace(-axlim, axlim, N)
y = np.linspace(-axlim, axlim, N)
X, Y = np.meshgrid(x, y)
norm = plt.Normalize(-2, 2)
cmap = LinearSegmentedColormap.from_list('', ['black', 'white', 'black'])
fig, ax = plt.subplots()
def update(f):
ax.cla()
C1 = np.sin(2*np.pi*f*np.sqrt((X - sources[0])**2 + Y**2))
C2 = np.sin(2*np.pi*f*np.sqrt((X - sources[1])**2 + Y**2))
Z = C1 + C2
ax.imshow(Z,
cmap = cmap,
norm = norm)
ax.plot(N/2*(1 + source/axlim), N/2, 'ro')
ax.plot(N/2*(1 - source/axlim), N/2, 'ro')
ax.set_title(f'f = {f} Hz')
ax.set_aspect('equal')
ax.axis('off')
ani = FuncAnimation(fig = fig, func = update, frames = 11, interval = 100)
plt.show()
由于你的场的波峰和波谷都是建设性的干扰点,而破坏性的点场是空的,所以我选择了黑-白-黑的色图,不能区分波峰和波谷,但更容易区分从破坏性干扰点建设性。
我正在尝试制作这样的 interference figure 动画:
不同的是,上图显示的是随时间变化的干涉图,因此相长干涉点和相消干涉点保持不变。相反,我试图制作一个动画,其中我改变了两个源的频率,使它们固定在 space.
这是我的代码:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
source = 0.5
sources = [-source, source]
axlim = max(sources)*2 + 1
N = 1000
x = np.linspace(-axlim, axlim, N)
y = np.linspace(-axlim, axlim, N)
X, Y = np.meshgrid(x, y)
fig = plt.figure()
def update(f):
plt.gca().cla()
C1 = np.sin(2*np.pi*f*((X - sources[0])**2 + Y**2))
C2 = np.sin(2*np.pi*f*((X - sources[1])**2 + Y**2))
Z = C1 + C2
plt.contour(X, Y, Z)
plt.plot(sources, [0, 0], 'ro')
plt.gca().set_aspect('equal')
plt.axis('off')
ani = FuncAnimation(fig = fig, func = update, frames = 11, interval = 100)
plt.show()
问题是奇怪的图案出现在最后几帧中:
那些图案不是物理的(它们不符合物理定律),所以我的代码一定有错误。我找不到哪里,但我认为问题出在 matplotlib contour
函数中:我怀疑它引入了一种别名...
问题出在您对 C1
和 C2
的定义中:您将正弦函数应用于 x 和 y 距离的平方和,而没有应用平方根。你应该使用:
C1 = np.sin(2*np.pi*f*np.sqrt((X - sources[0])**2 + Y**2))
C2 = np.sin(2*np.pi*f*np.sqrt((X - sources[1])**2 + Y**2))
contour
绘图方法没有问题,但是,我建议您将其替换为contourf
,或者更好的是imshow
。原因是 contour
在您的字段具有相同值的地方绘制线条,使绘图的其余部分为空。相反,contourf
或 imshow
用您选择的颜色图填充空白 space,这样您可以更好地显示您的字段并避免模棱两可的白色 space。
请参阅此代码以供参考:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.animation import FuncAnimation
source = 0.5
sources = [-source, source]
axlim = max(sources)*2 + 1
N = 1000
x = np.linspace(-axlim, axlim, N)
y = np.linspace(-axlim, axlim, N)
X, Y = np.meshgrid(x, y)
norm = plt.Normalize(-2, 2)
cmap = LinearSegmentedColormap.from_list('', ['black', 'white', 'black'])
fig, ax = plt.subplots()
def update(f):
ax.cla()
C1 = np.sin(2*np.pi*f*np.sqrt((X - sources[0])**2 + Y**2))
C2 = np.sin(2*np.pi*f*np.sqrt((X - sources[1])**2 + Y**2))
Z = C1 + C2
ax.imshow(Z,
cmap = cmap,
norm = norm)
ax.plot(N/2*(1 + source/axlim), N/2, 'ro')
ax.plot(N/2*(1 - source/axlim), N/2, 'ro')
ax.set_title(f'f = {f} Hz')
ax.set_aspect('equal')
ax.axis('off')
ani = FuncAnimation(fig = fig, func = update, frames = 11, interval = 100)
plt.show()
由于你的场的波峰和波谷都是建设性的干扰点,而破坏性的点场是空的,所以我选择了黑-白-黑的色图,不能区分波峰和波谷,但更容易区分从破坏性干扰点建设性。