Bokeh CheckboxButtonGroup - My plot do not update

Hi,

I am no very good in python and I need some help with the code attached.

I am trying to use a CheckboxButtonGroup to swicth between data based on a column value. Can some one have a look in the code and correct it.

Thanks a lot.

Bokeh_CheckboxButtonGroup.py (4.39 KB)

You need to make a
source and then set new data on it in your
update (as opposed to making new sources).

See here for an example:

                Notice that in the last example even though a

new da tasource is
created it is the o riginal source that is
updated with new data.

                        I think of

it like this:
I have one chance to set -up all my objects.
Once I have,
any chan ges
I make will
aut o-magically
update my plot. But if I make
new objects, bokeh
doesn’t know to push
them down ( without
more work).

Best,

Bird

···

https://github.com/bokeh/bokeh/blob/master/examples/app/movies/main.py#L88
https://github.com/bokeh/bokeh-demos/blob/master/weather/main.py#L60
On 5/15/16 2:40 PM, wrote:

[email protected]

Hi,

      I am no very good in python and I need some help with the

code attached.

      I am trying to use a CheckboxButtonGroup to swicth between

data based on a column value. Can some one have a look in the
code and correct it.

Thanks a lot.

  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/6d46f5a3-6646-4e28-86ba-8d4321ad1653%40continuum.io?utm_medium=email&utm_source=footer)      .

For more options, visit .


Sarah Bird
Developer, Bokeh

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

https://groups.google.com/a/continuum.io/d/msgid/bokeh/6d46f5a3-6646-4e28-86ba-8d4321ad1653%40continuum.io
https://groups.google.com/a/continuum.io/d/optout

Hi Sarah,

Thanks for the aswer.

I add the following code but still not worlking, any ideas why?

– Set up callbacks –
def select_cast(active):

    cast = cast_button_group.active

    if (cast == 1) is True:

        source = df1.loc[df1['Flag'] == "Downcast"]

    if (cast == 2) is True:

        source = df1.loc[df1['Flag'] == "Upcast"]

    if (cast == 0) is True:

        source = df1

    return source

def update_data(attrname, old, new):

    df = select_cast()

    source.data = dict(

            Pressure=df["Pressure"],

            Depth=df["Depth"],

            Temperature=df["Temperature"],

            Salinity=df["Salinity"],

            Conductivity=df["Conductivity"],

            Density=df["Density"],

            DescentRate=df["Descent Rate"],

            SoundVelocity=df["Sound Velocity"],

            Oxygenraw=df["Oxygen raw"],

            Oxygenmgl=df["Oxygen [mg/l]"],

            Oxygenpercent=df["Oxygen [%]"],

            Flag=df["Flag"]

            )

controls = [cast_button_group]

for control in controls:

    control.on_click(update_data)

Without error messages, and a small fully-runnable example (that
would include sample data) it’s very hard to know what’s going on,
but my guess is:

source = df1.loc[df1[‘Flag’] == “Upcast”]

You’re setting source to something from a pandas data frame.

  get the result of df1.loc[df1['Flag'] == "Upcast"], turn it into

a python dictionary called new_data and then do

source.data = new_data

···

On 5/15/16 7:49 PM, wrote:

[email protected]

Hi Sarah,

Thanks for the aswer.

      I add the following code but still not worlking, any ideas

why?

– Set up callbacks –
          def

select_cast(active):

           cast = cast_button_group.active
           if (cast == 1) is True:
               source = df1.loc[df1['Flag'] == "Downcast"]
           if (cast == 2) is True:
               source = df1.loc[df1['Flag'] == "Upcast"]
           if (cast == 0) is True:
               source = df1
           return source
          def

update_data(attrname, old, new):

           df = select_cast()
           source.data = dict(
                   Pressure=df["Pressure"],
                   Depth=df["Depth"],
                   Temperature=df["Temperature"],
                   Salinity=df["Salinity"],
                   Conductivity=df["Conductivity"],
                   Density=df["Density"],
                   DescentRate=df["Descent Rate"],
                   SoundVelocity=df["Sound Velocity"],
                   Oxygenraw=df["Oxygen raw"],
                   Oxygenmgl=df["Oxygen [mg/l]"],
                   Oxygenpercent=df["Oxygen [%]"],
                   Flag=df["Flag"]
                   )
          controls

= [cast_button_group]

          for

control in controls:

           control.on_click(update_data)

  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/766487ec-5adc-4510-b9f8-5d8e35e17a96%40continuum.io?utm_medium=email&utm_source=footer)      .

For more options, visit .


Sarah Bird
Developer, Bokeh

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

https://groups.google.com/a/continuum.io/d/msgid/bokeh/766487ec-5adc-4510-b9f8-5d8e35e17a96%40continuum.io
https://groups.google.com/a/continuum.io/d/optout

Hi Sarah,

Sorry I was not thinking correctly yesterday. I try to add the result in a python dictionary, but without success (Beginning in python programming).

The error message is <bokeh.models.sources.ColumnDataSource at 0x7f015705c8d0>

Please find attached the code and data example.

Thanks,

Bokeh_CheckboxButtonGroup.py (6.01 KB)

Example.xlsx (67.8 KB)

At a glance, this line is definitely wrong:

  source = new_data

You need to assign to the .data attribute of the existing source, not overwrite it:

  source.data = new_data

But Sarah's suggestion is that new_data itself needs to be a python dictionary. Right now is is a pandas dataframe, and that is also probably a problem. You need to try converting the result of

  df1.loc[df1['Flag'] == "Upcast"]

which is a date frame, to be a python dict.

Bryan

···

On May 16, 2016, at 10:04 AM, [email protected] wrote:

Hi Sarah,

Sorry I was not thinking correctly yesterday. I try to add the result in a python dictionary, but without success (Beginning in python programming).
The error message is <bokeh.models.sources.ColumnDataSource at 0x7f015705c8d0>

Please find attached the code and data example.

Thanks,

--
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/3d849689-5110-4932-9d2e-6e3b27803563%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.
<Bokeh_CheckboxButtonGroup.py><Example.xlsx>

Hi Bryan,

I convert the pandas dataframe to a python dictionary with the code .to_dict() , but with no success. The new_data is a dict now but my source give me the same problem <bokeh.models.sources.ColumnDataSource at 0x7f015705c8d0>.

My code

def select_cast():
new_data =
if (cast_button_group.active == 1) is True:
new_data = df1.loc[df1[‘Flag’] == “Downcast”].to_dict()
if (cast_button_group.active == 2) is True:
new_data = df1.loc[df1[‘Flag’] == “Upcast”].to_dict()
if (cast_button_group.active == 0) is True:
new_data = df1.to_dict()
return new_data

def update_data(attrname, old, new):
df = select_cast()
data = dict(
Pressure=df[“Pressure”],
Depth=df[“Depth”],
Temperature=df[“Temperature”],
Salinity=df[“Salinity”],
Conductivity=df[“Conductivity”],
Density=df[“Density”],
DescentRate=df[“Descent Rate”],
SoundVelocity=df[“Sound Velocity”],
Oxygenraw=df[“Oxygen raw”],
Oxygenmgl=df[“Oxygen [mg/l]”],
Oxygenpercent=df[“Oxygen [%]”],
Flag=df[“Flag”]
)
source.data = new_data

controls = [cast_button_group]
for control in controls:
control.on_click(update_data)

``

Thanks,

Maria

Maria,

That's not an error, that's the "repr" or printed representation of a python object that would show up in a python interpreter. How are you trying to run this code? Bokeh server applications have to be run by the bokeh server itself, not the normal python interpreter. So, if your code is in a file "myapp.py", you'd need to run something like:

  bokeh serve --show myapp.py

at your Bash or DOS command prompt.

Bryan

···

On May 16, 2016, at 10:40 AM, [email protected] wrote:

Hi Bryan,

I convert the pandas dataframe to a python dictionary with the code .to_dict() , but with no success. The new_data is a dict now but my source give me the same problem <bokeh.models.sources.ColumnDataSource at 0x7f015705c8d0>.

My code
def select_cast():
    new_data =
    if (cast_button_group.active == 1) is True:
        new_data = df1.loc[df1['Flag'] == "Downcast"].to_dict()
    if (cast_button_group.active == 2) is True:
        new_data = df1.loc[df1['Flag'] == "Upcast"].to_dict()
    if (cast_button_group.active == 0) is True:
        new_data = df1.to_dict()
    return new_data

def update_data(attrname, old, new):
    df = select_cast()
    data = dict(
            Pressure=df["Pressure"],
            Depth=df["Depth"],
            Temperature=df["Temperature"],
            Salinity=df["Salinity"],
            Conductivity=df["Conductivity"],
            Density=df["Density"],
            DescentRate=df["Descent Rate"],
            SoundVelocity=df["Sound Velocity"],
            Oxygenraw=df["Oxygen raw"],
            Oxygenmgl=df["Oxygen [mg/l]"],
            Oxygenpercent=df["Oxygen [%]"],
            Flag=df["Flag"]
            )
    source.data = new_data
    
controls = [cast_button_group]
for control in controls:
    control.on_click(update_data)

Thanks,

Maria

--
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/ed7af893-d7a9-4af5-a3a0-c6cb6a0cb76b%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hi Bryan,

I am running in a Jupyter notebook. The html generate by the code is empty (no data) maybe a problem with the if section?

···

Em segunda-feira, 16 de maio de 2016 12:43:26 UTC-3, Bryan Van de ven escreveu:

Maria,

That’s not an error, that’s the “repr” or printed representation of a python object that would show up in a python interpreter. How are you trying to run this code? Bokeh server applications have to be run by the bokeh server itself, not the normal python interpreter. So, if your code is in a file “myapp.py”, you’d need to run something like:

    bokeh serve --show myapp.py

at your Bash or DOS command prompt.

Bryan

On May 16, 2016, at 10:40 AM, [email protected] wrote:

Hi Bryan,

I convert the pandas dataframe to a python dictionary with the code .to_dict() , but with no success. The new_data is a dict now but my source give me the same problem <bokeh.models.sources.ColumnDataSource at 0x7f015705c8d0>.

My code

def select_cast():

new_data = []
if (cast_button_group.active == 1) is True:
    new_data = df1.loc[df1['Flag'] == "Downcast"].to_dict()
if (cast_button_group.active == 2) is True:
    new_data = df1.loc[df1['Flag'] == "Upcast"].to_dict()
if (cast_button_group.active == 0) is True:
    new_data = df1.to_dict()
return new_data

def update_data(attrname, old, new):

df = select_cast()
data = dict(
        Pressure=df["Pressure"],
        Depth=df["Depth"],
        Temperature=df["Temperature"],
        Salinity=df["Salinity"],
        Conductivity=df["Conductivity"],
        Density=df["Density"],
        DescentRate=df["Descent Rate"],
        SoundVelocity=df["Sound Velocity"],
        Oxygenraw=df["Oxygen raw"],
        Oxygenmgl=df["Oxygen [mg/l]"],
        Oxygenpercent=df["Oxygen [%]"],
        Flag=df["Flag"]
        )
source.data = new_data

controls = [cast_button_group]

for control in controls:

control.on_click(update_data)

Thanks,

Maria


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/ed7af893-d7a9-4af5-a3a0-c6cb6a0cb76b%40continuum.io.

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

That won't work. You need to run the code as a Bokeh server application using "bokeh serve" at the command line.

Bryan

···

On May 16, 2016, at 10:50 AM, [email protected] wrote:

Hi Bryan,

I am running in a Jupyter notebook. The html generate by the code is empty (no data) maybe a problem with the if section?

Em segunda-feira, 16 de maio de 2016 12:43:26 UTC-3, Bryan Van de ven escreveu:
Maria,

That's not an error, that's the "repr" or printed representation of a python object that would show up in a python interpreter. How are you trying to run this code? Bokeh server applications have to be run by the bokeh server itself, not the normal python interpreter. So, if your code is in a file "myapp.py", you'd need to run something like:

        bokeh serve --show myapp.py

at your Bash or DOS command prompt.

Bryan

> On May 16, 2016, at 10:40 AM, [email protected] wrote:
>
> Hi Bryan,
>
> I convert the pandas dataframe to a python dictionary with the code .to_dict() , but with no success. The new_data is a dict now but my source give me the same problem <bokeh.models.sources.ColumnDataSource at 0x7f015705c8d0>.
>
> My code
> def select_cast():
> new_data =
> if (cast_button_group.active == 1) is True:
> new_data = df1.loc[df1['Flag'] == "Downcast"].to_dict()
> if (cast_button_group.active == 2) is True:
> new_data = df1.loc[df1['Flag'] == "Upcast"].to_dict()
> if (cast_button_group.active == 0) is True:
> new_data = df1.to_dict()
> return new_data
>
>
>
>
> def update_data(attrname, old, new):
> df = select_cast()
> data = dict(
> Pressure=df["Pressure"],
> Depth=df["Depth"],
> Temperature=df["Temperature"],
> Salinity=df["Salinity"],
> Conductivity=df["Conductivity"],
> Density=df["Density"],
> DescentRate=df["Descent Rate"],
> SoundVelocity=df["Sound Velocity"],
> Oxygenraw=df["Oxygen raw"],
> Oxygenmgl=df["Oxygen [mg/l]"],
> Oxygenpercent=df["Oxygen [%]"],
> Flag=df["Flag"]
> )
> source.data = new_data
>
> controls = [cast_button_group]
> for control in controls:
> control.on_click(update_data)
>
>
> Thanks,
>
> Maria
>
> --
> 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/ed7af893-d7a9-4af5-a3a0-c6cb6a0cb76b%40continuum.io.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout.

--
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/3510bdc5-49b5-4df0-b6b4-2da02505e528%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hi Bryan,

I run the *.py in command line, good to know I need to run in command line.

I have the following message error:

TypeError: update_data() missing 2 required positional arguments: ‘old’ and ‘new’

Maria

Hi,

I change the code but no succes. I do not have any error but no data appear on the plots.

Maria

def update_data(old, new):
cast_val = cast_button_group.active
new_df = pd.read_excel(xlsx, ‘Day’)

if (cast_button_group.active == 1):
    new_df = new_df.loc[df1['Flag'] == "Downcast"].to_dict()
elif (cast_button_group.active == 2):
    new_df = dfU.loc[df1['Flag'] == "Upcast"].to_dict()
else:
    new_df = new_df.to_dict()

df = new_df
source.date = dict(
        Pressure=df["Pressure"],
        Depth=df["Depth"],
        Temperature=df["Temperature"],
        Salinity=df["Salinity"],
        Conductivity=df["Conductivity"],
        Density=df["Density"],
        DescentRate=df["Descent Rate"],
        SoundVelocity=df["Sound Velocity"],
        Oxygenraw=df["Oxygen raw"],
        Oxygenmgl=df["Oxygen [mg/l]"],
        Oxygenpercent=df["Oxygen [%]"],
        Flag=df["Flag"]
        )

controls = [cast_button_group]
for control in controls:
control.on_click(update_data)

– end –

``

Bokeh_CheckboxButtonGroup.py (6.18 KB)

Hi, I’m about to have 16 hours worth of flights. I apologize I can’t help more right now. I’d suggest you start with one of the existing working examples in the repository as a starting point, and make small incremental changes to it to gain more experience.

Thanks,

Bryan

···

On May 16, 2016, at 22:16, [email protected] wrote:

Hi,

I change the code but no succes. I do not have any error but no data appear on the plots.

Maria

def update_data(old, new):
cast_val = cast_button_group.active
new_df = pd.read_excel(xlsx, ‘Day’)

if (cast_button_group.active == 1):
    new_df = new_df.loc[df1['Flag'] == "Downcast"].to_dict()
elif (cast_button_group.active == 2):
    new_df = dfU.loc[df1['Flag'] == "Upcast"].to_dict()
else:
    new_df = new_df.to_dict()


df = new_df
source.date = dict(
        Pressure=df["Pressure"],
        Depth=df["Depth"],
        Temperature=df["Temperature"],
        Salinity=df["Salinity"],
        Conductivity=df["Conductivity"],
        Density=df["Density"],
        DescentRate=df["Descent Rate"],
        SoundVelocity=df["Sound Velocity"],
        Oxygenraw=df["Oxygen raw"],
        Oxygenmgl=df["Oxygen [mg/l]"],
        Oxygenpercent=df["Oxygen [%]"],
        Flag=df["Flag"]
        )

controls = [cast_button_group]
for control in controls:
control.on_click(update_data)

– end –

``

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/f578f441-800a-42aa-ac9d-e6f66a48d4d0%40continuum.io.

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

<Bokeh_CheckboxButtonGroup.py>

Thanks Bryan,

I will try with select and not ratio like example I have in the bokeh site.

Maria

Hi Bryan,

Thanks a lot your advise was perfect. My code is working but just with Dropdown tool and in the Bokeh server not the HTML.

Details:

My first problem was the If function, not properly write. The second was that I was not using a Iniatial state of Update_cast

update_cast(None, None, None) # initial load of the data

Now my code is working with the Dropdown tools but not with the RatioButton. The error I have is I need 4 arguments (way button is working) but I do not know how to do it. I add *def update_cast(active, attrname, old, new): *but not working.

self.on_change(‘active’, lambda attr, old, new: handler(new))

TypeError: update_cast() missing 3 required positional arguments: ‘attrname’, ‘old’, and ‘new’

I can use the Dropdown but I would like to work with RatoButton. :wink:

The code:

def select_cast():
cast_val = cast_select.value
selected = df1
if (cast_val != “Both”):
selected = selected[selected.Flag.str.contains(cast_val)==True]
return selected

def update_cast(attrname, old, new):
df = select_cast()
source.data = dict(
Pressure=df[“Pressure”],
Depth=df[“Depth”],
Temperature=df[“Temperature”],
Salinity=df[“Salinity”],
Conductivity=df[“Conductivity”],
Density=df[“Density”],
DescentRate=df[“Descent Rate”],
SoundVelocity=df[“Sound Velocity”],
Oxygenraw=df[“Oxygen raw”],
Oxygenmgl=df[“Oxygen [mg/l]”],
Oxygenpercent=df[“Oxygen [%]”],
Flag=df[“Flag”]
)

controls = [cast_select]
for control in controls:
control.on_change(‘value’, update_cast)

update_cast(None, None, None) # initial load of the data

``

Maria

Hi Bryan,

I find that I need to use a callback for the widget to work. (Ratio do not use callback, so this tool is not working inside a HTML, I think)

I try to use a callback but no success .

– Set up Ratio button to show/hide cast –

callback = CustomJS(args=dict(source=source), code="""

// get data source from Callback args

var plot_data = source.get(‘data’);

var original_data = original_source.get(‘data’);

var cast = cb_obj.get(‘value’);

/// update data source with new attribute

if (cast == ‘Both’) { return; };

else if (cast == ‘Downcast’) {

plot_data.filter(data[‘Flag’], cast);

//source = df1.loc[df1[‘Flag’] == “Downcast”];

};

// trigger update of data source

source.trigger(‘change’);

“”")

cast_select = Select(value=‘Both’, title=‘Cast’, options=[‘Both’, ‘Downcast’, ‘Upcast’], callback=callback)

Can you have a look?

Thanks

Can you provide some complete scripts that can be immediately run and investigated?

Thanks,

Bryan

···

On May 21, 2016, at 21:04, [email protected] wrote:

Hi Bryan,

I find that I need to use a callback for the widget to work. (Ratio do not use callback, so this tool is not working inside a HTML, I think)

I try to use a callback but no success .

– Set up Ratio button to show/hide cast –

callback = CustomJS(args=dict(source=source), code="""

// get data source from Callback args

var plot_data = source.get(‘data’);

var original_data = original_source.get(‘data’);

var cast = cb_obj.get(‘value’);

/// update data source with new attribute

if (cast == ‘Both’) { return; };

else if (cast == ‘Downcast’) {

plot_data.filter(data[‘Flag’], cast);

//source = df1.loc[df1[‘Flag’] == “Downcast”];

};

// trigger update of data source

source.trigger(‘change’);

“”")

cast_select = Select(value=‘Both’, title=‘Cast’, options=[‘Both’, ‘Downcast’, ‘Upcast’], callback=callback)

Can you have a look?

Thanks

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/1cdd21db-99a3-43e8-a641-f018ebe61a2b%40continuum.io.

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

Hi Bryan,

Please find attached the files.

Thanks a lot for your help.

Bokeh_CheckboxButtonGroup.py (7.37 KB)

Example.xlsx (67.8 KB)

···

Em domingo, 22 de maio de 2016 08:46:44 UTC-3, Bryan Van de ven escreveu:

Can you provide some complete scripts that can be immediately run and investigated?

Thanks,

Bryan

On May 21, 2016, at 21:04, [email protected] wrote:

Hi Bryan,

I find that I need to use a callback for the widget to work. (Ratio do not use callback, so this tool is not working inside a HTML, I think)

I try to use a callback but no success .

– Set up Ratio button to show/hide cast –

callback = CustomJS(args=dict(source=source), code="""

// get data source from Callback args

var plot_data = source.get(‘data’);

var original_data = original_source.get(‘data’);

var cast = cb_obj.get(‘value’);

/// update data source with new attribute

if (cast == ‘Both’) { return; };

else if (cast == ‘Downcast’) {

plot_data.filter(data[‘Flag’], cast);

//source = df1.loc[df1[‘Flag’] == “Downcast”];

};

// trigger update of data source

source.trigger(‘change’);

“”")

cast_select = Select(value=‘Both’, title=‘Cast’, options=[‘Both’, ‘Downcast’, ‘Upcast’], callback=callback)

Can you have a look?

Thanks

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/1cdd21db-99a3-43e8-a641-f018ebe61a2b%40continuum.io.

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