Python Forum

Full Version: numpy.float64 and plot_date in matplotlib
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,

I am trying to draw the data of IBM stock and I have problems with date formatting.
Format of raw data is as follows:

COLUMNS=DATE,CLOSE,HIGH,LOW,OPEN,VOLUME
a1496928660,151.0583,151.23,151,151,67556
1,151.08,151.12,150.92,151.0552,10547
2,151.2964,151.3,151,151.08,17150
...

Raw that starts with 'a' is actually UNIX time for which I made converter. Variable
'source_data' is tuple

I am having problem to plot data with matplotlib function plot_date(source_data,closep)
I create 'date' variable with numpy.loadtxt function and then function plot_date can not accept it.
Error that I get is:

ValueError: year 55224 is out of range

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
import urllib.request as r
from datetime import datetime

import tzlocal


def bytespdate2num(fmt, encoding='utf-8'):
   str_converter = mdates.strpdate2num(fmt)

   def bytes_converter(b):
       s = b.decode(encoding)
       return str_converter(s)

   return bytes_converter


def graph_data(stock):
   print('Currently pulling:', stock)
   url = 'URL string here'
   url1 = url.encode('utf-8')
   print(url1)

   csv = r.urlopen(url).readlines()
   source_data = []
   stock_data = []

   for bar in range(7, len(csv)):
       # print(csv[bar],'\n')
       tt = csv[bar].decode()
       # print(tt, '\n')


       if tt.count(',') != 5: continue
       offset, close, high, low, open_, volume = tt.split(',')

       if offset[0] == 'a':
           day = float(offset[1:])
           offset = 0
           dt = datetime.fromtimestamp(day + (240 * offset))
           # print(dt.strftime("%Y-%m-%d %H:%M:%S.%f%z (%Z)"), close, high, low, open_, volume)
           # source_data=dt.strftime("%Y-%m-%d %H:%M:%S.%f%z (%Z)"), close, high, low, open_, volume
           source_data = dt.strftime('%Y%m%d'), close, high, low, open_, volume
       else:
           offset = float(offset)
           open_, high, low, close = [float(x) for x in [open_, high, low, close]]
           dt = datetime.fromtimestamp(day + (240 * offset))
           # print(dt.strftime("%Y-%m-%d %H:%M:%S.%f%z (%Z)"),close, high, low, open_, volume)
           # source_data = dt.strftime("%Y-%m-%d %H:%M:%S.%f%z (%Z)"), close, high, low, open_, volume
           source_data = dt.strftime('%Y%m%d'), close, high, low, open_, volume


       #date = np.loadtxt(source_data, delimiter=',', unpack=True,
        #       converters={0: bytespdate2num('%Y%m%d')})


       date, closep, highp, lowp, openp, volumep = np.loadtxt(source_data, delimiter=',', unpack=True)
       print(type(date))


   plt.plot_date(date, closep)
   plt.show()
    
graph_data('IBM')
You do not convert your  date to matplotlib dates, value of your date is 20170608?, plt.plot_date takes it as number of days from 1.1.1, that is 55224 years, out of range of python datatetime.

Morever even with correct converting you would plot only last bar (you are not keeping older values). And with that strange way to convert datetime to matplotlib dates through string and loadtxt you are discarding time part of timestamp, so you could end with hundreds of bars with same date. Perhaps better way is to use something like
matplotlib_date = mdates.date2num(datetime.fromtimestamp(day + 240 * offset))
to convert posix timestamp to matplotlib date (real number where fractional part represents part of day).

You probably should split your function and have one function to convert downloaded data and second one to plot.