Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bokeh hovertool in multiple_line plot

Tags:

python

bokeh

I'm new to bokeh and I just jumped right into using hovertool as that's why I wanted to use bokeh in the first place. Now I'm plotting genes and what I want to achieve is multiple lines with the same y-coordinate and when you hover over a line you get the name and position of this gene.

I have tried to mimic this example, but for some reason the I can't even get it to show coordinates.

I'm sure that if someone who actually knows their way around bokeh looks at this code, the mistake will be apparent and I'd be very thankful if they showed it to me.

from bokeh.plotting import figure, HBox, output_file, show, VBox, ColumnDataSource
from bokeh.models import Range1d, HoverTool
from collections import OrderedDict
import random

ys = [10 for x in range(len(levelsdf2[(name, 'Start')]))]
xscale = zip(levelsdf2[('Log', 'Start')], levelsdf2[('Log', 'Stop')])
yscale = zip(ys,ys)

TOOLS="pan,wheel_zoom,box_zoom,reset,hover"
output_file("scatter.html")
hover_tips = levelsdf2.index.values
colors = ["#%06x" % random.randint(0,0xFFFFFF) for c in range(len(xscale))]

source = ColumnDataSource(
    data=dict(
        x=xscale,
        y=yscale,
        gene=hover_tips,
        colors=colors,
    )
)


p1 = figure(plot_width=1750, plot_height=950,y_range=[0, 15],tools=TOOLS)
p1.multi_line(xscale[1:10],yscale[1:10], alpha=1, source=source,line_width=10, line_color=colors[1:10])

hover = p1.select(dict(type=HoverTool))
hover.tooltips = [
    ("index", "$index"),
    ("(x,y)", "($x, $y)"),
]

show(p1)

the levelsdf2 is a pandas.DataFrame, if it matters.

like image 338
Markus Lippus Avatar asked Oct 20 '22 11:10

Markus Lippus


1 Answers

I figured it out on my own. It turns out that version 0.8.2 of Bokeh doesn't allow hovertool for lines so I did the same thing using quads.

from bokeh.plotting import figure, HBox, output_file, show, VBox, ColumnDataSource
from bokeh.models import Range1d, HoverTool
from collections import OrderedDict
import random


xscale = zip(levelsdf2[('series1', 'Start')], levelsdf2[('series1', 'Stop')])
xscale2 = zip(levelsdf2[('series2', 'Start')], levelsdf2[('series2', 'Stop')])
yscale2 = zip([9.2 for x in range(len(levelsdf2[(name, 'Start')]))],[9.2 for x in range(len(levelsdf2[(name, 'Start')]))])

TOOLS="pan,wheel_zoom,box_zoom,reset,hover"
output_file("linesandquads.html")
hover_tips = levelsdf2.index.values
colors = ["#%06x" % random.randint(0,0xFFFFFF) for c in range(len(xscale))]
proc1 = 'Log'
proc2 = 'MazF2h'
expression1 = levelsdf2[(proc1, 'Level')]
expression2 = levelsdf2[(proc2, 'Level')]
source = ColumnDataSource(
    data=dict(
        start=[min(xscale[x]) for x in range(len(xscale))],
        stop=[max(xscale[x]) for x in range(len(xscale))],
        start2=[min(xscale2[x]) for x in range(len(xscale2))],
        stop2=[max(xscale2[x]) for x in range(len(xscale2))],
        gene=hover_tips,
        colors=colors,
        expression1=expression1,
        expression2=expression2,

    )
)


p1 = figure(plot_width=900, plot_height=500,y_range=[8,10.5],tools=TOOLS)
p1.quad(left="start", right="stop", top=[9.211 for x in range(len(xscale))],
        bottom = [9.209 for x in range(len(xscale))], source=source, color="colors")

p1.multi_line(xscale2,yscale2, source=source, color="colors", line_width=20)


hover = p1.select(dict(type=HoverTool))

hover.tooltips = OrderedDict([
    (proc1+" (start,stop, expression)", "(@start| @stop| @expression1)"),

    ("Gene","@gene"),
])

show(p1)

Works like a charm.

EDIT: Added a picture of the result, as requested and edited code to match the screenshot posted.

Hovertool for lines - workaround using quads

It's not the best solution as it turns out it's not all that easy to plot several series of quads on one plot. It's probably possible but as it didn't matter much in my use case I didn't investigate too vigorously.

As all genes are represented on all series at the same place I just added tooltips for all series to the quads and plotted the other series as multi_line plots on the same figure.

This means that if you hovered on the top line at 9.21 you'd get tooltips for the line at 9.2 as well, but If you hovered on the 9.2 line you wouldn't get a tooltip at all.

like image 87
Markus Lippus Avatar answered Oct 29 '22 22:10

Markus Lippus