6

I need to plot the velocities of some objects(cars).

Each velocity are being calculated through a routine and written in a file, roughly through this ( I have deleted some lines to simplify):

thefile_v= open('vels.txt','w') 

for car in cars:
    velocities.append(new_velocity) 

     if len(car.velocities) > 4:
          try:
              thefile_v.write("%s\n" %car.velocities) #write vels once we get 5 values
              thefile_v.close

          except:
              print "Unexpected error:", sys.exc_info()[0]
              raise

The result of this is a text file with list of velocities for each car.

something like this:

[0.0, 3.8, 4.5, 4.3, 2.1, 2.2, 0.0]
[0.0, 2.8, 4.0, 4.2, 2.2, 2.1, 0.0]
[0.0, 1.8, 4.2, 4.1, 2.3, 2.2, 0.0]
[0.0, 3.8, 4.4, 4.2, 2.4, 2.4, 0.0]

Then I wanted to plot each velocity

with open('vels.txt') as f:
    lst = [line.rstrip() for line in f]

plt.plot(lst[1]) #lets plot the second line
plt.show()

This is what I found. The values are taken as a string and put them as yLabel.

enter image description here

I got it working through this:

from numpy import array

y = np.fromstring( str(lst[1])[1:-1], dtype=np.float, sep=',' )
plt.plot(y)
plt.show()

enter image description here

What I learnt is that, the set of velocity lists I built previously were treated as lines of data.

I had to convert them to arrays to be able to plot them. However the brackets [] were getting into the way. By converting the line of data to string and removing the brackets through this (i.e. [1:-1]).

It is working now, but I'm sure there is a better way of doing this.

Any comments?

2
  • Are you using python 2.7 or 3+? If your using 2.7 I recommending saving the array in a pickle file using the cPickle import. Otherwise you can look at Pickle for 3+. I know this doesn't answer your question but it would make it easier to read objects from hard drive. Commented Mar 21, 2018 at 1:36
  • Im using python 2.7 Commented Mar 21, 2018 at 1:56

3 Answers 3

11

Just say you had the array [0.0, 3.8, 4.5, 4.3, 2.1, 2.2, 0.0], to graph this the code would look something like:

import matplotlib.pyplot as plt

ys = [0.0, 3.8, 4.5, 4.3, 2.1, 2.2, 0.0]
xs = [x for x in range(len(ys))]

plt.plot(xs, ys)
plt.show()
# Make sure to close the plt object once done
plt.close()

if you wanted to have different intervals for the x axis then:

interval_size = 2.4 #example interval size
xs = [x * interval_size for x in range(len(ys))]

Also when reading your values from the text file make sure that you have converted your values from strings back to integers. This maybe why your code is assuming your input is the y label.

Sign up to request clarification or add additional context in comments.

5 Comments

I tried that, copy-pasting the values into another variable, works. However it doesnt when it is from the python script, then I got what I present on image 1. The values are taken as yLabel. Can you see image 1?
Check if the values you are passing are stored as str's or int's.. If they are strings you could add some code like xs = [int(x) for x in xs] to convert them back to integers
'lst = [line.rstrip() for line in f]' 'lst = [float(x) for x in lst]' I got: ValueError: could not convert string to float: [0.0, 3.8, 4.5, 4.3, 2.1, 2.2, 0.0] Im seriously getting crazy
So it is a string not a float! Your conversion should work if the string is prepared properly (not including non float characters). Maybe print the list to check if the string is involving any extra quotations or similar characters
Yes, the data was stored as string by default. I didnt know this. If I use np array when saving the data, all is fixed and all solutions given here work. i.e. np.savetxt("vels.txt", np.array(velocities))
2

The example is not complete, so some assumptions must be made here. In general, use numpy or pandas to store your data.

Suppose car is an object, with a velocity attribute, you can write all velocities in a list, save this list as text file with numpy, read it again with numpy and plot it.

import numpy as np
import matplotlib.pyplot as plt

class Car():
    def __init__(self):
        self.velocity = np.random.rand(5)

cars = [Car() for _ in range(5)]
velocities = [car.velocity for car in cars]
np.savetxt("vels.txt", np.array(velocities))

#### 

vels = np.loadtxt("vels.txt")
plt.plot(vels.T)
## or plot only the first velocity
#plt.plot(vels[0]

plt.show()

enter image description here

2 Comments

Thank you, this is the right approach I was looking for. I really messed up with lists, I certainly will never forget numpy to store data. I have data also for positions, which is a similar matrix for (x,y). What do you recommend? to store positions in a different file, or save the data in a single file as (x,y,vel) ?
It depends completely on how you want to use it. In this example the rows of the arrays are the velocities of the cars. So to add positions, you would need a 3D array. Or you completely change your format to a column array with (x,y,vel,car_number).
0

Just one possible easy solution. Use the map function. Say in your file, you have the data stored like, without any [ and ] non-convertible letters.

#file_name: test_example.txt
0.0, 3.8, 4.5, 4.3, 2.1, 2.2, 0.0
0.0, 2.8, 4.0, 4.2, 2.2, 2.1, 0.0
0.0, 1.8, 4.2, 4.1, 2.3, 2.2, 0.0
0.0, 3.8, 4.4, 4.2, 2.4, 2.4, 0.0

Then the next step is;

import matplotlib.pyplot as plt

path = r'VAR_DIRECTORY/test_example.txt' #the full path of the file


with open(path,'rt') as f:
    ltmp = [list(map(float,line.split(','))) for line in f]

plt.plot(ltmp[1],'r-')
plt.show()

In top, I just assume you want to plot the second line, 0.0, 2.8, 4.0, 4.2, 2.2, 2.1, 0.0. Then here is the result. enter image description here

4 Comments

Im getting this error: lst = [map(float,line.split()) for line in f] ValueError: could not convert string to float: [0.0,
Thanks but Im getting the same error. lst = [map(float,line.split(',')) for line in f] ValueError: could not convert string to float: [0.0
as I mentioned in my first post, the only way to get this work, is by converting the line to string, and deleting the brackets. Using [1:-1], i.e: y = np.fromstring( str(lst[1])[1:-1], dtype=np.float, sep=',' )
@user3766029 "The only way", no, I don't think so. Obviously, python cannot convert [ or ] to float number, so at the very first step, the assumption is that you have already removed left and right square brackets. Now, let me edit the answer again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.