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 函数中:我怀疑它引入了一种别名...

问题出在您对 C1C2 的定义中:您将正弦函数应用于 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 在您的字段具有相同值的地方绘制线条,使绘图的其余部分为空。相反,contourfimshow 用您选择的颜色图填充空白 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()

由于你的场的波峰和波谷都是建设性的干扰点,而破坏性的点场是空的,所以我选择了黑-白-黑的色图,不能区分波峰和波谷,但更容易区分从破坏性干扰点建设性。