Plotting elliptical orbits - python

I'm trying to write a code that plots the elliptical paths of an object using the equation for the ellipse r=a(1-e^2)/(1+e*cos(theta)). I'd also like this data to be put into an array for other use.
from numpy import *#Imports Python mathematical functions library
import matplotlib.pyplot as plt #Imports plot library
from pylab import *
a = 5
e = 0.3
theta = 0
while theta <= 2*pi:
r = (a*(1-e**2))/(1+e*cos(theta))
print("r = ",r,"theta = ",theta)
plt.polar(theta, r)
theta += pi/180
plt.show()
The code spits out correct values for r and theta, but the plot is blank. The polar plot window appears, but there is nothing plotted.
Please help. Thanks in advance.

Do not call plt.polar once for every point. Instead, call it once, with all the data as input:
import numpy as np #Imports Python mathematical functions library
import matplotlib.pyplot as plt #Imports plot library
cos = np.cos
pi = np.pi
a = 5
e = 0.3
theta = np.linspace(0,2*pi, 360)
r = (a*(1-e**2))/(1+e*cos(theta))
plt.polar(theta, r)
print(np.c_[r,theta])
plt.show()
By the way, numpy can do the calculation as a two-liner, instead of using a while-loop:
theta = np.linspace(0,2*pi, 360) # 360 equally spaced values between 0 and 2*pi
r = (a*(1-e**2))/(1+e*cos(theta))
This defines theta and r as numpy arrays (rather than single values).

I think you need to do points.append([theta,r]) then at the end plt.polar(points) ... that makes a kinda neat design too
from numpy import *#Imports Python mathematical functions library
import matplotlib.pyplot as plt #Imports plot library
from pylab import *
a = 5
e = 0.3
theta = 0
points = []
while theta <= 2*pi:
r = (a*(1-e**2))/(1+e*cos(theta))
print("r = ",r,"theta = ",theta)
points.append((theta, r))
theta += pi/180
#plt.polar(points) #this is cool but probably not what you want
plt.polar(*zip(*points))
plt.show()

Related

Arithmetic operations using list

I am trying to write a MATLAB code into python. The original MATLAB code is from this following vid: https://www.youtube.com/watch?v=T97ddyTMuro. Briefly, the MATLAB code is as follows:
v = 10;
theta = linspace(15, 75, 100);
g = 9.81;
t = 2*v*sin(theta)/g;
r = v*cos(theta).*t;
plot(r,theta)
I was trying to recreate this code in python, attached herewith is what I have tried and failed:
import numpy as np
import math as m
import matplotlib.pyplot as plt
theta = np.linspace(0,70,100)
v = 10 # velocity (m/s)
g = 9.81 # accel. due to grav.
t = []
r = []
a = []
multi =[]
for i in np.linspace(0,70,100):
t.append(2*v*(m.sin(np.deg2rad(i)))/g)
for j in np.linspace(0,70,100):
r.append(v*(m.cos(np.deg2rad(i))))
a.append(r[j]*t[j])
Unable to multiply two lists as they are not integers.
An easier approach is to directly use only numpy code:
import numpy as np
import matplotlib.pyplot as plt
theta = np.deg2rad(np.linspace(0,70,100))
v = 10 # velocity (m/s)
g = 9.81 # accel. due to grav.
t1 = 2*v*np.sin(theta)/g
r = v*np.cos(theta)*t1 # will compute elementwise multiplication
plt.plot(r, theta)
plt.show()

Python (matplotlib) only show normalized values, how do I get absolute values

Please have a check at this code, input data is much larger than 1, the plotted data has max value of 1, so it has to be normalized. I would like them to be absolute values. How can this be done. Many thanks.
import numpy as np
from fipy import *
from matplotlib import pyplot as plt
from scipy.integrate import odeint
import warnings
import time
import pdb
warnings.filterwarnings("ignore", category=DeprecationWarning)
Declare variable values
critical_radius = 1e-10
moments = 4
xf = 5e-3
yf = 2.95e-4
nx = 100
ny = 100
nelm = nx*ny
dx = xf / (nx - 1)
dy = yf / (ny - 1)
Create a 2D mesh
mesh = Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
phi = CellVariable(name = "moment 0",mesh = mesh, value = 0.)
phi_ss = phi.copy()
print(phi_ca)
store_no_180=np.load('store_no_180.npy')
show the values of the data
a=store_no_180[99,0,:]
phi_ss.value=a
viewer= Viewer(vars=phi_ss,title = "moment0")
viewer.plot()

I am getting two plots for one data set in python

I am working through example 8.1 titled Euler's Method from Mark Newman's book Computational Physics. I rewrote the example as a method with Numpy arrays but when I plot it I get two plots on the same figure not sure how to correct it. Also is there better way to convert my 2 1D arrays into 1 2D array to use for plotting in Matplotlib, thanks.
Newman's example :
from math import sin
from numpy import arange
from pylab import plot,xlabel,ylabel,show
def f(x,t):
return -x**3 + sin(t)
a = 0.0 # Start of the interval
b = 10.0 # End of the interval
N = 1000 # Number of steps
h = (b-a)/N # Size of a single step
x = 0.0 # Initial condition
tpoints = arange(a,b,h)
xpoints = []
for t in tpoints:
xpoints.append(x)
x += h*f(x,t)
plot(tpoints,xpoints)
xlabel("t")
ylabel("x(t)")
show()
My modifications:
from pylab import plot,show,xlabel,ylabel
from numpy import linspace,exp,sin,zeros,vstack,column_stack
def f(x,t):
return (-x**(3) + sin(t))
def Euler(f,x0,a,b):
N=1000
h = (b-a)/N
t = linspace(a,b,N)
x = zeros(N,float)
y = x0
for i in range(N):
x[i] = y
y += h*f(x[i],t[i])
return column_stack((t,x)) #vstack((t,x)).T
plot(Euler(f,0.0,0.0,10.0))
xlabel("t")
ylabel("x(t)")
show()
The reason you get two lines is that t as well as x are plotted against their index, instead of x plotted against t
I don't see why you'd want to stack the two arrays. Just keep then separate, which will also solve the problem of the two plots.
The following works fine.
import numpy as np
import matplotlib.pyplot as plt
f = lambda x,t: -x**3 + np.sin(t)
def Euler(f,x0,a,b):
N=1000
h = (b-a)/N
t = np.linspace(a,b,N)
x = np.zeros(N,float)
y = x0
for i in range(N):
x[i] = y
y += h*f(x[i],t[i])
return t,x
t,x = Euler(f,0.0,0.0,10.0)
plt.plot(t,x)
plt.xlabel("t")
plt.ylabel("x(t)")
plt.show()

Points on a graph falling out of a curve

I have to check whether a point is within an ellipse with semiaxes a and b. I generated a list of tuples (dots) and then generated another list of tuples (dotsin) where I only keep those points that are within an ellipse.
However, when generated, some points fall out of the ellipse. Is this error accumulation trough calculations, and if so how do I improve on this so the dots do not fall out of the curve?
Do note that I am a bit rusty in python and some things are not obvious for me.
Thanks in advance!
dots=[(random.uniform(-a,a),random.uniform(-b,b)) for i in range(1000)]#;dots
dotsin=[(x,y) for x,y in dots if (x**2 + y**2)<((a*cos(atan(y/x)))**2 + (b*sin(atan(y/x)))**2)]#;dotsin
plt.scatter([x[0] for x in dotsin],[y[1] for y in dotsin])
plt.grid()
Your condition (x**2 + y**2)<((a*cos(atan(y/x)))**2 + (b*sin(atan(y/x)))**2) is equivalent to (x**2 + y**2)**2 < (a*x) ** 2 + (b*y) ** 2. This is not an equation of ellipse. An equation of ellipse is (x/a)**2 + (y/b)**2 < 1.
from numpy import random
import numpy as np
from math import sin, cos, atan
import matplotlib.pyplot as plt
%matplotlib inline
a = 3
b = 2
n = 1000
dots=[(random.uniform(-a,a),random.uniform(-b,b)) for i in range(n)]#;dots
dotsin=[(x,y) for x,y in dots if (x/a)**2 + (y/b)**2 < 1]#;dotsin
plt.scatter([x[0] for x in dotsin],[y[1] for y in dotsin])
phi = np.linspace(0, 2*np.pi, 200)
plt.plot(a*np.cos(phi), b*np.sin(phi))
plt.grid()

Demonstration of Forward Time Central Space in Python's matplotlib animation package

I want to create a simple animation of how bad the Forward Time Central Space (FTCS) solves the flux conservation equation for a Gaussian velocity distribution ("Physics... yeah!"). I have written a small animation based on this tutorial. I have attached the code below. I'm satisfied with it (given that I don't really know anything about matplotlib's animation package), but I cannot get the animation to be slow enough so that I can actually see something.
This boils down to me not understanding how to set the parameters in the animation.FuncAnimation in the last line of the code. Could anybody explain, help?
import math
import numpy as np
import scipy as sci
import matplotlib.pyplot as plt
from matplotlib import animation
#generate velocity distribution
sigma = 1.
xZero = 0.
N = 101
x = np.linspace(-10,10,N)
uZero = 1. / math.sqrt(2 * math.pi * (sigma**2)) * np.exp(-0.5*((x - xZero)/(2*sigma))**2)
v = 1
xStep = x[2]-x[1]
tStep = 0.1
alpha = v * tStep/xStep * 0.5
#include boundary conditions
u = np.hstack((0.,uZero,0.))
uNext = np.zeros(N + 2)
#solve with forward time central space and store each outer loop in data
#so it can be used in the animation
data = []
data.append(u[1:-1])
for n in range(0,100):
for i in range(1,N+1):
uNext[i] = -alpha * u[i+1] + u[i] + alpha*u[i-1]
u = uNext
data.append(u[1:-1])
data = np.array(data)
#launch up the animation
fig = plt.figure()
ax = plt.axes(xlim=(-10,10),ylim=(-1,1))
line, = ax.plot([],[],lw=2)
def init():
line.set_data([],[])
return line,
#get the data for animation from the data array
def animate(i):
y = data[i]
line.set_data(x,y)
return line,
#the actual animation
anim = animation.FuncAnimation(fig,animate,init_func=init,frames=200,interval=2000,blit=True)
plt.show()
Explore your data variable first. If i run your code, only data[0] and data[1] are different, from data[1] onwards all data (thus frames) are the same.
np.allclose(data[1], data[100])
True

Categories

Resources