Plotting with matplotlib: TypeError: float() argument must be a string or a number

Question:

While searching for a solution to my previous question (which was obviously solved) I got another problem which is still unsolved. I would be very thankful to anyone who could help me to solve it!

There was a thought that I was using an outdated version of matplotlib 1.5.1, but I have updated it now to 2.1.1 as well as numpy to 1.14.0, this hasnt helped me, alas.

So, once again. I have a CSV file as input:

16,59,55,51 13.8
17,00,17,27 13.7
17,00,39,01 13.6
17,01,01,06 13.4

And I run this python script on it:

import matplotlib.pyplot as plt
import csv
from datetime import time

x = []
y = []

with open('calibrated.csv','r') as csvfile:
    plots = csv.reader(csvfile, delimiter=' ')
    for row in plots:
        hours,minutes,seconds,milliseconds = [int(s) for s in row[0].split(",")]

        x.append(time(hours,minutes,seconds,milliseconds))
        y.append(float(row[1]))

plt.plot(x,y, marker='o', label='brightness')
plt.gca().invert_yaxis()
plt.xlabel('time [UT]')
plt.ylabel('brightness [mag, CR]')
plt.legend()
plt.grid()
plt.show()

And I get this TypeError upon it (while the person who solved my previous question doesnt have it!):

Traceback (most recent call last):
  File "lightcurve.py", line 16, in <module>
    plt.plot(x,y, marker='o', label='brightness')
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/pyplot.py", line 3154, in plot
    ret = ax.plot(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/__init__.py", line 1812, in inner
    return func(ax, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/axes/_axes.py", line 1425, in plot
    self.add_line(line)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/axes/_base.py", line 1708, in add_line
    self._update_line_limits(line)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/axes/_base.py", line 1730, in _update_line_limits
    path = line.get_path()
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/lines.py", line 925, in get_path
    self.recache()
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/lines.py", line 612, in recache
    x = np.asarray(xconv, np.float_)
  File "/usr/local/lib/python2.7/dist-packages/numpy/core/numeric.py", line 531, in asarray
    return array(a, dtype, copy=False, order=order)
TypeError: float() argument must be a string or a number

I am stuck there.

Asked By: SergiusPro

||

Answers:

matplotlib has a built in function called plot_date that will help you out here. Note that your time series has to be in the date-time format (though you can add the year, month and day arbitrarily as they do not affect plotting if all times are on the same day).

Here is the code:

import matplotlib.pyplot as plt
import csv
import datetime

x = []
y = []

with open('calibrated.csv','r') as csvfile:
    plots = csv.reader(csvfile, delimiter=' ')
    year = 2017
    month = 1
    day = 16
    for row in plots:
        hours,minutes,seconds,milliseconds = [int(s) for s in row[0].split(",")]

        x.append(datetime.datetime(year,month,day,hours,minutes,seconds,milliseconds))
        y.append(float(row[1]))


plt.plot_date(x,y, marker='o', label='brightness')
plt.gca().invert_yaxis()
plt.xlabel('time [UT]')
plt.ylabel('brightness [mag, CR]')
plt.legend()
plt.grid()
plt.show()

enter image description here

As coldspeed pointed out you would likely benefit greatly from using pandas.

Note that now if the time series was much longer the plot still works correctly.

Thanks to @ImportanceOfBeingErnest for pointing out the original misunderstanding.

Answered By: Robbie

Using matplotlib 2.1 and numpy 1.13 the code from the question works fine as it is.

A plausible explanation for why most people are able to run the code without error could be that matplotlib would rely on pandas for the plotting of datetime.time objects. If pandas is not installed or not found, it would hence fail.

There is some assumption implicitly in the code, which may cause the problem and error seen. This is that the time alone may not be well represented on a matplotlib axes, which usually would expect datetime (i.e. including date) objects.

Introducing some date to the times on the axes might solve the problem.

import io

u = u"""16,59,55,51 13.8
17,00,17,27 13.7
17,00,39,01 13.6
17,01,01,06 13.4"""

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import csv
from datetime import datetime

x = []
y = []

plots = csv.reader(io.StringIO(u), delimiter=' ')
for row in plots:
    hours,minutes,seconds,milliseconds = [int(s) for s in row[0].split(",")]

    x.append(datetime(2018,1,1,hours,minutes,seconds,milliseconds))
    y.append(float(row[1]))

plt.plot(x,y, marker='o', label='brightness')
plt.gca().invert_yaxis()
plt.xlabel('time [UT]')
plt.ylabel('brightness [mag, CR]')
plt.legend()
plt.grid()

hours = mdates.SecondLocator(bysecond=[0,30])
t_fmt = mdates.DateFormatter('%H:%M:%S')
plt.gca().xaxis.set_major_locator(hours)
plt.gca().xaxis.set_major_formatter(t_fmt)

plt.show()

enter image description here

Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.