Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add tooltips to bokeh stacked bar plot

Tags:

bokeh

Considering a vertical stacked bar plot in which every column is composed of multiple bars (segments). Is it possible to add a tooltip on every segment? At the moment the same tooltip is attached to the all the segments that compose the column.

from bokeh.core.properties import value
from bokeh.io import show, output_file
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.models import HoverTool

fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
years = ["2015", "2016", "2017"]
colors = ["#c9d9d3", "#718dbf", "#e84d60"]

data = {'fruits' : fruits,
        '2015'   : [2, 1, 4, 3, 2, 4],
        '2016'   : [5, 3, 4, 2, 4, 6],
        '2017'   : [3, 2, 4, 4, 5, 3]}

source = ColumnDataSource(data=data)

p = figure(x_range=fruits, plot_height=250, title="Fruit Counts by Year",
           toolbar_location=None, tools="")

p.vbar_stack(years, x='fruits', width=0.9, color=colors, source=source,
             legend=[value(x) for x in years])


tooltips = HoverTool(
tooltips=[
    ("2015", "@2015"),
    ("2016", "@2016"),
    ("2017", "@2017"),
    ("index", "$index")
    ]
)

p.add_tools(tooltips)

show(p)
like image 913
Mihai Avatar asked Oct 23 '17 05:10

Mihai


1 Answers

This can be done by using basic glyphs. Add bar for each year separately, and add a hovertool to that.

from bokeh.core.properties import value
from bokeh.io import show, output_file, output_notebook
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.models import HoverTool
from copy import deepcopy

fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
years = ["2015", "2016", "2017"]
colors = ["#c9d9d3", "#718dbf", "#e84d60"]

data = {'fruits' : fruits,
        '2015'   : [2, 1, 4, 3, 2, 4],
        '2016'   : [5, 3, 4, 2, 4, 6],
        '2017'   : [3, 2, 4, 4, 5, 3]}
#deepcopy the data for later use
data1 =deepcopy(data)

#create cumulative sum over years for plotting using vbar
for i in range(1,len(years)):
    data[years[i]] = [sum(x) for x in zip(data[years[i]], data[years[i-1]])]

p = figure(x_range=fruits, plot_height=250, title="Fruit Counts by Year",
           toolbar_location=None, tools="")


#create bars for each years 
for i in range(len(years)):
    if i==0:
        rx = p.vbar(x=fruits, top=data[years[i]], bottom=[0]*len(fruits), width=0.9, color=colors[i], legend=years[i])
        rx.data_source.add(data1[years[i]], "count") #add a column in data source for just the count
    else:
        rx = p.vbar(x=fruits, top=data[years[i]], bottom=data[years[i-1]], width=0.9, color=colors[i], legend=years[i])
        rx.data_source.add(data1[years[i]], "count") #add a column in data source for just the count

#add hover tool for each bar chart        
for i in range(len(years)):
    p.add_tools(HoverTool(tooltips=[(str(years[i]), "@count"),("Fruit", "@x")], renderers=[r[i]]))

#output_notebook()
show(p)
like image 99
Aritesh Avatar answered Jan 03 '23 02:01

Aritesh