1

I'm using python/bokeh to plot some point with some attributes, and now I have a problem that I couldn't figure out: the hover tooltips does not for some columns.

enter image description here

Considering this line of my code:

    HOVER_TOOLTIPS = [("index", "$index"),("(x,y)", "($x, $y)"), ("weight","@weight"),("height","@height")]

What I'm trying to do is: when I pass the mouse it show me, the attributes of each point, the index, x and y positions are working fine, but the information regarding the weight and height columns appears as '???'. What could I been doing wrong?

What my data looks like:

               Names   weight (kg)  height (m)  x    y
0             Ledger         89.3       1.800  512  725
1           Nicholas        102.3       1.750  618  884
2               Axel         75.0       1.680  725  538
3                Kai         83.7       1.970  578  604
4               Lyle         78.4       1.660  605  586
5               Jair         66.1       1.830  621  817
6             Flynn          82.0       1.690  632  837
7             Baylor         96.0       1.730  608  786
8               Niko         89.5       1.850  628  797
9               Kian         71.2       1.760  710  674
10             Jonas         88.9       1.900  615  779
11             Rhett         65.8       1.880  820  766
12             Asher         93.8       1.560  719  615
13             Elian         56.3       1.640  830  889
14             Alora         60.2       0.165  602  635
15             Mylah         52.9       1.600  614  859

My complete code:
````````````````````````````````````````````````````````````````````````
from bokeh.plotting import figure
from bokeh.models import GraphRenderer, Ellipse
from bokeh.palettes import Spectral8
from bokeh.models import ColumnDataSource, GlyphRenderer, GraphRenderer, StaticLayoutProvider, Circle, CDSView, IndexFilter, Button
import pandas
import networkx
import matplotlib.pyplot as plt
import numpy as np
from bokeh.models.graphs import from_networkx
from bokeh.io import output_notebook, show, save
from bokeh.models import Range1d, Circle, ColumnDataSource, MultiLine
output_notebook()

df = pandas.read_excel('Graph.xlsx', engine='openpyxl')

count_rows = len(df)

weight = df['weight (kg)']
height = df['height (m)']

node_indices = list(range(count_rows))

HOVER_TOOLTIPS = [("index", "$index"),("(x,y)", "($x, $y)"), ("weight","@weight"),("height","@height")]

plot = figure(tooltips = HOVER_TOOLTIPS,
              tools="pan,wheel_zoom,save,reset", active_scroll='wheel_zoom',
            x_range=Range1d(-600, 600), y_range=Range1d(640, 790), title='Network')

graph = GraphRenderer()

graph.node_renderer.glyph = Circle(size=15, fill_color='skyblue')

graph.node_renderer.data_source.data = dict(index=node_indices)

x = df['x'].tolist()
y = df['y'].tolist()

graph.edge_renderer.data_source.data = dict(start=[0]*count_rows,end=node_indices)

graph_layout = dict(zip(node_indices,zip(x, y)))

graph.layout_provider = StaticLayoutProvider(graph_layout=graph_layout)

plot.renderers.append(graph)

show(plot)
  • You never add `"weight"` or `"height"` columns to the `ColumnDataSource` for the node renderer anywhere in the above code. You add `"index"` so it shows up, and `$x` and `$y` (with the `$`) are special variables that display the *mouse position* x- and y-values, which will also always show up. – bigreddot Nov 18 '21 at 22:03

1 Answers1

1

problem is when you define source data you didnt use ColumnDataSource or dict etc. You directly get data column by column and show in graph. So, you should create a data source.

Your source is :

{0: (512, 725), 1: (618, 884), 2: (725, 538)} # long version

and here there is not height, weight etc. only index and x/y coords.

so you should add :

graph.node_renderer.data_source.data['weight'] = weight.tolist()
graph.node_renderer.data_source.data['height'] = height.tolist()

networkx bokeh hovertool example

full code :

from bokeh.plotting import figure
from bokeh.models import GraphRenderer, Ellipse
from bokeh.palettes import Spectral8
from bokeh.models import ColumnDataSource, GlyphRenderer, GraphRenderer, StaticLayoutProvider, Circle, CDSView, IndexFilter, Button
import pandas as pd
import networkx
import matplotlib.pyplot as plt
import numpy as np
from bokeh.models.graphs import from_networkx
from bokeh.io import output_notebook, show, save
from bokeh.models import Range1d, Circle, ColumnDataSource, MultiLine


df = pd.DataFrame({'Names': ['Ledger', 'Nicholas', 'Axel'], 'weight (kg)': [89.3, 102.3, 75.0],
                  'height (m)': [1.800, 1.750, 1.680], 'x': [512, 618, 725], 'y':[725, 884, 538]})

count_rows = len(df)

weight = df['weight (kg)']
height = df['height (m)']

node_indices = list(range(count_rows))

HOVER_TOOLTIPS = [("index", "$index"),("(x,y)", "($x, $y)"), ("weight","@weight"),("height","@height")]

plot = figure(tooltips = HOVER_TOOLTIPS,
              tools="pan,wheel_zoom,save,reset", active_scroll='wheel_zoom',
            x_range=Range1d(-600, 600), y_range=Range1d(640, 790), title='Network')

graph = GraphRenderer()

graph.node_renderer.glyph = Circle(size=15, fill_color='skyblue')

graph.node_renderer.data_source.data = dict(index=node_indices)

x = df['x'].tolist()
y = df['y'].tolist()

data=dict(start=[0]*count_rows,end=node_indices)

graph.edge_renderer.data_source.data = data
graph.node_renderer.data_source.data['weight'] = weight.tolist()
graph.node_renderer.data_source.data['height']= height.tolist()


graph_layout = dict(zip(node_indices, zip(x, y)))

graph.layout_provider = StaticLayoutProvider(graph_layout=graph_layout)

plot.renderers.append(graph)

show(plot)