Ошибка виджета Bokeh DateRangeSlider, невозможно преобразовать строку в метку времени - PullRequest
0 голосов
/ 18 сентября 2018

Я пытаюсь внедрить виджет DateRangeSlider в мой проект bokeh.Я использую виджет, чтобы отрегулировать количество текущей даты запаса в диапазоне, который я накопил в CSV-файле.Всякий раз, когда я перемещаю виджет слайдера

enter image description here

, он выдает ошибку.enter image description here

Я предполагаю, что используемые типы данных неверны.Проблема заключается в моей функции обновления.

Как я могу решить эту проблему?

from math import pi
import pandas as pd
import numpy as np
import datetime
import time
from datetime import date
from bokeh.layouts import row, widgetbox, column
from bokeh.models import ColumnDataSource, PrintfTickFormatter, CDSView,BooleanFilter
from bokeh.models.widgets import PreText, Select, DateRangeSlider, Button, DataTable, TableColumn, NumberFormatter
from bokeh.io import curdoc, show, reset_output
from bokeh.plotting import figure, output_file

DEFAULT_TICKERS = ['AAPL','GOOG','NFLX', 'TSLA']
ticker1 = Select(value='AAPL', options = DEFAULT_TICKERS)
range_slider1 = DateRangeSlider(start=date(2014,1,1) , end=date(2017,1,1), value=(date(2014,2,1),date(2016,3,1)), step=1)

def load_ticker(ticker):
    fname = ( '%s.csv' % ticker.lower())
    data = pd.read_csv( fname, header = None, parse_dates = ['Date'],
                  names =['Date','Open','High','Low','Close','AdjClose','Volume'])
    return data

def get_data(t1):
    data = load_ticker(t1)
    return data

def ticker1_change(attrname, old, new):
    update()

def range_slider_change(attrname, old, new):
    update()

def update(selected=None):
    t1 = ticker1.value
    sd = str(range_slider1.value[0])
    ed = str(range_slider1.value[1])
    start_date = sd
    end_date = ed

    datarange = get_data(t1)
    datarange['Date'] = pd.to_datetime(datarange['Date'])

    mask = (datarange['Date'] > start_date) & (datarange['Date'] <= end_date)
    data = datarange.loc[mask]
    source.data = source.from_df(data)
    p.title.text = t1

data = get_data(ticker1.value)
source = ColumnDataSource(data)

p = figure(plot_width=900, plot_height=400, x_axis_type='datetime')
p.grid.grid_line_alpha = 0.3
p.line('Date', 'Close', source=source)


ticker1.on_change('value', ticker1_change)
range_slider1.on_change('value', range_slider_change)
update()

layout = column(ticker1,range_slider1, p)                                                              
curdoc().add_root(layout)
curdoc().title = "Stock"

1 Ответ

0 голосов
/ 18 сентября 2018

Вы конвертируете start_date и end_date в строки:

sd = str(range_slider1.value[0])
ed = str(range_slider1.value[1])
start_date = sd
end_date = ed

И затем используете их, где требуется TimeStamp:

mask = (datarange['Date'] > start_date) & (datarange['Date'] <= end_date)

Что именносообщение "не удалось преобразовать строку в метку времени" говорит вам.

Вам необходимо преобразовать значения ползунка в реальные TimeStamp объекты.Существует небольшая складка в том, что значение ползунка может быть date или int (Вы можете установить его изначально как дату, но, по крайней мере, для Bokeh 0.13 оно всегда возвращается в виде числовой метки времени, в частности,число миллисекунд с начала эпохи. Вы должны обработать оба случая, вот один из способов:

if isinstance(range_slider1.value[0], (int, float)):
    # pandas expects nanoseconds since epoch
    start_date = pd.Timestamp(float(range_slider1.value[0])*1e6)
    end_date = pd.Timestamp(float(range_slider1.value[1])*1e6)
else:
    start_date = pd.Timestamp(range_slider1.value[0])
    end_date = pd.Timestamp(range_slider1.value[1])

Это противоречивое поведение считается ошибкой, которая должна быть исправлена ​​в будущих выпусках. Для более подробной информации см. здесь.: https://github.com/bokeh/bokeh/issues/8015

...