Plotting orbits in Python from orbital elements - python

I have created a program to take position and velocity state vectors and calculate all of the Keplerian orbital elements. The next step I want to do is plot the orbit! Any advice on how to approach this using Python 3? Also, any advice about where to migrate this question (if this spot is not appropriate) would be much appreciated.

The best plotting package is, by far, pyplot. It is essentialy a port of the matlab plotting system to python, but it works better than the original. Install numpy & matplotlib and look at the simple plotting tutorials. Plotting would be something like:
import matplotlib.pyplot as plt;
plt.plot(X, Y, color);
plt.show();
where X and Y are 1D arrays of the corresponding x, y values. The answer can't be more specific, since you don't give details about how the variables are stored.

I recommend OpenCV. Here I used CV2 for Python.
import numpy as np
import cv2
cv2.namedWindow("Orbit",cv2.WINDOW_AUTOSIZE)
im_old = np.zeros((100,100))
for i in range(360*4):
xc = 50
yc = 50
im = im_old.copy()
x = 25*np.cos(i*np.pi/180.0)+xc
y = 25*np.sin(i*np.pi/180.0)+yc
im[(x-2):(x+3),(y-2):(y+3)] = 255
im_old[x,y] = 128
cv2.imshow("Orbit",im)
cv2.waitKey(10);
This is for Python 2.7, but I think it should still work.
EDIT: This is for visualizing the actual motion, if that's what you're looking for.

Related

Study of a vector field

I have an input data with 6 columns where the three first are the position x, y, z and the rest are vector components of a vector field. I could only make a 3d graph with quiver3d of the mayavi library in python (x,y,z,px,py,pz) creating 6 numpy arrays x,y,z,px,py,pz just to visualize it.
It would be great to get a 3D graph by any mean where I could insert cut planes where the vectors that are contained on it would be shown, or planes where I could see a color map that would help me to understand its beahaviour. Any help?
Here is the input:
https://pastebin.com/raw/pmGguxUc
Here is the code I used to get the visualization with quiver3d function.
import numpy as np
import mayavi.mlab as mlab
data = np.loadtxt("vectorfield.dat", dtype = float)
dataTranspuesta=data.T
x=dataTranspuesta[0]
y=dataTranspuesta[1]
z=dataTranspuesta[2]
px=dataTranspuesta[3]
py=dataTranspuesta[4]
pz=dataTranspuesta[5]
mlab.quiver3d(x, y, z, px, py, pz, line_width=0.7 ,scale_mode="vector" ,scale_factor=0.0045,mask_points=7 ,mode="arrow", colormap="seismic" )
mlab.show()
It is easier to organize everything using mayavi's pipeline. They are basically the same as using mlab plotting functions, but organize your visualization tasks in a pipeline fashion.
Pfld = mlab.pipeline.vector_field(x, y, z, px, py, pz)
Quiver = mlab.pipeline.vectors(Pfld)
Pcut = mlab.pipeline.vector_cut_plane(Quiver, plane_orientation='x_axes')
You can also draw isosurface contours for the vectors' magnitude
Pmag = mlab.pipeline.extract_vector_norm(Pfld)
Piso = mlab.pipeline.iso_surface(Pmag)
and plane cuts of the scalar field can be achieved through mlab.pipeline.scalar_cut_plane(Pmag) or mlab.pipeline.image_plane_widget(Pmag)
See documentations for more details on the allowed arguments, decorations, etc.
Also examples 1 and
exmaples 2 may fit your needs.

Python Overflow error multiplication

My code structure for a equation i am working on goes like this.
import matplotlib.pyplot as plt
for x in range (0 ,20):
temp = x * (-1*10**(-9)*(2.73**(x/0.0258*0.8) - 1) + 3.1)
P.append(temp)
Q.append(x)
print temp
plt.plot(Q,P)
plt.show()
Printing temp gives me this
4.759377049180328889121938118
-33447.32349862001706705983714
-2238083697441414267.104517188
-1.123028419942448387512537968E+32
-5.009018636753031534804021565E+45
-2.094526332030486492065138064E+59
-8.407952213322881981287736804E+72
-3.281407666305436036872349205E+86
-1.254513385166959745710275399E+100
-4.721184644539803475363811828E+113
-1.754816222227633792004755288E+127
-6.457248346728221564046430946E+140
-2.356455347384037854507854340E+154
-8.539736787129928434375037129E+167
-3.076467506425168063232368199E+181
-1.102652635599075169095479067E+195
-3.934509583907661118429424988E+208
-1.398436369682635574296418585E+222
-4.953240988408539700713401539E+235
-1.749015740500628326472633516E+249
The results shown are highly inaccurate. I know this because, the graph obtained is not what i am supposedly to get. A quick plotting of the same equation in google gave me this
This pic shows the differences in the graphs
The actual plot is the google.com one.
I m fairly certain that the errors are due to the floating point calculations. Can someone help me correct the formulated equations ?
Beginning from around 0.7 your scores drop into nothingness. Google is very clever to figure that out and limits the y-axis to a reasonable scale. In matplotlib you have to set this scale manually.
Also note that you are plotting integers from 0 to 19. When plotting continuous functions, linearly spaced points in an interval often make more sense.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 0.8, 100)
y = x * (-1e-9 *(2.73**(x/0.0258*0.8) - 1) + 3.1)
plt.plot(x,y)
plt.ylim(-0.5, 2)

Plot Mandelbrot with matplotlib / pyplot / numpy / python

I am new to python and learning by following Python "Scientific lecture notes Release 2013.1" tutorial. Please help me solve this Mandelbrot problem in the srcreenshot below (Pg 71). Please provide step-wise commands with explanation if possible because programming concepts are new to me.
http://dl.dropbox.com/u/50511173/mandelbrot.png
I tried to solve this as follows:
import numpy as np
import matplotlib.pyplot as plt
x,y=np.ogrid[-2:1:10j,-1.5:1.5:10j]
c=x + 1j*y
z=0
for g in range(50):
z=z**2 + c
plt.imshow(z.T, extent=[-2,1,-1.5,1.5])
I encountered the following error "TypeError: Image data can not convert to float"
What does this error exactly mean and how to correct it? I am finding it difficult to understand the imshow() function. What do the individual terms inside imshow() mean?
Thank You.
The Mandelbrot set is not the values of z you are trying to plot, which are giving you problems because they are complex numbers. The Mandelbrot set is made up of the points p of the complex plane for which the recurrence relation z_n = z_n-1**2 + p remains bounded. This is checked in a practical way by comparing the result after a few iterations to some threshold. In your case, if you add the following lines after your for loop:
threshold = 2
mask = np.abs(z) < threshold
and then plot mask you should see the set plot on screen.
To understand the general workings of imshow's arguments, you will be better off reading the docs than asking here.
Thanks to #Jan and #Jaime. I got it working as follows, takes too much time to calculate though:
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
x,y=np.ogrid[-2:1:5000j,-1.5:1.5:5000j]
print('')
print('Grid set')
print('')
c=x + 1j*y
z=0
for g in range(500):
print('Iteration number: ',g)
z=z**2 + c
threshold = 2
mask=np.abs(z) < threshold
print('')
print('Plotting using imshow()')
plt.imshow(mask.T,extent=[-2,1,-1.5,1.5])
print('')
print('plotting done')
print('')
plt.gray()
print('')
print('Preparing to render')
print('')
plt.show()
You get this error because plt.imshow does not accept arrays of complex numbers. You can address the real or imaginary part of an array Z as Z.real or Z.imag. Thus if you want to plot the real part
plt.imshow(z.real.T, extent=[-2,1,-1.5,1.5])
would do the job.
The arguments in 'imshow' define the following things.
If z is a N-by-M matrix, it is interpreted as point values on a regular grid. By extent you specify how this grid extends in space...
You're trying to plot a complex value with imshow which is why you're getting that error, can use a threshold as others have suggested, but you might want to consider using np.angle or np.abs as well. You can also simplify your calculation of z using Python's built-in reduce method.
Had some fun with this one, but this shows the general idea:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
x, y = np.ogrid[-2:1:500j, -1.5:1.5:500j]
# Increase this to improve the shape of the fractal
iterations = 9
c = x + 1j*y
z = reduce(lambda x, y: x**2 + c, [1] * iterations, c)
plt.figure(figsize=(10, 10))
plt.imshow(np.angle(z));
plt.figure(figsize=(10, 10))
plt.imshow(np.log(np.abs(z)));

Interpolate large irregular grid onto another irregular grid in Python

I am trying to interpolate complex values from one irregular grid to another irregular grid using Python. The grids are in 2D and there are 103,113 data points. I am using Python 2.6.6, Scipy 0.7.2, Numpy 1.3.0, Matplotlib 0.99.3
In Matlab using griddata this is achieved in roughly 5 seconds.
BnGRID2 = griddata(R_GRID1,Z_GRID1,BnGRID1,R_GRID2,Z_GRID2) (MATLAB)
(Note all arrays are 201 x 513)
However, if I try using matplotlib.mlab.griddata I get a memoryError even if I try to work with the real part only:
mlab.griddata(R_GRID1.flatten(),Z_GRID1.flatten(),num.real(BnGRID1.flatten()),R_GRID2.flatten(),Z_GRID2.flatten())
If I try using interp2d I get a segmentation fault and Python exits:
a = interp.interp2d(R_GRID1,Z_GRID1,num.real(BnGRID1))
I have tried using KDTree and this seems to work ok, however, it takes a few minutes compared with the few seconds for Matlab, but I haven't explored this option too much yet.
Was wondering if anyone has any ideas how I can get this done as quickly as Matlab seems to? I noticed that the newer version of Scipy also has griddata, does anyone know if this can handle large irregular grids?
Scipy's griddata seems to be able to deal with data sets of this size without problems:
import numpy as np
import scipy.interpolate
# old grid
x, y = np.mgrid[0:1:201j, 0:1:513j]
z = np.sin(x*20) * (1j + np.cos(y*3))**2 # some data
# new grid
x2, y2 = np.mgrid[0.1:0.9:201j, 0.1:0.9:513j]
# interpolate onto the new grid
z2 = scipy.interpolate.griddata((x.ravel(), y.ravel()), z.ravel(), (x2, y2), method='cubic')
The griddata step takes about 5s on an old AMD Athlon.
If your data is on a grid (i.e., the coordinates corresponding to value z[i,j] are (x[i], y[j])), you can get more speed by using scipy.interpolate.RectBivariateSpline
z3 = (scipy.interpolate.RectBivariateSpline(x[:,0], y[0,:], z.real)(x2[:,0], y2[0,:])
+ 1j*scipy.interpolate.RectBivariateSpline(x[:,0], y[0,:], z.imag)(x2[:,0], y2[0,:]))
which takes 0.05s. It's much faster, because even if your grid spacings are irregular, a more efficient algorithm can be used as long as the grid is rectangular.

How to display a volume with non-cubic voxels correctly in mayavi

I'm using mayavi (3.3.2) to display volume isosurfaces.
Generally, my volumes do not have cubic voxels; for example, the sampling grid might be 1mm x 1mm in X and Y, but 1.4mm in the Z direction.
How can I get such volumes to display with the correct spatial proportions using mayavi's mlab.contour3d or mlab.pipeline.iso_surface ? I'd really prefer to not resample the volumes to a cubic grid.
Another way of stating the problem: what can I do to get the below code to display a sphere instead of a flattened elipsoid (taking the volume with it's intended 1:1:2 aspect-ratio voxels as a given, and without regenerating or resampling the volume).
import numpy as np
from enthought.mayavi import mlab
def sqr(x): return x*x
s=64
x,y,z = np.ogrid[0:s,0:s,0:s/2]
volume = np.sqrt(sqr(x-s/2)+sqr(y-s/2)+sqr(2*z-s/2))
isos = mlab.contour3d(volume,contours=[5,15,25],transparent=True)
mlab.show()
I'm guessing there ought to be some way of getting at the underlying VTK graphics pipeline (its transforms etc) and inserting the appropriate anisotropic scaling (if there isn't some way of doing it more directly through the mlab API).
For this, it's easiest to explicitly create a scalar_field object from the input data.
I actually do this quite frequently, as we like to put things in depth (where positive is downwards) in geology. That means that you need a negative increment in the z-direction. It would be nice if it was just an argument to the various mlab functions, but its still not too hard to do.
from mayavi import mlab
import numpy as np
s=64
x,y,z = np.ogrid[0:s,0:s,0:s/2]
data = np.sqrt((x-s/2)**2 + (y-s/2)**2 + (2*z-s/2)**2)
grid = mlab.pipeline.scalar_field(data)
grid.spacing = [1.0, 1.0, 2.0]
contours = mlab.pipeline.contour_surface(grid,
contours=[5,15,25], transparent=True)
mlab.show()

Categories