4

Part 1 below illustrates using datetime objects to plot a curve.

Part 2 illustrates using floats to plot a set of segments.

Part 3 merely blends Parts 1 & 2, but it fails. Why?

import datetime
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import collections  as mc

#----------------Part 1----------------
d0 = datetime.datetime(2001, 1, 1)
d1 = datetime.datetime(2002, 1, 1)
d2 = datetime.datetime(2003, 1, 1)
d3 = datetime.datetime(2005, 1, 1)
d4 = datetime.datetime(2007, 1, 1)
d5 = datetime.datetime(2009, 1, 1)

date  = [ d0, d1, d2, d3, d4, d5 ]
price = [ 5, 4, 6, 7, 3, 8 ]

plt.plot(date, price)
plt.show()

#----------------Part 2----------------
lines = [ [ (0.5, 1.2), (1.1, 1.3) ],
          [ (2.2, 2.8), (3.1, 4.2) ],
          [ (1.9, 2.9), (0.2, 1.4) ] ]

lc = mc.LineCollection(lines)
fig, ax = plt.subplots()
ax.add_collection(lc)
ax.autoscale()
ax.margins(0.1)
plt.show()

#----------------Part 3----------------
lines = [ [ (d0, 1.2), (d1, 1.3) ],
          [ (d2, 2.8), (d3, 4.2) ],
          [ (d4, 2.9), (d5, 1.4) ] ]

lc = mc.LineCollection(lines)
fig, ax = plt.subplots()
ax.add_collection(lc)
ax.autoscale()
ax.margins(0.1)

plt.show()

Update

The line

lc = mc.LineCollection(lines)

in Part 3 bails out with the error:

Traceback (most recent call last):
  File "datetime-difficulty.py", line 37, in <module>
    lc = mc.LineCollection(lines)
  File "/lib/python/matplotlib/collections.py", line 897, in __init__
    self.set_segments(segments)
  File "/lib/python/matplotlib/collections.py", line 906, in set_segments
    seg = np.asarray(seg, np.float_)
  File "/lib/python/numpy/core/numeric.py", line 235, in asarray
    return array(a, dtype, copy=False, order=order)
TypeError: float() argument must be a string or a number
Community
  • 1
  • 1
Calaf
  • 10,113
  • 15
  • 57
  • 120
  • @alfasin Updated: "float() argument must be a string or a number" – Calaf Jan 24 '15 at 00:01
  • Well, that means that `LineCollection()` accepts line with a float as the first argument in every tuple, not a date-object ;) – Nir Alfasi Jan 24 '15 at 00:09
  • @alfasin I could compute and pass some floats, but then the x-labels will be meaningless. Suggestions? – Calaf Jan 24 '15 at 00:23

1 Answers1

2

It looks like you are using matplotlib, so you'll need to convert your dates into floats in order for your plots to work. Thankfully, matplotlib supplies the date2num() function. Run all of your dates through that function, and matplotlib should be able to give you a meaningful x-axis (depending on formatter / locator).

Zachary Cross
  • 2,298
  • 1
  • 15
  • 22
  • But then the x labels are meaningless, and moving the cursor to a point in the diagram gives a meaningless x-coordinate. As Part 1 illustrates, matplotlib already handles datetime just fine. – Calaf Jan 24 '15 at 03:03
  • @Calaf just because it manages to handle datetime doesn't mean it can combine it with non datetime on the same axis. – Mark Ransom Jan 24 '15 at 05:00