DateRangeSlider Bokeh Widget Error,无法将字符串转换为timestampdate

问题描述 投票:0回答:1

我正在尝试将DateRangeSlider Widget实现到我的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"
python date timestamp widget bokeh
1个回答
1
投票

您正在将start_dateend_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对象。有一个轻微的皱纹,滑块值可以是dateint(您可能最初将其设置为日期,但至少从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

© www.soinside.com 2019 - 2024. All rights reserved.