#!/usr/bin/env python # coding: utf-8 # ## Display hover data in Bokeh scatter plots # In[7]: """ Tested on bokeh 0.11.1, pandas 0.18.0 First plot has no groups and correct hover data, Second plot has groups but misaligned hover data. """ from bokeh.sampledata.autompg import autompg as df from bokeh.charts import Scatter, TimeSeries, output_notebook, show from bokeh.models import HoverTool, BoxZoomTool, ResetTool, CrosshairTool, BoxSelectTool, WheelZoomTool, PreviewSaveTool from bokeh.models.renderers import GlyphRenderer import copy hover = HoverTool( tooltips = [ ("cyl", "@cyl"), ("displ", "@displ"), ("Weight", "@weight"), ("Acceleration", "@accel"), ('Horsepower', '@hp'), ('MPG', '@mpg'), ('Origin', '@origin'), ]) tools = [hover, BoxZoomTool(), ResetTool(), CrosshairTool(), BoxSelectTool(), WheelZoomTool(), PreviewSaveTool()] scatter_sans_groups = Scatter(df, x='mpg', y='hp', title="Auto MPG", xlabel="Miles Per Gallon", ylabel="Horsepower", tools=tools) # In[8]: def patch_renderer(scatter_instance, hover_instance, data_frame): tooltip_fields = [value[1:] for label, value in hover_instance.tooltips if value[0] == '@'] glyph_renderer = [r for r in scatter_instance.renderers if isinstance(r, GlyphRenderer)][0] renderer_fields = glyph_renderer.data_source.data.keys() fields_to_add = [tooltip_field for tooltip_field in tooltip_fields if tooltip_field not in renderer_fields] print 'tooltip_fields: ', tooltip_fields print 'renderer_fields: ', renderer_fields print 'fields_to_add: ', fields_to_add print 'counts before adding: ', [(key, len(glyph_renderer.data_source.data[key])) for key in glyph_renderer.data_source.data] for field in fields_to_add: glyph_renderer.data_source.data[field] = list(data_frame[field]) print 'counts after adding: ', [(key, len(glyph_renderer.data_source.data[key])) for key in glyph_renderer.data_source.data] patch_renderer(scatter_sans_groups, hover, df) # In[9]: output_notebook() show(scatter_sans_groups) # this is correct output # ### Demonstrate problem when groups are introduced # In[10]: # Not sure why hover can't be reused without throwing an error in Scatter, so create hover2 hover2 = HoverTool( tooltips = [ ("cyl", "@cyl"), ("displ", "@displ"), ("Weight", "@weight"), ("Acceleration", "@accel"), ('Horsepower', '@hp'), ('MPG', '@mpg'), ('Origin', '@origin'), ]) scatter_with_groups = Scatter(df, x='mpg', y='hp', title="Auto MPG", xlabel="Miles Per Gallon", ylabel="Horsepower", tools=[hover2], color='cyl', marker='origin') patch_renderer(scatter_with_groups, hover2, df) output_notebook() show(scatter_with_groups) # The output plot is incorrect! Mismatch between # of unique combinations of color and marker (103) # vs. number of total rows (392) in df causes incorrect hover output