def __init__(self, kind="scatter", **kwargs): """Useful Chart kwargs: Parameters: xlabel (str): override the automatic x_axis_label. Default is None. ylabel (str): override the automatic y_axis_label. Default is None. callback (str): clicking on a point will link to the given HTML address. `@<IdProperty>` can be used as placeholder for the point id (e.g. Compound_Id). Default is None.""" self.data = {} self.kwargs = kwargs self.kind = kind self.height = kwargs.get("height", 450) self.title = kwargs.get("title", "Scatter Plot") self.position = kwargs.get("position", kwargs.get("pos", "top_left")) self.series_counter = 0 self.tools_added = False tools = ["pan", "wheel_zoom", "box_zoom", "reset", "resize", "save"] self.callback = kwargs.get("callback", None) if self.callback is not None: tools.append("tap") self.plot = figure(plot_height=self.height, title=self.title, tools=tools) self.plot.axis.axis_label_text_font_size = "14pt" self.plot.axis.major_label_text_font_size = "14pt" self.plot.title.text_font_size = "18pt" if self.callback is not None: taptool = self.plot.select(type=TapTool) taptool.callback = OpenURL(url=self.callback)
def make_plot_bio_overview(df, x_val, label_bio_overview, tooltips_bio_overview): hov_bio_overview = HoverTool(tooltips=tooltips_bio_overview, mode='mouse') p_bio_overview = figure(y_range=sorted(df.name, reverse=True), title=label_bio_overview + ' by Bioregion', width=fig_width, height=fig_height, x_axis_label=label_bio_overview, y_axis_label="Bioregion", tools=[ hov_bio_overview, TapTool(), BoxZoomTool(), WheelZoomTool(), SaveTool(), ResetTool() ]) p_bio_overview.hbar(y='name', height=0.9, left=0, right=x_val, color=primary_color, source=df) p_bio_overview.xaxis.major_label_orientation = x_angle p_bio_overview.xgrid.grid_line_color = None p_bio_overview.ygrid.grid_line_color = '#BFBFBF' p_bio_overview.x_range.start = 0 p_bio_overview.yaxis.minor_tick_line_color = None p_bio_overview.xaxis[0].formatter = NumeralTickFormatter(format="0") p_bio_overview_url = "https://www.antweb.org/bioregion.do?name=@name" taptoo1__bio_overview = p_bio_overview.select(type=TapTool) taptoo1__bio_overview.callback = OpenURL(url=p_bio_overview_url) return p_bio_overview
def chart_remaining_assignees(self, stats_data): self.log.info('Generating graph about remaining effort per assignee') plot_values, total_metric = self.get_points_per_assignee(stats_data) dat = pd.DataFrame(plot_values, columns=['entity', 'value', 'jira_url']) source = self.get_remaining_source(dat) # Declare tools hover = HoverTool( tooltips=[ ('Assignee:', '@x_values'), ('Points:', '@y_values') ] ) plot = figure( plot_width=600 , plot_height=300 , x_axis_label='Assignee' , y_axis_label=self.config.get_config_value('stats_metric') , title='Remaining ' + self.config.get_config_value('stats_metric') + ' per Jira Assignee (Total: ' + str( total_metric) + ')' , x_range=FactorRange(factors=list(dat.entity)) , tools=['save', 'pan', 'box_zoom', 'reset', hover, 'tap'] ) taptool = plot.select(type=TapTool) taptool.callback = OpenURL(url='@jira_url') plot.vbar(source=source, x='x_values', top='y_values', bottom=0, width=0.3, color='blue') return plot
def __init__(self, scheduler, width=600, **kwargs): with log_errors(): self.last = 0 self.scheduler = scheduler self.source = ColumnDataSource({'nprocessing': [1, 2], 'nprocessing-half': [0.5, 1], 'nprocessing-color': ['red', 'blue'], 'nbytes': [1, 2], 'nbytes-half': [0.5, 1], 'worker': ['a', 'b'], 'y': [1, 2], 'nbytes-color': ['blue', 'blue'], 'bokeh_address': ['', '']}) processing = figure(title='Tasks Processing', tools='resize', id='bk-nprocessing-plot', width=int(width / 2), **kwargs) processing.rect(source=self.source, x='nprocessing-half', y='y', width='nprocessing', height=1, color='nprocessing-color') processing.x_range.start = 0 nbytes = figure(title='Bytes stored', tools='resize', id='bk-nbytes-worker-plot', width=int(width / 2), **kwargs) nbytes.rect(source=self.source, x='nbytes-half', y='y', width='nbytes', height=1, color='nbytes-color') nbytes.xaxis[0].formatter = NumeralTickFormatter(format='0.0 b') nbytes.xaxis.major_label_orientation = -math.pi / 12 nbytes.x_range.start = 0 for fig in [processing, nbytes]: fig.xaxis.minor_tick_line_alpha = 0 fig.yaxis.visible = False fig.ygrid.visible = False tap = TapTool(callback=OpenURL(url='http://@bokeh_address/')) fig.add_tools(tap) fig.toolbar.logo = None fig.toolbar_location = None fig.yaxis.visible = False hover = HoverTool() hover.tooltips = "@worker : @nprocessing tasks. Click for worker page" hover.point_policy = 'follow_mouse' processing.add_tools(hover) hover = HoverTool() hover.tooltips = "@worker : @nbytes bytes. Click for worker page" hover.point_policy = 'follow_mouse' nbytes.add_tools(hover) self.processing_figure = processing self.nbytes_figure = nbytes processing.y_range = nbytes.y_range self.root = row(nbytes, processing, sizing_mode='scale_width')
def plot_map(self): today = self.df.groupby('location').last() today['size']=today.C/today.C.max()*50+5 wgs84_to_web_mercator(today) tile_provider = get_provider(CARTODBPOSITRON) p = figure(plot_width=900, plot_height=600, #x_range=x_range, y_range=y_range, #x_range=(today.long.min(), today.long.max()), y_range=(today.lat.min(), today.long.max()), x_axis_type="mercator", y_axis_type="mercator", tools='tap') p.add_tile(tile_provider) p.circle(x="x", y="y", size="size", fill_color="blue", fill_alpha=0.5, source=today) htool = HoverTool( tooltips=[ ("Location", "@location"), ("Confirmed", "@C"), ("Recovered", "@R"), ("Deaths", "@D") ] ) wzt = WheelZoomTool() p.add_tools(htool) p.add_tools(wzt) p.toolbar.active_scroll = wzt url = "/plot/@location" taptool = p.select(type=TapTool) taptool.callback = OpenURL(url=url, same_tab=True) return components(p)
def __init__(self, scheduler, **kwargs): with log_errors(): self.scheduler = scheduler self.source = ColumnDataSource({'occupancy': [0, 0], 'worker': ['a', 'b'], 'x': [0.0, 0.1], 'y': [1, 2], 'ms': [1, 2], 'color': ['red', 'blue'], 'bokeh_address': ['', '']}) fig = figure(title='Occupancy', tools='', id='bk-occupancy-plot', x_axis_type='datetime', **kwargs) rect = fig.rect(source=self.source, x='x', width='ms', y='y', height=1, color='color') rect.nonselection_glyph = None fig.xaxis.minor_tick_line_alpha = 0 fig.yaxis.visible = False fig.ygrid.visible = False # fig.xaxis[0].formatter = NumeralTickFormatter(format='0.0s') fig.x_range.start = 0 tap = TapTool(callback=OpenURL(url='http://@bokeh_address/')) hover = HoverTool() hover.tooltips = "@worker : @occupancy s." hover.point_policy = 'follow_mouse' fig.add_tools(hover, tap) self.root = fig
def graph_abs_magnitude(abs_mag=None, velocity=None): """Create Bokeh Scatter Plot.""" if len(abs_mag) != len(velocity): raise UnknownAxisException if abs_mag == None and velocity == None: abs_mag = [] velocity = [] here = os.path.abspath(__file__) graph_file_path = os.path.join(os.path.dirname(os.path.dirname(here)), "static/abs_magnitude.html") output_file(graph_file_path) p = figure(title="Brightness and Velocity", tools="tap", x_axis_label='Absolute Magnitude', y_axis_label='Velocity km/s') source = ColumnDataSource(data=dict( x=abs_mag, y=velocity, color=["navy" for i in range(len(abs_mag))])) p.circle('x', 'y', color='color', size=20, source=source) url = "static/details_neo1.html" #url = "http://www.colors.commutercreative.com/@color/" <---- save this for now, it is an example for later taptool = p.select(type=TapTool) taptool.callback = OpenURL(url=url) show(p)
def build_plot(tweet_feature): tweet_source = ColumnDataSource(data=dict(x=tweet_feature['x'], y=tweet_feature['y'], text=tweet_feature['text'], url=tweet_feature['url'], color=tweet_feature['color'])) p = figure(plot_width=600, plot_height=600, tools=[HoverTool(tooltips="""<div style="width:300px">@text</div>"""), TapTool()], toolbar_location=None, title='hover to view tweet text, click to view tweet in a pop-up window') tap = p.select(type=TapTool) tap.callback = OpenURL(url='@url') p.axis.visible = False p.xgrid.grid_line_color = None p.ygrid.grid_line_color = None color_mapper=LogColorMapper(palette='Viridis256', low=1, high=max(tweet_feature['popularity'])+1) color_bar=ColorBar(color_mapper=color_mapper, ticker=LogTicker(), label_standoff=6, border_line_color=None, location=(0,0), title="likes") p.circle(x='x', y='y', source=tweet_source, size=8, fill_color='color', line_color='color') p.add_layout(color_bar, 'right') return components(p)
def create_submit_chart_html(submits: List[Submit], assignments: List[AssignedTask]) -> str: main_assignment = assignments[0] if assignments else None def format_points(submit: Submit): if not main_assignment or not main_assignment.max_points: return "not graded" points = submit.points or submit.assigned_points if points is None: return "no points assigned" return f"{points}/{main_assignment.max_points}" frame = pd.DataFrame({ "date": [submit.created_at for submit in submits], "student": [submit.student.username for submit in submits], "submit_num": [submit.submit_num for submit in submits], "submit_url": [ reverse("task_detail", kwargs=dict(assignment_id=submit.assignment.id, login=submit.student.username, submit_num=submit.submit_num)) for submit in submits ], "points": [format_points(submit) for submit in submits], }) frame["count"] = 1 frame["cumsum"] = frame["count"].cumsum() source = ColumnDataSource(data=frame) plot = figure(plot_width=1200, plot_height=400, x_axis_type="datetime", tools="pan,wheel_zoom,box_zoom,save,reset,tap") plot.line("date", "cumsum", source=source) students = sorted(set(frame["student"])) mapper = factor_cmap(field_name="student", palette=CategoricalPalette, factors=students) points = plot.circle("date", "cumsum", color=mapper, source=source, size=8) plot.yaxis.axis_label = "# submits" url = "@submit_url#src" taptool = plot.select(type=TapTool) taptool.callback = OpenURL(url=url) hover = HoverTool(tooltips=[("submit", "@student #@submit_num"), ("points", "@points"), ("date", "@date{%d. %m. %Y %H:%M:%S}")], formatters={'@date': 'datetime'}, renderers=[points]) plot.add_tools(hover) for assignment in assignments: if assignment.deadline is not None: draw_deadline_line(plot, assignment.deadline) return file_html(plot, CDN, "Submits over time")
def patches(plot, div, patch_data): color_mapper = LinearColorMapper(palette=palette) patches = MultiPolygons(xs='xs', ys='ys', fill_color={ 'field': 'rank', 'transform': color_mapper }, fill_alpha=0.5, line_color="lightblue", line_alpha=0.3, line_width=3.0) hover_patches = MultiPolygons(xs='xs', ys='ys', fill_color={ 'field': 'rank', 'transform': color_mapper }, fill_alpha=0.5, line_color="purple", line_alpha=0.8, line_width=3.0) patch_source = geodf_patches_to_geods(patch_data) render = plot.add_glyph(patch_source, patches, hover_glyph=hover_patches, selection_glyph=patches, nonselection_glyph=patches) parsed_geojson = json.loads(patch_source.geojson) # str.source.selected.indices gives you a list of things that you # immediately clicked on code = """ var features = json_source['features']; var properties = features[cb_data.index.indices[0]]; if (properties != undefined) { var rank = properties['properties']['rank'] + 1; var name = properties['properties']['name']; var protestcount = properties['properties']['protestcount']; div.text = name + '<br>' + 'Protest Count: ' + protestcount } """ callback = CustomJS(args=dict(json_source=parsed_geojson, div=div), code=code) hover = HoverTool(tooltips=None, renderers=[render], point_policy="follow_mouse", callback=callback) plot.add_tools(hover) plot.toolbar.active_inspect = hover tap = TapTool(renderers=[render], callback=OpenURL(url='/spa/@perma{safe}')) plot.add_tools(tap) return plot
def plot_t_sne(read_counting_table, tsne_result, output_file_colorized_by_clusters): read_counting_table["t-SNE-component_1"] = [pos[0] for pos in tsne_result] read_counting_table["t-SNE-component_2"] = [pos[1] for pos in tsne_result] color_palette = bokeh.palettes.Colorblind[(len( read_counting_table["Cluster_label"].unique()))] color = read_counting_table["Cluster_label"].apply( lambda lable: color_palette[lable]) label = read_counting_table.apply(_label_clustering, axis=1) hower_data = dict(x=read_counting_table["t-SNE-component_1"], y=read_counting_table["t-SNE-component_2"], feature=read_counting_table["Protein.names"], id=read_counting_table["Protein.IDs"], cluster_label=read_counting_table["Cluster_label"], color=color, label=label) hower_data_df = pd.DataFrame.from_dict(hower_data) hower_data_df.to_csv("hower_data_df.csv", sep='\t', index=None) source = ColumnDataSource(hower_data) hover = HoverTool(tooltips=[("Protein.names", "@feature"), ("Protein.IDs", "@id")]) plot = figure(plot_width=900, plot_height=900, tools=[ hover, BoxZoomTool(), ResetTool(), PanTool(), WheelZoomTool(), "tap" ], title="Grad-Seq t-SNE proteins") plot.circle("x", "y", source=source, size=7, alpha=3, color='color', legend="label", line_color="black") plot.yaxis.axis_label_text_font_size = "15pt" plot.xaxis.axis_label_text_font_size = "15pt" plot.title.text_font_size = '15pt' url = "https://www.uniprot.org/uniprot/?query=@feature" taptool = plot.select(type=TapTool) taptool.callback = OpenURL(url=url) plot.xaxis.axis_label = "Dimension 1" plot.yaxis.axis_label = "Dimension 2" output_file(output_file_colorized_by_clusters) save(plot)
def generateNavigatorFigure(dataframe, i, title): global pixelsForTitle; global pixelsPerHeightUnit; global plotWidth; # Generate the colors, such that the current interval is shown in a # different color than the rest. # numIntervals = dataframe['intervalnumber'].size; color = ["white" for x in range(numIntervals)]; color[i] = "salmon"; dataframe['color'] = color; cds = ColumnDataSource(dataframe); title = title + " CLICK TO NAVIGATE"; hover = HoverTool(tooltips = [ ("interval #", "@intervalnumber"), ("interval start", "@intervalbegin{0,0}"), ("interval end", "@intervalend{0,0}")]); TOOLS = [hover, "tap"]; p = figure(title = title, plot_width = plotWidth, x_range = (0, numIntervals), plot_height = 2 * pixelsPerHeightUnit + pixelsForTitle, x_axis_label = "", y_axis_label = "", tools = TOOLS, toolbar_location="above"); # No minor ticks or labels on the y-axis p.yaxis.major_tick_line_color = None; p.yaxis.minor_tick_line_color = None; p.yaxis.major_label_text_font_size = '0pt'; p.yaxis.ticker = FixedTicker(ticks = range(0, 1)); p.ygrid.ticker = FixedTicker(ticks = range(0, 1)); p.xaxis.formatter = NumeralTickFormatter(format="0,"); p.title.align = "center"; p.title.text_font_style = "normal"; p.quad(left = 'intervalnumber', right = 'intervalnumbernext', bottom = 0, top = 2, color = 'color', source = cds, nonselection_fill_color='color', nonselection_fill_alpha = 1.0, line_color = "aliceblue", selection_fill_color = "white", selection_line_color="lightgrey" ); url = "@bucketfiles"; taptool = p.select(type=TapTool); taptool.callback = OpenURL(url=url); return p;
def bokeh_scatter(df, colourDimension='EmployerSize', title="Mean (x) vs Median (y) Scatter"): ''' Make a scatter plot from a dataframe :param df: :param colors: :return: ''' from bokeh.plotting import figure, output_file, show from bokeh.models import ColumnDataSource, HoverTool, TapTool, OpenURL from bokeh.transform import factor_cmap #bokeh data srce = ColumnDataSource(df[[ 'DiffMeanHourlyPercent', 'DiffMedianHourlyPercent', 'CurrentName', 'EmployerSize', 'DiffMeanHourlyPercent', 'DiffMedianHourlyPercent', 'CompanyLinkToGPGInfo', 'Sector' ]]) # output to static HTML file output_file("{}.html".format(title)) # create a new plot p = figure(tools="pan,box_zoom,reset,save, tap", title=title, x_axis_label='mean gap %', y_axis_label='median gap %') p.circle(source=srce, x='DiffMeanHourlyPercent', y='DiffMedianHourlyPercent', legend="y=x", color=colourDimension, fill_color=colourDimension, size=8) ##attempts to get colour grouping workings # color_map = CategoricalColorMapper(factors=df[colourDimension].unique()) # p.circle(source=srce, x='DiffMeanHourlyPercent', y='DiffMedianHourlyPercent', legend="y=x", color={'field': colourDimension, 'transform': color_map}, size=8) url = '@CompanyLinkToGPGInfo/' #make the axes stand out -- got rid of this as couldn't work out how to # p.xaxis.axis_line_width = 3 # p.yaxis.axis_line_width = 3 # p.xaxis.axis_line_color = "Black" # p.xaxis.axis_line_join() # add some renderers # index_cmap = factor_cmap('DiffMeanHourlyPercent', palette = Spectral6, factors=sorted(df[colourDimension].unique()), end=1) p.add_tools( HoverTool(tooltips=[( "Name", "@CurrentName"), ( "EmployerSize", "@EmployerSize"), ("MedianDiff", "@DiffMedianHourlyPercent" ), ("MeanDiff", "@DiffMeanHourlyPercent")])) # p.add_tools(TapTool()) # p.add_tools(TapTool(behaviour = '', tooltips=[("Name", "@CurrentName"), ("EmployerSize", "@EmployerSize"), ("MedianDiff", "@DiffMedianHourlyPercent"), ("MeanDiff", "@DiffMeanHourlyPercent")])) t = p.select(type=TapTool) t.callback = OpenURL(url=url) return p, t
def make_plot(source, title): plot = figure( tools="pan,wheel_zoom,box_zoom,reset,tap,lasso_select,save,hover", toolbar_location="above", plot_width=1100, plot_height=600) #plot2=figure() plot.title.text = title legends = [ "January", "february", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] color_list = [ "Red", "orange", "yellow", "maroon", "black", "blue", "blue", "black", "green", "blue", "blue", "Red" ] for i, j, k in zip(All_record, legends, color_list): plot.line(x='YEAR', y=i, source=source, color=k, legend=str(j), line_cap='butt', line_width=2) # plot.line(x='YEAR',y='JAN',source=source,color="black", legend="january",line_cap='butt',line_width=4) # plot.line(x='YEAR',y='FEB',source=source,color="yellow", legend="February") # plot.line(x='YEAR',y='MAR',source=source, legend="March",color="green") # plot.line(x='YEAR',y='APR',source=source, legend="April",color="red") # plot.line(x='YEAR',y='JUN',source=source, legend="june",color="orange") # plot.line(x='YEAR',y='JUL',source=source, legend="july") # plot.line(x='YEAR',y='AUG',source=source, legend="august") # plot.line(x='YEAR',y='SEP',source=source, legend="september") # plot.line(x='YEAR',y='OCT',source=source, legend="october") # plot.line(x='YEAR',y='NOV',source=source, legend="november") # plot.line(x='YEAR',y='DEC',source=source, legend="december") url = "https://data.gov.in/keywords/annual-rainfall" taptool = plot.select(type=TapTool) taptool.callback = OpenURL(url=url) #chup=source._df_index_name plot.xaxis.axis_label = "Year" plot.yaxis.axis_label = "Rain (mm)" plot.legend.click_policy = "hide" hover = plot.select(dict(type=HoverTool)) hover.tooltips = [ ("Year", "@YEAR"), ] hover.mode = 'mouse' return plot
def generate_plot(title, cds, x, y, tooltip): plot = figure(x_axis_type="datetime", title=title, tooltips=tooltip) plot.circle(x=x, y=y, source=cds, size=8) taptool = TapTool() # taptool.callback = OpenURL(url='http://www.dilbert.com/strip/@{AAPL_p}') # craft URL by hand, as flask escapes all the symbols - so bokeh doesnt interpolate taptool.callback = OpenURL(url="/display/@{AAPL_p}") plot.add_tools(taptool) script, div = components(plot) return {'script': script, 'div': div}
def __init__(self, scheduler, **kwargs): self.scheduler = scheduler self.layout = GraphLayout(scheduler) self.invisible_count = 0 # number of invisible nodes self.node_source = ColumnDataSource({ 'x': [], 'y': [], 'name': [], 'state': [], 'visible': [], 'key': [] }) self.edge_source = ColumnDataSource({'x': [], 'y': [], 'visible': []}) node_view = CDSView( source=self.node_source, filters=[GroupFilter(column_name='visible', group='True')]) edge_view = CDSView( source=self.edge_source, filters=[GroupFilter(column_name='visible', group='True')]) node_colors = factor_cmap( 'state', factors=['waiting', 'processing', 'memory', 'released', 'erred'], palette=['gray', 'green', 'red', 'blue', 'black']) self.root = figure(title='Task Graph', **kwargs) self.root.multi_line(xs='x', ys='y', source=self.edge_source, line_width=1, view=edge_view, color='black', alpha=0.3) rect = self.root.square(x='x', y='y', size=10, color=node_colors, source=self.node_source, view=node_view, legend='state') self.root.xgrid.grid_line_color = None self.root.ygrid.grid_line_color = None hover = HoverTool(point_policy="follow_mouse", tooltips="<b>@name</b>: @state", renderers=[rect]) tap = TapTool(callback=OpenURL(url='info/task/@key.html'), renderers=[rect]) rect.nonselection_glyph = None self.root.add_tools(hover, tap)
def onc_skyplot(t): """ Create a sky plot of the database objects """ # Convert to Pandas data frame data = t.to_pandas() data.index = data['id'] script, div, warning_message = '', '', '' if 'ra' in data and 'dec' in data: # Remove objects without RA/Dec num_missing = np.sum(pd.isnull(data.get('ra'))) if num_missing > 0: warning_message = 'Note: {} objects had missing coordinate information and were removed.'.format( num_missing) data = data[pd.notnull(data.get('ra'))] else: warning_message = '' # Coerce to numeric data['ra'] = pd.to_numeric(data['ra']) data['dec'] = pd.to_numeric(data['dec']) source = ColumnDataSource(data=data) tools = "resize,tap,pan,wheel_zoom,box_zoom,reset" p = figure(tools=tools, title='', plot_width=500, plot_height=300, min_border=0, min_border_bottom=0) # Add the data p.scatter('ra', 'dec', source=source, size=8, alpha=0.6) tooltip = [("Source ID", "@id"), ("Name", "@shortname"), ("(RA, Dec)", "(@ra, @dec)")] p.add_tools(HoverTool(tooltips=tooltip)) # When clicked, go to the Summary page url = "inventory/@id" taptool = p.select(type=TapTool) taptool.callback = OpenURL(url=url) # Axis labels p.yaxis.axis_label = 'Decl. (deg)' p.xaxis.axis_label = 'R.A. (deg)' script, div = components(p) return script, div, warning_message
def index(): cz = drought >> mask(X.country_name == 'Czech Republic') plotdf = utils.drought_add_facecolor(cz) f_drought = utils.drought_rate_plot(plotdf) url = "/station_detail/station_id=@station" # taptool = f_drought.select(type=TapTool) # taptool.callback = OpenURL(url=url) f_drought.add_tools(TapTool(callback=OpenURL(url=url))) bokeh_map = utils.drought_map(plotdf) bokeh_map.add_tools(TapTool(callback=OpenURL(url=url))) script_drought, div_drought = components(f_drought) script_map, div_map = components(bokeh_map) return render_template( 'main_page.html', stations=cz, js_resources=js_resources, css_resources=css_resources, script_drought=script_drought, script_map=script_map, div_drought=div_drought, div_map=div_map, )
def plot_errors(data, device="PTL_DEFAULT", **kwargs): dates = list(data.date) if 'x_range' in kwargs: x_range = kwargs['x_range'] x_range = x_range[0] - timedelta(days=1), x_range[1] + timedelta(days=1) else: x_range = (min(dates) - timedelta(days=1), max(dates) + timedelta(days=1)) y_range = kwargs.get('y_range', None) if y_range and y_range[1] >= 1000: bottom = 0.1 y_range = bottom, y_range[1] y_axis_type = "log" else: bottom = 0 y_axis_type = "linear" data_source = ColumnDataSource(data) vbar_width = timedelta(days=1) / 2 fig = figure(x_axis_type="datetime", x_range=x_range, y_axis_type=y_axis_type, y_range=y_range, plot_height=200, plot_width=800, title="Errors per day", tools="tap") fig.output_backend = "svg" fig.toolbar.logo = None error_hover_tool = HoverTool(names=['errors'], tooltips=[('date', '@date{%F}'), ('errors', '@error_count{%d}')], formatters={'date': 'datetime', 'error_count': 'printf'}, mode='vline') fig.add_tools(error_hover_tool) fig.add_tools(SaveTool()) fig.vbar(x='date', width=vbar_width, bottom=bottom, top='error_count', color='#c61803', source=data_source, name="errors") url = url_for("show_logs", device=device, timestamp="TIMESTAMP", duration=24*60, log_level="ERROR") url = url.replace("TIMESTAMP", "@end_of_day") taptool = fig.select(type=TapTool)[0] taptool.callback = OpenURL(url=url, same_tab=False) return fig
def lifecycles(data): "Returns (script, div) tuple of Bokeh chart of Issue lifecycles for a repo" source = ColumnDataSource(data=dict( left=[s['span']['start'] for s in data['spans']], date=[s['span']['start'].strftime('%d %B %Y') for s in data['spans']], right=[s['span']['end'] for s in data['spans']], bottom=[s['index'] * (THICKNESS + 2 * MARGIN) for s in data['spans']], top=[ s['index'] * (THICKNESS + 2 * MARGIN) + THICKNESS for s in data['spans'] ], color=data['colors'], issue=[s['issue'].title for s in data['spans']], status=[', '.join(s['span']['milestones']) for s in data['spans']], assignee=[s['issue'].assignee_login for s in data['spans']], url=[s['issue'].html_url for s in data['spans']], final=[s['final'] for s in data['spans']], )) fig = figure( x_axis_type='datetime', title='Issue progress', ) fig.yaxis.major_label_text_color = None fig.quad( left='left', bottom='bottom', right='right', top='top', source=source, color='color', ) hover = HoverTool(tooltips=[ ("issue", "@issue"), ("date", "@date"), ("status", "@status"), ("final", "@final"), ("assignee", "@assignee"), ("url", "@url"), ]) fig.add_tools(hover) taptool = TapTool(callback=OpenURL(url="@url")) fig.add_tools(taptool) result = components(fig) result = {'script': result[0], 'div': result[1]} return result
def render_grid(source, x_range, y_range, TOOLS="hover,tap"): """Function to render a bokeh figure with a rectangular grid representing the SOM nodes, colored by cluster id and showing the number of articles that they match. By hovering on the nodes one display the top topics. Parameters ---------- source: ColumnDataSource Data to be displayed, as generated by get_grid method x_range, yrange: lists List used to scale the nodes coordinates """ p = figure(title="Self-organizing map features and cluster ID", tools=TOOLS) p.plot_width = 800 p.toolbar_location = "left" # Draw the rectangular color grid p.rect("x", "y", 1, 1, source=source, fill_alpha=0.6, color="color") # Write some content in the boxes text_props = { "source": source, "angle": 0, "color": "black", "text_align": "left", "text_baseline": "middle" } p.text(x="x", y="y", text="hits", text_font_style="bold", text_font_size="8pts", **text_props) p.grid.grid_line_color = None # Create a hover tool for representing the node data hover = p.select(dict(type=HoverTool)) hover.tooltips = [("Node_id", "@node")] + [("Top Words no. %d\t" % (i + 1), "@word_%d" % (i + 1)) for i in range(3)] # Create a link to the node data url = "/som/node/@node" taptool = p.select(type=TapTool) taptool.callback = OpenURL(url=url) return p
def get_plot_stuff(plot): plot.xaxis.formatter = DatetimeTickFormatter(seconds=["%d %B %Y"], minutes=["%d %B %Y"], hours=["%d %b %Y"], days=["%d %b %Y"], months=["%d %b %Y"], years=["%d %b %Y"]) hover = plot.select(dict(type=HoverTool)) hover.tooltips = [("pic", "<img src='@pic' alt='' />"), ("id", "@object_id"), ("Address", "@address"), ("Info", "@desctext"), ("Description", "@desc"), ("Price", "@price"), ("Last scraped", "@lastdl")] hover.mode = 'mouse' taptool = plot.select(type=TapTool) taptool.callback = OpenURL(url="@link")
def price_partnum(self, dist): hover = HoverHandler('price_partnum') # formatters={'unit_price' : 'printf'}) ''' y_range = [ -50, dist.dist_found['nunit_price'].max()*1.07 if dist.dist_found['nunit_price'].max() > 1 or dist.dist_found['nunit_price'].max() < -1 else 0.5 ] ''' p = self.config_figure(plot_height=400, hover=[hover.make_hover_tool], x_range=self.x_range_range_partnum, yaxis_label='Unit ptice', xaxis_orient=pi / 4) p.add_tools(TapTool()) url = '@dist_partlink' taptool = p.select(type=TapTool) taptool.callback = OpenURL(url=url) p.yaxis[0].formatter = NumeralTickFormatter(format='$0.00') p.segment('part_num', 0, 'part_num', 'nunit_price', line_width=3, line_color='clr', source=self.source) p.circle('part_num', 'nunit_price', size=10, fill_color='dist_clr', line_color='dist_clr', line_width=3, hover_fill_color="white", hover_line_color='dist_clr', fill_alpha=1, muted_color='dist_clr', muted_alpha=0.2, legend='dist', source=self.source) p.legend.location = "top_left" p.legend.click_policy = "mute" return p
def dashboard_instrument_pie_chart(self): """Create piechart showing number of files per instrument Returns ------- plot : bokeh.plotting.figure Pie chart figure """ # Replace with jwql.website.apps.jwql.data_containers.build_table data = build_table('filesystem_instrument') if not pd.isnull(self.delta_t): data = data[(data['date'] >= self.date - self.delta_t) & (data['date'] <= self.date)] try: file_counts = {'nircam': data.instrument.str.count('nircam').sum(), 'nirspec': data.instrument.str.count('nirspec').sum(), 'niriss': data.instrument.str.count('niriss').sum(), 'miri': data.instrument.str.count('miri').sum(), 'fgs': data.instrument.str.count('fgs').sum()} except AttributeError: file_counts = {'nircam': 0, 'nirspec': 0, 'niriss': 0, 'miri': 0, 'fgs': 0} data = pd.Series(file_counts).reset_index(name='value').rename(columns={'index': 'instrument'}) data['angle'] = data['value'] / data['value'].sum() * 2 * pi data['color'] = ['#F8B195', '#F67280', '#C06C84', '#6C5B7B', '#355C7D'] plot = figure(title="Number of Files Per Instruments", toolbar_location=None, tools="hover,tap", tooltips="@instrument: @value", x_range=(-0.5, 1.0)) plot.wedge(x=0, y=1, radius=0.4, start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'), line_color="white", color='color', legend='instrument', source=data) url = "{}/@instrument".format(get_base_url()) taptool = plot.select(type=TapTool) taptool.callback = OpenURL(url=url) plot.axis.axis_label = None plot.axis.visible = False plot.grid.grid_line_color = None return plot
def histogram_plot(data, width=600, height=300): ''' ''' if len(data) > 5: data = data[:5] ids = [d['id'] for d in data] topics = ['Topic {}'.format(d['id']) for d in data] dist = [d['dist'] for d in data] labels = [', '.join(d['words']) for d in data] source = ColumnDataSource( data=dict(topics=topics, distribution=dist, ids=ids, labels=labels)) hover = HoverTool(tooltips=""" <div> <div> <span style="font-size: 20px;">Topics: <strong>@ids</strong></span><br> <span style="font-size: 12px;">(Click to see more about the topic)</span><br> <span style="font-size: 20px;">Words: @labels</span> </div> </div> """) hover.attachment = 'right' plot = figure(x_range=topics, width=width, height=height, tools=[hover, 'tap', 'save'], title='Relevant topics') plot.vbar(x='topics', top='distribution', width=0.8, source=source, line_color='white', fill_color=factor_cmap('topics', palette=COLORS, factors=topics)) plot.y_range.start = 0 plot.xgrid.grid_line_color = None plot.xaxis.axis_label = 'Topics' plot.yaxis.axis_label = 'Proportion' plot.title.text_font_size = '1.5em' plot.xaxis.axis_label_text_font_size = "1.5em" plot.yaxis.axis_label_text_font_size = "1.5em" plot.xaxis.major_label_text_font_size = "1em" taptool = plot.select(type=TapTool) taptool.callback = OpenURL(url="/topic/@ids") plot.toolbar.active_inspect = [hover] return components(plot)
def plot_error_heatmap(data, device="PTL_DEFAULT", **kwargs): if 'x_range' in kwargs: x_range = kwargs['x_range'] x_range = x_range[0] - timedelta(days=1), x_range[1] + timedelta(days=1) else: dates = list(data.date) x_range = (min(dates) - timedelta(days=1), max(dates) + timedelta(days=1)) fig = figure(plot_height=200, plot_width=800, title=f"Error heatmap", x_axis_type='datetime', x_range=x_range, y_range=(0, 1), tools="tap") fig.output_backend = "svg" fig.toolbar.logo = None fig.yaxis.formatter = NumeralTickFormatter(format='0 %') error_hover_tool = HoverTool(tooltips=[('date', '@date_label{%F}'), ('location', '@location'), ('errors', '@error_count{%d}')], formatters={'date_label': 'datetime', 'location': 'printf', 'error_count': 'printf'}) fig.add_tools(error_hover_tool) fig.add_tools(SaveTool()) for date in data.index.get_level_values(0).unique(): data_source = ColumnDataSource(data.loc[date]) fig.vbar(bottom=cumsum('error_count_normalized', include_zero=True), top=cumsum('error_count_normalized'), x=date, width=timedelta(days=1)/2, source=data_source, fill_color='colors') url = url_for("show_logs", device=device, timestamp="TIMESTAMP", duration=24*60, log_level="ERROR", filename='FILENAME', line_number='LINENUMBER') url = url.replace("TIMESTAMP", "@end_of_day") \ .replace("FILENAME", "@filename") \ .replace("LINENUMBER", "@line_number") taptool = fig.select(type=TapTool)[0] taptool.callback = OpenURL(url=url, same_tab=False) #tooltips="@location: @error_count Errors", return fig
def get_plot(data): countries = data.country_name.unique().tolist() countries = [country for country in countries if str(country) != 'nan'] countries.append(' All') countries.sort() p = figure(tools='pan, wheel_zoom, tap, reset', x_range=x_range, y_range=y_range, plot_width=950, toolbar_location="right", active_scroll='wheel_zoom') p.axis.visible = False url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}.jpg' attribution = "Tiles by Carto, under CC BY 3.0. Data by OSM, under ODbL" p.add_tile(WMTSTileSource(url=url, attribution=attribution)) source = ColumnDataSource( dict(latitude=latlon.latitude, longitude=latlon.longitude, country_name=latlon.country_name, latitude_t=latlon.latitude, longitude_t=latlon.longitude, country_name_t=latlon.country_name, landslide_size=latlon.landslide_size, source_link=latlon.source_link, location_description=latlon.location_description)) cmap = factor_cmap('landslide_size', palette=[ '#ffffff', '#f7a8e2', '#fcdc12', '#fa774c', '#FC3232', '#040100' ], factors=latlon.landslide_size.unique().tolist()) p.add_tools(HoverTool(tooltips='@location_description', mode='mouse')) url = "@source_link" taptool = p.select(type=TapTool) taptool.callback = OpenURL(url=url) p.circle(x='latitude', y='longitude', fill_color=cmap, size=8, source=source, legend='landslide_size') return (p)
def get_states_plot(): source = AjaxDataSource(data={ 'STATE': [], 'STNAME': [], 'STUSAB': [], 'TOT_POP': [], 'TOT_MALE': [], 'TOT_FEMALE': [] }, data_url='/api/states/', mode='replace', method='GET') hover = HoverTool(tooltips=[ ("State", "@STNAME"), ("Population", "@TOT_POP"), ("Female Population", "@TOT_FEMALE"), ("Male Population", "@TOT_MALE"), ]) plot = figure( title='Population by State', plot_width=1200, plot_height=500, x_range=FactorRange(factors=get_state_abbreviations()), y_range=(0, 40000000), tools=[hover, 'tap', 'box_zoom', 'wheel_zoom', 'save', 'reset']) plot.toolbar.active_tap = 'auto' plot.xaxis.axis_label = 'State' plot.yaxis.axis_label = 'Population' plot.yaxis.formatter = NumeralTickFormatter(format="0a") plot.sizing_mode = 'scale_width' plot.vbar(bottom=0, top='TOT_POP', x='STUSAB', legend=None, width=0.5, source=source) url = "/counties/@STATE/" taptool = plot.select(type=TapTool) taptool.callback = OpenURL(url=url) return plot
def scatter_any(df, x, y, xlabel=None, ylabel=None, color_field=None, xformatter=NumeralTickFormatter(), yformatter=NumeralTickFormatter(), **kwargs): f = figure(tools="wheel_zoom,pan,tap,save", webgl=True, width=defaults.plot_width, height=defaults.plot_height, **kwargs) f.xaxis[0].formatter = xformatter f.yaxis[0].formatter = yformatter f.xaxis.axis_label = xlabel f.yaxis.axis_label = ylabel taptool = f.select(type=TapTool) taptool.callback = OpenURL(url='@url') if color_field: uniques = sorted(df[color_field].unique()) # colors = brewer["PiYG"][len(uniques)] dark2 = [ "#1B9E77", "#D95F02", "#7570B3", "#E7298A", "#66A61E", "#E6AB02", "#A6761D", "#666666" ] for i, u in enumerate(uniques): sdf = df[df[color_field] == u] f.scatter(x, y, source=ColumnDataSource(sdf), color=dark2[i], legend=str(u)) else: f.scatter(x, y, source=ColumnDataSource(df)) return f
def do_plot_graph(nodes, edges, colors, sizes, description, output_plot): G = nx.Graph() G.add_nodes_from(nodes) G.add_edges_from(edges) hover = HoverTool(tooltips=[ ("name", "@index")]) plot = figure(plot_width=900, plot_height=900, x_range=Range1d(-1.1, 1.1), y_range=Range1d(-1.1, 1.1), tools=[hover, BoxZoomTool(), ResetTool(), PanTool(), WheelZoomTool(), "tap"], title=output_plot) plot.toolbar.logo = None plot.title.text = description url_protein = "https://www.ncbi.nlm.nih.gov/gene/?term=@index" taptool = plot.select(type=TapTool) taptool.callback = OpenURL(url=url_protein) graph_renderer = from_networkx(G, nx.fruchterman_reingold_layout, scale=1) source = ColumnDataSource({'index': nodes, 'fill_color': colors, 'size': sizes}) graph_renderer.node_renderer.data_source = source graph_renderer.node_renderer.glyph = Circle(size="size", fill_color="fill_color", line_width=0, line_color="fill_color") graph_renderer.node_renderer.selection_glyph = Circle(size="size", fill_color=Spectral4[2], line_width=0, line_color=Spectral4[1]) graph_renderer.node_renderer.hover_glyph = Circle(size="size", fill_color=Spectral4[1], line_width=0, line_color=Spectral4[1]) graph_renderer.edge_renderer.glyph = MultiLine(line_color="#CCCCCC", line_alpha=1, line_width=0.2) graph_renderer.edge_renderer.selection_glyph = MultiLine(line_color=Spectral4[2], line_width=1) graph_renderer.edge_renderer.hover_glyph = MultiLine(line_color=Spectral4[1], line_width=1) graph_renderer.selection_policy = NodesAndLinkedEdges() graph_renderer.inspection_policy = NodesAndLinkedEdges() plot.renderers.append(graph_renderer) output_file(output_plot)