def changed_layout(self, change): self.selected_nodes = [] if self.graph is None: self.output_graph = None self.display_datashader_vis(self.output_graph) elif len(self.graph) == 0: self.output_graph = None self.display_datashader_vis("Cannot display blank graph.") elif isinstance(self.graph, nx.classes.graph.Graph): original = hv.Graph.from_networkx( self.graph, self._nx_layout, **self.graph_layout_params ) self.output_graph = bundle_graph(original) self.tap_selection_stream = streams.Tap(source=self.output_graph) self.tap_selection_stream.add_subscriber(self.tap_stream_subscriber) self.box_selection_stream = streams.BoundsXY(source=self.output_graph) self.box_selection_stream.add_subscriber(self.box_stream_subscriber) self.final_graph = self.set_options(self.output_graph) self.display_datashader_vis(self.final_graph) else: self.output_graph = self.strip_and_produce_rdf_graph(self.graph) self.tap_selection_stream = streams.Tap(source=self.output_graph) self.tap_selection_stream.add_subscriber(self.tap_stream_subscriber) self.box_selection_stream = streams.BoundsXY(source=self.output_graph) self.box_selection_stream.add_subscriber(self.box_stream_subscriber) self.final_graph = self.set_options(self.output_graph) self.display_datashader_vis(self.final_graph)
def node_bundle_tab(filename): G = scripts.MakeNetworkxGraph.__makegraph__(sep_type='semicolon', nodes_df_link=filename) """ Make HV network """ hv_graph = hv.Graph.from_networkx(G, nx.spring_layout, k=1).relabel('Force-Directed Spring') hv_graph.opts(width=650, height=650, xaxis=None, yaxis=None, padding=0.1, node_size=hv.dim('size'), node_color=hv.dim('node_type'), cmap='YlOrBr', edge_color=hv.dim('weight'), edge_cmap='YlGnBu', edge_line_width=hv.dim('weight')) bundle_graph_plot = bundle_graph(hv_graph) """ END HERE """ # Output files to Flask renderer = hv.renderer('bokeh') # plot = renderer.get_plot(hv_graph, show=True).state bundle_plot = renderer.get_plot(bundle_graph_plot, show=True).state return bundle_plot
def get_net(layout, bundled, shade): if (layout.lower() == 'circle'): net = hv.Graph.from_networkx( G, nx.layout.circular_layout).relabel('Circular Layout').opts( width=650, height=650, xaxis=None, yaxis=None, padding=0.1) elif layout.lower() == 'spring': net = hv.Graph.from_networkx( G, nx.layout.spring_layout, k=0.8, iterations=100).relabel( 'Force-Directed Fruchterman-Reingold').opts(width=650, height=650, xaxis=None, yaxis=None, padding=0.1) # , node_size=node_dict[i] for i in node_dict.keys()) else: net = "Error 1: layout type must be: 'circle', 'spring'" net.opts(width=650, height=650, xaxis=None, yaxis=None, padding=0.1, edge_color_index='weight', edge_cmap='jet') if bundled: net = bundle_graph(net) if B_edge_select: net.opts(inspection_policy='edges') if shade: net = hd.datashade(net).opts(plot=dict(height=650, width=650)) return net
def view_network(self): if self.mapdf is None: return pn.indicators.LoadingSpinner(value=True, width=100, height=100) G = get_graph(self.model_path) if G.order == 0: return pn.pane.Alert( f'## No network file found on {self.model_path}') nodeloc = list( filter(lambda n: n[1]['name'] == self.localities, G.nodes(data=True))) # print(nodeloc, self.localities) if nodeloc == []: return pn.pane.Alert(f'## Please select a locality.') H = get_subgraph(G, nodeloc[0][0]) partial_map = self.mapdf[self.mapdf.geocode.isin(H.nodes)] partial_map = partial_map.set_crs(4326) partial_map = partial_map.to_crs(3857) # Converting to web mercator centroids = [(c.x, c.y) for c in partial_map.centroid] # Draw the graph using Altair gcs = [int(gc) for gc in partial_map.geocode] pos = dict(zip(gcs, centroids)) # viz = nxa.draw_networkx( # G, pos=pos, # node_color='weight', # cmap='viridis', # width='weight', # edge_color='black', # ) kwargs = dict(width=800, height=800, xaxis=None, yaxis=None) hv.opts.defaults(opts.Nodes(**kwargs), opts.Graph(**kwargs)) colors = ['#000000'] + hv.Cycle('Category20').values epi_graph = hv.Graph.from_networkx(H, positions=pos) epi_graph.opts(cmap=colors, node_size=10, edge_line_width=1, directed=True, node_line_color='gray', edge_color='gray', node_color='circle') tiles = gv.tile_sources.Wikipedia f = bundle_graph(epi_graph) * tiles source = epi_graph.nodes.clone() # print(epi_graph.nodes.data.iloc[0]) source.data = epi_graph.nodes.data[epi_graph.nodes.data.name == self.localities] return f * source.opts(color='red')
def strip_and_produce_rdf_graph(self, rdf_graph: Graph): """ A function that takes in an rdflib.graph.Graph object and transforms it into a datashader holoviews graph. Also performs the sparql query on the graph that can be set via the 'sparql' parameter """ sparql = self.sparql qres = rdf_graph.query(sparql) uri_graph = Graph() for row in qres: uri_graph.add(row) new_netx = rdflib_to_networkx_graph(uri_graph) original = hv.Graph.from_networkx(new_netx, self._nx_layout, **self.graph_layout_params) output_graph = bundle_graph(original) return output_graph
# make sure there aren't any edges that go to a nonexistant node edf = edf[((edf['start'].isin(ndf['user index'])) & (edf['stop'].isin(ndf['user index'])))] # create graph and save #----------------------------------------------------------------------------# # initialize default args for Holoviews kwargs = dict(width=600, height=600, xaxis=None, yaxis=None) opts.defaults(opts.Nodes(**kwargs), opts.Graph(**kwargs)) # construct Holoviews graph with Bokeh backend hv_nodes = hv.Nodes(ndf).sort() hv_graph = hv.Graph((edf, hv_nodes)) hv_graph.opts(node_color='log degree', node_size=10, edge_line_width=1, node_line_color='gray', edge_hover_line_color='#DF0000') # bundle edges for aestheticss bundled = bundle_graph(hv_graph) # save html of interactive visualizations renderer.save(bundled, 'ff_reaction_graph_bundled') renderer.save(hv_graph, 'ff_reaction_graph') #----------------------------------------------------------------------------# #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
graph = hv.Graph.from_networkx(NetworkX_Graph, nx.spectral_layout).relabel('Spectral Layout') else: graph = hv.Graph.from_networkx(NetworkX_Graph, nx.circular_layout).relabel('Circular Layout') layout = 'circular' PickleMe.pickelize(graph, new_name) return graph hv_graph = makeHVGraph(layout='spring', filename='Wikipedia', NetworkX_Graph=G) hv_graph.opts(width=650, height=650, xaxis=None, yaxis=None, padding=0.1, node_size=hv.dim('size'), node_color=hv.dim('node_type'), cmap='viridis', edge_color=hv.dim('weight'), edge_cmap='viridis', edge_line_width=hv.dim('weight')) bundle_graph = bundle_graph(hv_graph) """ END HERE """ # TO DO (Ani): add HoloMap here, on attribute iterations between 0 and 1000? play with it frequencies = [0, 50, 100, 250, 500, 750, 1000] hmap=hv.HoloMap(hv_graph, kdims='frequencies') hmap # Save files # TO DO (Asaf): # Output file, TO DO: add naming system based on CSV name and graph properties hv.save(hv_graph, 'pickledtest.html', backend='bokeh') hv.save(bundle_graph, 'pickledtestbundled.html', backend='bokeh') # Output files to Flask
def get_similarity_graphs(csv_template, metadata, figure_folder, groupby='species', ksizes=KSIZES, log2sketchsizes=LOG2SKETCHSIZES, molecules=MOLECULES, sketch_id_template=SKETCH_ID_TEMPLATE, n_neighbors=N_NEIGHBORS, plaidplot=False, palettes=PALETTES, color_cols=COLOR_COLS, verbose=False, make_within_groupby_graphs=False): """Read similarity csvs and create holoviews graphs Parameters ---------- csv_template : str format-string to insert molecule, ksize, and log2sketchsize values into to get csv. e.g.: 'similarities_molecule-{molecule}_ksize-{ksize}_log2sketchsize-{log2sketchsize}.csv' metadata : pandas.DataFrame Sample-by-feature metadata encoding additional information about samples, such as species, cell type label, or tissue groupby : str Which column of the metadata to groupby to get sub-graphs for ksizes : tuple of int Which k-mer sizes to look for similarity files for, default (9, 12, 15, 21) log2sketchsizes : tuple of int Which log2 sketch sizes to look for similarity files for, default (10, 12, 14, 16) molecules : tuple of str Which molecules to use, default both 'dna' and 'protein' sketch_id_template : str String to use as a unique identifier for the sketch, e.g. 'molecule-{molecule}_ksize-{ksize}_log2sketchsize-{log2sketchsize}' plaidplot : bool If true, make a clustered heatmap with the sides labeled with the color_cols palettes : dict Column name (must be in 'metadata') to palette name mapping color_cols : list Column names in 'metadata' to color by Returns ------- graph_dict : dict of holoviews.Graph (molecule, ksize, log2sketchsize) : holoviews.Graph mapping for all similarity matrices found. To be used by 'draw_holoviews_graphs' """ # Strip the final slash because it makes s3 stuff weird figure_folder = figure_folder.rstrip('/') iterable = itertools.product(molecules, ksizes, log2sketchsizes) graph_dict = {} categories = metadata[color_cols] for molecule, ksize, log2sketchsize in iterable: template_kwargs = dict(molecule=molecule, ksize=ksize, log2sketchsize=log2sketchsize) sketch_id = sketch_id_template.format(**template_kwargs) if verbose: print(sketch_id.replace('-', ": ").replace("_", ", ")) csv = csv_template.format(**template_kwargs) try: similarities = pd.read_csv(csv) except FileNotFoundError: warnings.warn(f"file {csv} not found") # File doesn't exist yet continue similarities.index = similarities.columns if verbose: print(f"\tsimilarities.shape: {similarities.shape}") title = f"molecule: {molecule}, ksize: {ksize}, " \ f"log2sketchsize: {log2sketchsize}" if plaidplot: try: g = sourmash_utils.plaidplot(similarities, metric='cosine', row_categories=categories, col_categories=categories, row_palette=palettes, col_palette=palettes) g.fig.suptitle(title) png = f'{figure_folder}/{sketch_id}_plaidplot.png' savefig(g, png, dpi=150) except FloatingPointError: warnings.warn("\tCouldn't compute linkage -- no plaidplot " \ "generated") graph, pos = build_graph_and_plot(similarities, metadata, n_neighbors, color_cols, palettes, figure_folder, sketch_id, title) # hv.extension('matplotlib') graph_hv = hv.Graph.from_networkx(graph, pos) graph_hv = graph_hv.opts(node_size=10, edge_line_width=1, cmap='Set2', node_color=dim(groupby), node_line_color='gray') bundled = bundle_graph(graph_hv) # hv.save(bundled, '.pdf', backend='matplotlib') graph_dict[(molecule, ksize, log2sketchsize)] = bundled if make_within_groupby_graphs: # make within-group (e.g. within-species) graphs for species, df in metadata.groupby(groupby): data = similarities.loc[df.index, df.index] figure_prefix = f"{sketch_id}_{species}" graph_title = f"{title} ({species})" build_graph_and_plot(data, df, n_neighbors, color_cols, palettes, figure_folder, figure_prefix, graph_title) return graph_dict
graph.opts(cmap='Category20', edge_cmap='Category20', node_size=10, edge_line_width=1, node_color=dim('Id').str(), edge_color=dim('Source').str()) hv.save(graph, 'coloured_chord.html') # Facebook data as graph with predifined coordinate system kwargs = dict(width=300, height=300, xaxis=None, yaxis=None) opts.defaults(opts.Nodes(**kwargs), opts.Graph(**kwargs)) colors = ['#000000'] + hv.Cycle('Category20').values edges_df = pd.read_csv('data/fb_edges.csv') fb_nodes = hv.Nodes(pd.read_csv('data/fb_nodes.csv')).sort() fb_graph = hv.Graph((edges_df, fb_nodes), label='Facebook Circles') fb_graph.opts(cmap=colors, node_size=10, edge_line_width=1, node_line_color='gray', node_color='circle') hv.save(fb_graph, 'fb_graph.html') # Bundled graph of facebook data from holoviews.operation.datashader import datashade, bundle_graph bundled = bundle_graph(fb_graph) hv.save(bundled, 'fb_bundled.html')
def make_plot(self): from graphion.session.handler import get_directed # dependency cycle fix if get_directed(self.sid): G = from_pandas_adjacency(df, create_using=DiGraph) else: G = from_pandas_adjacency(df, create_using=Graph) self.nodeCount = number_of_nodes(G) """ Create NetworkX graph layout manager """ if diagramType == "FORCE": layout = spring_layout(G, k=10.42 / sqrt(self.nodeCount), seed=server.config['SEED']) elif diagramType == "HIERARCHICAL": if self.nodeCount > 1: layout = graphviz_layout(Graph([ (u, v, d) for u, v, d in G.edges(data=True) ]), prog='dot') else: layout = circular_layout( G ) # graphviz_layout does not work with one node, just display a "circular_layout" elif diagramType == "RADIAL": layout = circular_layout(G) else: pass # get node and edge information from graph nodes, nodes_coordinates = zip(*sorted(layout.items())) nodes_x, nodes_y = list(zip(*nodes_coordinates)) # calculate centrality centrality = degree_centrality(G) _, nodeCentralities = zip(*sorted(centrality.items())) if self.nodeCount > 1: # get degree information if is_directed(G): inDegreeSize = dict(G.in_degree) inDegree = inDegreeSize.copy() outDegreeSize = dict(G.out_degree) outDegree = outDegreeSize.copy() totalDegreeSize = {} for n in nodes: totalDegreeSize[n] = inDegreeSize[n] + outDegreeSize[n] totalDegree = totalDegreeSize.copy() else: inDegreeSize = dict(G.degree) inDegree = inDegreeSize.copy() outDegreeSize = inDegreeSize.copy() outDegree = inDegreeSize.copy() totalDegreeSize = inDegreeSize.copy() totalDegree = inDegreeSize.copy() # get weight information if is_directed(G): inWeightSize = dict(G.in_degree(weight='weight')) inWeight = inWeightSize.copy() outWeightSize = dict(G.out_degree(weight='weight')) outWeight = outWeightSize.copy() totalWeightSize = {} for n in nodes: totalWeightSize[n] = inWeightSize[n] + outWeightSize[n] totalWeight = totalWeightSize.copy() else: inWeightSize = dict(G.degree(weight='weight')) inWeight = inWeightSize.copy() outWeightSize = inWeightSize.copy() outWeight = inWeightSize.copy() totalWeightSize = inWeightSize.copy() totalWeight = inWeightSize.copy() # Creating a scale to ensure that the node sizes don't go bananas minNodeSize = 0.1 # minNodeSize * maxNodeSize = minimum node size maxIn = -maxsize - 1 minIn = maxsize maxOut = -maxsize - 1 minOut = maxsize maxTot = -maxsize - 1 minTot = maxsize maxInw = -maxsize - 1 minInw = maxsize maxOutw = -maxsize - 1 minOutw = maxsize maxTotw = -maxsize - 1 minTotw = maxsize for n in nodes: ind = inDegreeSize[n] outd = outDegreeSize[n] totd = totalDegreeSize[n] inw = inWeightSize[n] outw = outWeightSize[n] totw = totalWeightSize[n] if ind > maxIn: maxIn = ind elif ind < minIn: minIn = ind if outd > maxOut: maxOut = outd elif outd < minOut: minOut = outd if totd > maxTot: maxTot = totd elif totd < minTot: minTot = totd if inw > maxInw: maxInw = inw elif inw < minInw: minInw = inw if outw > maxOutw: maxOutw = outw elif outw < minOutw: minOutw = outw if totw > maxTotw: maxTotw = totw elif totw < minTotw: minTotw = totw if maxIn == minIn: sameInDegree = True else: sameInDegree = False for n in nodes: result = (inDegreeSize[n] - minIn) / maxIn if result < minNodeSize: inDegreeSize[n] = minNodeSize else: inDegreeSize[n] = result if maxOut == minOut: sameOutDegree = True else: sameOutDegree = False for n in nodes: result = (outDegreeSize[n] - minOut) / maxOut if result < minNodeSize: outDegreeSize[n] = minNodeSize else: outDegreeSize[n] = result if maxTot == minTot: sameTotalDegree = True else: sameTotalDegree = False for n in nodes: result = (totalDegreeSize[n] - minTot) / maxTot if result < minNodeSize: totalDegreeSize[n] = minNodeSize else: totalDegreeSize[n] = result if maxInw == minInw: sameInWeight = True else: sameInWeight = False for n in nodes: result = (inWeightSize[n] - minInw) / maxInw if result < minNodeSize: inWeightSize[n] = minNodeSize else: inWeightSize[n] = result if maxOutw == minOutw: sameOutWeight = True else: sameOutWeight = False for n in nodes: result = (outWeightSize[n] - minOutw) / maxOutw if result < minNodeSize: outWeightSize[n] = minNodeSize else: outWeightSize[n] = result if maxTotw == minTotw: sameTotalWeight = True else: sameTotalWeight = False for n in nodes: result = (totalWeightSize[n] - minTotw) / maxTotw if result < minNodeSize: totalWeightSize[n] = minNodeSize else: totalWeightSize[n] = result # Making a dictionary for all attributes, and ensuring none of the values go crazy. attributes = {} maxNodeSize = 30 for n in nodes: outd = outDegreeSize[n] totd = totalDegreeSize[n] inw = inWeightSize[n] outw = outWeightSize[n] totw = totalWeightSize[n] if sameInDegree: ind = 1 else: ind = inDegreeSize[n] if sameOutDegree: outd = 1 else: outd = outDegreeSize[n] if sameTotalDegree: totd = 1 else: totd = totalDegreeSize[n] if sameInWeight: inw = 1 else: inw = inWeightSize[n] if sameOutWeight: outw = 1 else: outw = outWeightSize[n] if sameTotalWeight: totw = 1 else: totw = totalWeightSize[n] attributes[n] = { 'indegreesize': ind * maxNodeSize, 'outdegreesize': outd * maxNodeSize, 'totaldegreesize': totd * maxNodeSize, 'inweightsize': inw * maxNodeSize, 'outweightsize': outw * maxNodeSize, 'totalweightsize': totw * maxNodeSize, 'indegree': inDegree[n], 'outdegree': outDegree[n], 'totaldegree': totalDegree[n], 'inweight': inWeight[n], 'outweight': outWeight[n], 'totalweight': totalWeight[n], 'count': 0 } set_node_attributes(G, attributes) plot = HVGraph.from_networkx(G, layout).opts( directed=get_directed(self.sid), arrowhead_length=0.01) # disabling displaying all node info on hovering over the node tooltips = [('Index', '@index'), ('In-Degree', '@indegree'), ('Out-Degree', '@outdegree'), ('Total Degree', '@totaldegree'), ('In Edge Weight', '@inweight'), ('Out Edge-Weight', '@outweight'), ('Total Edge-Weight', '@totalweight')] hover = HoverTool(tooltips=tooltips) else: attributes = {} for n in nodes: attributes[n] = { 'indegreesize': 1, 'outdegreesize': 1, 'totaldegreesize': 1, 'inweightsize': 1, 'outweightsize': 1, 'totalweightsize': 1, 'indegree': 0, 'outdegree': 0, 'totaldegree': 0, 'inweight': 0, 'outweight': 0, 'totalweight': 0, 'count': 0 } set_node_attributes(G, attributes) plot = HVGraph.from_networkx(G, layout).opts( directed=get_directed(self.sid), arrowhead_length=0.01) tooltips = [('Index', '@index'), ('In-Degree', '@indegree'), ('Out-Degree', '@outdegree'), ('Total Degree', '@totaldegree'), ('In Edge Weight', '@inweight'), ('Out Edge-Weight', '@outweight'), ('Total Edge-Weight', '@totalweight')] hover = HoverTool(tooltips=tooltips) # Make custom dictionary with color palettes for c in self.colorList: if c == 'cividis': self.colorMap[c] = Cividis256 elif c == 'viridis': self.colorMap[c] = Viridis256 elif c == 'inferno': self.colorMap[c] = Inferno256 else: self.colorMap[c] = palette[c] if max(nodeCentralities) > 0: if datashaded and self.nodeCount > 1: plot = bundle_graph(plot) points = plot.nodes points.opts(cmap=self.colorMap[self.color_palette], color=self.node_color, size=self.node_size, tools=['box_select', 'lasso_select', 'tap', hover], active_tools=['wheel_zoom'], toolbar='above', show_legend=False, width=self.size, height=self.size) plot.opts(node_size=0, node_color=None, node_line_width=0, node_hover_fill_color='green') return plot, points
labels_no_labels = labels.clone() labels_no_labels[:] = -1 labels = { i: { 'labels_all': labels[i], 'labels_no_test': labels_no_test[i], 'labels_only_train': labels_only_train[i], 'labels_no_labels': labels_no_labels[i] } for i in range(len(labels)) } print('Setting attributes') nx.set_node_attributes(G, labels) print('Bundling') G = bundle_graph( hv.Graph.from_networkx(G, nx.layout.spring_layout).opts(tools=['hover'])) cmap = [ '#0000ff', '#8888ff', '#ffffff', '#ff8888', '#ff0000', '#00ffff', '#ffff00' ] draw_graph(G, 'labels_all', cmap) draw_graph(G, 'labels_no_test', ['#222222'] + cmap) draw_graph(G, 'labels_only_train', ['#222222'] + cmap) draw_graph(G, 'labels_no_labels', ['#222222'])