I have no idea about how to plot fourier series graph from equation like this
I try to use matplotlib to plot this but there are so many values. Here are code that I used. Not sure about algorithm.
import numpy as np
import matplotlib.pyplot as plt
x_ = np.linspace(0, 30, 10000)
a0 = 3/5
##an = 1/n * np.pi * (np.sin(0.4 * n * np.pi) + np.sin(0.8 * n * np.pi))
##bn = 1/n * np.pi * (2 - np.cos(0.4 * n * np.pi) - np.cos(0.8 * n * np.pi))
f0 = 5
def a(n):
return 1/n * np.pi * (np.sin(0.4 * n * np.pi) + np.sin(0.8 * n * np.pi))
def b(n):
return 1/n * np.pi * (2 - np.cos(0.4 * n * np.pi) - np.cos(0.8 * n * np.pi))
def s(t, n):
temp = 0
for i in range (1, n + 1):
temp = temp + (a(i) * np.cos(2 * np.pi * i * f0 * t) \
+ b(i) * np.sin(2 * np.pi * n * f0 * t))
temp += a0
return temp
st = []
for i in range (1, 6):
st.append(s(1, 6))
plt.title("Test")
plt.plot(x_, st, color="red")
plt.show()
Tried this then got this error
ValueError: x and y must have same first dimension, but have shapes (10000,) and (5,)
thanks for any help
Related
I need to generate a double 3D gyroid structure. For this, I'm using vedo
from matplotlib import pyplot as plt
from scipy.constants import speed_of_light
from vedo import *
import numpy as np
# Paramters
a = 5
length = 100
width = 100
height = 10
pi = np.pi
x, y, z = np.mgrid[:length, :width, :height]
def gen_strut(start, stop):
'''Generate the strut parameter t for the gyroid surface. Create a linear gradient'''
strut_param = np.ones((length, 1))
strut_param = strut_param * np.linspace(start, stop, width)
t = np.repeat(strut_param[:, :, np.newaxis], height, axis=2)
return t
plt = Plotter(shape=(1, 1), interactive=False, axes=3)
scale=0.5
cox = cos(scale * pi * x / a)
siy = sin(scale * pi * y / a)
coy = cos(scale * pi * y / a)
siz = sin(scale * pi * z / a)
coz = cos(scale * pi * z / a)
six = sin(scale * pi * x / a)
U1 = ((six ** 2) * (coy ** 2) +
(siy ** 2) * (coz ** 2) +
(siz ** 2) * (cox ** 2) +
(2 * six * coy * siy * coz) +
(2 * six * coy * siz * cox) +
(2 * cox * siy * siz * coz)) - (gen_strut(0, 1.3) ** 2)
threshold = 0
iso1 = Volume(U1).isosurface(threshold).c('silver').alpha(1)
cube = TessellatedBox(n=(int(length-1), int(width-1), int(height-1)), spacing=(1, 1, 1))
iso_cut = cube.cutWithMesh(iso1).c('silver').alpha(1)
# Combine the two meshes into a single mesh
plt.at(0).show([cube, iso1], "Double Gyroid 1", resetcam=False)
plt.interactive().close()
The result looks quite good, but now I'm struggling with exporting the volume. Although vedo has over 300 examples, I did not find anything in the documentation to export this as a watertight volume for 3D-Printing. How can I achieve this?
I assume you mean that you want to extract a watertight mesh as an STL (?).
This is a non trivial problem because it is only well defined on a subset of the mesh regions where the in/out is not ambiguous, in those cases fill_holes() seems to do a decent job..
Other cases should be dealt "manually". Eg, you can access the boundaries with mesh.boundaries() and try to snap the vertices to a closest common vertex. This script is not a solution, but I hope can give some ideas on how to proceed.
from vedo import *
# Paramters
a = 5
length = 100
width = 100
height = 10
def gen_strut(start, stop):
strut_param = np.ones((length, 1))
strut_param = strut_param * np.linspace(start, stop, width)
t = np.repeat(strut_param[:, :, np.newaxis], height, axis=2)
return t
scale=0.5
pi = np.pi
x, y, z = np.mgrid[:length, :width, :height]
cox = cos(scale * pi * x / a)
siy = sin(scale * pi * y / a)
coy = cos(scale * pi * y / a)
siz = sin(scale * pi * z / a)
coz = cos(scale * pi * z / a)
six = sin(scale * pi * x / a)
U1 = ((six ** 2) * (coy ** 2) +
(siy ** 2) * (coz ** 2) +
(siz ** 2) * (cox ** 2) +
(2 * six * coy * siy * coz) +
(2 * six * coy * siz * cox) +
(2 * cox * siy * siz * coz)) - (gen_strut(0, 1.3) ** 2)
iso = Volume(U1).isosurface(0).c('silver').backcolor("p5").lw(1).flat()
cube = TessellatedBox(n=(length-1, width-1, height-1)).c('red5').alpha(1)
cube.triangulate().compute_normals()
cube.cut_with_mesh(iso).compute_normals()
print(iso.boundaries(return_point_ids=True))
print(cube.boundaries(return_point_ids=True))
print(iso.boundaries().join().lines())
show(iso, cube).close()
merge(iso, cube).clean().backcolor("p5").show().close()
iso.clone().fill_holes(15).backcolor("p5").show().close()
I am trying to create a recurrence plot with the generated signal. However, the plot is empty for some reason. Why is this happening?
The source for the waveform code is: https://towardsdatascience.com/synthetic-signal-generation-for-engineers-using-python-fee023ad5aec
The source for the recurrence plot is: https://pyts.readthedocs.io/en/stable/generated/pyts.image.RecurrencePlot.html
import numpy as np
import matplotlib.pyplot as plt
from pyts.image import RecurrencePlot
def recurrence_plot(input_arr):
X = input_arr.reshape(-1, 1)
rp = RecurrencePlot(threshold=np.pi / 18)
X_rp = rp.transform(X)
fig, ax = plt.subplots()
ax.imshow(X_rp[0], cmap='binary', origin='lower',
extent=[0, 4 * np.pi, 0, 4 * np.pi])
ax.set_title('A single plot')
def damage_toneburst(nocycles=5, freq=1.3 * 10 ** 5, samplefreq=4 * 10 ** 6):
# nocycles = 5
# freq = 130000
# samplefreq = 4000000
T = nocycles / freq
N = (nocycles / freq) * samplefreq
n = np.arange(0, N, 1)
tone = np.sin((nocycles * 2 * np.pi * n) / N)
burst = 0.5 * (1 - np.cos((2 * np.pi * n) / N))
tb = tone * burst
return tb
burst = damage_toneburst(nocycles=20, freq=1.3 * 10 ** 5)
plt.plot(burst, color='firebrick')
plt.xlabel('Index Datapoint')
plt.ylabel('Signal')
recurrence_plot(burst)
Here is the attachment of the python code:
from scipy.stats import norm
import matplotlib.pyplot as plt
import numpy as np
import math
def V(S0):
# nx = norm.cdf(x)
K = 1.5
T = 1
sigma = 0.1
rd = 0.03
ry = 0.02
e = math.e
d1 = (math.log((S0 * e ** ((rd - ry) * T)) / K) + (sigma ** 2 * T) / 2) / (sigma * math.sqrt(T))
d2 = (math.log((S0 * e ** ((rd - ry) * T)) / K) - (sigma ** 2 * T) / 2) / (sigma * math.sqrt(T))
nd1 = norm.cdf(d1)
nd2 = norm.cdf(d2)
V = e ** (-rd * T) * (S0 * e ** ((rd - ry) * T) * nd1 - K * nd2)
V2 = np.vectorize(V)
S0 = np.arange(1, 1000, 1)
plt.title('V as a function of S0')
plt.xlabel('S0')
plt.ylabel('V')
plt.plot(S0, V2(S0))
plt.show()
And the code with such a result:
How can I fix it?
There are two issues
math.log only accepts size-1 arrays
Removed the math module and switched to numpy methods
Nothing is returned by the function V
Added return V
from scipy.stats import norm
import matplotlib.pyplot as plt
import numpy as np
def V(S0):
# nx = norm.cdf(x)
K = 1.5
T = 1
sigma = 0.1
rd = 0.03
ry = 0.02
e = np.e
d1 = (np.log((S0 * e ** ((rd - ry) * T)) / K) + (sigma ** 2 * T) / 2) / (sigma * np.sqrt(T))
d2 = (np.log((S0 * e ** ((rd - ry) * T)) / K) - (sigma ** 2 * T) / 2) / (sigma * np.sqrt(T))
nd1 = norm.cdf(d1)
nd2 = norm.cdf(d2)
V = e ** (-rd * T) * (S0 * e ** ((rd - ry) * T) * nd1 - K * nd2)
return V # return V added
V2 = np.vectorize(V)
S0 = np.arange(1, 1000, 1)
plt.title('V as a function of S0')
plt.xlabel('S0')
plt.ylabel('V')
plt.plot(S0, V2(S0))
plt.show()
Below is my code, I'm supposed to use the electric field equation and the given variables to create a density plot and surface plot of the equation. I'm getting "invalid dimensions for image data" probably because the function E takes multiple variables and is trying to display them all as multiple dimensions. I know the issue is that I have to turn E into an array so that the density plot can be displayed, but I cannot figure out how to do so. Please help.
import numpy as np
from numpy import array,empty,linspace,exp,cos,sqrt,pi
import matplotlib.pyplot as plt
lam = 500 #Nanometers
x = linspace(-10*lam,10*lam,10)
z = linspace(-20*lam,20*lam,10)
w0 = lam
E0 = 5
def E(E0,w0,x,z,lam):
E = np.zeros((len(x),len(z)))
for i in z:
for j in x:
E = ((E0 * w0) / w(z,w0,zR(w0,lam)))
E = E * exp((-r(x)**2) / (w(z,w0,zR(w0,lam)))**2)
E = E * cos((2 * pi / lam) * (z + (r(x)**2 / (2 * Rz(z,zR,lam)))))
return E
def r(x):
r = sqrt(x**2)
return r
def w(z,w0,lam):
w = w0 * sqrt(1 + (z / zR(w0,lam))**2)
return w
def Rz(z,w0,lam):
Rz = z * (1 + (zR(w0,lam) / z)**2)
return Rz
def zR(w0,lam):
zR = pi * lam
return zR
p = E(E0,w0,x,z,lam)
plt.imshow(p)
It took me way too much time and thinking but I finally figured it out after searching for similar examples of codes for similar problems. The correct code looks like:
import numpy as np
from numpy import array,empty,linspace,exp,cos,sqrt,pi
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
lam = 500*10**-9 #Nanometers
x1 = linspace(-10*lam,10*lam,100)
z1 = linspace(-20*lam,20*lam,100)
[x,y] = np.meshgrid(x1,z1)
w0 = lam
E0 = 5
r = sqrt(x**2)
zR = pi * lam
w = w0 * sqrt(1 + (y / zR)**2)
Rz = y * (1 + (zR / y)**2)
E = (E0 * w0) / w
E = E * exp((-r**2 / w**2))
E = E * cos((2 * pi / lam) * (y + (r**2 / (2 * Rz))))
def field(x,y):
lam = 500*10**-9
k = (5 * lam) / lam * sqrt(1 + (y / (pi*lam))**2)
k *= exp(((-sqrt(x**2)**2 / (lam * sqrt(1 + (y / pi * lam)**2))**2)))
k *= cos((2 / lam) * (y + ((sqrt(x**2)**2 / (2 * y * (1 + (pi * lam / y)**2))))))
return k
#Density Plot
f = field(x,y)
plt.imshow(f)
plt.show()
#Surface Plot
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(x,y,E,rstride=1,cstride=1)
plt.show
I want to "animate" a circle rolling over the sin graph, I made a code where the circle moves rapidly down a straight line, now I want the same but the acceleration will be changing.
My previous code:
import numpy as np
import matplotlib.pyplot as plt
theta = np.arange(0, np.pi * 2, (0.01 * np.pi))
x = np.arange(-50, 1, 1)
y = x - 7
plt.figure()
for t in np.arange(0, 4, 0.1):
plt.plot(x, y)
xc = ((-9.81 * t**2 * np.sin(np.pi / 2)) / 3) + (5 * np.cos(theta))
yc = ((-9.81 * t**2 * np.sin(np.pi / 2)) / 3) + (5 * np.sin(theta))
plt.plot(xc, yc, 'r')
xp = ((-9.81 * t**2 * np.sin(np.pi / 2)) / 3) + (5 * np.cos(np.pi * t))
yp = ((-9.81 * t**2 * np.sin(np.pi / 2)) / 3) + (5 * np.sin(np.pi * t))
plt.plot(xp, yp, 'bo')
plt.pause(0.01)
plt.cla()
plt.show()
You can do this by numerically integrating:
dt = 0.01
lst_x = []
lst_y = []
t = 0
while t < 10: #for instance
t += dt
a = get_acceleration(function, x)
x += v * dt + 0.5 * a * dt * dt
v += a * dt
y = get_position(fuction, x)
lst_x.append(x)
lst_y.append(y)
This is assuming the ball never leaves your slope! If it does, you'll also have to integrate in y in a similar way as done in x!!
Where your acceleration is going to be equal to g * cos(slope).