If you run the code you will see that I'm displaying contour lines for the Momentum Capacity (variable AM - Contour Line Plot) for different diameters. What I wish to do is to display the 2.0 contour line for different RPM values, while keeping the current X and Y axes.
Currently, RPM is a fixed value with which I compute AM. If for example, I increase the RPM, the 2.0 contour line will move "up", and "down" if I decrease it. I wish to display this variation in 2.0 contour line positioning. In the end, I want the graph to have a 4000 RPM 2.0 line, then a 4500 RPM 2.0 line, then a 5000 RPM 2.0 line, and so on.
Any advice is greatly appreciated! Thank you!
import numpy as np
import matplotlib.pyplot as plt
from pylab import meshgrid
"""
________________________________________________________________________________________________________________________
Functions
________________________________________________________________________________________________________________________
"""
def mm2m(value):
return value * 10 ** (-3)
def m2mm(value):
return value * 10 ** 3
def rpm2rad(value):
return value * 2 * np.pi / 60
def get_percentage_diff(previous, current):
try:
percentage = abs(previous - current) / max(previous, current) * 100
except ZeroDivisionError:
percentage = float('inf')
if current < previous:
percentage = - percentage
return percentage
def angular_momentum(d1, d2):
R1 = d1 / 2
R2 = d2 / 2
V = (np.pi * R1 ** 2 - np.pi * R2 ** 2) * width
M = rho * V
inertia = 1 / 2 * M * (R1 ** 2 + R2 ** 2)
omega = rpm2rad(RPM)
return inertia * omega
def angular_momentum_test(inertia, rpm):
omega = rpm2rad(rpm)
return inertia * omega
def get_inertia(d1, d2, w):
R1 = d1 / 2
R2 = d2 / 2
V = (np.pi * R1 ** 2 - np.pi * R2 ** 2) * w
M = rho * V
return 1 / 2 * M * (R1 ** 2 + R2 ** 2)
def angular_momentum_rod(d1, d2):
R1 = d1 / 2
R2 = d2 / 2
V = (np.pi * R1 ** 2 - np.pi * R2 ** 2) * rod_width
M = rho * V
inertia = 1 / 2 * M * (R1 ** 2 + R2 ** 2)
omega = rpm2rad(RPM)
return inertia * omega
"""
________________________________________________________________________________________________________________________
Input
________________________________________________________________________________________________________________________
"""
RPM = 6000
rho = 2700
width = mm2m(50)
rod_width = mm2m(250)
rod_diameter = mm2m(10)
"""
________________________________________________________________________________________________________________________
Calculation
________________________________________________________________________________________________________________________
"""
D1 = mm2m(np.arange(100, 150, 1))
D2 = mm2m(np.arange(50, 140, 1))
X, Y = meshgrid(D1, D2)
AM = angular_momentum(X, Y) + angular_momentum_rod(rod_diameter, 0)
# Testing Values
OD = mm2m(145)
ID = mm2m(80)
test_width = mm2m(60)
test_RPM = 6000
I_test = get_inertia(OD, ID, test_width) * 10 ** 6
AM_test = angular_momentum_test(I_test / 10 ** 6, test_RPM) + angular_momentum_rod(rod_diameter, 0)
Inventor_I_Value = 3190.667
# rod_I_test = get_inertia(mm2m(10),0,mm2m(250)) * 10 ** 6
"""
________________________________________________________________________________________________________________________
Printing
________________________________________________________________________________________________________________________
"""
print("The momentum capacity is: ", AM_test, " [Nms]\n")
print("The moment of inertia is: ", I_test,
" [Nmm2] , diff: {} \n".format(get_percentage_diff(I_test, Inventor_I_Value)))
# print(rod_I_test)
"""
________________________________________________________________________________________________________________________
Plotting
________________________________________________________________________________________________________________________
"""
plt.figure(figsize=(10, 10), dpi=300)
ctr = plt.contour(X, Y, AM, np.arange(0, 10, 0.5), colors='k')
fil = plt.contourf(X, Y, AM, levels=200, cmap="turbo")
plt.grid(True, which='both', zorder=1, alpha=0.69, linewidth=0.75,linestyle='-')
plt.text(0.102, 0.132, " Width = {} [mm] \n \u03C1 = {} [kg/m3]\n RPM = {} ".format(m2mm(width), rho, RPM), style='normal',
bbox={'facecolor': 'white', 'alpha': 1, 'pad': 10})
plt.minorticks_on()
plt.xlabel("Outer Diameter [m]")
plt.ylabel("Inner Diameter [m]")
plt.title("Flywheel Momentum Capacity [Nms]")
plt.clabel(ctr)
plt.colorbar(fil)
plt.savefig('Flywheel_Momentum_Capacity.png')
plt.tight_layout()
plt.show()
The key is to set levels=[2] inside the plt.contour call.
I'm going to give you a recipe. Start by creating two lists with the same number of elements
RPMS = [4500, 5000, 5500, 6000]
colors = ["r", "g", "b", "k"]
Loop over each RPM, do the computation and plot it:
# this are needed to create a legend when using contour
from matplotlib.lines import Line2D
labels, artists = [], []
plt.figure(figsize=(10, 10), dpi=300)
for RPM, col in zip(RPMS, colors):
# do the computations
# plotting
plt.contour(X, Y, AM_, np.arange(0, 10, 0.5), levels=[2], colors=col)
labels.append(str(RPM))
artists.append(Line2D([0, 1], [0, 0], color=col))
# create a legend
plt.legend(artists, labels)
# all other customizations
I solve the motion in gravitational field around the sun with scipy and mathplotlib and have a problem. My solution is not correct. It is not like in example. Formulas that I used.
from scipy.integrate import odeint
import scipy.constants as constants
import numpy as np
import matplotlib.pyplot as plt
M = 1.989 * (10 ** 30)
G = constants.G
alpha = 30
alpha0 = (alpha / 180) * np.pi
v00 = 0.7
v0 = v00 * 1000
def dqdt(q, t):
x = q[0]
y = q[2]
ax = - G * M * (x / ((x ** 2 + y ** 2) ** 1.5))
ay = - G * M * (y / ((x ** 2 + y ** 2) ** 1.5))
return [q[1], ax, q[3], ay]
vx0 = v0 * np.cos(alpha0)
vy0 = v0 * np.sin(alpha0)
x0 = -150 * (10 ** 11)
y0 = 0 * (10 ** 11)
q0 = [x0, vx0, y0, vy0]
N = 1000000
t = np.linspace(0.0, 100000000000.0, N)
pos = odeint(dqdt, q0, t)
x1 = pos[:, 0]
y1 = pos[:, 2]
plt.plot(x1, y1, 0, 0, 'ro')
plt.ylabel('y')
plt.xlabel('x')
plt.grid(True)
plt.show()
How can I fix this?
Maybe you can tell me solution with another method for example with Euler's formula or with using other library.
I will be very greatful if you help me.
How to get one graph which consist of two different sinusoidal waves? I wrote this code but it makes two separate waves..
Fs = 1000
f = 2
sample = 1000
sample_rate= 0.1
x = np.arange(sample)
noise = 0.0003*np.asarray(random.sample(range(0,1000),sample))
y = np.sin(2 * np.pi * f * x / Fs)+noise
f1 = 10
x1 = np.arange(sample)
y1 = np.sin(2 * np.pi * f1 * x / Fs)+noise
plt.plot(x, y, x1, y1)
plt.xlabel('Time(s)')
plt.ylabel('Amplitude(V)')
plt.show()
I got this
but I need to get this one
Aside from the "spike" joining the two different signals, this looks more like what you're looking for:
import numpy as np
import matplotlib.pyplot as plt
rng = np.random.default_rng()
Fs = 1000
def generate_noisy_signal(*, length, f, noise_amp=0):
x = np.arange(length)
noise = noise_amp * rng.random(length)
return np.sin(2 * np.pi * f * x / Fs) + noise
signal1 = generate_noisy_signal(length=1000, f=2, noise_amp=0.3)
signal2 = generate_noisy_signal(length=1000, f=10, noise_amp=0.3) + 1.5
signal = np.concatenate([signal1, signal2])
plt.plot(signal)
plt.xlabel("Time(s)")
plt.ylabel("Amplitude(V)")
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).
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