0
votes

I'm having some trouble using matplotlib to plot the path of something. Here's a basic version of the type of thing I'm doing.

Essentially, I'm seeing if the value breaks a certain threshold (6 in this case) at any point during the path and then doing something with it later on.

Now, I have 3 lists set-up. The end_vector will be based on the other two lists. If the value breaks past 2 any time during a single simulation, I will add the last position of the object to my end_vector

trajectories_vect is something I want to keep track of my trajectories for all 5 simulations, by keeping a list of lists. I'll clarify this below. And, timestep_vect stores the path for a single simulation.

from random import gauss
from matplotlib import pyplot as plt
import numpy as np

starting_val = 5
T = 1                   #1 year
delta_t = .1            #time-step
N = int(T/delta_t)      #how many points on the path looked at
trials = 5              #number of simulations

#main iterative loop
end_vect = []
trajectories_vect = []
for k in xrange(trials):
    s_j = starting_val
    timestep_vect = []
    for j in xrange(N-1):
        xi = gauss(0,1.0)
        s_j *= xi
        timestep_vect.append(s_j)
    trajectories_vect.append(timestep_vect)
    if max(timestep_vect) > 5:
        end_vect.append(timestep_vect[-1])
    else:
        end_vect.append(0)

Okay, at this part if I print my trajectories, I get something like this (I only posted two simulations, instead of the full 5):

[[ -3.61689976e+00   2.85839230e+00  -1.59673115e+00   6.22743522e-01
1.95127718e-02  -1.72827152e-02   1.79295788e-02   4.26807446e-02
-4.06175288e-02]  [  4.29119818e-01   4.50321728e-01  -7.62901016e-01
-8.31124346e-02 -6.40330554e-03   1.28172906e-02  -1.91664737e-02
-8.29173982e-03 4.03917926e-03]]

This is good and what I want to happen.

Now, my problem is that I don't know how to plot my path (y-axis) against my time (x-axis) properly.

First, I want to put my data into numpy arrays because I'll need to use them later on to compute some statistics and other things which from experience numpy makes very easy.

 #creating numpy arrays from list
 #might need to use this with matplotlib somehow
 np_trajectories = np.array(trajectories_vect)
 time_array = np.arange(1,10)

Here's the crux of the issue though. When i'm putting my trajectories (y-axis) into matplotlib, it's not treating each "list" (row in numpy) as one path. Instead of getting 5 paths for 5 simulations, I am getting 9 paths for 5 simulations. I believe I am inputing stuff wrong hence it is using the 9 time intervals in the wrong way.

 #matplotlib stuff
 plt.plot(np_trajectories)
 plt.xlabel('timestep')
 plt.ylabel('trajectories')
 plt.show()

Here's the image produced:

enter image description here

Obviously, this is wrong for the aforementioned reason. Instead, I want to have 5 paths based on the 5 lists (rows) in my trajectories. I seem to understand what the problem is but don't know how to go about fixing it.

Thanks in advance for the help.

1

1 Answers

3
votes

When you call np_trajectories = np.array(trajectories_vect), your list of trajectories is transformed into a 2d numpy array. The information about its dimensions is stored in np_trajectories.shape, and, in your case, is (5, 9). Therefore, when you pass np_trajectories to plt.plot(), the plotting library assumes that the y-values are stored in the first dimension, while the second dimension describes individual lines to plot.

In your case, all you need to do is to transpose your np_trajectories array. In numpy, it is as simple as

plt.plot(np_trajectories.T)
plt.xlabel('timestep')
plt.ylabel('trajectories')
plt.show()

If you want to plot the x-axis as time, instead of steps of one, you have to define your time progression as a list or an array. In numpy, you can do something like

times = np.linspace(0, T, N-1)
plt.plot(times, np_trajectories.T)
plt.xlabel('timestep')
plt.ylabel('trajectories')
plt.show()

which produces the following figure: timesteps