Bokeh Columnsourcedata查找最小值和最大值

时间:2018-09-21 06:31:58

标签: python max updates bokeh min

我正在尝试在source = columndatasource中查找每个类别的最大值和最小值,在该类别中,我的股票数据通过(开盘,最高价,最低价,收盘价,平仓价,成交量等)组织成列。

我尝试使用

 max(source.data['Close'])
 min(source.data['Close']) 

但是,max(source.data ['Open']的问题在于,当我使用滑块和选择小部件来更新数据时,值不会更新。

有没有一种方法可以找到每次更新数据时都会更新的每一列的最小值和最大值?

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 DataRange1d, LinearAxis, Range1d, ColumnDataSource, PrintfTickFormatter, CDSView, BooleanFilter, NumeralTickFormatter
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

    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])

    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', y_range = Range1d(min(source.data['Close']), max(source.data['Close'])))
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 :(得分:0)

  • 是的。您的问题有点令人困惑

简短的回答:您需要创建另一个包含最大值和最小值的“源”。

长答案: 您的代码无法正常运行。我复制/粘贴了您的代码^^并在本地bokeh服务器上运行了它。没有输出,即您需要先修复代码。

但是,假设您的代码正在运行。到目前为止,每次更改 bokeh滑块或其他窗口小部件值时自动更新最大值或最小值的唯一方法是创建另一个源,例如source2。

source = ColumnDataSource(data_max_min)

然后,将键匹配到相同的值。在您的示例^^中,很可能是字典中的日期(data_max_min)。

例如

pd = read_csv('.../AAPL.csv', header=0, index=None)
aapl_close = pd.DataFrame(aapl_df['close'])
aapl_close.index = aapl_df.date
aapl_close

    close
date    
2018/11/23  172.29
2018/11/26  174.62
2018/11/27  174.24

我假设您想获得要滚动分析的每个时间范围的最大值和最小值(或类似值)。作为示例,我的代码将仅获得每次关闭的最大值(*它将是相同的值)。如果您不明白这一点,建议您再次阅读一些文档。

aapl_max_df = pd.DataFrame()
aapl_max_df['max'] = [max(prices) for prices in aapl_close['close']]
aapl_max_df.index = aapl_close.index

aapl_max_min = {}
dates = aapl_max_min.index
for i in range(aapl_max_min.shape[0]):
    aapl_max_min[aapl_max_min.index.values[i]] = aapl_max_min['max'].values[i]

source2 = ColumnDataSource(data=aapl_max_min[dates[0]])

然后,当您更新滑块时,将需要更新两个源的“日期”。这是代码中还没有的内容。在线上有几个有关如何执行此操作的示例(https://github.com/bokeh/bokeh/tree/master/examples/app/gapminder)。

像这样->

def slider_update(attrname, old, new):
    year = slider.value
    label.text = str(year)
    source.data = data[year]
    source2.data = data[year]