Is that possible to update a hover tooltips on change?

Hi,
I have a pandas dataframe with fixed columns, let say x and y, and a selection of variable columns I chose using a multiselect widget.

I turn this dataframe into a ColumnDataSource and generate a plot with my variable columns printed in a hover tool.

So my question is: Is that possible to update the hover tool tooltips on widget change?

The only solution I came up with, which is a very bad solution, is to add a new hovertool every time the widget is used.

Ideally, I would like to do something likehover.tooltips = [(“x”, “@x”), (“y”, “@y”)] + my_variable_cols but that doesn’t work.

An alternative could be to delete the previous hover tool before creating the new one.

I reduced my use case to a minimal example (attached file).

Thanks!!

Julien

test.py (1.4 KB)

Hi again!
Just to rephrase my initial question which was not super clear.

Is there a way to update hover tool list of displayed variables on widget change?

May I open an issue on Github for this?

Thanks

Julien

···

Le mercredi 15 mars 2017 12:15:45 UTC+1, Julien Jouganous a écrit :

Hi,
I have a pandas dataframe with fixed columns, let say x and y, and a selection of variable columns I chose using a multiselect widget.

I turn this dataframe into a ColumnDataSource and generate a plot with my variable columns printed in a hover tool.

So my question is: Is that possible to update the hover tool tooltips on widget change?

The only solution I came up with, which is a very bad solution, is to add a new hovertool every time the widget is used.

Ideally, I would like to do something likehover.tooltips = [(“x”, “@x”), (“y”, “@y”)] + my_variable_cols but that doesn’t work.

An alternative could be to delete the previous hover tool before creating the new one.

I reduced my use case to a minimal example (attached file).

Thanks!!

Julien

Hey Julien,

In my experience updating the hover tool on it’s own breaks the plot. Some objects are very closely tied to other objects in the underlying structure of the figure model and updating those objects has this effect. The cleanest way around this is creating a new figure on callback with a new hovertool and replacing the old figure in your layout. Here’s an example of what I mean:

from bokeh.layouts import row
from bokeh.models.widgets import MultiSelect
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.plotting import figure
import pandas as pd
df_test = pd.DataFrame({
'x': [1, 2, 3, 4    ],
'height': [2, 3, 4, 5    ],
'col1': ['a', 'b', 'c', 'd'    ],
'col2': [2, 4, 6, 8    ],
'col3': ['mon', 'tues', 'wed', 'fri']
})
df_test['y'] = df_test.height / 2.0

# facets select
ms = MultiSelect(title="column selection"                 ,
options=['col1', 'col2', 'col3'                 ],
value=[], width=200
)
def create_plot():
    # create data source for plot based on multi select values
    v = ms.value
df_plot = df_test[['x', 'y', 'height'    ]+v]
datasource = ColumnDataSource(df_plot)
# create figure for plot and add glyphs
    # took out x_range=datasource.data['x'], x_range takes only takes a tuple or range model
    p = figure(width=800, height=500    )
p.rect(x="x", y="y", width=0.8, height="height"           ,
source=datasource, color="#2171b5", alpha=0.6    )
# create hover tool based on multi select values
    tt = [(x, '@'+x) for x in v]
p.add_tools(HoverTool(tooltips=[("x", "@x"), ("y", "@y"    )]+tt))
return p
def update(attribute, old, new):
    # replace the plot in our layout with a shiny new plot
    l.children[1
] = create_plot()
ms.on_change('value'
, update)
# changed layout to row, for my own familiarty
l = row(ms, create_plot())
curdoc().add_root(l)
curdoc().title = "bokeh app"

There is a pretty good discussion on updating hovertools here. Although the focus in the linked discussion is on changing the interactions of the hover tool, it should still be applicable to updating the fields. The solution presented by Corleo is an interesting alternative to my solution that can work if you know what possible fields will be added to the hovertool.

Hope that helps,
Tyler

···

On Monday, March 27, 2017 at 1:06:19 AM UTC-7, Julien Jouganous wrote:

Hi again!
Just to rephrase my initial question which was not super clear.

Is there a way to update hover tool list of displayed variables on widget change?

May I open an issue on Github for this?

Thanks

Julien

Le mercredi 15 mars 2017 12:15:45 UTC+1, Julien Jouganous a écrit :

Hi,
I have a pandas dataframe with fixed columns, let say x and y, and a selection of variable columns I chose using a multiselect widget.

I turn this dataframe into a ColumnDataSource and generate a plot with my variable columns printed in a hover tool.

So my question is: Is that possible to update the hover tool tooltips on widget change?

The only solution I came up with, which is a very bad solution, is to add a new hovertool every time the widget is used.

Ideally, I would like to do something likehover.tooltips = [(“x”, “@x”), (“y”, “@y”)] + my_variable_cols but that doesn’t work.

An alternative could be to delete the previous hover tool before creating the new one.

I reduced my use case to a minimal example (attached file).

Thanks!!

Julien

Hi Tyler,
Thanks for your help! I’ll try to adapt that to my case. I was hopping there was a way to update the hover tool instead of creating a new figure.

I created an issue on github here: https://github.com/bokeh/bokeh/issues/6085

Best,

Julien

···

Le vendredi 31 mars 2017 19:40:50 UTC+2, Tyler Nickerson a écrit :

Hey Julien,

In my experience updating the hover tool on it’s own breaks the plot. Some objects are very closely tied to other objects in the underlying structure of the figure model and updating those objects has this effect. The cleanest way around this is creating a new figure on callback with a new hovertool and replacing the old figure in your layout. Here’s an example of what I mean:

from bokeh.layouts import row
from bokeh.models.widgets import MultiSelect
from [bokeh.io](http://bokeh.io) import curdoc
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.plotting import figure
import pandas as pd
df_test = pd.DataFrame({
'x': [1, 2, 3, 4    ],
'height': [2, 3, 4, 5    ],
'col1': ['a', 'b', 'c', 'd'    ],
'col2': [2, 4, 6, 8    ],
'col3': ['mon', 'tues', 'wed', 'fri']
})
df_test['y'] = df_test.height / 2.0

# facets select
ms = MultiSelect(title="column selection"                 ,
options=['col1', 'col2', 'col3'                 ],
value=[], width=200
)
def create_plot():
    # create data source for plot based on multi select values
    v = ms.value
df_plot = df_test[['x', 'y', 'height'    ]+v]
datasource = ColumnDataSource(df_plot)
# create figure for plot and add glyphs
    # took out x_range=datasource.data['x'], x_range takes only takes a tuple or range model
    p = figure(width=800, height=500    )
p.rect(x="x", y="y", width=0.8, height="height"           ,
source=datasource, color="#2171b5", alpha=0.6    )
# create hover tool based on multi select values
    tt = [(x, '@'+x) for x in v]
p.add_tools(HoverTool(tooltips=[("x", "@x"), ("y", "@y"    )]+tt))
return p
def update(attribute, old, new):
    # replace the plot in our layout with a shiny new plot
    l.children[1
] = create_plot()
ms.on_change('value'
, update)
# changed layout to row, for my own familiarty
l = row(ms, create_plot())
curdoc().add_root(l)
curdoc().title = "bokeh app"

There is a pretty good discussion on updating hovertools here. Although the focus in the linked discussion is on changing the interactions of the hover tool, it should still be applicable to updating the fields. The solution presented by Corleo is an interesting alternative to my solution that can work if you know what possible fields will be added to the hovertool.

Hope that helps,
Tyler

On Monday, March 27, 2017 at 1:06:19 AM UTC-7, Julien Jouganous wrote:

Hi again!
Just to rephrase my initial question which was not super clear.

Is there a way to update hover tool list of displayed variables on widget change?

May I open an issue on Github for this?

Thanks

Julien

Le mercredi 15 mars 2017 12:15:45 UTC+1, Julien Jouganous a écrit :

Hi,
I have a pandas dataframe with fixed columns, let say x and y, and a selection of variable columns I chose using a multiselect widget.

I turn this dataframe into a ColumnDataSource and generate a plot with my variable columns printed in a hover tool.

So my question is: Is that possible to update the hover tool tooltips on widget change?

The only solution I came up with, which is a very bad solution, is to add a new hovertool every time the widget is used.

Ideally, I would like to do something likehover.tooltips = [(“x”, “@x”), (“y”, “@y”)] + my_variable_cols but that doesn’t work.

An alternative could be to delete the previous hover tool before creating the new one.

I reduced my use case to a minimal example (attached file).

Thanks!!

Julien