首页 > 解决方案 > Matplotlib 干涉图奇怪图案

问题描述

我正在尝试制作像这样的干涉图动画:

在此处输入图像描述

不同之处在于上图显示了一段时间内的干涉图,因此相长干涉和相消干涉点保持不变。相反,我正在尝试制作一个动画,在其中更改两个源的频率,使它们固定在空间中。
这是我的代码:

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()

在此处输入图像描述

问题是奇怪的模式出现在最后一帧中:

在此处输入图像描述

这些模式不是物理的(它们不符合物理定律),所以我的代码中一定有错误。我不知道在哪里,但我认为问题出在 matplotlibcontour函数中:我怀疑它引入了一种别名......

标签: pythonpython-3.xmatplotlibanimationphysics

解决方案


问题在于您对C1and的定义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))

plot 方法没有问题contour,但是,我建议您将其替换为contourfor,甚至更好,imshow. 原因是contour您的字段具有相同值的情节线,使情节的其余部分保持空白。相反,contourf或者imshow用您选择的颜色图填充空白空间,这样您就可以更好地显示您的字段并避免模棱两可的空白。
请参阅此代码以供参考:

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()

在此处输入图像描述

由于您场的峰和谷都是建设性干涉点,而在破坏性点中,场是空的,我选择了黑 - 白 - 黑颜色图,您无法区分峰和谷,但更容易区分建设性和破坏性干涉点.


推荐阅读