Странный узор на интерференции matplotlib - PullRequest
2 голосов
/ 11 июля 2020

Я пытаюсь сделать анимацию интерференционной фигуры , как эта:

enter image description here

The difference is that the above image shows the interference figure over time, so the constructive and destructive interference points remain fixed. On the contrary, I am trying to make an animation where I change the frequency of the two sources, keeping them fixed in the space.
Here is my code:

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

enter image description here

The issue is that strange patterns appear like in the last frames:

введите описание изображения здесь

эти шаблоны не являются физическими (они не согласуются с физикой l aws), поэтому в моем коде должна быть ошибка. Я не могу узнать где, но думаю, что проблема в функции matplotlib contour: я подозреваю, что это вводит своего рода псевдоним ...

1 Ответ

2 голосов
/ 11 июля 2020

Проблема заключается в вашем определении C1 и C2: вы применяете синусоидальную функцию к сумме возведенных в квадрат расстояний x и y без применения квадрата root. Вы должны использовать:

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 заполняют пустое пространство выбранной вами цветовой картой, чтобы вы могли лучше отображать свое поле и избегать неоднозначных пробелов. См. Этот код для справки:

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

введите описание изображения здесь

Так как пики и впадины вашего поля являются точками конструктивной интерференции, а в деструктивных точках поле нулевое, я выбрал черно-белую-черную цветовую карту, вы не можете различить guish пики от впадин, но легче отличить guish конструктивные от деструктивных точек пересечения.

...