Reputation: 911
I've tried to go through some of the answers about plotting timestamps as strings using pyplot, but none of the answers quite address my situation.
Here is a sample of what I am trying to do with the data organized as [timestamp, open,close , max, min, avg, volume]. The candlestick works fine, but I'm trying to add in the x-axis for showing datetimes.
I understand I need to convert them to a datetime object for the formatter to work, but I'm not sure what is the best way to accomplish this with this type of plot. This is what I have now:
results=[[1388893323, 24.309684210526317, 24.302, 24.309684210526317, 24.261, 24.2828875, 172.1496], [1388893203, 24.301997222222223, 24.2501, 24.301997222222223, 24.2501, 24.28035104166669, 198.16475999999997],
[1388893083, 24.2501, 24.311, 24.311, 24.2501, 24.276614722222227, 1002.402654],
[1388892963, 24.311, 24.311, 24.37764285714286, 24.311, 24.313886785714317, 111.5695297]]
xfmt = DateFormatter('%Y-%m-%d %H:%M:%S')
fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2)
ax.xaxis.set_major_formatter(xfmt)
candlestick(ax, results, width=20)
ax.xaxis_date()
ax.autoscale_view()
plt.setp( plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')
plt.show()
Which produces an error I believe is related to not being a datetime object:
File "sma.py", line 27, in <module>
plt.setp( plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 2530, in get_xticklabels
self.xaxis.get_ticklabels(minor=minor))
File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 1109, in get_ticklabels
return self.get_majorticklabels()
File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 1093, in get_majorticklabels
ticks = self.get_major_ticks()
File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 1191, in get_major_ticks
numticks = len(self.get_major_locator()())
File "/usr/lib/pymodules/python2.7/matplotlib/dates.py", line 749, in __call__
self.refresh()
File "/usr/lib/pymodules/python2.7/matplotlib/dates.py", line 758, in refresh
dmin, dmax = self.viewlim_to_dt()
File "/usr/lib/pymodules/python2.7/matplotlib/dates.py", line 530, in viewlim_to_dt
return num2date(vmin, self.tz), num2date(vmax, self.tz)
File "/usr/lib/pymodules/python2.7/matplotlib/dates.py", line 289, in num2date
if not cbook.iterable(x): return _from_ordinalf(x, tz)
File "/usr/lib/pymodules/python2.7/matplotlib/dates.py", line 203, in _from_ordinalf
dt = datetime.datetime.fromordinal(ix)
ValueError: year is out of range
I'm new to python and I've tried a few things that don't seem to work. How do I resolve this problem?
I tried remapping as suggested and it seems to be working:
results=[[1388897101, 24.52, 24.51, 24.52, 24.51, 24.51562500000004, 58.848754], [1388896981, 24.51, 24.54544, 24.54544, 24.51, 24.521243333333334, 44.292754], [1388896861, 24.546877777777777, 24.5, 24.575633333333332, 24.5, 24.523650277777747, 71.937206], [1388896741, 24.5, 24.5, 24.5, 24.5, 24.5, 27.362592], [1388896621, 24.5, 24.516213513513513, 24.516213513513513, 24.5, 24.504934459459466, 87.731023]]
i=0;
for data in results:
results[i][0] = epoch2num(data[0])
i+=1
results=[[735238.19792824076, 24.52, 24.51, 24.52, 24.51, 24.51562500000004, 58.848754], [735238.19653935183, 24.51, 24.54544, 24.54544, 24.51, 24.521243333333334, 44.292754], [735238.19515046291, 24.546877777777777, 24.5, 24.575633333333332, 24.5, 24.523650277777747, 71.937206], [735238.1937615741, 24.5, 24.5, 24.5, 24.5, 24.5, 27.362592], [735238.19237268518, 24.5, 24.516213513513513, 24.516213513513513, 24.5, 24.504934459459466, 87.731023]]
But the scale on the x-axis covers months instead of just just a few hours of data. How do you adjust the scale for dates?
Upvotes: 2
Views: 2584
Reputation: 368964
matplotlib use different number for time, according to matplotlib.dates
documentation:
Matplotlib provides sophisticated date plotting capabilities, standing on the shoulders of python datetime, the add-on modules pytz and dateutils. datetime objects are converted to floating point numbers which represent time in days since 0001-01-01 UTC, plus 1. For example, 0001-01-01, 06:00 is 1.25, not 0.25.
You need to convert epoch timestamp using matplotlib.dates.epoch2num
:
results=[
...
]
for data in results:
data[0] = epoch2num(data[0]) # <---
Upvotes: 4