def edge_labels(graph_render): source = graph_render.edge_renderer.data_source xcoord = bkm.CustomJSTransform(v_func=EDGE_JS_CODE % "0", args=dict( provider=graph_render.layout_provider, source=source)) ycoord = bkm.CustomJSTransform(v_func=EDGE_JS_CODE % "1", args=dict( provider=graph_render.layout_provider, source=source)) source.data['labels'] = [ str(datum) if not pd.isnull(datum) else '' for datum in source.data['relative_allocation'] ] # Use the transforms to supply coords to a LabelSet labels = bkm.LabelSet(x=bkt.transform('start', xcoord), y=bkt.transform('start', ycoord), text='labels', text_font_size="12px", x_offset=0, y_offset=0, source=source, render_mode='canvas') return labels
def node_labels(graph_render): source = graph_render.node_renderer.data_source xcoord = bkm.CustomJSTransform( v_func=NODE_JS_CODE % "0", args=dict(provider=graph_render.layout_provider)) ycoord = bkm.CustomJSTransform( v_func=NODE_JS_CODE % "1", args=dict(provider=graph_render.layout_provider)) # Use the transforms to supply coords to a LabelSet labels = bkm.LabelSet(x=bkt.transform('index', xcoord), y=bkt.transform('index', ycoord), text='index', text_font_size="10px", x_offset=0, y_offset=-5, source=source, render_mode='canvas', text_align='center') return labels
def execute_callback(event) -> None: nonlocal render nonlocal dependency_source np.random.seed(0) all_pathes = nx.all_simple_paths( graph, source=f"{source_text.value}", target=f"{target_text.value}", cutoff=int(f"{cutoff_text.value}"), ) pathes: Set = set() for path in all_pathes: pathes |= set(path) subgraph = graph.subgraph(pathes) render = bkgraphs.from_networkx(subgraph, nx.spring_layout, scale=1, center=(0, 0)) render.node_renderer.glyph = bkmodels.Circle( size=8, fill_color=bkpalettes.Spectral4[0]) p.renderers.clear() p.renderers.append(render) data_table.source = render.node_renderer.data_source x, y = zip(*render.layout_provider.graph_layout.values()) render.node_renderer.data_source.data["x"] = x render.node_renderer.data_source.data["y"] = y labels = bkmodels.LabelSet(x="x", y="y", text="index", source=render.node_renderer.data_source) p.renderers.append(labels) dependency_df = df[df["name"].isin(pathes) & df["parent"].isin(pathes)].drop_duplicates( subset=["name", "parent"]) dependency_source = bkmodels.ColumnDataSource(dependency_df) dependency_table.source = dependency_source
def plot_task_communication(trace_events, workers, show_communication=False): """ Plots individual tasks on workers into a grid chart (one chart per worker). :param show_communication: Merge all worker charts into one and plot communication edges. """ from bokeh import models, plotting from bokeh.layouts import gridplot from pandas import DataFrame end_time = math.ceil(max([e.time for e in trace_events])) plots = [] if show_communication: plot = plotting.figure(plot_width=1200, plot_height=850, x_range=(0, end_time), title='CPU schedules') plot.yaxis.axis_label = 'Worker' plot.xaxis.axis_label = 'Time' plots.append(plot) def get_worker_plot(): if show_communication: return plot else: p = plotting.figure(plot_width=600, plot_height=300, x_range=(0, end_time), title='Worker task execution') p.yaxis.axis_label = 'Task' p.xaxis.axis_label = 'Time' plots.append(p) return p task_to_loc = {} # render task rectangles for index, worker in enumerate(workers): locations = list(build_task_locations(trace_events, worker)) def normalize_height(height): if show_communication: return height / (worker.cpus * 2) + index return height worker_plot = get_worker_plot() rectangles = [(rect[0], rect[1], normalize_height(rect[2]), normalize_height(rect[3])) for (task, rect) in locations] render_rectangles(worker_plot, rectangles) for i, (task, _) in enumerate(locations): task_to_loc[task] = rectangles[i] frame = DataFrame() frame["label"] = [t[0].name for t in locations] frame["bottom"] = [normalize_height(t[1][2]) for t in locations] frame["left"] = [t[1][0] for t in locations] source = models.ColumnDataSource(frame) labels = models.LabelSet(x='left', y='bottom', x_offset=2, y_offset=2, text='label', source=source, text_color="white", render_mode='canvas') worker_plot.add_layout(labels) if show_communication: frame = DataFrame( merge_trace_events( trace_events, lambda e: isinstance(e, FetchStartTraceEvent), lambda e: isinstance(e, FetchEndTraceEvent), lambda e: (e.output, e.target_worker, e.source_worker), end_map=lambda e1, e2: (workers.index(e1.source_worker), e1.time, workers.index(e2.target_worker), e2.time, "{}/{:.2f}". format(e1.output.parent.name, e1.output.size), e1.output)), columns=["worker", "start", "worker2", "end", "label", "output"]) frame["src_task_y"] = frame["output"].map(lambda o: (task_to_loc[ o.parent][2] + task_to_loc[o.parent][3]) / 2) plot = plots[-1] source = models.ColumnDataSource(frame.drop(columns=["output"])) plot.segment(y0='src_task_y', x0='start', y1='worker2', x1='end', source=source, line_color="black", line_width=2) plot.circle(y="worker2", x="end", source=source, size=15, color="black") labels = models.LabelSet(x='end', y='worker2', text='label', x_offset=-10, source=source, text_color="black", text_align="right", render_mode='canvas') plot.add_layout(labels) return gridplot(plots, ncols=2)
'field': value_to_draw, 'transform': color_mapper }, line_color='black', line_width=1.0, source=plot_df) color_bar = bm.ColorBar(color_mapper=color_mapper, ticker=bm.LogTicker(), label_standoff=12, border_line_color=None, location=(0, 0)) p.add_layout(color_bar, 'right') p.add_tools(bm.WheelZoomTool()) labels = bm.LabelSet( x='x', y='y', text='text', source=plot_df, text_align='center', text_color='#FFFFFF', text_font_size={'value': '10px'}, render_mode='canvas', ) p.add_layout(labels) bio.show(p) try: bio.export_png(p, filename="{}.png".format(value_to_draw)) except: pass
def plot_network(network, layout_algorithm=None, scale=1.0, threshold=0.0, node_description=None, node_proportions=None, weight_scale=5.0, normalize_weights=True, node_opts=None, line_opts=None, element_id='nx_id3', figsize=(900, 900)): if threshold > 0: values = nx.get_edge_attributes(network, 'weight').values() max_weight = max(1.0, max(values)) print('Max weigth: {}'.format(max_weight)) print('Mean weigth: {}'.format(sum(values) / len(values))) filter_edges = [(u, v) for u, v, d in network.edges(data=True) \ if d['weight'] >= (threshold * max_weight)] sub_network = network.edge_subgraph(filter_edges) else: sub_network = network args = PlotNetworkUtility.layout_args(layout_algorithm, sub_network, scale) layout = (PlotNetworkUtility.get_layout_algorithm(layout_algorithm))( sub_network, **args) lines_source = NetworkUtility.get_edges_source( sub_network, layout, scale=weight_scale, normalize=normalize_weights) nodes_source = NetworkUtility.create_nodes_data_source( sub_network, layout) nodes_community = NetworkMetricHelper.compute_partition(sub_network) community_colors = NetworkMetricHelper.partition_colors( nodes_community, bokeh.palettes.Category20[20]) nodes_source.add(nodes_community, 'community') nodes_source.add(community_colors, 'community_color') nodes_size = 5 if node_proportions is not None: # NOTE!!! By pd index - not iloc!! nodes_weight = node_proportions.loc[list(sub_network.nodes)] nodes_weight = PlotNetworkUtility.project_series_to_range( nodes_weight, 20, 60) nodes_size = 'size' nodes_source.add(nodes_weight, nodes_size) node_opts = extend(DFLT_NODE_OPTS, node_opts or {}) line_opts = extend(DFLT_EDGE_OPTS, line_opts or {}) p = figure(plot_width=figsize[0], plot_height=figsize[1], x_axis_type=None, y_axis_type=None) #node_size = 'size' if node_proportions is not None else 5 r_lines = p.multi_line('xs', 'ys', line_width='weights', source=lines_source, **line_opts) r_nodes = p.circle('x', 'y', size=nodes_size, source=nodes_source, **node_opts) p.add_tools(bm.HoverTool(renderers=[r_nodes], tooltips=None, callback=WidgetUtility.\ glyph_hover_callback(nodes_source, 'node_id', text_ids=node_description.index, \ text=node_description, element_id=element_id)) ) text_opts = dict(x='x', y='y', text='name', level='overlay', text_align='center', text_baseline='middle') r_nodes.glyph.fill_color = 'lightgreen' # 'community_color' p.add_layout( bm.LabelSet(source=nodes_source, text_color='black', **text_opts)) return p
def plot_bipartite_network( network: nx.Graph, layout_data: nu.NodesLayout, scale: float = 1.0, titles: pd.DataFrame = None, highlight_topic_ids=None, element_id: str = 'nx_id1', plot_width: int = 1000, plot_height: int = 600, ) -> bp.Figure: """Plot a bipartite network. Return bokeh.Figure""" tools: str = 'pan,wheel_zoom,box_zoom,reset,hover,save' source_nodes, target_nodes = nu.get_bipartite_node_set(network, bipartite=0) color_map: dict = ( {x: 'brown' if x in highlight_topic_ids else 'skyblue' for x in target_nodes} if highlight_topic_ids is not None else None ) color_specifier: str = 'colors' if highlight_topic_ids is not None else 'skyblue' source_source: bm.ColumnDataSource = layout_source.create_nodes_subset_data_source( network, layout_data, source_nodes ) target_source: bm.ColumnDataSource = layout_source.create_nodes_subset_data_source( network, layout_data, target_nodes, color_map=color_map ) lines_source: bm.ColumnDataSource = layout_source.create_edges_layout_data_source( network, layout_data, scale=6.0, normalize=False ) edges_alphas: List[float] = metrics.compute_alpha_vector(lines_source.data['weights']) lines_source.add(edges_alphas, 'alphas') p: bp.Figure = bp.figure( plot_width=plot_width, plot_height=plot_height, x_axis_type=None, y_axis_type=None, tools=tools ) _ = p.multi_line( xs='xs', ys='ys', line_width='weights', level='underlay', alpha='alphas', color='black', source=lines_source ) _ = p.circle(x='x', y='y', size=40, source=source_source, color='lightgreen', line_width=1, alpha=1.0) r_targets: bm.GlyphRenderer = p.circle( x='x', y='y', size=25, source=target_source, color=color_specifier, alpha=1.0 ) p.add_tools( bm.HoverTool( renderers=[r_targets], tooltips=None, callback=wu.glyph_hover_callback2( glyph_source=target_source, glyph_id='node_id', text_ids=titles.index, text=titles, element_id=element_id, ), ) ) text_opts: dict = dict(x='x', y='y', text='name', level='overlay', x_offset=0, y_offset=0, text_font_size='8pt') p.add_layout( bm.LabelSet(source=source_source, text_color='black', text_align='center', text_baseline='middle', **text_opts) ) target_source.data['name'] = [str(x) for x in target_source.data['name']] # pylint: disable=unsubscriptable-object p.add_layout( bm.LabelSet(source=target_source, text_color='black', text_align='center', text_baseline='middle', **text_opts) ) return p
def _plot_network( network: nx.Graph, layout_algorithm: str = None, scale: float = 1.0, threshold: float = 0.0, node_description: pd.Series = None, node_proportions: Union[int, str] = None, weight_name: str = 'weight', weight_scale: float = 5.0, normalize_weights: bool = True, node_opts=None, line_opts=None, element_id: str = 'nx_id3', figsize: Tuple[int, int] = (900, 900), node_range: Tuple[int, int] = (20, 60), edge_range: Tuple[int, int] = (1.0, 5.0), ): if threshold > 0: values = nx.get_edge_attributes(network, weight_name).values() max_weight = max(1.0, max(values)) print('Max weigth: {}'.format(max_weight)) print('Mean weigth: {}'.format(sum(values) / len(values))) filter_edges = [(u, v) for u, v, d in network.edges(data=True) if d[weight_name] >= (threshold * max_weight)] sub_network = network.edge_subgraph(filter_edges) else: sub_network = network args = _layout_args(layout_algorithm, sub_network, scale) layout = (_get_layout_algorithm(layout_algorithm))(sub_network, **args) lines_source = layout_source.create_edges_layout_data_source( sub_network, layout, weight=weight_name, scale=weight_scale, normalize=normalize_weights, project_range=edge_range, ) nodes_source = layout_source.create_nodes_data_source(sub_network, layout) nodes_community = metrics.compute_partition(sub_network) community_colors = metrics.partition_colors(nodes_community, bokeh.palettes.Category20[20]) nodes_source.add(nodes_community, 'community') nodes_source.add(community_colors, 'community_color') nodes_size = 5 if node_proportions is not None: if isinstance(node_proportions, int): nodes_size = node_proportions else: nodes_size = 'size' nodes_weight = project_values_to_range( [node_proportions[n] for n in sub_network.nodes], *node_range) nodes_source.add(nodes_weight, nodes_size) node_opts = extend(dict(color='green', alpha=1.0), node_opts or {}) line_opts = extend(dict(color='black', alpha=0.4), line_opts or {}) p = figure(plot_width=figsize[0], plot_height=figsize[1], x_axis_type=None, y_axis_type=None) _ = p.multi_line('xs', 'ys', line_width='weights', level='underlay', source=lines_source, **line_opts) r_nodes = p.circle('x', 'y', size=nodes_size, source=nodes_source, **node_opts) p.add_tools( bokeh.models.HoverTool( renderers=[r_nodes], tooltips=None, callback=wu.glyph_hover_callback2(nodes_source, 'node_id', text_ids=node_description.index, text=node_description, element_id=element_id), )) text_opts = dict(x='x', y='y', text='name', level='overlay', x_offset=0, y_offset=0, text_font_size='12pt') r_nodes.glyph.fill_color = 'lightgreen' # 'community_color' nodes_source.data['name'] = [str(x) for x in nodes_source.data['name']] # pylint: disable=unsubscriptable-object p.add_layout( bm.LabelSet(source=nodes_source, text_align='center', text_baseline='middle', text_color='black', **text_opts)) return p