24

Here is my problem: polyfit does not take datetime values, so that I converted datetime with mktime producing the polynomial fit works

z4 = polyfit(d, y, 3) 
p4 = poly1d(z4)

For the plot however, I would like the datetime description on the axis and didn't # figure out how to do that. Can you help me?

fig = plt.figure(1)
cx= fig.add_subplot(111) 

xx = linspace(0,  d[3], 100)
pylab.plot(d, y, '+', xx, p4(xx),'-g')
cx.plot(d, y,'+', color= 'b', label='blub')
plt.errorbar(d, y,
           yerr,
           marker='.',
           color='k',
           ecolor='b',
           markerfacecolor='b',
           label="series 1",
           capsize=0,
           linestyle='')

cx.grid()
cx.set_ylim(0,0.03)
plt.show()

rest of the code:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import axis
from datetime import datetime
from numpy import *
import pylab
import time

my first 4 time data points

x = [datetime(1978, 7, 7), 
     datetime(1980, 9, 26), 
     datetime(1983, 8, 1), 
     datetime(1985,8,8)]

d=[]
for i in x:
    d.append(time.mktime(i.timetuple()))

my first 4 data values

y = [0.00134328779552718,
     0.00155187668863844,
     0.0039431374327427,
     0.00780037563783297]

my calculated standard deviations for error bars

yerr = [0.0000137547160254577,
        0.0000225670232594083,
        0.000105623642510075,
        0.00011343121508]
Cœur
  • 37,241
  • 25
  • 195
  • 267
Corins
  • 241
  • 1
  • 2
  • 3

1 Answers1

25

Instead of plotting datenums, use the associated datetimes.


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime as DT
import time

dates = [DT.datetime(1978, 7, 7),
     DT.datetime(1980, 9, 26),
     DT.datetime(1983, 8, 1),
     DT.datetime(1985, 8, 8)]

y = [0.00134328779552718,
     0.00155187668863844,
     0.0039431374327427,
     0.00780037563783297]


yerr = [0.0000137547160254577,
        0.0000225670232594083,
        0.000105623642510075,
        0.00011343121508]

x = mdates.date2num(dates)

z4 = np.polyfit(x, y, 3)
p4 = np.poly1d(z4)

fig, cx = plt.subplots()

xx = np.linspace(x.min(), x.max(), 100)
dd = mdates.num2date(xx)

cx.plot(dd, p4(xx), '-g')
cx.plot(dates, y, '+', color='b', label='blub')
cx.errorbar(dates, y,
             yerr,
             marker='.',
             color='k',
             ecolor='b',
             markerfacecolor='b',
             label="series 1",
             capsize=0,
             linestyle='')

cx.grid()
cx.set_ylim(0, 0.03)
plt.show()

yields

enter image description here

Note in your code, x represented a list of datetimes, and d represented numbers. I've decided to reverse that: I use dates for a list of datetimes, and x to represent numbers.

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • This is what I was looking for - thanks! I'm surprised though that matplotlib is needed if you want to do something useful with datetime objects. Is there an equivalent function to `matplotlib.dates.date2num()` in datetime? – AstroFloyd Mar 28 '20 at 17:30
  • The function `date2num` returns the number of days that have elapsed since January 1st, 1970 (Unix epoch). – Mykola Zotko Feb 08 '23 at 13:11