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)
Related
I run the following code to animate a moving sphere, in which the coordinates are in a text file:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
from matplotlib import cm
from matplotlib import animation
import pandas as pd
df = pd.read_csv('/path/to/text/file', sep=" ", header=None)
fig = plt.figure(facecolor='black')
ax = plt.axes(projection = "3d")
u = np.linspace(0, 2*np.pi, 100)
v = np.linspace(0, np.pi, 100)
r = 4
ax.set_xlim(0, 60)
ax.set_ylim(0, 60)
ax.set_zlim(0, 60)
x0 = r * np.outer(np.cos(u), np.sin(v)) + df[1][0]
y0 = r * np.outer(np.sin(u), np.sin(v)) + df[2][0]
z0 = r * np.outer(np.ones(np.size(u)), np.cos(v)) + df[3][0]
surface_color = "tab:blue"
def init():
ax.plot_trisurf(x0, y0, z0, linewidth=0, antialiased=False)
return fig,
def animate(i):
# remove previous collections
ax.collections.clear()
x = df[1][i]
y = df[2][i]
z = df[3][i]
# add the new sphere
ax.plot_trisurf(x, y, z, linewidth=0, antialiased=False)
return fig,
ani = animation. FuncAnimation(fig, animate, init_func = init, frames = 500, interval = 2)
plt.show()
I get the following error "ValueError: x and y must be equal-length 1D arrays" even though I'm sure the arrays are of equal size. How do I make them equal size and solve this error?
As a sample of whats in the file:
0.196812 19.992262 29.989437 30.040883 0.080273 39.999358 30.009271 30.052325
0.288626 19.998165 29.986778 30.083568 0.305931 39.993330 30.011351 30.126911
0.080401 20.012453 29.982994 30.138681 0.224338 39.986476 30.010048 30.204666
0.380893 20.017042 29.984149 30.196864 0.289713 39.984835 30.009015 30.285159
0.396571 20.009539 29.998625 30.259610 0.350441 39.993791 30.017738 30.361558
0.647959 20.012771 29.995641 30.328414 0.275493 39.992826 30.019380 30.433242
0.741711 20.000002 29.978545 30.397738 0.248958 39.992041 30.010427 30.508367
0.867323 19.991656 29.971294 30.464908 0.313612 39.999097 30.004667 30.591674
The text file is very large, around 20,000 lines.
If the surface you are about to plot has a parametric equation (such as a sphere), use the meshgrid approach (x, y, z must be 2D arrays) and call ax.plot_surface. Instead, you used 1D arrays and later called ax.plot_trisurf: this function is better suited when it's not easy to represent the surface with a meshgrid approach (which is not your case). Do not complicate your life: keep it simply!
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
from matplotlib import cm
from matplotlib import animation
import pandas as pd
df = pd.read_csv('path/to/file', sep=" ", header=None)
fig = plt.figure(facecolor='black')
ax = plt.axes(projection = "3d")
u = np.linspace(0, 2*np.pi, 40)
v = np.linspace(0, np.pi, 20)
u, v = np.meshgrid(u, v)
r = 4
ax.set_xlim(0, 60)
ax.set_ylim(0, 60)
ax.set_zlim(0, 60)
x0 = r * np.outer(np.cos(u), np.sin(v)) + df[1][0]
y0 = r * np.outer(np.sin(u), np.sin(v)) + df[2][0]
z0 = r * np.outer(np.ones(np.size(u)), np.cos(v)) + df[3][0]
surface_color = "tab:blue"
def init():
ax.plot_surface(x0, y0, z0, color=surface_color)
return fig,
def animate(i):
# remove previous collections
ax.collections.clear()
x = df[1][i]
y = df[2][i]
z = df[3][i]
# add the new sphere
ax.plot_surface(x0 + x, y0 + y, z0 + z, color=surface_color)
return fig,
ani = animation. FuncAnimation(fig, animate, init_func = init, frames = 500, interval = 2)
plt.show()
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'd like to be able to catch an error while plotting using the matplotlib animation function.
This is necessary for me as I have a program where it can happen that an error occurs in the updatefig function after a couple of loops. I'd like to then continue in the script to save all the data generated up to that point.
Instead of throwing an error, running the code below will just lead to the following output:
Process finished with exit code 1
I tried to put the try except clause at all positions I could think of but was never able to go to the last print().
See this MWE (taken from here):
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure()
def f(x, y):
return np.sin(x) + np.cos(y)
x = np.linspace(0, 2 * np.pi, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
counter = 0
im = plt.imshow(f(x, y), animated=True)
def updatefig(*args):
global x, y, counter
x += np.pi / 15.
y += np.pi / 20.
im.set_array(f(x, y))
counter += 1
# do something that might fail at one point (and will fail in this example)
if counter > 10:
b = 0
print('bla ' + b) # error
return im,
ani = animation.FuncAnimation(fig, updatefig, interval=50, blit=True)
plt.show()
print('do other stuff now, e.g. save x and y')
There is an error because you are attempting to concatenate a string with an int:
Option 1:
correct the error:
import matplotlib
matplotlib.use('TkAgg')
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure()
def f(x, y):
return np.sin(x) + np.cos(y)
x = np.linspace(0, 2 * np.pi, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
counter = 0
im = plt.imshow(f(x, y), animated=True)
def updatefig(*args):
global x, y, counter
x += np.pi / 15.
y += np.pi / 20.
im.set_array(f(x, y))
counter += 1
# do something that will not fail
if counter > 10:
b = 0
print('bla ' + str(b))
return im,
ani = animation.FuncAnimation(fig, updatefig, interval=50, blit=True)
plt.show()
print('do other stuff now, e.g. save x and y')
option 2:
catch the Error, save the data, and continue:
import matplotlib
matplotlib.use('TkAgg')
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure()
def f(x, y):
return np.sin(x) + np.cos(y)
x = np.linspace(0, 2 * np.pi, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
counter = 0
im = plt.imshow(f(x, y), animated=True)
def save_if_error():
print('do other stuff now, e.g. save x and y')
def updatefig(*args):
global x, y, counter
x += np.pi / 15.
y += np.pi / 20.
im.set_array(f(x, y))
counter += 1
# do something that might fail at one point and catch the error, save the data and continue
if counter > 10:
b = 0
try:
print('bla ' + b) # error
except TypeError:
print("save the data here")
save_if_error()
return im,
ani = animation.FuncAnimation(fig, updatefig, interval=50, blit=True)
plt.show()
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()
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()