I am trying to crate a program that randomly generates line segments using parametric equations. What I have created kinds of does the job, but instead of the lines being disconnected from one another they form one continues line. This is what I have written in python.
enter import numpy as np
import random as rand
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect("equal")
npoints = 10
V = np.zeros(npoints)
def point1 (npoints):
x0 = np.zeros(npoints)
y0 = np.zeros(npoints)
z0 = np.zeros(npoints)
for k in range (npoints):
theta = rand.uniform(0.0, np.pi)
phi = rand.uniform(0.0, (2 * np.pi))
x0[k] = 10 * np.sin(phi) * np.cos(theta)
y0[k] = 10 * np.sin(phi) * np.sin(theta)
z0[k] = 10 * np.cos(theta)
return np.array([x0,y0,z0])
def point2 (npoints):
x1 = np.zeros(npoints)
y1 = np.zeros(npoints)
z1 = np.zeros(npoints)
for j in range (npoints):
theta = rand.uniform(0.0, np.pi)
phi = rand.uniform(0.0, (2 * np.pi))
x1[j] = 10 * np.sin(phi) * np.cos(theta)
y1[j] = 10 * np.sin(phi) * np.sin(theta)
z1[j] = 10 * np.cos(theta)
return np.array([x1,y1,z1])
n = 10
def t_parameter(n):
t = np.zeros(n)
for i in range (n):
t[i] = rand.uniform(-10,10)
return np.array([t])
p1 = point1(npoints)
p2 = point2(npoints)
V = p2-p1
d = t_paramiter(n)
Lx = d*V[0]+p1[0]
Ly = d*V[1]+p1[1]
Lz = d*V[2]+p1[2]
ax.plot_wireframe(Lx,Ly,Lz)
When I run the code this is what is generated plot of what is generated. What I would like to code to do is keep the values of the initial point and direction vector constant while just updating the d with random values.
I have tried doing something like this
Lx = np.zeros(npoints)
Ly = np.zeros(npoints)
Lz = np.zeros(npoints)
for i in range (n):
Lx[i] = d[i]*V[i]+p1[i]
Ly[i] = d[i]*V[i]+p1[i]
Lz[i] = d[i]*V[i]+p1[i]
but I get an error "setting an array element with a sequence".
Related
At the moment this is my code:
import scipy
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import EventCollection
import math
from scipy import integrate
from scipy import constants
K_b = 1.380649e-23 # Boltzmanns Constant
a_n = 6.022e23 # Avogrados Number
T = 10 # Kelvin
mass = 28
a = 10e-5
def mantleEvolution(tMax, dt) :
N = int(tMax/dt) + 1
timeArray = np.zeros(N)
numberArray = np.zeros(N)
t = 0
n_m = 1 #per cubic centimeter
n_s = 0
i = 0
while i < N:
m_m = float(mass) / a_n
V_m = math.sqrt((8.0 * K_b * float(T)) / (math.pi * float(m_m)))
R = math.pi * pow(float(a), 2) * n_m * V_m
ρ_d = 3 # g/cm^3
μ_g = 2 * 1.67e-23
m_d = (4 / 3) * math.pi * pow(float(a), 3)
n_g = 10e4
d_g = 0.01 # 1% mass density of gas
n_d = (d_g * n_g * μ_g) / (m_d * float(ρ_d))
n_s = n_s + R * dt
n_m = n_m - R * n_d * dt
timeArray[i] = t
numberArray[i] = n_m
t = t + dt
i = i + 1
return [timeArray, numberArray, n_s]
timeArray, numberArray, n_s = mantleEvolution(5.0 * 10**15, 5.0 * 10**9)
fig = plt.figure(figsize=(6.4, 6.4))
ax1 = plt.subplot(111)
ax1.plot(timeArray, numberArray)
ax1.set_xlabel('time, seconds', fontsize=20)
ax1.set_ylabel('number', fontsize=20)
plt.setp(ax1.get_xticklabels(), fontsize=16)
plt.setp(ax1.get_yticklabels(), fontsize=16)
fig.subplots_adjust(left=.18)
plt.savefig('mantleEvolution.pdf')
This is the graph I recieve from graphing my code:
What I wish to find out is how I could plot a second line which behaves the exact opposite where it grows at the same rate the other declines
So for example, something that ressembles this:
If you look at the graph you'll see that the value on the y axis is for both graphs the same for two opposite x values at the x axis. That means that all you want to do is invert the x axis. That is fairly easy done using the formula:
new_x = -1 * (old_x - 2.5) + 2.5
By the way, I see some interesting comments in your code. What is it that you are trying to do here if I may ask?
I am trying to create a matrix with 3 columns and p rows that contains p rows of x, y and z values, later i transpose this matrix and go on. The problem is I do not know how to create this matrix. Any tips?enter code here
time=np.arange(0,100,1)
fphi = 2 #kampo phi daznis
ftheta = 3 #kampo i daznis
Amp = np.pi/2
phi = ()
theta = ()
print(time)
points = []
for p in time:
phi = 2*np.pi*fphi*p
theta = Amp*np.sin(2*np.pi*ftheta*p)
x = r * np.cos(phi)
y = r * np.sin(phi) * np.cos(theta) - h *
np.sin(theta)
z = r * np.sin(phi) * np.sin(theta) + h *
np.cos(theta)
points = np.vstack((points, [x, y, z]))
import numpy as np
r=10
h=8
time=np.arange(0,100,1)
fphi = 2 #kampo phi daznis
ftheta = 3 #kampo i daznis
Amp = np.pi/2
phi = ()
theta = ()
print(time)
points = []
for p in time:
phi = 2*np.pi*fphi*p
theta = Amp*np.sin(2*np.pi*ftheta*p)
x = r * np.cos(phi)
y = r * np.sin(phi) * np.cos(theta) - h * np.sin(theta)
z = r * np.sin(phi) * np.sin(theta) + h * np.cos(theta)
points.append([x,y,z])
result_matrix = np.matrix(points)
U can use np.matrix() with a 2-d nested list as parameter
I have trouble with plt.contourf.
The program is supposed to calculate the distance between s1 and m called s1m and S2 and m called s2m than using s1m and s2m we calculate the wave functions psi and psiP than we multiply them to get the intensity of light, we use what we get in contourf to see the results in a screen.
When I run the program I
import numpy as np
import matplotlib.pyplot as plt
S1 = np.array([100,0,-1])
S2 = np.array([-100,0,-1])
M = np.array([1,1,0])
Lambda = 633
s1m= np.substract(m,S1)#vector S1M
s2m= np.substract(m,S2)#vector S2M
SM1= np.multiply(s1m,s1m)
SM2= np.multiply(s2m,s2m)
S1M= np.sqrt(SM1)#distance s1m
S2M= np.sqrt(SM2)#distance s2m
def intensity (S1M,S2M):
Phi1=(2 * np pi * S1M)/lambda
Phi2=(2 * np.pi * S2M)/lambda
Tet1=(-2 * np.pi * S1M)/lambda
Tet2=(-2 * np.pi * S2M)/lambda
Psi1 = np.exp(Phi1)
Psi2 = np.exp(Phi2)
Psi1P = np.exp(Tet1)
Psi2P = np.exp(Tet2)
Psi = Psi1 + Psi2
PsiP = Psi1P + Psi2P
I = Psi * PsiP
x = np.linspace(1,5,5)
y = np.linspace(1,5,5)
XX,YY = np.meshgrid(x,y)
ZZ = intensity (S1M, S2M)
plt.contourf (XX, YY, ZZ)
plt.show()
In this code I want to have animation something like this. But I dont want the other pendulums that come into picture later. Just the initial one. Currently this is my output. This is the image after the animation completes. In the animation, I want to have a ball(blob) which plots the red lines and another one which plots the green lines.
import numpy as np
from numpy import cos, sin, arange, pi
import matplotlib.pyplot as plt
import matplotlib.animation as animation
h = 0.0002 #the change in runge kutta
figsize = 6
dpi = 1000
N = 200000 # iterations
L1=1 #length 1
L2=1.5 #lenth 2
m1=50 #mass of bob 1
m2=1 #mass of bob2
g = 9.81#gravity
theta_01 = (np.pi/180)*90
theta_02 = (np.pi/180)*60
w_1 = 0
w_2 = 0
# dw/dt function oft theta 1
def funcdwdt1(theta1,theta2,w1,w2):
cos12 = cos(theta1 - theta2)#for wrirting the main equation in less complex manner
sin12 = sin(theta1 - theta2)
sin1 = sin(theta1)
sin2 = sin(theta2)
denom = cos12**2*m2 - m1 - m2
ans = ( L1*m2*cos12*sin12*w1**2 + L2*m2*sin12*w2**2
- m2*g*cos12*sin2 + (m1 + m2)*g*sin1)/(L1*denom)
return ans
# dw/dt function oft thetas 2
def funcdwdt2(theta2,theta1,w1,w2):
cos12 = cos(theta1 - theta2)
sin12 = sin(theta1 - theta2)
sin1 = sin(theta1)
sin2 = sin(theta2)
denom = cos12**2*m2 - m1 - m2
ans2 = -( L2*m2*cos12*sin12*w2**2 + L1*(m1 + m2)*sin12*w1**2
+ (m1 + m2)*g*sin1*cos12 - (m1 + m2)*g*sin2 )/(L2*denom)
return ans2
# d0/dt function for theta 1
def funcd0dt1(w0):
return w0
# d0/dt function for theta 2
def funcd0dt2(w0):
return w0
X1= []
X2= []
Y1= []
Y2= []
def func(w1,w2, theta1,theta2):
for i in range(N):
k1a = h * funcd0dt1(w1) # gives theta1
k1b = h * funcdwdt1(theta1,theta2,w1,w2) # gives omega1
k1c = h * funcd0dt2(w2) # gives theta2
k1d = h * funcdwdt2(theta2,theta1,w1,w2) # gives omega2
k2a = h * funcd0dt1(w1 + (0.5 * k1b))
k2b = h * funcdwdt1(theta1 + (0.5 * k1a),theta2,w1,w2)
k2c = h * funcd0dt2(w2 + (0.5 * k1d))
k2d = h * funcdwdt2(theta2 + (0.5 * k1c),theta1,w1,w2)
k3a = h * funcd0dt1(w1 + (0.5 * k2b))
k3b = h * funcdwdt1(theta1 + (0.5 * k2a),theta2,w1,w2)
k3c = h * funcd0dt2(w2 + (0.5 * k2d))
k3d = h * funcdwdt2(theta2 + (0.5 * k2c),theta1,w1,w2)
k4a = h * funcd0dt1(w1 + k3b)
k4b = h * funcdwdt1(theta1 + k3a,theta2,w1,w2)
k4c = h * funcd0dt2(w2 + k3d)
k4d = h * funcdwdt2(theta2 + k3c,theta1,w1,w2)
#addidng the vakue aftyer the iterartions
theta1 += 1 / 6 * (k1a + 2 * k2a + 2 * k3a + k4a)
w1 +=1 / 6 * (k1b + 2 * k2b + 2 * k3b + k4b)
theta2 += + 1 / 6 * (k1c + 2 * k2c + 2 * k3c + k4c)
w2 += 1 / 6 * (k1d + 2 * k2d + 2 * k3d + k4d)
x1 = L1 * sin(theta1)
y1 = -L1 * cos(theta1)
x2 = x1 + L2 * sin(theta2)
y2 = y1 - L2 * cos(theta2)
X1.append(x1)
X2.append(x2)
Y1.append(y1)
Y2.append(y2)
return x1,y1,x2,y2
print(func(w_1, w_2, theta_01, theta_02))
fig, ax = plt.subplots()
l1, = ax.plot([], [])
l2, = ax.plot([],[])
ax.set(xlim=(-3, 3), ylim=(-2,2))
def animate(i):
l1.set_data(X1[:i], Y2[:i])
l2.set_data(X2[:i], Y2[:i])
return l1,l2,
ani = animation.FuncAnimation(fig, animate, interval = 5, frames=len(X1))
# plt.show()
ani.save('save.mp4', writer='ffmpeg')
Just add another line
l3, = ax.plot([],[], '-ob', lw=2, ms=8)
and in the animate function set its values to
l3.set_data([0,X1[i],X2[i]], [0,Y1[i],Y2[i]])
Adapt line-width and marker-size as necessary. This should draw filled circles at the pendulum positions and the origin with lines connecting them.
You should use Y1 in the l1 data. With a total pendulum length of 2.5, the vertical limits are too small. It is sufficient to use
h = 0.005 #the change in runge kutta
N = 5000 # iterations
to get an animation with realistic speed. Or combine several RK4 steps for each frame. For minimum error you can use h=1e-3, smaller step sizes only lead to the accumulation of floating point errors dominating the method error.
How can I remove the asymptote?
import numpy as np
e = 1.26
beta = .705 * np.pi
rph = 7000
re = 6378
def r(nuh):
return rph * (1 + e) / (1 + e * np.cos(nuh + beta))
theta = np.linspace(-np.pi, np.pi, 50000)
fig2 = pylab.figure()
ax2 = fig2.add_subplot(111)
ax2.plot(r(theta) * np.cos(theta), r(theta) * np.sin(theta))
ax2.plot(rph * np.cos(theta), rph * np.sin(theta), 'r')
# adding the Earth
earth2 = pylab.Circle((0, 0), radius = re, color = 'b')
ax2.add_patch(earth2)
pylab.xlim((-50000, 100000))
pylab.ylim((-50000, 100000))
pylab.show()
As you can see here, setting the divergent points to np.nan will cause them not to be plotted.
In your problem, it is r(theta) which diverges. Define r and theta in the usual way, but then, you want to set the extrema of r(theta) to np.nan.
To do this, make an array first, then change its extrema to np.nan:
rt = r(theta)
ext = [np.argmin(rt), np.argmax(rt)]
rt[ext] = np.nan
Now, be sure to plot with the modified rt array not the original function:
ax2.plot(rt * np.cos(theta), rt * np.sin(theta))