How can I plot in 3D in python?
I am trying to plot orbital trajectories. Plotting Orbital Trajectories
From the link above, I was able to get help with setting up the function. However I don't know how to plot in 3D.
When this is run, it doesn't generate the correct trajectory.
Switching np.linspace to np.arnage cause a memory error and I am running this on a 64bit system running Xubuntu with 16 GB of Ram.
So I tried converting Distance Units and Time Units but something isn't correct. Maybe my math or something else.
I let 149.6 * 10 ** 6 = 1 DU. A TU is defined as mu = DU ** 3 / TU ** 2 so 1TU = 2241.15 and DU/TU = 66751.4 Using these conversion, I have: I also tried using x2,y2,z2 to see if that would work.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from numpy import linspace
from mpl_toolkits.mplot3d import Axes3D
mu = 1
# r0 = [-149.6 * 10 ** 6, 0.0, 0.0] # Initial position
# v0 = [29.9652, -5.04769, 0.0] # Initial velocity
u0 = [-1, 0.0, 0.0, 0.000448907, -0.0000756192, 0.0]
def deriv(u, dt):
n = -mu / np.sqrt(u[0] ** 2 + u[1] ** 2 + u[2] ** 2)
return [u[3], # dotu[0] = u[3]'
u[4], # dotu[1] = u[4]'
u[5], # dotu[2] = u[5]'
u[0] * n, # dotu[3] = u[0] * n
u[1] * n, # dotu[4] = u[1] * n
u[2] * n] # dotu[5] = u[2] * n
dt = np.arange(0.0, 20, .0001) # Time to run code in seconds'
u = odeint(deriv, u0, dt)
x, y, z, x2, y2, z2 = u.T
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(x2, y2, z2)
plt.show()
but this plot isn't correct either. It should be an ellipse that stays on the same trajectory.
#!/usr/bin/env python
# This program solves the 3 Body Problem numerically and plots the
# trajectories
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from numpy import linspace
from mpl_toolkits.mplot3d import Axes3D
mu = 132712000000.0
# r0 = [-149.6 * 10 ** 6, 0.0, 0.0] # Initial position
# v0 = [29.9652, -5.04769, 0.0] # Initial velocity
u0 = [-149.6 * 10 ** 6, 0.0, 0.0, 29.9652, -5.04769, 0.0]
def deriv(u, dt):
n = -mu / np.sqrt(u[0] ** 2 + u[1] ** 2 + u[2] ** 2)
return [u[3], # dotu[0] = u[3]'
u[4], # dotu[1] = u[4]'
u[5], # dotu[2] = u[5]'
u[0] * n, # dotu[3] = u[0] * n
u[1] * n, # dotu[4] = u[1] * n
u[2] * n] # dotu[5] = u[2] * n
dt = np.linspace(0.0, 86400 * 700, 5000) # Time to run code in seconds'
u = odeint(deriv, u0, dt)
x, y, z, x2, y2, z2 = u.T
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(x, y, z)
plt.show()
You can literally take the first several lines from that page that #sashkello, and plug in the x,y, and z that you got from the ode solver.
Copied from http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html :
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
#<<solve for x, y, z here>>#
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(x, y, z)
plt.show()
Related
We consider the following funtion depending of $t$ and $x$:
$f(t,x) = e^{-4t\pi^2}\sin(\pi x)$
So, for each time $t$ in the list [0., 0.025, 0.05 , 0.075, 0.1] I would like to plot the graph of the function f(t,.) in Python.
I have tried the following code:
import numpy as np
import matplotlib.pyplot as plt
'time discretization'
dt = 0.025
t = np.arange(0, 0.1 + dt, dt)
m = len(t)
'space discretization'
dx = 0.025
x = np.arange(0, 1 + dx, dx)
n = len(x)
'Matrix E'
E = np.zeros((n,m))
'Loop'
for j in range(0,m-1):
E[:, j ] = np.exp(-4jnp.pi**2)np.sin(np.pix)
'Graphic'
plt.plot(E)
plt.legend([f't = {value}s' for value in t])
However, with the exception of $t = 0$ the graphs displayed after I run the code are completely wrong.
Does some of you have some idea or know some tutorial that can help me to solve this problem?
I thank you in advance for the answer.
I think you might have a couple problems---one main thing is that when calling plt.plot, you generally want to supply x and y coordinates. Also, you are generating 41 values for x, and 5 values for t, which might lead to issues. But, maybe something like this is what you want?
import numpy as np
import matplotlib.pyplot as plt
def f(t, x):
return np.exp(-4 * t * np.pi ** 2) * np.sin(np.pi * x)
# creating the data
dt = 0.025
t = np.arange(0, 0.1 + dt, dt)
m = len(t)
dx = 0.025
x = np.arange(0, 1 + dx, dx)
# making the plot
plt.figure(figsize=(10, 5))
plt.plot(x, f(0, x), label='t = 0')
for i in range(1, m):
plt.plot(x, f(t[i], x), label=f't = {f[i]}')
plt.xlabel('x')
plt.ylabel('f(t, x)')
plt.legend()
plt.show()
I have code that looks like this:
import matplotlib.pyplot as plt
import numpy as np
from nfft import nfft
# number of sample points
N = 400
# Simulated non-uniform data
x = np.linspace(0.0, 1 / 2, N) + np.random.random((N)) * 0.001
y = np.sin(50.0 * 2.0 * np.pi * x) + 0.5 * np.sin(80.0 * 2.0 * np.pi * x)
yf = np.abs(nfft(x, y))
fig, axs = plt.subplots(1)
fig_f, axs_f = plt.subplots(1)
axs.plot(x, y, '.', color='red')
axs_f.plot(x, yf, color='red')
How do I convert the values on the second graph to represent frequency?
The use of the nfft module is not required, answers using pynfft or scipy will be greatly appreciated.
See also:
How do I obtain the frequencies of each value in an FFT?
The following seems to work. Notice the line inserted before graphing the Fourier transform, to generate the frequencies, and that we graph N/2 of the data.
import matplotlib.pyplot as plt
import numpy as np
from nfft import nfft
# number of sample points
N = 400
# Simulated non-uniform data
x = np.linspace(0.0,0.5-0.02, N) + np.random.random((N)) * 0.001
print(x)
print( 'random' )
print( np.random.random((N)) * 0.001 )
y = np.sin(50.0 * 2.0 * np.pi * x) + 0.5 * np.sin(80.0 * 2.0 * np.pi * x)
yf = np.abs(nfft(x, y))
fig, axs = plt.subplots(1)
fig_f, axs_f = plt.subplots(1)
axs.plot(x, y, '.', color='red')
xf = np.fft.fftfreq(N,1./N)
axs_f.plot(xf[:int(N/2)], yf[:int(N/2)], color='red')
plt.show()
Output:
I don't understand why this code (reference):
from numpy import zeros, linspace
import matplotlib.pyplot as plt
# Time unit: 1 h
beta = 10./(40*8*24)
gamma = 3./(15*24)
dt = 0.1 # 6 min
D = 30 # Simulate for D days
N_t = int(D*24/dt) # Corresponding no of hours
t = linspace(0, N_t*dt, N_t+1)
S = zeros(N_t+1)
I = zeros(N_t+1)
R = zeros(N_t+1)
# Initial condition
S[0] = 50
I[0] = 1
R[0] = 0
# Step equations forward in time
for n in range(N_t):
S[n+1] = S[n] - dt*beta*S[n]*I[n]
I[n+1] = I[n] + dt*beta*S[n]*I[n] - dt*gamma*I[n]
R[n+1] = R[n] + dt*gamma*I[n]
fig = plt.figure()
l1, l2, l3 = plt.plot(t, S, t, I, t, R)
fig.legend((l1, l2, l3), ('S', 'I', 'R'), 'upper left')
plt.xlabel('hours')
plt.show()
doesn't produce the same results as this code I made:
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
beta = 10. / (40 * 8 * 24)
gamma = 3. / (15 * 24)
def flu(y, t):
S = y[0]
P = y[1]
R = y[2]
S = - beta * S * P
P = beta * S * P - gamma * P
R = gamma * P
return [S, P, R]
C_I = [50, 1, 0]
t = np.linspace(0, 1000, 1000)
y = odeint(flu, C_I, t)
S = y[:, 0]
P = y[:, 1]
R = y[:, 2]
fig, ax = plt.subplots()
ax.plot(t, S, 'b--', label='S')
ax.plot(t, P, 'r--', label='I')
ax.plot(t, R, 'g--', label='R')
legend = ax.legend(loc='upper right', shadow=True, fontsize='x-large')
legend.get_frame().set_facecolor('#FFFCCC')
plt.show()
I used P instead of I to avoid confusion.
The equations solved with odeint should be the same as the ones provided in the reference link above. And if the equations I use are correct, which I am convinced they are, I don't understand where the mistake(s) lie(s).
Thank you for your help
You set S=y[0] then you set S=- beta * S * P. This overwrites y[0]!!! Similar problems for P and R
Try this:
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
beta = 10. / (40 * 8 * 24)
gamma = 3. / (15 * 24)
def flu(y, t):
S = y[0]
P = y[1]
R = y[2]
dS = - beta * S * P
dP = beta * S * P - gamma * P
dR = gamma * P
return [dS, dP, dR]
C_I = [50, 1, 0]
t = np.linspace(0, 1000, 1000)
y = odeint(flu, C_I, t)
S = y[:, 0]
P = y[:, 1]
R = y[:, 2]
fig, ax = plt.subplots()
ax.plot(t, S, 'b--', label='S')
ax.plot(t, P, 'r--', label='I')
ax.plot(t, R, 'g--', label='R')
legend = ax.legend(loc='upper right', shadow=True, fontsize='x-large')
legend.get_frame().set_facecolor('#FFFCCC')
plt.show()
I am using the below manual method so as to plot the summation of harmonics. The below method is working fine.Please refer the image below.When the same thing implemented in for loop,it is not working as desired.The for loop is meant to take care of n number of harmonic values.Could any help me in this?
import numpy as np
import matplotlib.pyplot as plt
# omega =2*pi
x=np.linspace(0,2*np.pi,2000)
y1=np.sin(1*2*np.pi*x)/1
y2=np.sin(3*2*np.pi*x)/3
y3=np.sin(5*2*np.pi*x)/5
y4=np.sin(7*2*np.pi*x)/7
y5=np.sin(9*2*np.pi*x)/9
Y=y1+y2+y3+y4+y5
plt.plot(x,Y)
plt.grid()
plt.show()
#Implementation in for loop is not working
def Harmonic(i):
y = []
for n in range(0,i):
y=np.sin((2*n+1)*(2*np.pi)*(x))/(2*n+1)
y += y
plt.plot(x,y)
plt.grid()
plt.show()
If the goal was to see the impact of increasing the number of harmonics in "real time", you should use FuncAnimation
fig,ax = plt.subplots()
x=np.linspace(0,2*np.pi,2000)
y=np.zeros((2000,))
l, = ax.plot(x,y)
def initPlot():
ax.set_xlim(0,2*np.pi)
ax.set_ylim(-1,1)
l, = ax.plot(x,y)
return l,
def Harmonic(i):
y=l.get_ydata()
y += np.sin((2*i+1)*(2*np.pi)*(x))/(2*i+1)
l.set_ydata(y)
return l,
anim = animation.FuncAnimation(fig, Harmonic, init_func=initPlot, frames=150, interval=100, blit=True)
Here's a working example for you with a little bit of refactoring:
import numpy as np
import matplotlib.pyplot as plt
def first_solution(N=2000):
w = 2 * np.pi
x = np.linspace(0, w, N)
y1 = np.sin(1 * w * x) / 1
y2 = np.sin(3 * w * x) / 3
y3 = np.sin(5 * w * x) / 5
y4 = np.sin(7 * w * x) / 7
y5 = np.sin(9 * w * x) / 9
y = y1 + y2 + y3 + y4 + y5
plt.plot(x, y)
def second_solution(i, N=2000):
w = 2 * np.pi
x, y = np.linspace(0, w, N), []
harmonics = [np.sin((n * 2 + 1) * w * x) / (n * 2 + 1) for n in range(i)]
plt.plot(x, sum(harmonics))
plt.figure(1)
plt.subplot(211)
first_solution()
plt.grid()
plt.subplot(212)
second_solution(5)
plt.grid()
plt.show()
I've called first_solution to your working method and second_solution to your buggy one. Hope it helps
Do you mean something like that?
import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(0,2*np.pi,2000)
y = [0 for _ in x]
def Harmonic(i):
global y
global x
for n in range(0,i):
y += np.sin((2*n+1)*(2*np.pi)*(x))/(2*n+1)
Harmonic(5)
plt.plot(x,y)
plt.grid()
plt.show()
Or, if you want to have the function the make the plot:
import numpy as np
import matplotlib.pyplot as plt
def Harmonic(i):
x=np.linspace(0,2*np.pi,2000)
y = [0 for _ in x]
for n in range(0,i):
y += np.sin((2*n+1)*(2*np.pi)*(x))/(2*n+1)
plt.plot(x,y)
plt.grid()
plt.show()
Harmonic(5)
I'd like to plot pulse propagation in such a way at each step, it plots the pulse shape. In other words, I want a serie of x-z plots, for each values of y. Something like this (without color):
How can I do this using matplotlib (or Mayavi)? Here is what I did so far:
def drawPropagation(beta2, C, z):
""" beta2 in ps / km
C is chirp
z is an array of z positions """
T = numpy.linspace(-10, 10, 100)
sx = T.size
sy = z.size
T = numpy.tile(T, (sy, 1))
z = numpy.tile(z, (sx, 1)).T
U = 1 / numpy.sqrt(1 - 1j*beta2*z * (1 + 1j * C)) * numpy.exp(- 0.5 * (1 + 1j * C) * T * T / (1 - 1j*beta2*z*(1 + 1j*C)))
fig = pyplot.figure()
ax = fig.add_subplot(1,1,1, projection='3d')
surf = ax.plot_wireframe(T, z, abs(U))
Change to:
ax.plot_wireframe(T, z, abs(U), cstride=1000)
and call:
drawPropagation(1.0, 1.0, numpy.linspace(-2, 2, 10))
will create the following graph:
If you need the curve been filled with white color:
import numpy
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pyplot
from matplotlib.collections import PolyCollection
def drawPropagation(beta2, C, z):
""" beta2 in ps / km
C is chirp
z is an array of z positions """
T = numpy.linspace(-10, 10, 100)
sx = T.size
sy = z.size
T = numpy.tile(T, (sy, 1))
z = numpy.tile(z, (sx, 1)).T
U = 1 / numpy.sqrt(1 - 1j*beta2*z * (1 + 1j * C)) * numpy.exp(- 0.5 * (1 + 1j * C) * T * T / (1 - 1j*beta2*z*(1 + 1j*C)))
fig = pyplot.figure()
ax = fig.add_subplot(1,1,1, projection='3d')
U = numpy.abs(U)
verts = []
for i in xrange(T.shape[0]):
verts.append(zip(T[i, :], U[i, :]))
poly = PolyCollection(verts, facecolors=(1,1,1,1), edgecolors=(0,0,1,1))
ax.add_collection3d(poly, zs=z[:, 0], zdir='y')
ax.set_xlim3d(numpy.min(T), numpy.max(T))
ax.set_ylim3d(numpy.min(z), numpy.max(z))
ax.set_zlim3d(numpy.min(U), numpy.max(U))
drawPropagation(1.0, 1.0, numpy.linspace(-2, 2, 10))
pyplot.show()