def __init__(self, controller): """Initialize object. First part of two-part initialization. Put initialization code here that's very unlikely to fail. """ self.controller = controller self.state = None self.state_src = None # State maop of the US. self.stateusmap = figure( title="""Electoral college votes by time and geography""", x_axis_location=None, y_axis_location=None, x_axis_type="""linear""", sizing_mode="""stretch_both""") self.stateusmap.xgrid.visible = False self.stateusmap.ygrid.visible = False # The date for charting. self.choosethedatefordisplay = DateSlider( title="""Choose the date for display""", start="""2018-11-13T20:20:39+00:00""", end="""2025-11-13T20:20:39+00:00""", step=24 * 60 * 60 * 1000, value="""2018-11-13T20:20:39+00:00""", sizing_mode="stretch_width") # Layout the widgets row1 = row(children=[ Spacer(width=10), self.choosethedatefordisplay, Spacer(width=10) ], sizing_mode='stretch_width') self.layout = column(children=[ self.stateusmap, row1, Spacer(height=75, sizing_mode='scale_width') ], sizing_mode='stretch_both') self.panel = Panel(child=self.layout, title='Forecast by geography')
disabled_slider = Slider(title="Disabled", value=50, start=0, end=96, step=5, disabled=True) range_slider = RangeSlider(title="Numerical range", value=[30, 70], start=0, end=100, step=0.5) date_slider = DateSlider(title="Date", value=date(2014, 1, 1), start=date(2010, 1, 1), end=date(2020, 1, 1), step=1) date_range_slider = DateRangeSlider(title="Date range", value=(date(2014, 1, 1), date(2018, 12, 31)), start=date(2010, 1, 1), end=date(2020, 1, 1), step=1) only_value_slider = Slider(value=50, start=0, end=96, step=5) no_title_slider = Slider(title=None, value=50, start=0, end=96, step=5)
# Set up data #global: param_choice = data['resolution2'] # source = ColumnDataSource(data=dict(x=data['scene_lat'] , y=data['scene_lon'], c=param_choice )) plot.circle('x', 'y', color='c', source=source, line_width=3, alpha=0.6) # Set up widgets text = TextInput(title="title", value='Daily Resolution') print("You've made it this far, traveller!") year_slider = Slider(title="Year", value=data['year'].min(), start=data['year'].min(), end=data['year'].max(), step=1) month_slider = Slider(title="Month", value=data['yearmonth'].min(), start=data['yearmonth'].min(), end=data['yearmonth'].max(), step=1) day_slider = DateSlider(title="Day", start=data['date'].min(), end=data['date'].max(), value=data['date'].min(), step=1) #date = DateSlider(title="Day", start=data['date'].min(), end=data['date'].max(), value=data['date'].min(), step=1) param_button_group = RadioButtonGroup(labels=["Resolution", "Potential Water", "Cloud Coverage", "Gelbstoff"], active=0) time_button_group = RadioButtonGroup(labels=["Yearly", "Monthly", "Daily"], active=0) # Set up callbacks #global: chosen_slider = year_slider chosen_timeline = data['year'] inputs = widgetbox(chosen_slider, param_button_group, time_button_group) #(text, ) # def update_title(attrname, old, new): plot.title.text = text.value
# Initialize interactive widgets before calling first update ############################# update() date_selector = DateRangeSlider(title="Select Timeframe", end=VARS['global_end'], start=VARS['global_start'], step=1, value=( VARS['time_range'][0], VARS['time_range'][1], )) single_day_selector = DateSlider( title="Select Day", end=VARS['global_end'], start=VARS['global_start'], step=1, value=VARS['selected_day'], ) date_selector.on_change('value', update_time_range) single_day_selector.on_change('value', update_highlighted_day) ################################################################## # Bokeh Plots ################################################################## TOOLS = "pan,wheel_zoom,box_select,lasso_select,reset" ########## # Stage Time Series ##########
radio_button_group = RadioButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=0) text_input = TextInput(placeholder="Enter value ...") completions = ["aaa", "aab", "aac", "baa", "caa"] autocomplete_input = AutocompleteInput(placeholder="Enter value (auto-complete) ...", completions=completions) select = Select(options=["Option 1", "Option 2", "Option 3"]) multi_select = MultiSelect(options=["Option %d" % (i+1) for i in range(16)], size=6) slider = Slider(value=10, start=0, end=100, step=0.5) range_slider = RangeSlider(value=[10, 90], start=0, end=100, step=0.5) date_slider = DateSlider(value=date(2016, 1, 1), start=date(2015, 1, 1), end=date(2017, 12, 31)) date_range_slider = DateRangeSlider(value=(date(2016, 1, 1), date(2016, 12, 31)), start=date(2015, 1, 1), end=date(2017, 12, 31)) spinner = Spinner(value=100) color_picker = ColorPicker(color="red", title="Choose color:") date_picker = DatePicker(value=date(2017, 8, 1)) paragraph = Paragraph(text="some text") div = Div(text="some <b>text</b>") pre_text = PreText(text="some text")
'transform': mapper }, line_color='white', source=source) p.add_layout(color_bar, 'right') return p palette.reverse() plot = make_plot(LinearColorMapper(palette=palette, low=-2, high=15)) # Set up widgets #text=TextInput(title="Title", value='my sine wave') Date = DateSlider(title="Date", start=start_date, end=end_date, value=start_date, step=1) # Set up callbacks # ============================================================================= # def update_title(attrname, old, new): # plot.title.text = text.value # # text.on_change('value', update_title) # ============================================================================= # ============================================================================= # group=gdf.groupby('county') # sample=group.agg({'cofiltered':'mean'}).reset_index(drop=False) # lnd_bor.join(sample.set_index('county'),on='name') #
var closest = stats[dates.indexOf(dates.reduce(function(prev, curr) { return (Math.abs(curr - len) < Math.abs(prev - len) ? curr : prev); }))] plots[0].x_range.end=len; plots[0].y_range.end=closest; plots[0].y_range.start=0; plots[1].x_range.end=len; plots[1].y_range.end=closest; plots[1].y_range.start=1; ''') #changes x range to be (0,slider_value) #changes y range to be (0 or 1, the closest stastics value to slider) slider = DateSlider(start=min(dates), end=max(dates), value=max(dates), step=1, title='Time') slider.js_on_change('value', callback) loopchange = CustomJS(args=dict(slider=slider, endlen=max(dates), minlen=min(dates)), code=''' function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function run() { var len = slider.value; var loopcount=0; while (cb_obj.active){
def bokeh_spacetimepop( frm, geometry, title = '', preamble = '', varNames = None, varNotes = dict(), pw = 700, ph = 700, xZones = dict(), ): import numpy as np import pandas as pd df = pd.DataFrame idx = pd.IndexSlice import geopandas as gpd gdf = gpd.GeoDataFrame from bokeh.models import ColumnDataSource, HoverTool, Legend, LegendItem, CDSView, IndexFilter from bokeh.plotting import figure, show from bokeh.io import output_notebook # frm = frm.reset_index().pivot(index = frm.index.names[0], columns = frm.index.names[1]) frm = frm.copy() frm = frm.sort_index() # geometry = geometry.copy() from bokeh.models import Div title = f'<h1>{title}</h1>' title = Div( text = title, width = pw, ) preamble = Div( text = preamble, width = pw, ) if varNames is None: varNames = frm.columns.sort_values() varMetaName = varNames.name else: varMetaName = 'variable' varNames = list(varNames) seriesNames = frm.index.levels[1].sort_values() seriesMetaName = seriesNames.name seriesNames = list(seriesNames) dates = [str(int(round(i.to_numpy().astype(int) / 1e6))) for i in frm.index.levels[0]] frm.index = frm.index.set_levels(dates, level = 0) defaultVar = varNames[0] defaultDate = dates[-1] pivotFrm = frm.reset_index() \ .pivot(index = frm.index.names[0], columns = frm.index.names[1]) \ .sort_index() defaultVar = varNames[0] defaultDate = dates[-1] for key in varNames: if not key in varNotes: varNotes[key] = '' else: varNotes[key] = f'<i>{varNotes[key]}</i>' varNote = Div( text = varNotes[defaultVar], width = pw - 120, ) lineSources = { key: ColumnDataSource(pivotFrm[key]) for key in pivotFrm.columns.levels[0] } lineSource = ColumnDataSource(pivotFrm[defaultVar]) lineSource.name = defaultVar barSources = dict() for varName in varNames: for index, date in zip(sorted(pivotFrm.index), dates): series = pivotFrm.loc[index, varName] subFrm = df(dict( name = series.index, value = series.values, height = abs(series.values), offset = series.values / 2. )) barSources[varName + '_' + date] = ColumnDataSource(subFrm) barSource = ColumnDataSource(barSources[defaultVar + '_' + defaultDate].data) barSource.name = ', '.join([str(defaultVar), str(defaultDate)]) bounds = geometry.bounds minx = np.min(bounds['minx']) maxx = np.max(bounds['maxx']) miny = np.min(bounds['miny']) maxy = np.max(bounds['maxy']) aspect = (maxx - minx) / (maxy - miny) from shapely.geometry import Polygon import itertools corners = list(itertools.product(geometry.total_bounds[::2], geometry.total_bounds[1::2])) allPoly = Polygon([corners[0], corners[1], corners[3], corners[2]]) allPoly = allPoly.centroid.buffer(np.sqrt(allPoly.area) / 1e6) for name in frm.index.levels[1]: if not name in geometry.index: geometry[name] = allPoly geometry = geometry.simplify(np.sqrt(geometry.area).min() * 10. ** 3.5) geoFrm = frm.reset_index().pivot(index = frm.index.names[1], columns = frm.index.names[0]) geoFrm.columns = geoFrm.columns.map('_'.join).str.strip('_') geoFrm['geometry'] = geometry geoFrm = gdf(geoFrm) from bokeh.models import GeoJSONDataSource geoJSON = geoFrm.reset_index().to_json() geoSource = GeoJSONDataSource(geojson = geoJSON) mins = {n: frm[n].min() for n in varNames} maxs = {n: frm[n].max() for n in varNames} xName = frm.index.names[0] lineFig = figure( x_axis_type = 'datetime', y_range = (mins[defaultVar], maxs[defaultVar]), plot_height = int((ph - 100) * 1. / 3.), plot_width = pw, toolbar_location = 'left', tools = 'save, xpan, box_zoom, reset, xwheel_zoom', active_scroll = 'auto', # title = title, ) barFig = figure( x_range = seriesNames, plot_height = int((ph - 100) * 1. / 2.), plot_width = pw, # title = "Scores on my birthday", toolbar_location = None, tools = "" ) barFig.xgrid.grid_line_color = None barFig.xaxis.major_label_orientation = 'vertical' mapFig = figure( plot_width = pw - 20, plot_height = int(round((pw - 20) / aspect)), toolbar_location = 'right', tools = 'pan, wheel_zoom, reset', background_fill_color = "lightgrey" ) mapFig.xgrid.grid_line_color = None mapFig.ygrid.grid_line_color = None from matplotlib.pyplot import get_cmap from matplotlib.colors import rgb2hex cmap = get_cmap('nipy_spectral') cs = [rgb2hex(cmap(i / len(seriesNames), alpha = 0.5)) for i in range(len(seriesNames))] lines = [] for seriesName, colour in zip(seriesNames, cs): line = lineFig.line( xName, seriesName, source = lineSource, color = colour, alpha = 0.8, muted_color = 'gray', muted_alpha = 0.3, muted = True, line_width = 2, # legend_label = seriesName, ) from bokeh.models import HoverTool lineFig.add_tools(HoverTool( renderers = [ line, ], tooltips = [ (seriesMetaName.capitalize(), seriesName), (xName.capitalize(), f'@{xName}' + '{%Y-%m-%d}'), ('Value', f'@{{{seriesName}}}'), ], formatters = { f'@{xName}': 'datetime', seriesName: 'numeral', }, toggleable = False )) lines.append(line) bars = [] for i, (seriesName, colour) in enumerate(zip(seriesNames, cs)): view = CDSView(source = barSource, filters = [IndexFilter([i,]),]) bar = barFig.rect( source = barSource, view = view, x = 'name', y = 'offset', height = 'height', width = 0.9, color = colour, muted_color = 'gray', muted_alpha = 0.3, muted = True, ) bars.append(bar) from bokeh.palettes import Viridis256 from bokeh.models import LinearColorMapper, ColorBar palette = Viridis256 mapColourMapper = LinearColorMapper( palette = palette, low = frm.loc[idx[defaultDate, :], defaultVar].min(), high = frm.loc[idx[defaultDate, :], defaultVar].max(), ) mapColourBar = ColorBar( color_mapper = mapColourMapper, label_standoff = 8, width = 30, height = int(round(mapFig.plot_height * 0.9)), border_line_color = None, location = (0, 0), orientation = 'vertical', ) mapFig.add_layout(mapColourBar, 'left') patches = [] for i, seriesName in enumerate(seriesNames): view = CDSView(source = geoSource, filters = [IndexFilter([i,]),]) patch = mapFig.patches( 'xs', 'ys', source = geoSource, view = view, fill_color = dict( field = '_'.join([defaultVar, defaultDate]), transform = mapColourMapper, ), line_color = 'grey', line_width = 0.25, fill_alpha = 0., name = '_'.join([defaultVar, defaultDate]) ) patches.append(patch) from bokeh.models import HoverTool mapHover = HoverTool( renderers = patches, tooltips = [ (seriesMetaName.capitalize(), f'@{seriesMetaName}'), ('Value', '@$name'), ] ) mapFig.add_tools(mapHover) from bokeh.models import BoxAnnotation from bokeh.models import Label for name, zone in xZones.items(): convD = lambda x: int(round(pd.Timestamp(x).to_numpy().astype(int) / 1e6)) left, right = [None if val is None else convD(val) for val in zone] zone = BoxAnnotation( left = left, right = right, fill_alpha = 0.1, fill_color = 'gray', ) zoneLabel = Label( text = name + ' (end)' if left is None else name, text_font_size = '8pt', x = right if left is None else left, y = 10, x_units = 'data', y_units = 'screen', angle = -90 if left is None else 90, angle_units = 'deg', x_offset = -10 if left is None else 10, y_offset = 5 * (len(name) + 6) if left is None else 0 ) lineFig.add_layout(zone) lineFig.add_layout(zoneLabel) from bokeh.models import Span span = Span( location = int(defaultDate), dimension = 'height', line_color = 'red', # line_dash = 'dashed', line_width = 1 ) lineFig.add_layout(span) from bokeh.models.widgets import DateSlider slider = DateSlider( title = 'Date', start = int(dates[0]), end = int(dates[-1]), step = int(8.64 * 1e7), # days value = int(defaultDate), width = pw - 60, align = 'end' ) from bokeh.models.widgets import Select select = Select( title = "Choose data:", options = varNames, value = defaultVar, width = 100, ) from bokeh.models import CheckboxGroup checkboxes = CheckboxGroup( labels = seriesNames, active = [], ) checkboxAll = CheckboxGroup( labels = ['All',], active = [], ) from bokeh.models import CustomJS callback = CustomJS( args = dict( y_range = lineFig.y_range, lineSources = lineSources, lineSource = lineSource, barSources = barSources, barSource = barSource, bars = bars, lines = lines, patches = patches, select = select, slider = slider, span = span, checkboxes = checkboxes, varNote = varNote, varNotes = varNotes, geoSource = geoSource, mapColourMapper = mapColourMapper, mins = mins, maxs = maxs, ), code = """ lineSource.data = lineSources[select.value].data lineSource.name = select.value lineSource.change.emit() span.location = slider.value span.change.emit() y_range.setv({'start': mins[select.value], 'end': maxs[select.value]}) varNote.text = varNotes[select.value] varNote.change.emit() const barChoice = select.value + '_' + slider.value barSource.data = barSources[barChoice].data barSource.name = select.value.toString() + ', ' + slider.value.toString() barSource.change.emit() for (let i = 0; i < lines.length; i++){ let checked = checkboxes.active.includes(i) lines[i].muted = !(checked) bars[i].muted = !(checked) var alpha = checked ? 1 : 0; patches[i].glyph.fill_alpha = alpha } const newCol = select.value + '_' + slider.value for (let i = 0; i < lines.length; i++){ patches[i].glyph.fill_color['field'] = newCol patches[i].name = newCol } mapColourMapper.low = mins[select.value] mapColourMapper.high = maxs[select.value] geoSource.change.emit() """, ) allCheckCallback = CustomJS( args = dict( lines = lines, checkboxes = checkboxes, checkboxAll = checkboxAll, callback = callback ), code = """ checkboxes.active.length = 0 if (checkboxAll.active.length > 0) { let arr = [] for (let i = 0; i < lines.length; i++){ arr.push(i) } checkboxes.active.push(...arr) } checkboxes.change.emit() callback.execute() """ ) slider.js_on_change('value', callback) select.js_on_change('value', callback) checkboxes.js_on_change('active', callback) checkboxAll.js_on_change('active', allCheckCallback) from bokeh.layouts import column, row layout = column( title, preamble, row(select, varNote), row(column(lineFig, slider, barFig), column(checkboxes, checkboxAll)), mapFig ) return layout
def make_dateMap(frm, name, title, size = 600, nonVisKeys = {}): minx = np.min(frm.bounds['minx']) maxx = np.max(frm.bounds['maxx']) miny = np.min(frm.bounds['miny']) maxy = np.max(frm.bounds['maxy']) aspect = (maxx - minx) / (maxy - miny) ts = sorted(set([n.split('_')[-1] for n in frm.columns])) ts = [n for n in ts if n.isnumeric()] assert len(ts) ns = sorted(set([n.split('_')[0] for n in frm.columns])) ns = [n for n in ns if not n in [*nonVisKeys, 'geometry']] assert len(ns) defaultCol = '_'.join([ns[0], ts[-1]]) indexName = frm.index.name mins = {n: frm[['_'.join([n, t]) for t in ts]].min().min() for n in ns} maxs = {n: frm[['_'.join([n, t]) for t in ts]].max().max() for n in ns} from bokeh.models import GeoJSONDataSource geoJSON = frm.reset_index().to_json() source = GeoJSONDataSource(geojson = geoJSON) from bokeh.io import output_file outFilename = name + '.html' outPath = os.path.join(dataDir, outFilename) if os.path.isfile(outPath): os.remove(outPath) output_file(outPath) from bokeh.plotting import figure fig = figure( title = title, plot_height = size, plot_width = int(round(size * aspect)) + 50, toolbar_location = 'right', tools = 'pan, zoom_in, zoom_out, wheel_zoom, reset', background_fill_color = "lightgrey" ) fig.xgrid.grid_line_color = None fig.ygrid.grid_line_color = None from bokeh.palettes import Viridis256 from bokeh.models import LinearColorMapper, ColorBar palette = Viridis256 colourMapper = LinearColorMapper( palette = palette, low = mins[ns[0]], high = maxs[ns[0]], ) colourBar = ColorBar( color_mapper = colourMapper, label_standoff = 8, width = 30, height = int(round(fig.plot_height * 0.9)), border_line_color = None, location = (0, 0), orientation = 'vertical', ) fig.add_layout(colourBar, 'left') patches = fig.patches( 'xs', 'ys', source = source, fill_color = dict( field = defaultCol, transform = colourMapper, ), line_color = 'grey', line_width = 0.25, fill_alpha = 1, name = defaultCol ) from bokeh.models.widgets import DateSlider as Slider slider = Slider( title = 'Date', start = int(ts[0]), end = int(ts[-1]), step = int(8.64 * 1e7), # days value = int(ts[-1]), width = fig.plot_width - 70 ) from bokeh.models.widgets import Select select = Select( title = "Dataset", options = ns, value = defaultCol.split('_')[0], width = 60 ) from bokeh.models import CustomJS callback = CustomJS( args = dict( patches = patches, source = source, slider = slider, # key = 'stay', # <--- TESTING select = select, colourMapper = colourMapper, mins = mins, maxs = maxs, ), code = """ const newCol = select.value + '_' + slider.value patches.glyph.fill_color['field'] = newCol patches.name = newCol colourMapper.low = mins[select.value] colourMapper.high = maxs[select.value] source.change.emit() """, ) from bokeh.models import HoverTool tooltips = [ ('Index', '@' + indexName), ('Value', '@$name') ] tooltips.extend([(k.capitalize(), '@' + k) for k in nonVisKeys]) hover = HoverTool( renderers = [patches], tooltips = tooltips ) fig.add_tools(hover) slider.js_on_change('value', callback) select.js_on_change('value', callback) from bokeh.layouts import column, row layout = column(fig, row(select, slider)) from bokeh.io import show show(layout)
return { 'selected': ColumnDataSource(data=selected), 'unselected': ColumnDataSource(unselected) } def update_plot(): src = get_datasets(df) selected_data_source.data.update(src['selected'].data) unselected_data_source.data.update(src['unselected'].data) df0 = pd.read_pickle(join(dirname(__file__), 'data', 'tremors.pkl')) df = df0.sample(frac=0.1) date_slider = DateSlider(start=df['date'].min(), end=df['date'].max(), step=100, value=df['date'].min()) date_slider.on_change('value', lambda attr, old, new: update_plot()) slider_box = widgetbox(children=[date_slider], width=600) datasets_init = get_datasets(df) # get bokeh ColumnDataSource selected_data_source = datasets_init['selected'] unselected_data_source = datasets_init['unselected'] p = make_plot(selected_data_source, unselected_data_source) layout = layout(children=[[p], [slider_box]], sizing_mode='fixed') curdoc().add_root(layout)
# Define the callback function: update_plot def update_plot(attr, old, new): day = datetime.utcfromtimestamp(date_slider.value // 1000.0) #date_slider.value #slider.value #geosource = GeoJSONDataSource(geojson = json_data(day)) new_data = json_data(day) geosource.geojson = new_data p.title.text = 'CovIndex, {:%d %b %Y}'.format(day) #'CovIndex, %d' %day date_slider = DateSlider( title="Date Range: ", start=date(2020, 3, 25), end=date(2020, 5, 14), value=date(2020, 3, 25), step=86400000 ) # https://discourse.bokeh.org/t/bokeh-dateslider-still-broken/2466 date_slider.on_change('value', update_plot) # Make a column layout of widgetbox(slider) and plot, and add it to the current document layout = column(p, column(date_slider)) curdoc().add_root(layout) #Display plot inline in Jupyter notebook output_notebook() #Display plot show(layout)
def scatter(df): #global df1 def make_dataset(df): return ColumnDataSource(df) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p def make_plot(src): # Blank plot with correct labels p = figure(plot_width = 1000, plot_height = 600, title = 'Confirmed Cases vs Recovered Cases (Size of glyph = Confirmed Death)', x_axis_label = 'Confirmed Cases', y_axis_label = 'Recovered Cases') p.circle('confirmed_cases', 'recovered_cases', source=src, fill_alpha=0.7, size='death1', hover_fill_color = 'purple', hover_fill_alpha = 0.7, color='color', legend_field = 'continent') hover = HoverTool(tooltips=[('As at', '@Date{%F}'), ('Country', '@Country'), ('Confirmed', '@confirm'), ('Recovered', '@recovered'), ('Death', '@death')], formatters={'@Date': 'datetime'}) p.add_tools(hover) p.legend.location = "center_right" p.legend.click_policy = 'hide' # Styling p = style(p) return p # Callback function def update(attr, old, new): continent_to_plot = [continent_selection.labels[i] for i in continent_selection.active] df1 = df.set_index(['continent']) df1 = df1.loc[continent_to_plot] a = day_slider.value_as_date date = pd.to_datetime(a) d = df1[df1['Date'] == date] new_src = make_dataset(d) src.data.update(new_src.data) def animate_update(): day = day_slider.value_as_date + timedelta(days=1) if day>df['Date'].max(): day = df['Date'].min() day_slider.value = day def animate(): global callback_id if button.label == '► Play': button.label = '❚❚ Pause' callback_id = curdoc().add_periodic_callback(animate_update, 200) else: button.label = '► Play' curdoc().remove_periodic_callback(callback_id) callback_id = None button = Button(label='► Play', width=60) button.on_click(animate) value = list(df['continent'].unique()) continent_selection = CheckboxGroup(labels=value, active = [0, 1]) continent_selection.on_change('active', update) day_slider = DateSlider(title="Date: ", start=df['Date'].min(), end=df['Date'].max(), value=df['Date'].max(), step=1) day_slider.on_change('value', update) controls = row(continent_selection, day_slider, button) initial = [continent_selection.labels[i] for i in continent_selection.active] df1 = df.set_index(['continent']) df1 = df1.loc[initial] dat = df1['Date'].max() d = df1[df1['Date'] == dat] src = make_dataset(d) p = make_plot(src) layout = column([controls, p]) tab = Panel(child = layout, title = 'Progression') return tab
def third_tab_create(filterData): #def arima(date = dummy_date, house = dummy_house , data = dummy_data,trainDays = dummy_trainDays): def arima(date, state, data, trainDays): houseData = filterData.groupby( filterData[filterData['state'] == state]['time']).sum() houseData['time'] = houseData.index #houseData['time'] = pd.to_datetime(houseData['time']) #houseData = houseData[['car1','grid','solar','time','load']] houseData = houseData[['time', data]] #houseData = filterData[filterData['dataid'] == house][['time',data]] #houseData = houseData.sort_values('time', ascending = True) houseData = houseData.sort_index() #houseData.index = houseData['time'] startDate = pd.to_datetime(date) + pd.DateOffset(days=-trainDays) endDate = pd.to_datetime(date) + pd.DateOffset(days=1) daterange = [startDate, endDate] houseData = houseData.loc[daterange[0]:daterange[1], :] houseData[data] = houseData[data] * 60 * 15 / 3600 # kWh #houseData[data] = ( houseData[data] > .01 ) * houseData[data] weekdays = houseData[houseData.index.dayofweek < 5] weekends = houseData[houseData.index.dayofweek > 4] weekdayProfile = weekdays.groupby(weekdays['time'].dt.time).mean() weekendProfile = weekends.groupby(weekends['time'].dt.time).mean() houseData['detrend'] = houseData[data] for i in range(0, len(houseData)): if houseData['time'][i].dayofweek > 4: houseData['detrend'][i] = houseData['detrend'][ i] - weekendProfile[weekendProfile.index == houseData['time'].dt.time[i]][data] else: houseData['detrend'][i] = houseData['detrend'][ i] - weekdayProfile[weekdayProfile.index == houseData['time'].dt.time[i]][data] trainData = houseData['detrend'] stepwise_model = auto_arima(trainData, start_p=1, start_q=1, max_p=3, max_q=3, m=7, start_P=0, seasonal=True, d=1, D=1, trace=True, error_action='ignore', suppress_warnings=True, stepwise=True) train = houseData[data].loc[startDate:date] test = pd.DataFrame(data=houseData.loc[date:endDate]) test = test.drop(columns='detrend') future_forecast = stepwise_model.predict(n_periods=len(test)) test['arima'] = future_forecast if pd.to_datetime(date).dayofweek > 4: aveProfile = weekendProfile else: aveProfile = weekdayProfile for i in range(0, len(test)): test['arima'][i] = test['arima'][i] + aveProfile[ aveProfile.index == test['time'].dt.time[i]][data] test['error'] = abs(test[data] - test['arima']) #test['error'] = ( test['error'] > .03 ) * test['error'] test = test.rename(columns={data: 'data'}) test = test.drop(columns='time') #mape = 100 * sum( abs( test['error'] / test['data'] ) ) / len (test) mape = 100 * sum(abs(test['error'] / test['data'].max())) / len(test) print(stepwise_model.summary()) return ColumnDataSource(test), mape def plot1_plot(src, mape): plot1 = figure( title='PV Generation + Battery(Discharge) forecasting of NY', x_axis_label='Time', y_axis_label='Generation [kWh]', x_axis_type="datetime") a = plot1.line('time', 'data', source=src, color='blue') b = plot1.line('time', 'arima', source=src, color='green') c = plot1.line('time', 'error', source=src, color='red') plot1.plot_width = 1300 legend = Legend(items=[ LegendItem(label="Raw Data", renderers=[a], index=0), LegendItem(label="Forecast", renderers=[b], index=1), LegendItem(label="Error", renderers=[c], index=2), ]) plot1.add_layout(legend) plot1.legend.title = f'Abs Error = {round(mape1,3)}%' return plot1 def update(attr, old, new): button.update(button_type='warning', label='Loading, please wait') def calculate(): global home_to_plot, state_dict data_selector = data_type_selector.labels[ data_type_selector.active] if data_selector == 'Net Load': data_to_plot = 'grid' plot1.yaxis.axis_label = 'Net Load [kWh]' if data_selector == 'Load + Battery(Charging)': data_to_plot = 'Load_+_Battery(Charging)' plot1.yaxis.axis_label = 'Load [kWh]' if data_selector == "Electric Vehicle Consumption": data_to_plot = 'car1' plot1.yaxis.axis_label = 'Consumption [kWh]' if data_selector == "PV Generation + Battery(Discharge)": data_to_plot = 'PV_+_Battery(Discharge)' plot1.yaxis.axis_label = 'Generation [kWh]' trainDays_to_plot = int(trainDays_input.value) new_home_to_plot = state_dict[community_selector.active] #new_home_to_plot = int(home_id_selector.value) ### plot1.title.text = f'{data_selector} forecasting of {new_home_to_plot} for date {date_slider.value}' if new_home_to_plot != home_to_plot: startDate = filterData[ filterData['state'] == new_home_to_plot]['time'].iloc[0].date() ##change endDate = filterData[filterData['state'] == new_home_to_plot]['time'].iloc[-1].date() middle = startDate + (endDate - startDate) / 1.5 date_slider.start = startDate date_slider.end = endDate date_slider.value = middle date_to_plot = str(middle) print(startDate, endDate, middle) #daterange_raw = list(date_slider.value_as_datetime) #daterange_to_plot = [daterange_raw[0].strftime("%Y-%m-%d"), daterange_raw[1].strftime("%Y-%m-%d")] date_to_plot = date_slider.value new_src1, new_mape1 = arima(date=date_to_plot, state=new_home_to_plot, data=data_to_plot, trainDays=trainDays_to_plot) src1.data.update(new_src1.data) plot1.legend.title = f'Abs Error = {round(new_mape1,3)}%' button.update(button_type='success', label='Done') home_to_plot = new_home_to_plot curdoc().add_next_tick_callback(calculate) ## Initialize src and plot src1, mape1 = arima(date='2019-07-20', state='NY', data='PV_+_Battery(Discharge)', trainDays=2) plot1 = plot1_plot(src1, mape1) ## Date Slider date_slider = DateSlider(title="Date: ", start=date(2019, 5, 1), end=date(2019, 8, 20), value=date(2019, 7, 20), step=1, callback_policy='mouseup', width=1300) date_slider.on_change("value_throttled", update) ## Text input trainDays_input = TextInput(value='2', title='Training Days', max_width=200, max_height=50) trainDays_input.on_change('value', update) ## Data Options data_type_selector = RadioGroup(labels=[ "PV Generation + Battery(Discharge)", "Load + Battery(Charging)", "Net Load", "Electric Vehicle Consumption" ], active=0) data_type_selector.on_change('active', update) ## Loading Status button = Button(label="Done", button_type="success") ## Home Selector #home_ids_available = np.unique(filterData['dataid']) #home_ids_available = list(map(str, home_ids_available)) #home_id_selector = Dropdown(label="Home ID", button_type="warning", menu=home_ids_available, value="5679", max_width = 200) #home_id_selector.on_change('value',update) ## Agg house selection community_selector = RadioGroup(labels=list(np.unique( filterData['state'])), active=6, max_width=200) community_selector.on_change('active', update) row1 = row( plot1, column(data_type_selector, trainDays_input, community_selector, button, sizing_mode="scale_width")) row2 = row(date_slider) ## Layout layout = column(row1, row2) tab = Panel(child=layout, title='Forecasting') return tab
class ForecastByGeography(): """Shows US map and electoral college votes by state.""" # %% def __init__(self, controller): """Initialize object. First part of two-part initialization. Put initialization code here that's very unlikely to fail. """ self.controller = controller self.state = None self.state_src = None # State maop of the US. self.stateusmap = figure( title="""Electoral college votes by time and geography""", x_axis_location=None, y_axis_location=None, x_axis_type="""linear""", sizing_mode="""stretch_both""") self.stateusmap.xgrid.visible = False self.stateusmap.ygrid.visible = False # The date for charting. self.choosethedatefordisplay = DateSlider( title="""Choose the date for display""", start="""2018-11-13T20:20:39+00:00""", end="""2025-11-13T20:20:39+00:00""", step=24 * 60 * 60 * 1000, value="""2018-11-13T20:20:39+00:00""", sizing_mode="stretch_width") # Layout the widgets row1 = row(children=[ Spacer(width=10), self.choosethedatefordisplay, Spacer(width=10) ], sizing_mode='stretch_width') self.layout = column(children=[ self.stateusmap, row1, Spacer(height=75, sizing_mode='scale_width') ], sizing_mode='stretch_both') self.panel = Panel(child=self.layout, title='Forecast by geography') # %% def setup(self): """Set up object. Second part of two-part initialization. Place initialization code here that's more likely to fail. """ # Load the files containing the state outlines and the Alaska/Hawaii # dividing lines _folder = os.path.dirname(os.path.realpath(__file__)) _state_j = json.load( open(os.path.join(_folder, MAP_FOLDER, "state.json"), 'r')) _state = pd.DataFrame(_state_j['data']) _state = _state.sort_values('State abbreviation') _state['color'] = random.choices(brewer['RdBu'][11], k=_state.shape[0]) _state['Democratic percentage'] = np.random.rand(_state.shape[0]) _state['Republican percentage'] = np.random.rand(_state.shape[0]) _frame_j = json.load( open(os.path.join(_folder, MAP_FOLDER, "frame.json"), 'r')) # Set up the sources self.state_src = ColumnDataSource(_state) frame_src = ColumnDataSource( data=dict(x=_frame_j['data']['x'], y=_frame_j['data']['y'])) # Draw the states and the lines states = self.stateusmap.patches(xs='x', ys='y', source=self.state_src, fill_alpha=0.5, fill_color='color', line_color="gray", line_width=0.5) # The frame that separates AK, HI from the rest of the US self.stateusmap.multi_line(xs='x', ys='y', source=frame_src, line_color="gray", line_width=1.0) # Now set up the hover tool - so the state name is given hover = HoverTool(point_policy="follow_mouse", renderers=[states], tooltips=[ ("State name", "@{State name}"), ("State abbreviation", "@{State abbreviation}"), ("Democratic", "@{Democratic percentage}{%0.1f}"), ("Republican", "@{Republican percentage}{%0.1f}") ]) self.stateusmap.add_tools(hover) # Setup the callbacks. self.choosethedatefordisplay.on_change( "value", self.callback_choosethedatefordisplay) # %% def update(self, state): """Update view object.""" # Make a copy of the state data and change the copy self.state = state.copy() self.state['color index'] = self.state['Spread D-R'] * 100 self.state['color index'] = pd.cut( self.state['color index'], [-100, -10, -5, -2, -1, -0.5, 0.5, 1, 2, 5, 10, 100], labels=[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]) self.state['color'] =\ self.state['color index'].map( {k: v for k, v in enumerate(brewer['RdBu'][11])}) self.choosethedatefordisplay.start = self.state['Date'].min() self.choosethedatefordisplay.value = self.state['Date'].max() self.choosethedatefordisplay.end = self.state['Date'].max() self._update_chart(self.choosethedatefordisplay.value_as_datetime) # %% def _update_chart(self, date): """Update chart based on date.""" _slice = self.state[self.state['Date'] == date] self.state_src.data['color'] = \ _slice[['State abbreviation', 'color']].sort_values( 'State abbreviation')['color'].to_list() self.state_src.data['Democratic percentage'] = \ _slice[['State abbreviation', 'Democratic proportion']].sort_values( 'State abbreviation')[ 'Democratic proportion'].to_list() self.state_src.data['Republican percentage'] = \ _slice[['State abbreviation', 'Republican proportion']].sort_values( 'State abbreviation')[ 'Republican proportion'].to_list() # %% def callback_choosethedatefordisplay(self, attrname, old, new): """Execute callback method for self.choosethedatefordisplay.""" # pylint: disable=W0613 self._update_chart(self.choosethedatefordisplay.value_as_datetime)