user569474
user569474

Reputation: 451

Matplotlib and timestamp are causing troubles

Why is this not working? How to fix it? I am trying to plot a figure where x-axis is the temporal axis and y values are the second column in csv file. I want the x plot labels to be in a more human readable format...

testi.csv

1315655275.0,0.1,1.4
1325655275.0,0.11,2.2
1335655275.0,0.23,11.96
1345655275.0,0.81,63.18
1355655275.0,2.76,560.28
1365655275.0,5.54,609.4
1375655275.0,7.21,576.8

testi2.py

import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as md
data = np.genfromtxt('testi.csv', delimiter=',', names=['t', 'btc', 'eur'])
plt.xkcd()
plt.plot(data['t'], data['btc'], label='the data')
plt.xticks(rotation=75)
ax=plt.gca()
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S')
ax.xaxis.set_major_formatter(xfmt)
plt.savefig('testi2.png')

This is the error message after I give "python < testi2.py":

Traceback (most recent call last):
  File "<stdin>", line 13, in <module>
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/pyplot.py", line 564, in savefig
    return fig.savefig(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/figure.py", line 1421, in savefig
    self.canvas.print_figure(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/backend_bases.py", line 2220, in print_figure
    **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/backends/backend_agg.py", line 505, in print_png
    FigureCanvasAgg.draw(self)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/backends/backend_agg.py", line 451, in draw
    self.figure.draw(self.renderer)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/artist.py", line 54, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/figure.py", line 1034, in draw
    func(*args)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/artist.py", line 54, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/axes/_base.py", line 2056, in draw
    a.draw(renderer)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/artist.py", line 54, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/axis.py", line 1087, in draw
    ticks_to_draw = self._update_ticks(renderer)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/axis.py", line 945, in _update_ticks
    tick_tups = [t for t in self.iter_ticks()]
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/axis.py", line 893, in iter_ticks
    for i, val in enumerate(majorLocs)]
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/dates.py", line 395, in __call__
    dt = num2date(x, self.tz)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/dates.py", line 329, in num2date
    return _from_ordinalf(x, tz)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-i686.egg/matplotlib/dates.py", line 218, in _from_ordinalf
    dt = datetime.datetime.fromordinal(ix)
ValueError: year is out of range

Upvotes: 3

Views: 3497

Answers (1)

sodd
sodd

Reputation: 12923

You have to convert your timestamps to datetime objects.

import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as md
import datetime as dt

# create vectorized converter (can take list-like objects as arguments)
dateconv = np.vectorize(dt.datetime.fromtimestamp)

data = np.genfromtxt('testi.csv', delimiter=',', names=['t', 'btc', 'eur'])
plt.xkcd()

dates = dateconv(data['t']) # convert timestamps to datetime objects

plt.plot(dates, data['btc'], label='the data')
plt.xticks(dates, rotation=75, ha='right') # set ticks at plotted datetimes
ax=plt.gca()
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S')
ax.xaxis.set_major_formatter(xfmt)

plt.tight_layout() # to make sure everything fits inside the figures boundaries

plt.savefig('testi2.png')

Output without legend

In order to make the label you set for the plot appear, you have to call plt.legend() before plt.savefig('testi2.png'). With plt.legend(loc=2) (places the legend in upper left corner) the output becomes:

Output with legend

Upvotes: 5

Related Questions