George
George

Reputation: 232

Python- Plotting phase space trajectories (quiver function)

In the code below, I have found the solution to a system of differential equations. I have plotted the phase space trajectory within this code and it works fine. However, I was looking to repeat the plot but with arrows to help me clearly show what the plot means. I have seen that a similar question has been asked: Drawing phase space trajectories with arrows in matplotlib and hence in the code below I have tried to replicate it for my situation. (I would post this question on that thread, but it won't allow me to)

When i run the code, the images I get are as follows:

Phase space trajectories

Obviously I have misunderstood the quiver function at some point (as the plots should look the same (just the second one should have arrows) this is clearly not the case, also I have seen that altering the number of points in my linspace changes the second plot drastically).

My code is as follows:

# Import the required modules
import numpy as np
from run_kut4 import *
from printSoln import *
import pylab

def G2(x,y):
    G2=np.zeros(2)
    G2[0]=y[1]
    G2[1]=-np.sin(y[0])+0.02*np.cos(y[0])*np.sin(x)
    return G2
x2=0.0
xstop2=40.0
y2=np.array([0.0,0.0]) 
h2=0.005#step size
#freq=1

X2,Y2=integrate(G2,x2,y2,xstop2,h2)

pylab.plot(Y2[:,0],Y2[:,1])
pylab.xlabel('θ')
pylab.ylabel('dθ/dx')
pylab.title('Phase space trajectory (resonant case)')
pylab.show()

y1=np.linspace(-0.4,0.4,100)
y2=np.linspace(-0.4,0.4,100)
U,V=np.meshgrid(y1,y2)

pylab.quiver(U,V,Y2[:,0],Y2[:,1])
pylab.xlabel('θ')
pylab.ylabel('dθ/dx')
pylab.title('Phase space trajectory (resonant case)')
pylab.show()

I was just wondering if anyone could see where I have gone wrong, any help is appreciated. Thanks :)

I have attempted to switch U and V as the syntax suggested, and gotten this: Phase space traj 2

Runge Kutta code used:

  ## module run_kut4
  ''' X,Y = integrate(F,x,y,xStop,h).
  4th-order Runge-Kutta method for solving the
  initial value problem {y}' = {F(x,{y})}, where
  {y} = {y[0],y[1],...y[n-1]}.
  x,y   = initial conditions
  xStop = terminal value of x
  h     = increment of x used in integration
  F     = user-supplied function that returns the
  array F(x,y) = {y'[0],y'[1],...,y'[n-1]}.
  '''
import numpy as np
def integrate(F,x,y,xStop,h):

def run_kut4(F,x,y,h):
    K0 = h*F(x,y)
    K1 = h*F(x + h/2.0, y + K0/2.0)
    K2 = h*F(x + h/2.0, y + K1/2.0)
    K3 = h*F(x + h, y + K2)
    return (K0 + 2.0*K1 + 2.0*K2 + K3)/6.0    

X = []
Y = []
X.append(x)
Y.append(y)
while x < xStop:
    h = min(h,xStop - x)
    y = y + run_kut4(F,x,y,h)
    x = x + h
    X.append(x)
    Y.append(y)
return np.array(X),np.array(Y)

Upvotes: 9

Views: 19006

Answers (2)

user6764549
user6764549

Reputation:

The code given in "Drawing phase space trajectories in Matplotlib with arrows" works for your case too if you reduce the step size h=0.1. We can generate the following figure. Arrows

# Import the required modules
import numpy as np
from run_kut4 import *
import pylab

def G2(x,y):
    G2=np.zeros(2)
    G2[0]=y[1]
    G2[1]=-np.sin(y[0])+0.02*np.cos(y[0])*np.sin(x)
    return G2
x2=0.0
xstop2=40.0
y2=np.array([0.0,0.0])
h2=0.1#step size
#freq=1

X2,Y2=integrate(G2,x2,y2,xstop2,h2)

#pylab.plot(Y2[:,0],Y2[:,1])
pylab.xlabel('θ')
pylab.ylabel('dθ/dx')
pylab.title('Phase space trajectory (resonant case)')
pylab.show()

pylab.quiver(Y2[:-1,0], Y2[:-1,1], Y2[1:,0]-Y2[:-1,0], Y2[1:,1]-Y2[:-1, 1])
pylab.xlabel('θ')
pylab.ylabel('dθ/dx')
pylab.title('Phase space trajectory (resonant case)')
pylab.show()

If you don't like the previous plot you can skip the quiver plot altogether and simply change the plot command to pylab.plot(Y2[:,0],Y2[:,1],'->'). This gives a plot like Arrows2

Upvotes: 2

andrew_reece
andrew_reece

Reputation: 21264

If you're just looking to overlay the quiver on your plot, use y1 and y2 in the X and Y positions:

plt.quiver(y1, y2, U, V, alpha=.3)

quiver

Note: The post you linked to actually has arrows tracking the curves themselves, but you're using a meshgrid over linspace for U and V here, so I'm assuming you just want this grid of arrows.

Upvotes: 0

Related Questions