У меня есть программа, которая отображает информацию о фондовом рынке для Google. Я могу настроить его с помощью DateRangeSlider, чтобы увеличить даты, на которые мы смотрим. У меня также есть набор инструментов наведения на диаграмме для отображения различных аспектов данных за каждый соответствующий день.
Проблема, с которой я столкнулся, связана с обратным вызовом. Вместо того, чтобы обновлять данные при наведении при каждом вызове, он сохраняет память о предыдущих вызовах и просто складывает предыдущую информацию о наведении поверх новой.
Вот мой код для работы в Jupyter:
from pandas_datareader import data
from pandas import Timedelta
from datetime import datetime, date
from bokeh.plotting import figure, show
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, HoverTool, NumeralTickFormatter, DatetimeTickFormatter, TextInput, DateRangeSlider
from bokeh.io import output_notebook, curdoc
output_notebook()
def inc_dec(c, o):
"""Determines if the financial day with and Increase or Decrease"""
if c > o:
return "Increase"
elif c == 0:
return "Equal"
else:
return "Decrease"
def get_sources(start = date(2016, 3, 1), end = date(2016, 3, 10), company = "GOOG"):
"""Gets all my dataframes for each glyph below"""
#Gather data for df's
df = data.DataReader(company, data_source="yahoo", start=start, end=end)
df["Status"] = [inc_dec(c, o) for c, o in zip(df.Close, df.Open)]
df["Mid"] = (df.Open + df.Close) / 2
df["Height"] = abs(df.Open - df.Close)
df["Width"] = 12*60*60*1000
df["Segment, Left"] = df.index - Timedelta(hours=2)
df["Segment, Right"] = df.index + Timedelta(hours=2)
#my df is complete. Split them
inc_df = df[df.Status == "Increase"]
dec_df = df[df.Status == "Decrease"]
#inc_s = ColumnDataSource(inc_df)
#dec_s = ColumnDataSource(dec_df)
#tot_s = ColumnDataSource(df)
#Dictionary of dataframes, Increasing, Decreasing, and Total
dfs = {"I": inc_df, "D": dec_df, "T": df}
return dfs
def fin(doc):
"""Initialize the graphs and make an application"""
#Get df's and convert to CDS
dfs = get_sources()
inc_s = ColumnDataSource(dfs["I"])
dec_s = ColumnDataSource(dfs["D"])
tot_s = ColumnDataSource(dfs["T"])
hover = HoverTool(names=["inc","dec"],
tooltips = [("Date", "@Date{%m/%d/%Y}"),
("High", "@High{$0.00}"),
("Low","@Low{$0.00}"),
("Open","@Open{$0.00}"),
("Close","@Close{$0.00}"),
("Volume", "@Volume{0,0}")],
formatters = {"@Date" : "datetime"})
#Formatting the plot, p
p = figure(x_axis_type="datetime", width=1000, height=300, sizing_mode="scale_width", tools="crosshair,pan,wheel_zoom,box_zoom,reset")
#p.title.text = "{}: Finacial Data".format(company) #Change this with company later
p.title.text = "GOOG: Financial Data"
p.title.align = "center"
p.xaxis.axis_label="Date"
p.yaxis.axis_label="Price"
p.yaxis.formatter = NumeralTickFormatter(format="$0,0.00")
p.grid.grid_line_alpha = 0.3
#Add glyphs
p.segment(x0='Date', y0='High', x1='Date', y1='Low', source=tot_s) #vertical
p.segment(x0='Segment, Left', y0='High', x1='Segment, Right', y1='High', source=tot_s) #high
p.segment(x0='Segment, Left', y0='Low', x1='Segment, Right', y1='Low', source=tot_s) #low
p.rect(x="Date", y="Mid", width="Width", height="Height", name="inc",
fill_color="#00FFFF", line_color="black", source=inc_s)
p.rect(x="Date", y="Mid", width="Width", height="Height", name="dec",
fill_color="#B22222", line_color="black", source=dec_s)
p.add_tools(hover)
#the callbacks
def cb_date(attr, new, old):
"""Callback for the DateRangeSlider"""
if not isinstance(new[0], int):
return None
else:
#Get new dates, pass them to get_sources to get df's, add new CDS's
start = date.fromtimestamp(new[0]/1000)
end = date.fromtimestamp(new[1]/1000)
dfs = get_sources(start=start, end=end)
inc_s.stream(dfs["I"])
dec_s.stream(dfs["D"])
tot_s.stream(dfs["T"])
#def cb_com(attr, new, old):
#Changes the company name, do later
#add widgets
slider = DateRangeSlider(start=date(2016, 1, 1),
end=date(2016, 5, 1),
value=(date(2016, 3, 1), date(2016, 3, 10)),
step=1,
title="Change Dates:")
slider.on_change('value', cb_date)
doc.add_root(column(slider,p))
show(fin)
Дайте мне знать, как я могу go передать это. Я очень потерян.