plot_1 = create_graph(nx.circular_layout, inspection_policy=NodesAndLinkedEdges(), scale=1, center=(0, 0)) plot_1.title.text = "Circular Layout (NodesAndLinkedEdges inspection policy)" plot_1.add_tools(HoverTool(tooltips=None)) plot_2 = create_graph(nx.spring_layout, selection_policy=NodesAndLinkedEdges(), scale=2, center=(0, 0)) plot_2.title.text = "Spring Layout (NodesAndLinkedEdges selection policy)" plot_2.add_tools(TapTool(), BoxSelectTool()) plot_3 = create_graph(nx.random_layout, inspection_policy=EdgesAndLinkedNodes(), center=(0, 0)) plot_3.title.text = "Random Layout (EdgesAndLinkedNodes inspection policy)" plot_3.add_tools(HoverTool(tooltips=None)) plot_4 = create_graph(nx.fruchterman_reingold_layout, selection_policy=EdgesAndLinkedNodes(), scale=2, center=(0, 0), dim=2) plot_4.title.text = "FR Layout (EdgesAndLinkedNodes selection policy)" plot_4.add_tools(TapTool()) layout = Column(Row(plot_1, plot_2), Row(plot_3, plot_4)) doc = curdoc()
def _init_glyphs(self, plot, element, ranges, source): # Get data and initialize data source style = self.style[self.cyclic_index] data, mapping, style = self.get_data(element, ranges, style) edge_mapping = { k: v for k, v in mapping[self.edge_glyph].items() if 'color' not in k } self.handles['previous_id'] = element._plot_id properties = {} mappings = {} for key in list(mapping): if not any(glyph in key for glyph in ('scatter_1', self.edge_glyph)): continue source = self._init_datasource(data.pop(key, {})) self.handles[key + '_source'] = source glyph_props = self._glyph_properties(plot, element, source, ranges, style) properties.update(glyph_props) mappings.update(mapping.pop(key, {})) properties = { p: v for p, v in properties.items() if p not in ('legend', 'source') } properties.update(mappings) layout = data.pop('layout', {}) if data and mapping: CompositeElementPlot._init_glyphs(self, plot, element, ranges, source, data, mapping, style) # Define static layout layout = StaticLayoutProvider(graph_layout=layout) node_source = self.handles['scatter_1_source'] edge_source = self.handles[self.edge_glyph + '_source'] renderer = plot.graph(node_source, edge_source, layout, **properties) # Initialize GraphRenderer if self.selection_policy == 'nodes': renderer.selection_policy = NodesAndLinkedEdges() elif self.selection_policy == 'edges': renderer.selection_policy = EdgesAndLinkedNodes() else: renderer.selection_policy = None if self.inspection_policy == 'nodes': renderer.inspection_policy = NodesAndLinkedEdges() elif self.inspection_policy == 'edges': renderer.inspection_policy = EdgesAndLinkedNodes() else: renderer.inspection_policy = None self.handles['layout_source'] = layout self.handles['glyph_renderer'] = renderer self.handles['scatter_1_glyph_renderer'] = renderer.node_renderer self.handles[self.edge_glyph + '_glyph_renderer'] = renderer.edge_renderer self.handles['scatter_1_glyph'] = renderer.node_renderer.glyph if self.filled or self.bezier: glyph_model = Patches if self.filled else Bezier allowed_properties = glyph_model.properties() for glyph_type in ('', 'selection_', 'nonselection_', 'hover_', 'muted_'): glyph = getattr(renderer.edge_renderer, glyph_type + 'glyph', None) if glyph is None: continue props = self._process_properties(self.edge_glyph, properties, mappings) filtered = self._filter_properties(props, glyph_type, allowed_properties) new_glyph = glyph_model(**dict(filtered, **edge_mapping)) setattr(renderer.edge_renderer, glyph_type + 'glyph', new_glyph) self.handles[self.edge_glyph + '_glyph'] = renderer.edge_renderer.glyph if 'hover' in self.handles: if self.handles['hover'].renderers == 'auto': self.handles['hover'].renderers = [] self.handles['hover'].renderers.append(renderer)
height=400, x_range=Range1d(-1.1, 1.1), y_range=Range1d(-1.1, 1.1)) plot.title.text = "Graph Interaction Demonstration" plot.add_tools(HoverTool(tooltips=None), TapTool(), BoxSelectTool()) graph_renderer = from_networkx(G, nx.circular_layout, scale=1, center=(0, 0)) graph_renderer.node_renderer.glyph = Circle(size=15, fill_color=Spectral4[0]) graph_renderer.node_renderer.selection_glyph = Circle(size=15, fill_color=Spectral4[2]) graph_renderer.node_renderer.hover_glyph = Circle(size=15, fill_color=Spectral4[1]) graph_renderer.edge_renderer.glyph = MultiLine(line_color="#CCCCCC", line_alpha=0.8, line_width=5) graph_renderer.edge_renderer.selection_glyph = MultiLine( line_color=Spectral4[2], line_width=5) graph_renderer.edge_renderer.hover_glyph = MultiLine(line_color=Spectral4[1], line_width=5) graph_renderer.selection_policy = NodesAndLinkedEdges() graph_renderer.inspection_policy = EdgesAndLinkedNodes() plot.renderers.append(graph_renderer) output_file("interactive_graphs.html") show(plot)
network_graph.node_renderer.glyph = Circle(size=15, fill_color=Spectral4[0]) network_graph.node_renderer.selection_glyph = Circle(size=15, fill_color=Spectral4[2]) network_graph.node_renderer.hover_glyph = Circle(size=15, fill_color=Spectral4[1]) height_slider = Slider(start=1, end=10, value=1, step=1, title="Height") network_graph.edge_renderer.glyph = MultiLine(line_color="#CCCCCC", line_alpha=0.8, line_width=5) network_graph.edge_renderer.selection_glyph = MultiLine( line_color=Spectral4[2], line_width=5) network_graph.edge_renderer.hover_glyph = MultiLine(line_color=Spectral4[1], line_width=5) network_graph.selection_policy = NodesAndLinkedEdges() network_graph.inspection_policy = EdgesAndLinkedNodes() plot.renderers.append(network_graph) text_input = TextInput(value="Enter Concept ID", title="Concept ID:") layout = column(row(height_slider, plot), row(text_input), sizing_mode="stretch_both") curdoc().add_root(layout) def find_shortest_path(G, start, end, path=[]): if start not in G.nodes(): return None elif end not in G.nodes(): return None
graph_renderer.inspection_policy = inspection_policy graph_renderer.selection_policy = selection_policy plot.renderers.append(graph_renderer) return plot plot_1 = create_graph(nx.circular_layout, inspection_policy=NodesAndLinkedEdges(), scale=1, center=(0,0)) plot_1.title.text = "Circular Layout (NodesAndLinkedEdges inspection policy)" plot_1.add_tools(HoverTool(tooltips=None)) plot_2 = create_graph(nx.spring_layout, selection_policy=NodesAndLinkedEdges(), scale=2, center=(0,0)) plot_2.title.text = "Spring Layout (NodesAndLinkedEdges selection policy)" plot_2.add_tools(TapTool(), BoxSelectTool()) plot_3 = create_graph(nx.random_layout, inspection_policy=EdgesAndLinkedNodes(), center=(0,0)) plot_3.title.text = "Random Layout (EdgesAndLinkedNodes inspection policy)" plot_3.add_tools(HoverTool(tooltips=None)) plot_4 = create_graph(nx.fruchterman_reingold_layout, selection_policy=EdgesAndLinkedNodes(), scale=2, center=(0,0), dim=2) plot_4.title.text = "FR Layout (EdgesAndLinkedNodes selection policy)" plot_4.add_tools(TapTool()) layout = Column(Row(plot_1, plot_2), Row(plot_3, plot_4)) doc = curdoc() doc.add_root(layout) show(layout)
def graphPlot(DG,DGspecies,DGreactions,plot,layout="force",positions=None,posscale = 1.0,layoutfunc=None): """given a directed graph, plot it! Inputs: DG: a directed graph of type DiGraph DGspecies: a directed graph which only contains the species nodes DGreactions: a directed graph which only contains the reaction nodes plot: a bokeh plot object layout: graph layout function. 'force' uses fa2 to push nodes apart 'circle' plots the nodes and reactions in two overlapping circles, with the reactions on the inside of the circle 'custom' allows user input "layoutfunc". Internally, layoutfunc is passed the three inputs (DG, DGspecies, DGreactions) and should output a position dictionary with node {<node number>:(x,y)} positions: a dictionary of node names and x,y positions. this gets passed into the layout function posscale: multiply the scaling of the plot. This only affects the arrows because the arrows are a hack :(""" if(layout=="force"): #below are parameters for the force directed graph visualization forceatlas2 = ForceAtlas2( # Behavior alternatives outboundAttractionDistribution=True, # Dissuade hubs linLogMode=False, # NOT IMPLEMENTED adjustSizes=False, # Prevent overlap (NOT IMPLEMENTED) edgeWeightInfluence=1.0, # Performance jitterTolerance=1.0, # Tolerance barnesHutOptimize=True, barnesHutTheta=1.2, multiThreaded=False, # NOT IMPLEMENTED # Tuning scalingRatio=2.4*posscale, strongGravityMode=False, gravity=1.0, # Log verbose=False) positions = forceatlas2.forceatlas2_networkx_layout(DG, pos=positions, iterations=2000) elif(layout == "circle"): positions = nx.circular_layout(DGspecies,scale=50*posscale) positions.update(nx.circular_layout(DGreactions,scale=35*posscale)) elif(layout == "custom"): positions = layoutfunc(DG,DGspecies,DGreactions) reaction_renderer = from_networkx(DGreactions, positions, center=(0, 0)) species_renderer = from_networkx(DGspecies, positions, center=(0, 0)) edges_renderer = from_networkx(DG, positions, center=(0, 0)) #edges edges_renderer.node_renderer.glyph = Circle(size=12,line_alpha=0,fill_alpha=0, fill_color="color") edges_renderer.edge_renderer.glyph = MultiLine( line_alpha=0.2, line_width=4) edges_renderer.edge_renderer.selection_glyph = MultiLine(line_color=Spectral4[2], line_width=5) edges_renderer.edge_renderer.hover_glyph = MultiLine(line_color=Spectral4[1], line_width=5) xbounds,ybounds = makeArrows2(edges_renderer,DG,positions,headsize=5) #make the arrows! #we want to find the middle of the graph and plot a square that is 1:1 aspect ratio #find the midpoint of the graph xmid = statistics.mean(xbounds) ymid = statistics.mean(ybounds) #now, subtract the middle from the edges xmiddlized = [a-xmid for a in xbounds] ymiddlized = [a-ymid for a in ybounds] #now, find the biggest dimension absdim = max([abs(a) for a in xmiddlized+ymiddlized]) xlim = [xmid-absdim*1.05,xmid + absdim*1.05] ylim = [ymid-absdim*1.05,ymid + absdim*1.05] #now set it on the plot! plot.x_range = Range1d(xlim[0],xlim[1]) plot.y_range = Range1d(ylim[0],ylim[1]) #reactions reaction_renderer.node_renderer.glyph = Square(size=8, fill_color=Spectral4[0]) reaction_renderer.node_renderer.selection_glyph = Square(size=8, fill_color=Spectral4[2]) reaction_renderer.node_renderer.hover_glyph = Square(size=8, fill_color=Spectral4[1]) #nodes species_renderer.node_renderer.glyph = Circle(size=12, fill_color="color") species_renderer.node_renderer.selection_glyph = Circle(size=15, fill_color=Spectral4[2]) species_renderer.node_renderer.hover_glyph = Circle(size=15, fill_color=Spectral4[1]) #this part adds the interactive elements that make it so that the lines are highlighted #when you mouse over and click edge_hover_tool = HoverTool(tooltips= None,renderers=[edges_renderer]) species_hover_tool = HoverTool(tooltips=[("name", "@species"), ("type", "@type")],\ renderers=[species_renderer],attachment="right") rxn_hover_tool = HoverTool(tooltips=[("reaction", "@species"), ("type", "@type"),("k_f","@k"),("k_r","@k_r")],\ renderers=[reaction_renderer],attachment="right") plot.add_tools(edge_hover_tool,species_hover_tool,rxn_hover_tool, TapTool(), BoxSelectTool(),PanTool(),WheelZoomTool()) edges_renderer.selection_policy = NodesAndLinkedEdges() edges_renderer.inspection_policy = EdgesAndLinkedNodes() plot.renderers.append(edges_renderer) plot.renderers.append(reaction_renderer) plot.renderers.append(species_renderer)
# Network Graph - h, w, csvSrc, graphTileTextColor, currFrame, mySkeleton, myStudy xmin, ymin, xmax, ymax = zoomCenterSmCoords(h,w) graphTileTextColor="#7e685a" #brown silver? skPlot = figure(x_range=(0, w), y_range=(h, 0), name="netGraph", outline_line_color=None, tools='pan,wheel_zoom,box_zoom,reset,tap,box_select,hover', plot_width=570,plot_height=300, tooltips=[("coord", "$x{0.0} $y{0.0}"), ("art", "$index")]) skPlot.xaxis.visible = False skPlot.title.text_color = graphTileTextColor skPlot.title.text_font_size="15px" skPlot.title.align = "center" netGraph.selection_policy = NodesAndLinkedEdges() netGraph.inspection_policy = EdgesAndLinkedNodes() netGraph.node_renderer.data_source.add(myBkSkeleton.index, 'index') netGraph.node_renderer.data_source.add(myBkSkeleton['color'], 'color') netGraph.node_renderer.glyph = Circle(size=10, line_color='color', fill_color='color', fill_alpha=0.4) netGraph.node_renderer.selection_glyph = Circle(size=12, fill_color='color', fill_alpha=0.7) netGraph.node_renderer.hover_glyph = Circle(size=12, fill_color='color') netGraph.edge_renderer.data_source.data = connxs netGraph.edge_renderer.glyph = MultiLine(line_color="#c8c8c8", line_width=2) netGraph.edge_renderer.selection_glyph = MultiLine(line_color='#777777', line_width=2) netGraph.edge_renderer.hover_glyph = MultiLine(line_color='#888888', line_width=2) graph_layout = dict(zip(myBkSkeleton.index, myBkSkeleton["coord2d"])) netGraph.layout_provider = StaticLayoutProvider(graph_layout=graph_layout) skPlot.renderers.append(netGraph) skPlot.on_event('reset', updateGraphSkeleton)