Skip to content

Instantly share code, notes, and snippets.

@ajoros
Created July 28, 2015 23:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ajoros/e80760c3ede0562cd379 to your computer and use it in GitHub Desktop.
Save ajoros/e80760c3ede0562cd379 to your computer and use it in GitHub Desktop.
import logging
logging.basicConfig(level=logging.DEBUG)
import pandas as pd
from pprint import pprint
from bokeh.plotting import figure
from bokeh.models import Plot, ColumnDataSource
from bokeh.properties import Instance
from bokeh.server.app import bokeh_app
from bokeh.server.utils.plugins import object_page
from bokeh.models.widgets import (
HBox,
VBoxForm,
CheckboxGroup)
from os import listdir
# build up list of stock data in the daily folder
# input_fn = 'cumulative-reported-cases-all.csv'
# fn_list = find_csv_filenames('.')
# fn_list.remove(input_fn)
path_to_dir = 'D:/ajoros/Dropbox/AIC/SEIRD/outputtemp/'
# path_to_dir = 'E:/Dropbox/AIC/SEIRD/output/'
# cache stock data as dict of pandas DataFrames
pd_cache = {}
def get_filenames(path_to_dir, suffix=".csv"):
filenames = listdir(path_to_dir)
fns = [filename for filename in filenames if filename.endswith(suffix)]
return fns
def load_csv_to_dflist(path_to_dir, suffix=".csv"):
fns = get_filenames(path_to_dir, suffix='.csv')
df_list = []
for file_ in fns:
df = pd.read_csv(path_to_dir + file_,
usecols=['Date', 'C', 'D', 'Cases', 'Deaths'],
parse_dates=['Date'])
df_list.append(df)
return df_list
class HackApp(HBox):
"""An example of a browser-based, interactive plot with checkbox controls."""
extra_generated_classes = [["HackApp", "HackApp", "HBox"]]
inputs = Instance(VBoxForm)
toggle = Instance(CheckboxGroup)
source1 = Instance(ColumnDataSource)
source2 = Instance(ColumnDataSource)
source3 = Instance(ColumnDataSource)
plot = Instance(Plot)
@classmethod
def create(cls):
"""One-time creation of app's objects.
This function is called once, and is responsible for
creating all objects (plots, datasources, etc)
"""
obj = cls()
obj.source1 = ColumnDataSource(data=dict(xs=[], ys=[]))
obj.source2 = ColumnDataSource(data=dict(xs=[], ys=[]))
obj.source3 = ColumnDataSource(data=dict(xs=[], ys=[]))
fns = get_filenames(path_to_dir, suffix='.csv')
obj.toggle = CheckboxGroup(labels=fns, active=[0])
print(obj.toggle)
# colors= ['#3498DB', 'F1C40F', '#16A085', '#C0392B']
toolset = "crosshair,pan,reset,resize,save,wheel_zoom"
plot = figure(plot_height=400,
plot_width=800,
tools=toolset,
x_axis_type="datetime"
)
plot.multi_line('xs', 'ys', source=obj.source1,
line_width=3,
line_color=['red','green','blue','purple']
)
plot.multi_line('xs', 'ys', source=obj.source2,
line_width=3,
line_color=['red','green','blue','purple']
)
plot.multi_line('xs', 'ys', source=obj.source3,
line_width=3,
line_color=['red','green','blue','purple']
)
obj.plot = plot
obj.update_data()
obj.inputs = VBoxForm(
children=[
obj.toggle
]
)
obj.children.append(obj.inputs)
obj.children.append(obj.plot)
return obj
def checkbox_handler(self, active):
self.update_data(active)
def setup_events(self):
"""Attaches the on_change event to the value property of the widget.
The callback is set to the input_change method of this app.
"""
super(HackApp, self).setup_events()
if not self.toggle:
return
# pprint(dir(HackApp))
# sourcenames = [source1']
# for w in fns:
# getattr(self, w).on_change('value', self, 'input_change')
#
# logging.debug('setup_events')
# WHEN CHECKBOX CHANGES
self.toggle.on_click(self.checkbox_handler)
def input_change(self, obj, attrname, old, new):
"""Executes whenever the input form changes.
It is responsible for updating the plot, or anything else you want.
Args:
obj : the object that changed
attrname : the attr that changed
old : old value of attr
new : new value of attr
"""
self.update_data()
self.plot.title = self.text.value
def update_data(self, hide=False):
"""Called each time that any watched property changes.
This updates the sin wave data with the most recent values of the
sliders. This is stored as two numpy arrays in a dict into the app's
data source property.
"""
logging.debug('update_data')
df_list = load_csv_to_dflist(path_to_dir, suffix=".csv")
x1 = x2 = x3 = []
y1 = y2 = y3 = []
print(self.toggle.active, "self.toggle")
for p in self.toggle.active:
if p == 0:
DT = df_list[p].Date.tolist()
print('DT IS TYPE: ' + str(type(DT)))
x1 = [DT, DT, DT, DT]
print('x1 IS TYPE: ' + str(type(x1)))
y1 = [df_list[p].C.tolist(),
df_list[p].D.tolist(),
df_list[p].Cases.tolist(),
df_list[p].Deaths.tolist()]
print('y1 IS TYPE: ' + str(type(y1)))
if p == 1:
DT = df_list[p].Date.tolist()
print('DT IS TYPE: ' + str(type(DT)))
x2 = [DT, DT, DT, DT]
print('x2 IS TYPE: ' + str(type(x2)))
y2 = [df_list[p].C.tolist(),
df_list[p].D.tolist(),
df_list[p].Cases.tolist(),
df_list[p].Deaths.tolist()]
print('y2 IS TYPE: ' + str(type(y2)))
if p == 2:
DT = df_list[p].Date.tolist()
print('DT IS TYPE: ' + str(type(DT)))
x3 = [DT, DT, DT, DT]
print('x2 IS TYPE: ' + str(type(x3)))
y3 = [df_list[p].C.tolist(),
df_list[p].D.tolist(),
df_list[p].Cases.tolist(),
df_list[p].Deaths.tolist()]
print('y2 IS TYPE: ' + str(type(y3)))
self.source1.data = dict(xs=x1, ys=y1)
self.source2.data = dict(xs=x2, ys=y2)
self.source3.data = dict(xs=x3, ys=y3)
@bokeh_app.route("/bokeh/Toggle2/")
@object_page("sin")
def make_hack():
app = HackApp.create()
return app
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment