Hi all,
I’m trying to write an app plotting a bar chart with a streamed dataset. Ideally what I would like is to have an api similar to for example a line plot where the dataset is updated by updating the ColumnDataSource. But it seems to me that can’t be done and a new Bar Chart needs to be created each time the data is updated, is that the case? If so what is the best way to avoid getting in the way of users, for example if a user zooms into a plot then on the next update this is lost. Below is an example of what I’ve tried so far.
import pandas as pd
from pandas.util.testing import assert_frame_equal
from bokeh.client import push_session
from bokeh.charts import Line, Bar
from bokeh.charts.operations import blend
from bokeh.models import Paragraph
from bokeh.io import curdoc, hplot, vplot
pd.DataFrame(
{
'Italy':[3016.17,3114.73, 3128.31, 3137.38, 3089.51, 3016.32, 2942.62, 2735.05, 2813.51],
'Japan':[4004.67, 3963.47, 4089.39, 4073.75, 4068.52, 4031.99, 3880.45, 3700.22, 3883.046557],
'Brazil':[1084.48, 1075.76, 1092.31, 1096.13, 1140.61, 1158.39, 1186.27, 1240.22, 1297.91],
'USA':[8056.55, 7825.18, 7838.52, 7788.32, 7875.28, 7840.53, 7691.69, 7749.23, 7481.02],
'year':[2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008],
}).to_csv(“test.csv”)
energy_per_capita = pd.read_csv(“test.csv”) #pd.DataFrame(data[1:], columns=data[0])
countries = [‘Brazil’, ‘Italy’, ‘USA’, ‘Japan’]
def create_bar(data):
op = blend(*countries, labels_name='countries', name='energy')
return Bar(data, label='year', values=op, color='countries', group='countries',
width=1400, height=600, responsive = False, ylabel='Energy use per capita',
palette=['purple', 'green', 'blue', 'pink'],
legend=True)
def data_changed(old):
""" Returns a new dataframe if data has changed on the excel workbook """
# data = xw.Range('A1').table.value
df = pd.read_csv("test.csv")
try:
assert_frame_equal(df, old)
return None
except AssertionError:
return df
open a session to keep our local document in sync with server
def update():
global layout
global energy_per_capita
new_df = data_changed(energy_per_capita)
if new_df is not None:
energy_per_capita = new_df
# plots_box.children[0] = create_line(energy_per_capita)
plots_box.children[0] = create_bar(energy_per_capita)
bar = create_bar(energy_per_capita)
plots_box = hplot(bar)
layout = vplot(plots_box)
curdoc().add_root(layout)
curdoc().add_periodic_callback(update, 500)
``
Thanks
Em