Bokeh hovertool in a multi-line plot

I'm new to bokeh, and I just jumped right into using hovertool, so I wanted to use bokeh first. Now I draw the genes, and what I want to achieve is a few lines with the same y coordinate, and when you hover over the line, you get the name and position of this gene.

I tried to imitate this example, but for some reason I canโ€™t even show it to show the coordinates.

I am sure that if someone who really knows their way around bokeh is looking at this code, the error will be obvious, and I would be very grateful 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) 

levelsdf2 is pandas.DataFrame, if that matters.

+5
source share
1 answer

I figured it out myself. It turns out that version 0.8.2 of Bokeh does not allow hovertool for strings, so I did the same using squares.

 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) 

It works like a charm.

EDIT: Added a photo of the result in accordance with the request and the edited code in accordance with the published screenshot.

Hovertool for lines - workaround using quads

This is not the best solution, as it turns out that it is not so easy to build several series on the same plot. This is probably possible, but since it did not make much difference in my use case, I did not investigate too vigorously.

Since all genes are represented in all series in the same place, I simply added tooltips for all series to ATVs and built another series as multi-line graphs in the same figure.

This means that if you were hovering the top line at 9.21, you would also receive tooltips for the line in 9.2, but if you hung on line 9.2, you would not get a tooltip at all.

+3
source

All Articles