def _create_varexp_pie_plt(comptable_cds, n_comps): fig = plotting.figure(plot_width=400, plot_height=400, title='Variance Explained View', tools=['hover,tap,save'], tooltips=[('Component ID', ' @component'), ('Kappa', '@kappa{0.00}'), ('Rho', '@rho{0.00}'), ('Var. Exp.', '@varexp{0.00}%')]) fig.wedge(x=0, y=1, radius=.9, start_angle=transform.cumsum('angle', include_zero=True), end_angle=transform.cumsum('angle'), line_color="white", fill_color='color', source=comptable_cds, fill_alpha=0.7) fig.axis.visible = False fig.grid.visible = False fig.toolbar.logo = None circle = models.Circle(x=0, y=1, size=150, fill_color='white', line_color='white') fig.add_glyph(circle) return fig
def plot_bokeh(self, labels, output_file=None, node_size=4, node_color=None, edge_color=None, width=None, **kwargs): # Unfortunately, nodes in Bokeh have to be strings or ints plot_d = nx.relabel.relabel_nodes(self, labels) tooltips = [] for node, data in plot_d.nodes(data=True): for key in data: tooltips += [(key, f"@{key}")] break if node_color is None: node_color = {labels[node]: "green" if node in self.path else "lightgray" for node in self.nodes} nx.set_node_attributes(plot_d, node_color, "node_color") fill_color = "node_color" if edge_color is None: edge_color = {(labels[edge[0]], labels[edge[1]]): "limegreen" if edge in self.solution or edge[::-1] in self.solution else "gray" for edge in self.edges} nx.set_edge_attributes(plot_d, edge_color, "edge_color") line_color = "edge_color" if width is None: width = {(labels[edge[0]], labels[edge[1]]): 2 if edge in self.solution else 0.1 for edge in self.edges} nx.set_edge_attributes(plot_d, width, "edge_width") line_width = "edge_width" graph = bkplt.from_networkx(plot_d, nx.circular_layout) graph.node_renderer.glyph = mod.Circle(size=node_size, line_color=fill_color, fill_color=fill_color) graph.edge_renderer.glyph = mod.MultiLine(line_color=line_color, line_width=line_width) plot = mod.Plot() plot.renderers.append(graph) tooltips = [("Label", "@index")] + tooltips node_hover_tool = mod.HoverTool(tooltips=tooltips) plot.add_tools(node_hover_tool, mod.PanTool(), mod.BoxZoomTool(), mod.WheelZoomTool(), mod.SaveTool(), mod.ResetTool()) if output_file: bkplt.output_file(output_file) bkplt.show(plot)
def clear_callback(event) -> None: np.random.seed(0) render = bkgraphs.from_networkx(graph, 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) # p.renderers.pop(0) data_table.source = render.node_renderer.data_source
def visualize_clusters(peaklistpath, plotfilepath, title, x, y): """Visualize cluster in 2D space.""" TOOLS = "pan,box_zoom,box_select,resize,reset,wheel_zoom,save" bkp.output_file(plotfilepath) plot = bkp.figure(tools=TOOLS, title=title) plot.xaxis.axis_label, plot.yaxis.axis_label = "{}, ppm".format( x), "{}, ppm".format(y) for cluster, color in zip( grouping.DBSCAN.global_clusters[peaklistpath].values(), COLOR_HEX): x_coords = cluster.coordinates(x) y_coords = cluster.coordinates(y) assignments = cluster.assignments() source = bkp.ColumnDataSource( data=dict(x=x_coords, y=y_coords, assignment=assignments)) for point in cluster.members: if cluster.label == -1: g = bkm.CircleX(x='x', y='y', line_color='#6666ee', fill_color='black', fill_alpha=0.5, size=5) else: g = bkm.Circle(x='x', y='y', line_color='#6666ee', fill_color=color, fill_alpha=0.5, size=10) gr = plot.add_glyph(source_or_glyph=source, glyph=g) g_hover = bkm.HoverTool(renderers=[gr], tooltips=[('x', '@x'), ('y', '@y'), ('assignment', '@assignment')]) plot.add_tools(g_hover) plot.text(np.mean(x_coords), np.mean(y_coords), text=[cluster.label], text_color='black', text_align='center', text_font_size='10pt') # bkp.show(plot) bkp.save(plot)
def hospital_plot(self): """ Plot hospital locations. .. warning:: This method requires a Google API Key """ map_options = { 'lat': 40.70, 'lng': -73.92, 'map_type': 'roadmap', 'zoom': 10, } plot = bkm.GMapPlot( api_key=keys.GOOGLE_API_KEY, x_range=bkm.Range1d(), y_range=bkm.Range1d(), map_options=bkm.GMapOptions(**map_options), plot_width=400, plot_height=600, ) plot.title.text = 'New York City Hospitals' hospital = bkm.Circle( x='longitude', y='latitude', fill_alpha=0.8, fill_color='#cd5b1b', line_color=None, size=14, ) hospitals = bkm.sources.ColumnDataSource(self.hospitals) plot.add_glyph(hospitals, hospital) hover = bkm.HoverTool() hover.tooltips = [ ('Location', '@name'), ] plot.add_tools( hover, bkm.PanTool(), bkm.WheelZoomTool(), ) bkio.output_file('hospitals.html') bkio.show(plot)
def main() -> None: """メイン処理 Note: from_networkx ではランダム値によりグラフ中のノード位置が決定する。 そのため、 numpy の random seed を固定することで、毎回同じ形のグラフが出力されるようにする。 """ # グラフデータ graph = nx.karate_club_graph() # エッジの色を設定 SAME_CLUB_COLOR, DIFFERENT_CLUB_COLOR = "black", "red" edge_attrs = {} for start_node, end_node, _ in graph.edges(data=True): edge_attrs[(start_node, end_node)] = ( SAME_CLUB_COLOR if graph.nodes[start_node]["club"] == graph.nodes[end_node]["club"] else DIFFERENT_CLUB_COLOR) nx.set_edge_attributes(graph, edge_attrs, "edge_color") # グラフ初期設定 p = bkplotting.figure( tools=("pan,box_zoom,lasso_select,box_select,poly_select" ",tap,wheel_zoom,reset,save,zoom_in"), title="Networkx Integration Demonstration", x_range=(-2.1, 2.1), y_range=(-2.1, 2.1), ) p.add_tools( bkmodels.HoverTool(tooltips=[("index", "@index"), ("club", "@club")])) np.random.seed(0) render = bkgraphs.from_networkx(graph, nx.spring_layout, scale=2, center=(0, 0)) render.node_renderer.glyph = bkmodels.Circle( size=15, fill_color=bkpalettes.Spectral4[0]) render.edge_renderer.glyph = bkmodels.MultiLine(line_color="edge_color", line_alpha=0.6, line_width=2) p.renderers.append(render) # レイアウト layout = bklayouts.layout([p], sizing_mode="stretch_both") bkio.curdoc().add_root(layout)
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 _create_varexp_pie_plt(comptable_cds, n_comps): fig = plotting.figure( plot_width=400, plot_height=400, title="Variance Explained View", tools=["hover,tap,save"], tooltips=[ ("Component ID", " @component"), ("Kappa", "@kappa{0.00}"), ("Rho", "@rho{0.00}"), ("Var. Exp.", "@varexp{0.00}%"), ], ) fig.wedge( x=0, y=1, radius=0.9, start_angle=transform.cumsum("angle", include_zero=True), end_angle=transform.cumsum("angle"), line_color="white", fill_color="color", source=comptable_cds, fill_alpha=0.7, ) fig.axis.visible = False fig.grid.visible = False fig.toolbar.logo = None circle = models.Circle(x=0, y=1, size=150, fill_color="white", line_color="white") fig.add_glyph(circle) return fig
def get_base_plot(prot, title='syn and deg curves'): #print temp_prot.name #print temp_prot.description fig_fit = figure(width=600, height=400, title=title, toolbar_location="above") circle_data_deg_x = [] circle_data_deg_y = [] diamond_data_deg_x = [] diamond_data_deg_y = [] square_data_deg_x = [] square_data_deg_y = [] for x, y, code in zip(prot.X, prot.Y, prot.Ycode): if code == 3: circle_data_deg_x.append(x) circle_data_deg_y.append(y) elif code == 2: diamond_data_deg_x.append(x) diamond_data_deg_y.append(y) elif code == 1: square_data_deg_x.append(x) square_data_deg_y.append(y) source_circle_deg = bkm.ColumnDataSource( data=dict(x=circle_data_deg_x, y=circle_data_deg_y)) source_diamond_deg = bkm.ColumnDataSource( data=dict(x=diamond_data_deg_x, y=diamond_data_deg_y)) source_square_deg = bkm.ColumnDataSource( data=dict(x=square_data_deg_x, y=square_data_deg_y)) fig_fit.scatter(x='x', y='y', source=source_square_deg, marker="square", color='red', size=0, fill_alpha=0.2) square = bkm.Square(x='x', y='y', fill_color='red', size=8, fill_alpha=0.2) square_r = fig_fit.add_glyph(source_or_glyph=source_square_deg, glyph=square) square_hover = bkm.HoverTool(renderers=[square_r], tooltips=[('time', '@x'), ('N', '@y')]) fig_fit.add_tools(square_hover) fig_fit.scatter(x='x', y='y', source=source_diamond_deg, marker="diamond", color='red', size=0, fill_alpha=0.2) diamond = bkm.Diamond(x='x', y='y', fill_color='red', size=12, fill_alpha=0.2) diamond_r = fig_fit.add_glyph(source_or_glyph=source_diamond_deg, glyph=diamond) diamond_hover = bkm.HoverTool(renderers=[diamond_r], tooltips=[('time', '@x'), ('N', '@y')]) fig_fit.add_tools(diamond_hover) fig_fit.scatter(x='x', y='y', source=source_circle_deg, marker="circle", color='red', size=0, fill_alpha=0.2) circle = bkm.Circle(x='x', y='y', fill_color='red', size=8, fill_alpha=0.2) circle_r = fig_fit.add_glyph(source_or_glyph=source_circle_deg, glyph=circle) circle_hover = bkm.HoverTool(renderers=[circle_r], tooltips=[('time', '@x'), ('N', '@y')]) fig_fit.add_tools(circle_hover) circle_data_syn_x = [] circle_data_syn_y = [] diamond_data_syn_x = [] diamond_data_syn_y = [] square_data_syn_x = [] square_data_syn_y = [] complement_Y = 1 - prot.Y for x, y, code in zip(prot.X, complement_Y, prot.Ycode): if code == 3: circle_data_syn_x.append(x) circle_data_syn_y.append(y) #s2.scatter(x,y,marker="circle",color='green',size=8) elif code == 2: diamond_data_syn_x.append(x) diamond_data_syn_y.append(y) #s2.scatter(x,y,marker="diamond",color='green',size=12, fill_alpha=0.2) elif code == 1: square_data_syn_x.append(x) square_data_syn_y.append(y) #s2.scatter(x,y,marker="square",color='green',size=8, fill_alpha=0.2 ) source_circle_syn = bkm.ColumnDataSource( data=dict(x=circle_data_syn_x, y=circle_data_syn_y)) source_diamond_syn = bkm.ColumnDataSource( data=dict(x=diamond_data_syn_x, y=diamond_data_syn_y)) source_square_syn = bkm.ColumnDataSource( data=dict(x=square_data_syn_x, y=square_data_syn_y)) fig_fit.scatter(x='x', y='y', source=source_square_syn, marker="square", color='green', size=0, fill_alpha=0.2) square = bkm.Square(x='x', y='y', fill_color='green', size=8, fill_alpha=0.2) square_r = fig_fit.add_glyph(source_or_glyph=source_square_syn, glyph=square) square_hover = bkm.HoverTool(renderers=[square_r], tooltips=[('time', '@x'), ('N', '@y')]) fig_fit.add_tools(square_hover) fig_fit.scatter(x='x', y='y', source=source_diamond_syn, marker="diamond", color='green', size=0, fill_alpha=0.2) diamond = bkm.Diamond(x='x', y='y', fill_color='green', size=12, fill_alpha=0.2) diamond_r = fig_fit.add_glyph(source_or_glyph=source_diamond_syn, glyph=diamond) diamond_hover = bkm.HoverTool(renderers=[diamond_r], tooltips=[('time', '@x'), ('N', '@y')]) fig_fit.add_tools(diamond_hover) fig_fit.scatter(x='x', y='y', source=source_circle_syn, marker="circle", color='green', size=0, fill_alpha=0.2) circle = bkm.Circle(x='x', y='y', fill_color='green', size=8, fill_alpha=0.2) circle_r = fig_fit.add_glyph(source_or_glyph=source_circle_syn, glyph=circle) circle_hover = bkm.HoverTool(renderers=[circle_r], tooltips=[('time', '@x'), ('N', '@y')]) fig_fit.add_tools(circle_hover) err_y = [] err_x = [] for x, y, yerr in zip(prot.X, prot.Y, prot.Yerr): err_x.append((x, x)) err_y.append((y - yerr, y + yerr)) fig_fit.multi_line(err_x, err_y, color='red', line_dash="4 4") err_y = [] err_x = [] for x, y, yerr in zip(prot.X, complement_Y, prot.Yerr): err_x.append((x, x)) err_y.append((y - yerr, y + yerr)) fig_fit.multi_line(err_x, err_y, color='green', line_dash="4 4") return fig_fit
def main() -> None: """dependencty walker のツリー情報を解析する。 """ FILEPATH = "hoge.txt" df = to_df(FILEPATH) df = df[df["legend2"] != "Missing Module"] np.random.seed(0) graph = nx.from_pandas_edgelist(df, "name", "parent", edge_attr=None, create_using=nx.DiGraph()) nx.set_node_attributes( graph, df.drop_duplicates(subset="name").set_index("name").to_dict("index")) # グラフデータを bokeh 用に変換 render = bkgraphs.from_networkx(graph, nx.spring_layout, scale=1, center=(0, 0)) render.node_renderer.glyph = bkmodels.Circle( size=8, fill_color=bkpalettes.Spectral4[0]) # グラフ初期設定 p = bkplotting.figure( tools=("pan,box_zoom,lasso_select,box_select,poly_select" ",tap,wheel_zoom,reset,save,zoom_in"), title="dependency link", x_range=(-1.1, 1.1), y_range=(-1.1, 1.1), ) tooltips = [ ("name", "@index"), ("legend1", "@legend1"), ("legend2", "@legend2"), ("legend3", "@legend3"), ] p.add_tools(bkmodels.HoverTool(tooltips=tooltips)) p.renderers.append(render) # データ表示データテーブル data_table = bkwidgets.DataTable( source=render.node_renderer.data_source, columns=[ bkwidgets.TableColumn(field=column, title=column) for column in ["index", "legend1", "legend2", "legend3"] ], fit_columns=True, ) dependency_source = bkmodels.ColumnDataSource(df) dependency_table = bkwidgets.DataTable( source=dependency_source, columns=[ bkwidgets.TableColumn(field=column, title=column) for column in ["name", "parent", "legend1", "legend2", "legend3"] ], fit_columns=True, ) # 依存関係の始点と終点を設定するテキストボックス target_text = bkwidgets.TextInput(value="None", title="Target Module") source_text = bkwidgets.TextInput(value="Input Module Name", title="Source Module") cutoff_text = bkwidgets.TextInput(value="3", title="Number of Cutoff") # 実行ボタン 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 execute_button = bkwidgets.Button(label="execute", button_type="success") execute_button.on_click(execute_callback) # 検索結果をクリアするボタン def clear_callback(event) -> None: np.random.seed(0) render = bkgraphs.from_networkx(graph, 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) # p.renderers.pop(0) data_table.source = render.node_renderer.data_source clear_button = bkwidgets.Button(label="clear", button_type="success") clear_button.on_click(clear_callback) # レイアウト execute_button_area = bklayouts.layout([[execute_button, clear_button]], sizing_mode="stretch_width") execute_area = bklayouts.layout( [ target_text, source_text, cutoff_text, execute_button_area, dependency_table ], sizing_mode="stretch_width", ) operation_area = bklayouts.layout([data_table, execute_area], sizing_mode="stretch_both") layout = bklayouts.layout([[p, operation_area]], sizing_mode="stretch_both") bkio.curdoc().add_root(layout)
def plot_conjugate(resolution=100, pixelsize=350): ######### # SOURCES ######### # a source is made of columns with equal lengths # all the primal and dual ingredients go to their respective source primal_source = ColumnDataSource(data=dict( xx=[], ff=[], grad=[], fcc=[], idgopt=[], gopt=[], gzeros=[])) # note to self : gopt is also the gradient of f** dual_source = ColumnDataSource( data=dict(gg=[], fc=[], idxopt=[], xopt=[], xzeros=[])) # for images it's a bit more complex. # each column has length 1. # The image itself is an element # along with coordinates and width images_dict = {'gxminusf': [], 'gxminusfc': [], 'youngs': []} source2d = ColumnDataSource(data={ **images_dict, 'x0': [], 'delta_x': [], 'g0': [], 'delta_g': [] }) image_titles = { 'gxminusf': 'g.x - f(x) (maximize on x to get f*)', 'gxminusfc': 'g.x - f*(g) (maximize on g to get f**)', 'youngs': "Young's duality gap f(x)+f*(g)-g.x" } # COLORS palette = palettes.Category10_10 # palettes.Colorblind7 primalcolor = palette[0] # blue dualcolor = palette[1] # orange gapcolor = palette[2] # green tangentcolor = palette[3] # red heightcolor = palette[4] # purple monochromemaps = colormap2hexpalette(['Purples', 'Purples', 'Greens']) ######## # GLYPHS ######## # global options for the figures opts = dict(plot_width=pixelsize, plot_height=pixelsize) # plot the primal function primalfig = plotting.figure( title='Primal f(x)', **opts, tools='', name='primalfig', # tools='pan,wheel_zoom', active_scroll='wheel_zoom', x_axis_label='x', y_axis_label='y') primalfig.line('xx', 'fcc', source=primal_source, line_width=3, color=primalcolor, alpha=.5) primal_line = primalfig.line('xx', 'ff', source=primal_source, line_width=3, color=primalcolor) primalfig.y_range.renderers = primalfig.x_range.renderers = [primal_line] # temporary hovering glyphs primalpoint = primalfig.circle('x', 'y', size=10, color=tangentcolor, source=ColumnDataSource(dict(x=[], y=[]))) primaltangent = primalfig.line('x', 'y', line_width=2, color=tangentcolor, source=ColumnDataSource(dict(x=[], y=[]))) primaldroite = primalfig.line('x', 'y', line_width=2, color='black', source=ColumnDataSource(dict(x=[], y=[]))) primalheight = primalfig.line('x', 'y', line_width=3, color=heightcolor, line_cap='round', source=ColumnDataSource(dict(x=[], y=[]))) primalgap = primalfig.line('x', 'y', line_width=3, color=gapcolor, line_dash='dotted', source=ColumnDataSource(dict(x=[], y=[]))) # plot the dual function dualfig = plotting.figure(title='Dual f*(g)', **opts, tools='', name='dualfig', x_axis_label='g', y_axis_label='y') dual_line = dualfig.line('gg', 'fc', source=dual_source, line_width=3, color=dualcolor) dualfig.y_range.renderers = dualfig.x_range.renderers = [dual_line] # temporary hovering glyphs dualpoint = dualfig.circle('g', 'y', size=10, color=tangentcolor, alpha=.7, source=ColumnDataSource(dict(g=[], y=[]))) dualtangent = dualfig.line('g', 'y', line_width=2, color=tangentcolor, source=ColumnDataSource(dict(g=[], y=[]))) dualdroite = dualfig.line('g', 'y', line_width=2, color='black', source=ColumnDataSource(dict(g=[], y=[]))) dualheight = dualfig.line('g', 'y', line_width=3, color=heightcolor, line_cap='round', source=ColumnDataSource(dict(g=[], y=[]))) dualgap = dualfig.line('g', 'y', line_width=3, color=gapcolor, line_dash='dotted', source=ColumnDataSource(dict(g=[], y=[]))) # highlight lines x=0 and y=0 in primal and dual plots for fig in [primalfig, dualfig]: for dimension in [0, 1]: grid0 = models.Grid(dimension=dimension, grid_line_color='black', ticker=models.FixedTicker(ticks=[0])) fig.add_layout(grid0) # displaying information on primal plot # infolabel = models.Label(text='', x=30, y=100, x_units='screen', y_units='screen') # fig1.add_layout(infolabel) # plot gradients gradientfig = plotting.figure(title='Derivatives', **opts, tools='', x_axis_label='x', y_axis_label='g') gradientfig.line('xx', 'gopt', source=primal_source, color=primalcolor, alpha=.5, line_width=3) gradientfig.line('xx', 'grad', source=primal_source, color=primalcolor, line_width=3) # IMAGES images = [ plotting.figure(**opts, tools='', x_axis_label='x', y_axis_label='g') for _ in range(3) ] for fig, name, colormap in zip(images, image_titles, monochromemaps): fig.title.text = image_titles[name] fig.image(image=name, x='x0', dw='delta_x', y='g0', dh='delta_g', alpha=.7, source=source2d, palette=colormap) lw = 2 images[0].line('xx', 'gzeros', source=primal_source, color=primalcolor, line_width=lw, legend_label='-f(x)') images[0].line('xopt', 'gg', source=dual_source, color=dualcolor, line_width=lw, legend_label='f*(g)') images[1].line('xzeros', 'gg', source=dual_source, color=dualcolor, line_width=lw, legend_label='-f*(g)') images[1].line('xx', 'gopt', source=primal_source, color=primalcolor, line_width=lw, legend_label='f(x)') images[2].line('xx', 'gzeros', source=primal_source, color=primalcolor, line_width=lw, legend_label='f(x)') images[2].line('xzeros', 'gg', source=dual_source, color=dualcolor, line_width=lw, legend_label='f*(g)') images[2].line('xopt', 'gg', source=dual_source, color='black', alpha=.5, line_width=lw, legend_label='0') for fig in images: fig.legend.background_fill_alpha = .1 fig.legend.location = 'top_left' # temporary hover glyphs gxcircle = models.Circle(x='x', y='g', size=10, fill_color=tangentcolor, line_color=tangentcolor, fill_alpha=.7) gxline = models.Line(x='x', y='g', line_width=lw, line_color=tangentcolor) hline = images[0].add_glyph(ColumnDataSource(data=dict(x=[], g=[])), gxline) hpoint = images[0].add_glyph(ColumnDataSource(data=dict(x=[], g=[])), gxcircle) vline = images[1].add_glyph(ColumnDataSource(data=dict(x=[], g=[])), gxline) vpoint = images[1].add_glyph(ColumnDataSource(data=dict(x=[], g=[])), gxcircle) for fig in [gradientfig, images[2]]: fig.add_glyph(hpoint.data_source, gxcircle) fig.add_glyph(vpoint.data_source, gxcircle) ############## # INTERACTIONS ############## hover_source_dict = { 'primalpoint': primalpoint.data_source, 'primaltangent': primaltangent.data_source, 'primaldroite': primaldroite.data_source, 'primalheight': primalheight.data_source, 'primalgap': primalgap.data_source, 'dualpoint': dualpoint.data_source, 'dualtangent': dualtangent.data_source, 'dualdroite': dualdroite.data_source, 'dualheight': dualheight.data_source, 'dualgap': dualgap.data_source, 'hpoint': hpoint.data_source, 'vpoint': vpoint.data_source, 'hline': hline.data_source, 'vline': vline.data_source, } js_args = { 'primal': primal_source, 'dual': dual_source, 'primalfig': primalfig, 'dualfig': dualfig, **hover_source_dict } # INPUT FUNCTION # complicated without going full blown JS inputfunc = bokeh.models.TextInput(title='f(x) =', value='x^4', name='functionInputBox') lower_x = bokeh.models.TextInput(title='minimum x =', value='-1', name='lowerXInput') upper_x = bokeh.models.TextInput(title='maximum x =', value='1', name='upperXInput') textinput_js = CustomJS(name='functionRefreshScript', args=dict(inputfunc=inputfunc, lower_x=lower_x, upper_x=upper_x, resolution=resolution, primal=primal_source, dual=dual_source, source2d=source2d, primalfig=primalfig, dualfig=dualfig), code=""" let xmin = +lower_x.value; let xmax = +upper_x.value; // clean all arrays for (let sourceData of [primal.data, dual.data]){ for (let name in sourceData){ sourceData[name] = []; } } function linspace(min,max,n) { let step=(max-min)/(n-1); let out = []; for (let i=0; i<n; i++) { out.push(min + i * step); } return out; } let xx = primal.data.xx = linspace(xmin,xmax,resolution); function primalFunc(x) { let out; try { out = math.evaluate(inputfunc.value, {'x':x}); } catch (e) { return x; } if (out == undefined) return x; return out; } let ff = primal.data.ff = xx.map(primalFunc); try{ let inputDerivative = math.derivative(inputfunc.value, 'x'); function primalDerivative(x) { let out; try { out = inputDerivative.evaluate({'x': x}); } catch (e) { return x; } if (out == undefined) return x; return out; } primal.data.grad = xx.map(primalDerivative); } catch (e) { primal.data.grad = []; primal.data.grad.push((ff[1]-ff[0])/(xx[1]-xx[0])); for (let i=0; i<xx.length-1; i++){ primal.data.grad.push((ff[i+1]-ff[i])/(xx[i+1]-xx[i])); } } let gmax = Math.max(...primal.data.grad); let gmin = Math.min(...primal.data.grad); let delta_g = 0.1*(gmax-gmin); gmax += delta_g; gmin -= delta_g; let gg = linspace(gmin,gmax,resolution); function customMax(array) { // return [max, argmax] return array.map((x, i) => [x, i]).reduce((r, a) => (a[0] > r[0] ? a : r)); } function getConjugate(xx,gg,ff){ let gxminusf = []; let d = {gg:gg, fc:[], idxopt:[], xopt:[], xzeros:[]}; for (let i=0; i<resolution; i++){ let rowi = []; for(let j=0; j<resolution; j++){ rowi.push(gg[i]*xx[j] - ff[j]) } gxminusf.push(rowi); let [max, argmax] = customMax(rowi); d.fc.push(max); d.idxopt.push(argmax) d.xopt.push(xx[argmax]); d.xzeros.push(0); } return [gxminusf, d]; } let [gxminusf, dualdata] = getConjugate(xx,gg,ff); dual.data = dualdata; dual.change.emit(); // CONVEX ENVELOPE let [gxminusfc, envelopedata] = getConjugate(gg, xx, dual.data.fc) primal.data.fcc = envelopedata.fc; primal.data.idgopt = envelopedata.idxopt; primal.data.gopt = envelopedata.xopt; primal.data.gzeros = envelopedata.xzeros; primal.change.emit(); // SOURCE 2D let youngs = []; let rowi; for (let i =0; i<resolution; i++) { rowi = []; for (let j=0; j<resolution; j++) { rowi.push(dual.data.fc[i]+primal.data.ff[j] - gg[i]*xx[j]); } youngs.push(rowi); } source2d.data.gxminusf = [gxminusf]; source2d.data.gxminusfc = [gxminusfc]; source2d.data.youngs = [youngs]; source2d.data.x0 = [xmin]; source2d.data.delta_x = [xmax - xmin]; source2d.data.g0 = [gmin]; source2d.data.delta_g = [gmax - gmin]; source2d.change.emit(); """) for textinput in [inputfunc, lower_x, upper_x]: textinput.js_on_change('value', textinput_js) # RADIO BUTTON to select function function_samples = { 'x^4': ('x^4', -1, 1), 'x^4 + 4 x^3': ('x^4 + 4 x^3', -1, 1), 'absolute value': ('max(x, -x)', -1, 1), 'quadratic': ('1/2 x^2', -1, 1), 'x^2 - cos(2 x)': ('x^2 - cos(2 x)', -5, 5), 'sin(x)': ('sin(x)', -3.14, 0), 'x sin(1/x)': ('x sin(1/x)', -1, 1), 'Entropy': ('x log(x) + (1-x) log(1-x)', 0.00001, 1 - 0.00001), 'Hinge': ('max(0, 1-x)', -2, 2), 'Squared Hinge': ('max(0, 1-x)^2', -2, 2), } radio_function_selection = models.RadioButtonGroup(labels=list( function_samples.keys()), active=0) radio_function_selection.js_on_change( 'active', CustomJS(args=dict(function_samples=function_samples, inputfunc=inputfunc, lower_x=lower_x, upper_x=upper_x, textinput_js=textinput_js), code=""" let active_button = cb_obj.active; [inputfunc.value, lower_x.value, upper_x.value] = function_samples[cb_obj.labels[ active_button]].map(String); textinput_js.execute(); """)) # HOVERING # hover over primal plot primalhoverjs = CustomJS(args=js_args, code=""" let x0 = cb_obj.x; let y0 = cb_obj.y; let xx = primal.data['xx']; let i = xx.findIndex(x => x >=x0); if (i==-1){i = xx.length-1}; let x1 = xx[i]; let y1 = primal.data['fcc'][i]; primalpoint.data['x'] = [x1]; primalpoint.data['y'] = [y1]; primalpoint.change.emit(); primalheight.data['x'] = [x1,x1]; primalheight.data['y'] = [y0,y1] primalheight.change.emit(); let j = primal.data['idgopt'][i]; let gg = dual.data['gg']; let g1 = gg[j]; let fc1 = dual.data['fc'][j]; dualpoint.data['g'] = [g1]; dualpoint.data['y'] = [fc1]; dualpoint.change.emit(); dualheight.data['g'] = [g1,g1]; dualheight.data['y'] = [x0*g1 - y0, fc1]; dualheight.change.emit(); dualtangent.data['g'] = [gg[0]-10, gg[gg.length-1]+10]; dualtangent.data['y'] = dualtangent.data['g'].map(g => fc1 + x1*(g-g1)); dualtangent.change.emit(); dualdroite.data.g = dualtangent.data.g; dualdroite.data.y = dualdroite.data.g.map(g => x0*g - y0); dualdroite.change.emit(); vpoint.data['x'] = [x1]; vpoint.data['g'] = [g1]; vpoint.change.emit(); vline.data['x'] = [x1, x1]; vline.data['g'] = [gg[0], gg[gg.length - 1]]; vline.change.emit(); """) # hover over dual plot dualhoverjs = CustomJS(args=js_args, code=""" let g0 = cb_obj.x; let y0 = cb_obj.y; let gg = dual.data['gg']; let j = gg.findIndex(g => g >=g0); if (j==-1){j = gg.length-1}; let g1 = gg[j]; let fc1 = dual.data['fc'][j]; dualpoint.data['g'] = [g1]; dualpoint.data['y'] = [fc1]; dualpoint.change.emit(); dualheight.data['g'] = [g1, g1]; dualheight.data['y'] = [y0, fc1]; dualheight.change.emit(); let i = dual.data['idxopt'][j]; let xx = primal.data['xx']; let x1 = xx[i]; let ff1 = primal.data['ff'][i]; primalpoint.data['x'] = [x1]; primalpoint.data['y'] = [ff1]; primalpoint.change.emit(); primaltangent.data['x'] = [xx[0]-10, xx[xx.length-1]+10]; primaltangent.data['y'] = primaltangent.data['x'].map(x => g0*(x-x1) + ff1); primaltangent.change.emit(); primaldroite.data.x = primaltangent.data.x; primaldroite.data.y = primaldroite.data.x.map(x => g0 * x - y0); primaldroite.change.emit(); primalheight.data['x'] = [x1, x1]; primalheight.data['y'] = [g0*x1 - y0, ff1]; primalheight.change.emit(); hpoint.data['x'] = [x1]; hpoint.data['g'] = [g1]; hpoint.change.emit(); hline.data['x'] = [xx[0], xx[xx.length - 1]]; hline.data['g'] = [g1, g1]; hline.change.emit(); """) # Hover over X,G plots code_get_xg = """ let x0 = cb_obj.x; let g0 = cb_obj.y; let xx = primal.data['xx']; let gg = dual.data['gg']; let i = xx.findIndex(x => x >=x0); if (i==-1){i = xx.length-1}; let x1 = xx[i]; let ff1 = primal.data['ff'][i]; primalpoint.data['x'] = [x1]; primalpoint.data['y'] = [ff1]; primalpoint.change.emit(); let j = gg.findIndex(g => g >=g0); if (j==-1){j = gg.length-1}; let g1 = gg[j]; let fc1 = dual.data['fc'][j]; dualpoint.data['g'] = [g1]; dualpoint.data['y'] = [fc1]; dualpoint.change.emit(); """ # hover over g.x-f(x) primalimage_js = CustomJS(args=js_args, code=code_get_xg + """ hpoint.data['x'] = [x1]; hpoint.data['g'] = [g1]; hpoint.change.emit(); hline.data['x'] = [xx[0], xx[xx.length - 1]]; hline.data['g'] = [g1, g1]; hline.change.emit(); primaltangent.data['x'] = [xx[0], xx[xx.length-1]]; primaltangent.data['y'] = primaltangent.data['x'].map(x => g1*x); primaltangent.change.emit(); primalheight.data['x'] = [x1,x1]; primalheight.data['y'] = [g1*x1, ff1]; primalheight.change.emit(); dualheight.data['g'] = [g1, g1]; dualheight.data['y'] = [0, g1*x1-ff1]; dualheight.change.emit(); dualgap.data['g'] = [g1, g1]; dualgap.data['y'] = [g1*x1-ff1, fc1]; dualgap.change.emit(); """) # hover over g.x-f*(g) dualimage_js = CustomJS(args=js_args, code=code_get_xg + """ vpoint.data['x'] = [x1]; vpoint.data['g'] = [g1]; vpoint.change.emit(); vline.data['x'] = [x1, x1]; vline.data['g'] = [gg[0], gg[gg.length - 1]]; vline.change.emit(); dualtangent.data['g'] = [gg[0], gg[gg.length-1]]; dualtangent.data['y'] = dualtangent.data['g'].map(g => x1*g); dualtangent.change.emit(); dualheight.data['g'] = [g1,g1]; dualheight.data['y'] = [fc1, g1*x1]; dualheight.change.emit(); primalheight.data['x'] = [x1, x1]; primalheight.data['y'] = [0, g1*x1-fc1]; primalheight.change.emit(); primalgap.data['x'] = [x1, x1]; primalgap.data['y'] = [g1*x1-fc1, ff1]; primalgap.change.emit(); """) hover_events = [bokeh.events.MouseMove, bokeh.events.Tap] for event in hover_events: primalfig.js_on_event(event, primalhoverjs) dualfig.js_on_event(event, dualhoverjs) images[0].js_on_event(event, primalimage_js) images[1].js_on_event(event, dualimage_js) # Remove all temporary glyphs on MouseLeave jsleave = CustomJS(args={'sourcelist': list(hover_source_dict.values())}, code=""" for(let source of sourcelist){ for(let key in source.data){ source.data[key]=[]; } source.change.emit(); } """) for fig in [primalfig, dualfig, gradientfig] + images: fig.js_on_event(bokeh.events.MouseLeave, jsleave) bigfig = layouts.column([ layouts.row([inputfunc, lower_x, upper_x]), radio_function_selection, layouts.gridplot([ [primalfig, dualfig, gradientfig], images, ], toolbar_location=None) ]) return bigfig
def makeComparison(df, title, Compare1, Compare2, drawLine): df["longitude_id"] = [ df["longitude_" + Compare1][i] if df["longitude_" + Compare1][i] == df["longitude_" + Compare2][i] else np.nan for i in range(len(df)) ] df["latitude_id"] = [ df["latitude_" + Compare1][i] if df["latitude_" + Compare1][i] == df["latitude_" + Compare2][i] else np.nan for i in range(len(df)) ] scale = 50 offsetX = 0.5 if np.max(np.array(df["latitude_" + Compare1])) >= np.max( np.array(df["latitude_" + Compare2])): if math.ceil(np.max(np.array(df["latitude_" + Compare1]))) == np.max( np.array(df["latitude_" + Compare1])): offsetYup = 0.5 else: offsetYup = 0 if math.floor(np.min(np.array(df["latitude_" + Compare1]))) == np.min( np.array(df["latitude_" + Compare1])): offsetYdown = 0.5 else: offsetYdown = 0 else: if math.ceil(np.max(np.array(df["latitude_" + Compare2]))) == np.max( np.array(df["latitude_" + Compare2])): offsetYup = 0.5 else: offsetYup = 0 if math.floor(np.min(np.array(df["latitude_" + Compare2]))) == np.min( np.array(df["latitude_" + Compare2])): offsetYdown = 0.5 else: offsetYdown = 0 if np.max(np.array(df["latitude_" + Compare1])) >= np.max( np.array(df["latitude_" + Compare2])): maxLat = math.ceil(np.max(np.array( df["latitude_" + Compare1]))) + offsetYup maxLong = math.ceil(np.max(np.array( df["longitude_" + Compare1]))) + offsetX minLat = math.floor(np.min(np.array( df["latitude_" + Compare1]))) - offsetYdown minLong = math.floor(np.min(np.array( df["longitude_" + Compare1]))) - offsetX else: maxLat = math.ceil(np.max(np.array( df["latitude_" + Compare2]))) + offsetYup maxLong = math.ceil(np.max(np.array( df["longitude_" + Compare2]))) + offsetX minLat = math.floor(np.min(np.array( df["latitude_" + Compare2]))) - offsetYdown minLong = math.floor(np.min(np.array( df["longitude_" + Compare2]))) - offsetX diffLat = int(maxLat - minLat) diffLong = int(maxLong - minLong) source = bkm.ColumnDataSource(data=df) r = bkp.figure(title=title, width=diffLong * scale * 3, height=diffLat * scale * 4, x_range=(minLong, maxLong), y_range=(minLat, maxLat), tools=['pan', 'wheel_zoom']) r.xaxis.axis_label = 'Longitude [°]' r.yaxis.axis_label = 'Latitude [°]' g1 = bkm.Circle(x="longitude_" + Compare1, y="latitude_" + Compare1, fill_color='red', size=6, fill_alpha=0.4, line_color='darkred') g1_r = r.add_glyph(source_or_glyph=source, glyph=g1) g1_hover = bkm.HoverTool(renderers=[g1_r], tooltips=[("toponym", "@toponym")]) g2 = bkm.Circle(x="longitude_" + Compare2, y="latitude_" + Compare2, fill_color='blue', size=6, fill_alpha=0.4, line_color='darkblue') g2_r = r.add_glyph(source_or_glyph=source, glyph=g2) g2_hover = bkm.HoverTool(renderers=[g2_r], tooltips=[("toponym", "@toponym")]) g3 = bkm.Circle(x="longitude_" + "id", y="latitude_" + "id", fill_color='grey', size=6, fill_alpha=0.4, line_color='grey') g3_r = r.add_glyph(source_or_glyph=source, glyph=g3) g3_hover = bkm.HoverTool(renderers=[g3_r], tooltips=[("toponym", "@toponym")]) if drawLine: g_l = bkm.Segment(x0="longitude_" + Compare1, y0="latitude_" + Compare1, x1="longitude_" + Compare2, y1="latitude_" + Compare2, line_color="grey", line_width=1) r.add_glyph(source_or_glyph=source, glyph=g_l) r.add_tools(g1_hover, g2_hover) df.drop(["longitude_id", "latitude_id"], axis=1, inplace=True) return r
def __init__(self): try: self.api_key = keys.GOOGLE_API_KEY except NameError: self.api_key = None self.data = None self.data_url = ('https://timothyhelton.github.io/assets/data/' 'nyc_subway_locations.csv') self.data_types = { 'division': str, 'line': str, 'name': str, 'latitude': np.float64, 'longitude': np.float64, 'route_1': str, 'route_2': str, 'route_3': str, 'route_4': str, 'route_5': str, 'route_6': str, 'route_7': str, 'route_8': str, 'route_9': str, 'route_10': str, 'route_11': str, 'entrance_type': str, 'entry': str, 'exit_only': str, 'vending': str, 'staffing': str, 'staff_hours': str, 'ada': str, 'ada_notes': str, 'free_crossover': str, 'north_south_street': str, 'east_west_street': str, 'corner': str, 'entrance_latitude': np.float64, 'entrance_longitude': np.float64, 'station_location': str, 'entrance_location': str, } self.hosp = locations.Hospitals() self.hosp_dist = None self.hosp_prox = None self.hosp_stations = None self.map_glyph_hospital = bkm.Circle( x='longitude', y='latitude', fill_alpha=0.8, fill_color='#cd5b1b', line_color=None, size=14, ) self.map_glyph_subway = bkm.Diamond( x='longitude', y='latitude', fill_color='#3062C8', line_color=None, size=10, ) self.map_options = { 'lat': 40.70, 'lng': -73.92, 'map_type': 'roadmap', 'zoom': 10, } self.map_plot = bkm.GMapPlot( api_key=self.api_key, x_range=bkm.Range1d(), y_range=bkm.Range1d(), map_options=bkm.GMapOptions(**self.map_options), plot_width=400, plot_height=600, ) self.trains = None self.load_data()
tools="reset, save, pan, wheel_zoom") lines_source = models.ColumnDataSource( get_plot_data(date_select.value, extract_race_number(race_select.value), field_select.value, event_select.value, (start_slider.value, end_slider.value))) lines = models.MultiLine(xs='Secs', ys=field_select.value, line_color='Colors') data_plot.add_glyph(lines_source, lines) # plot mark data mark_source = models.ColumnDataSource( get_mark_data(date_select.value, extract_race_number(race_select.value))) circle = models.Circle(x="Lon", y="Lat", size=7, fill_color="magenta", fill_alpha=0.4, line_color=None) race_map.add_glyph(mark_source, circle) # plot boat data boat_source = models.ColumnDataSource( get_boat_data(date_select.value, extract_race_number(race_select.value), event_select.value, (start_slider.value, end_slider.value), frequency_slider.value)) boat_glyph = models.Patches(xs='Lons', ys='Lats', fill_color='Color', fill_alpha=0.7, line_color=None)
map_figure.title.text_font_size = "24px" map_figure.xaxis.axis_label = "Longitude" map_figure.yaxis.axis_label = "Latitude" # first glyphs, Seattle city data g1 = bkm.CircleX(x='longitude', y='latitude', size=20, line_color='black', fill_alpha=0.5) g1_render = map_figure.add_glyph(source_or_glyph=source_obs, glyph=g1) # 2nd glyph, CRD data collected g2 = bkm.Circle(x='longitude', y='latitude', size=20, fill_alpha=0, line_color=transform('pred_class', color_mapper_crd)) g2_render = map_figure.add_glyph(source_or_glyph=source_crd, glyph=g2) g2_hover = bkm.HoverTool(renderers=[g2_render], tooltips=tooltip_html) map_figure.add_tools(g2_hover) map_figure.add_tile(STAMEN_TONER) #map_figure.add_layout(color_bar, 'right') # useful for multi-class """ color_bar_label = Label(x=-40, y=cfg.PROFILE_DETAIL_PLOT_HEIGHT / 2 - 50, x_units='screen', y_units='screen', text='Test Labeling', text_align='center', render_mode='canvas',
def visualize_clusters(clusters_path, x_idx, y_idx, x_label, y_label, title, plot_output_path=None): """Visualize cluster in 2D space. :param str clusters_path: Path to grouping results JSON file. :param str plot_output_path: Path where to save interactive HTML plot. :param str title: Plot title. :param int x_idx: Index of x dimension within peak. :param int y_idx: Index of y dimension within peak. :param str x_label: X axis label. :param str y_label: Y axis label. :return: None :rtype: :py:obj:`None` """ TOOLS = "pan,box_zoom,box_select,resize,reset,wheel_zoom,save" if plot_output_path is None: plot_output_path = clusters_path + ".html" bkp.output_file(plot_output_path) else: bkp.output_file(plot_output_path) plot = bkp.figure(tools=TOOLS, title=title, toolbar_location="below") plot.title.text_font_size = "15pt" plot.title.align = "center" plot.xaxis.axis_label, plot.yaxis.axis_label = "{}, ppm".format( x_label), "{}, ppm".format(y_label) plot.xaxis.axis_label_text_font_size = "15pt" plot.yaxis.axis_label_text_font_size = "15pt" with open(clusters_path, "r") as infile: clusters_list = json.load(infile) for cluster in clusters_list: color = "#%02X%02X%02X" % (random_color(), random_color(), random_color()) cluster_x_coords = [] cluster_y_coords = [] cluster_assignments = [] for peak in cluster["peaks"]: cluster_x_coords.append(peak["dimensions"][x_idx]) cluster_y_coords.append(peak["dimensions"][y_idx]) cluster_assignments.append(peak["assignment"]) cluster_x_centroid = mean(cluster_x_coords) cluster_y_centroid = mean(cluster_y_coords) source = bkp.ColumnDataSource( data=dict(x=cluster_x_coords, y=cluster_y_coords, assignment=cluster_assignments)) for _ in cluster["peaks"]: if cluster["label"] == -1: g = bkm.CircleX(x='x', y='y', line_color='#6666ee', fill_color='black', fill_alpha=0.5, size=5) else: g = bkm.Circle(x='x', y='y', line_color='#6666ee', fill_color=color, fill_alpha=0.5, size=10) gr = plot.add_glyph(source_or_glyph=source, glyph=g) g_hover = bkm.HoverTool(renderers=[gr], tooltips=[('x', '@x'), ('y', '@y'), ('assignment', '@assignment')]) plot.add_tools(g_hover) plot.text(x=cluster_x_centroid, y=cluster_y_centroid, text=[cluster["label"]], text_color='black', text_align='center', text_font_size='10pt') if cluster["label"] >= 0: x_tolerance = cluster["stds"][x_label] * 4 y_tolerance = cluster["stds"][y_label] * 4 plot.ellipse(x=cluster_x_centroid, y=cluster_y_centroid, width=x_tolerance, height=y_tolerance, fill_color=None) print("saving plot to:", os.path.abspath(plot_output_path)) bkp.save(plot)