I've written the following program using python in order to graph multiple sine waves of different frequencies, as well as display the points of intersection between them;
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("ggplot")
fig = plt.figure()
ax = plt.axes()
f1 = float(input("Enter first frequency: "))
f2 = float(input("Enter second frequency: "))
t = np.linspace(0, 10, 1000)
y1 = np.sin(2*np.pi*f1*t)
y2 = np.sin(2*np.pi*f2*t)
plt.plot(t,y1, color = "firebrick", label = "sin({}Hz)".format(f1))
plt.plot(t,y2, color = "teal", label = "sin({}Hz)".format(f2))
plt.axhline(y = 0, color = "grey", linestyle = "dashed", label = "y = 0")
idx = np.argwhere(np.diff(np.sign(y1 - y2))).flatten()
plt.plot(t[idx], y1[idx], 'k.')
plt.legend(loc = "best", frameon=True, fancybox = True,
shadow = True, facecolor = "white")
plt.axis([-0.5, 10.5, -1.5, 1.5])
plt.title("Sine Waves")
plt.xlabel("Time")
plt.ylabel("Amplitude")
plt.show()
Sometimes the output looks just as it's supposed to, for example in this screenshot. However, at other times i obtain an undesired output such as in this one. Could someone demonstrate how to fix this problem? Thank you.
I would like to suggest you to increase your time discretization or simply plot these waves in terms of number of n_T
periods of the highest/lowest frequency to avoid undersampling problems. For instance, if you more interested in the lowest frequency you could modified your code as follows:
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("ggplot")
fig = plt.figure()
ax = plt.axes()
f1 = float(input("Enter first frequency: "))
f2 = float(input("Enter second frequency: "))
n_T = float(input("Enter number of periods of lowest frequency to display: "))
t_max = n_T/min(f1,f2) # change here max or min if you want highest or lowest frequency to be represented on n_T periods
t = np.linspace(0, t_max, 1000)
y1 = np.sin(2*np.pi*f1*t)
y2 = np.sin(2*np.pi*f2*t)
plt.plot(t,y1, color = "firebrick", label = "sin({}Hz)".format(f1))
plt.plot(t,y2, color = "teal", label = "sin({}Hz)".format(f2))
plt.axhline(y = 0, color = "grey", linestyle = "dashed", label = "y = 0")
idx = np.argwhere(np.diff(np.sign(y1 - y2))).flatten()
plt.plot(t[idx], y1[idx], 'k.')
plt.legend(loc = "best", frameon=True, fancybox = True,
shadow = True, facecolor = "white")
plt.axis([-0.05*t_max, 1.05*t_max, -1.5, 1.5])
plt.title("Sine Waves")
plt.xlabel("Time")
plt.ylabel("Amplitude")
plt.show()
which gives for n_T=3
and f1=200
and f2=400
Hz :
and for your problematic case f1=520
and f2=750
Hz:
BONUS : if you want to compute automatically the minimum number n_T
of periods to display the exact number of unique intersections between the two oscillating components. First, convert user inputs f1
and f2
from floats to integers, then find the lowest common multiple lcm
between them (using greatest common divisor gcd
function from math
) and divide it by the highest frequency, here you are:
from math import gcd
def lcm(a,b):
"""
Compute the lowest common multiple of a and b
"""
return a*b/gcd(a,b)
# minimum of n_T periods to visualize every unique intersections of waves
n_T = lcm(f1,f2)/max(f1,f2)
for instance for f1=250
and f2=300
Hz, n_T=1500/300=5
which will give: