Bokeh bar chart with server

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

Hi Emma,

You are completely correct. Charts and the server do
not currently play well together as the Charts interface
does a lot of work behind the scenes to auto-magically
transform your data so the
chart comes out.

Your b est bet is to use the
plotting in terface
to create your bar chart slightly more manually
so that you can
use server as
you’d expect to.

I believe it is on
our radar to support what
you want to do th ough,
I’m just not sure about
time frames.

Sincerely,

                                                Sa                                                      rah

Bird

  On

5/3/16 3:55 AM, Emma wrote:

···

https://groups.google.com/a/continuum.io/d/msgid/bokeh/3704c46d-c279-4c7d-9f54-9d5f91e53bc8%40continuum.io
https://groups.google.com/a/continuum.io/d/optout

Sarah Bird
Developer, Bokeh

    [
      ![Continuum Analytics](http://docs.continuum.io/_static/img/ContinuumWordmark.png)
    ](http://continuum.io)

Hi Sarah,
Thanks, would a segment plot be the best way to go about this?

Thanks

Emma

···

On Wednesday, 4 May 2016 06:43:29 UTC+10, Sarah Bird wrote:

Hi Emma,

You are completely correct. Charts and the server do
not currently play well together as the Charts interface
does a lot of work behind the scenes to auto-magically
transform your data so the
chart comes out.

Your b est bet is to use the
plotting in terface
to create your bar chart slightly more manually
so that you can
use server as
you’d expect to.

I believe it is on
our radar to support what
you want to do th ough,
I’m just not sure about
time frames.

Sincerely,

                                                Sa                                                      rah

Bird

  On

5/3/16 3:55 AM, Emma wrote:

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

  You received this message because you are subscribed to the Google

Groups “Bokeh Discussion - Public” group.

  To unsubscribe from this group and stop receiving emails from it,

send an email to [email protected].

  To post to this group, send email to [email protected]

  To view this discussion on the web visit [](https://groups.google.com/a/continuum.io/d/msgid/bokeh/3704c46d-c279-4c7d-9f54-9d5f91e53bc8%40continuum.io?utm_medium=email&utm_source=footer)[https://groups.google.com/a/continuum.io/d/msgid/bokeh/3704c46d-c279-4c7d-9f54-9d5f91e53bc8%40continuum.io](https://groups.google.com/a/continuum.io/d/msgid/bokeh/3704c46d-c279-4c7d-9f54-9d5f91e53bc8%40continuum.io).

  For more options, visit [https://groups.google.com/a/continuum.io/d/optout](https://groups.google.com/a/continuum.io/d/optout).


Sarah Bird
Developer, Bokeh

    [
      <img alt="Continuum Analytics" src="https://lh6.googleusercontent.com/proxy/VYgVjggTk1hCXSN9wFkffE3I6kxTvJ51tT4KvDXOuKbs1WyFG66k7kt2-vkDimbyxfWtP-d1paJmstMYhPPnDYSUF4rLPoYM2GM2QFM=w5000-h5000" height="30px" width="150px">
    ](http://continuum.io)

Using "segment" is definitely an option, especially if you don't to have different line/fill properties. But be aware the "width" property of the segment only controls the width in pixels, which means the bar "size" will not change if the users zooms in or out. If you want to specify a bar width that is in data-space units (and so gets bigger or smaller as the zoom level changes) then I would recommend "rect" or "quad".

FYI there is an open issue to add "vbar" and "hbar" glyph primitives which would make drawing bars a little bit easier with a more convenient interface, e.g. vbar would accept (x, width, top, bottom) which is probably the data people already have if they want to draw bars. This could be an appropriate "starter" task for a new contributor, ff you have any interest in developing this feature, please let us know.

Bryan

···

On May 4, 2016, at 5:23 AM, Emma <[email protected]> wrote:

Hi Sarah,
Thanks, would a segment plot be the best way to go about this?

Thanks
Emma

On Wednesday, 4 May 2016 06:43:29 UTC+10, Sarah Bird wrote:
Hi Emma,

You are completely correct. Charts and the server do not currently play well together as the Charts interface does a lot of work behind the scenes to auto-magically transform your data so the chart comes out.

Your best bet is to use the plotting interface to create your bar chart slightly more manually so that you can use server as you'd expect to.

I believe it is on our radar to support what you want to do though, I'm just not sure about time frames.

Sincerely,

Sarah Bird

On 5/3/16 3:55 AM, Emma wrote:

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

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/3704c46d-c279-4c7d-9f54-9d5f91e53bc8%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

--
Sarah Bird
Developer, Bokeh

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/a0603593-b379-4ac5-98bb-df2be6036fd1%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hi Bryan,

yes I wouldn’t mind contributing is there an issue created for this? or how would i go about starting this? Its my first time contributing so I may need a little guidance.

Thanks

Em

···

On Thursday, 5 May 2016 01:56:47 UTC+10, Bryan Van de ven wrote:

Using “segment” is definitely an option, especially if you don’t to have different line/fill properties. But be aware the “width” property of the segment only controls the width in pixels, which means the bar “size” will not change if the users zooms in or out. If you want to specify a bar width that is in data-space units (and so gets bigger or smaller as the zoom level changes) then I would recommend “rect” or “quad”.

FYI there is an open issue to add “vbar” and “hbar” glyph primitives which would make drawing bars a little bit easier with a more convenient interface, e.g. vbar would accept (x, width, top, bottom) which is probably the data people already have if they want to draw bars. This could be an appropriate “starter” task for a new contributor, ff you have any interest in developing this feature, please let us know.

Bryan

On May 4, 2016, at 5:23 AM, Emma [email protected] wrote:

Hi Sarah,
Thanks, would a segment plot be the best way to go about this?

Thanks

Emma

On Wednesday, 4 May 2016 06:43:29 UTC+10, Sarah Bird wrote:

Hi Emma,

You are completely correct. Charts and the server do not currently play well together as the Charts interface does a lot of work behind the scenes to auto-magically transform your data so the chart comes out.

Your best bet is to use the plotting interface to create your bar chart slightly more manually so that you can use server as you’d expect to.

I believe it is on our radar to support what you want to do though, I’m just not sure about time frames.

Sincerely,

Sarah Bird

On 5/3/16 3:55 AM, Emma wrote:

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


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/3704c46d-c279-4c7d-9f54-9d5f91e53bc8%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.


Sarah Bird

Developer, Bokeh


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/a0603593-b379-4ac5-98bb-df2be6036fd1%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.