#!/usr/bin/env python # coding: utf-8 # # # # # #
# # # # #

Bokeh Tutorial

#
# #

08. Graph and Network Plots

# This chapter will cover how to plot network node/link graphs in Bokeh using NetworkX. For information on creating graph renderers from a low level, see [Visualizing Network Graphs](https://docs.bokeh.org/en/latest/docs/user_guide/graph.html) # # In[ ]: from bokeh.io import show, output_notebook from bokeh.plotting import figure output_notebook() # ## Plotting from NetworkX # # The easiest way to plot network graphs with Bokeh is to use the `from_networkx` function. This function accepts any NetworkX graph and returns a Bokeh `GraphRenderer` that can be added to a plot. The `GraphRenderer` has `node_renderer` and `edge_renderer` properties that contain the Bokeh renderers that draw the nodes and edges, respectively. # # The example below shows a Bokeh plot of `nx.desargues_graph()`, setting some of the node and edge properties. # In[ ]: import networkx as nx from bokeh.models import Range1d, Plot from bokeh.plotting import from_networkx G = nx.desargues_graph() # We could use figure here but don't want all the axes and titles plot = Plot(x_range=Range1d(-2, 2), y_range=Range1d(-2, 2)) # Create a Bokeh graph from the NetworkX input using nx.spring_layout graph = from_networkx(G, nx.spring_layout, scale=1.8, center=(0,0)) plot.renderers.append(graph) # Set some of the default node glyph (Circle) properties graph.node_renderer.glyph.update(size=20, fill_color="orange") # Set some edge properties too graph.edge_renderer.glyph.line_dash = [2,2] show(plot) # In[ ]: # Exercise: try a different NetworkX layout, and set some properies on `graph.edge_renderer.glyph` # and `graph.node_renderer.glyph` # ## Adding Extra Data Columns. # # The `node_renderer` and `edge_renderer` properties of the graph renderer each have a `data_source` that is a standard `ColumnDataSource` that you can add new data to, e.g. to drive a hover tool, or to specify colors for the renderer. The example below demonstates both. # In[ ]: from bokeh.models import HoverTool from bokeh.palettes import Category20_20 G = nx.desargues_graph() # always 20 nodes # We could use figure here but don't want all the axes and titles plot = Plot(x_range=Range1d(-2, 2), y_range=Range1d(-2, 2)) # Create a Bokeh graph from the NetworkX input using nx.spring_layout graph = from_networkx(G, nx.spring_layout, scale=1.8, center=(0,0)) plot.renderers.append(graph) # Add some new columns to the node renderer data source graph.node_renderer.data_source.data['index'] = list(range(len(G))) graph.node_renderer.data_source.data['colors'] = Category20_20 graph.node_renderer.glyph.update(size=20, fill_color="colors") plot.add_tools(HoverTool(tooltips="index: @index")) show(plot) # In[ ]: # Exercise: Add your own columns for other node or edge properties e.g. fill_alpha or line_color, # or to show other fields in a tooltoip # ## Inspection and Selection Policies # # Bokeh graph renderers have `inspection_policy` and `selection_policy` properties. These can be used to control how hover inspections highlight the graph, or how selection tools make selections. These properties may be set to any of the inpection policies in `bokeh.graphs`. For instance, if a user hovers over a node, you may wish to highlight all the associated edges as well. This can be accomplished by setting the inspection policy: # # graph.inspection_policy = NodesAndLinkedEdges() # # as the example below demonstrates. # In[ ]: from bokeh.models.graphs import NodesAndLinkedEdges from bokeh.models import Circle, HoverTool, MultiLine G = nx.gnm_random_graph(15, 30) # We could use figure here but don't want all the axes and titles plot = Plot(x_range=Range1d(-2, 2), y_range=Range1d(-2 ,2)) # Create a Bokeh graph from the NetworkX input using nx.spring_layout graph = from_networkx(G, nx.spring_layout, scale=1.8, center=(0,0)) plot.renderers.append(graph) # Blue circles for nodes, and light grey lines for edges graph.node_renderer.glyph = Circle(size=25, fill_color='#2b83ba') graph.edge_renderer.glyph = MultiLine(line_color="#cccccc", line_alpha=0.8, line_width=2) # green hover for both nodes and edges graph.node_renderer.hover_glyph = Circle(size=25, fill_color='#abdda4') graph.edge_renderer.hover_glyph = MultiLine(line_color='#abdda4', line_width=4) # When we hover over nodes, highlight adjecent edges too graph.inspection_policy = NodesAndLinkedEdges() plot.add_tools(HoverTool(tooltips=None)) show(plot) # In[ ]: # Exercise: try a different inspection (or selection) policy like NodesOnly or EdgesAndLinkedNodes # # Next Section # Click on this link to go to the next notebook: [09 - Geographic Plots](09%20-%20Geographic%20Plots.ipynb). # # To go back to the overview, click [here](00%20-%20Introduction%20and%20Setup.ipynb). # In[ ]: