def test_bad_source(self): with pytest.raises(ValueError): bpl._handle_legend_group("foo", "legend", GlyphRenderer()) with pytest.raises(ValueError): bpl._handle_legend_group( "foo", "legend", GlyphRenderer(data_source=ColumnDataSource(data=dict(bar=[]))))
def test_can_add_multiple_glyph_renderers_to_legend_item(): legend_item = LegendItem() gr_1 = GlyphRenderer() gr_2 = GlyphRenderer() legend_item.renderers = [gr_1, gr_2] with mock.patch('bokeh.core.validation.check.logger') as mock_logger: check_integrity([legend_item]) assert mock_logger.error.call_count == 0
def test_legend_item_with_value_label_and_different_data_sources_does_not_raise_a_validation_error(): legend_item = LegendItem() gr_1 = GlyphRenderer(data_source=ColumnDataSource()) gr_2 = GlyphRenderer(data_source=ColumnDataSource()) legend_item.label = value('label') legend_item.renderers = [gr_1, gr_2] with mock.patch('bokeh.core.validation.check.logger') as mock_logger: check_integrity([legend_item]) assert mock_logger.error.call_count == 0
def test_can_add_multiple_glyph_renderers_to_legend_item() -> None: legend_item = LegendItem() gr_1 = GlyphRenderer(data_source=ColumnDataSource()) gr_2 = GlyphRenderer(data_source=ColumnDataSource()) legend_item.renderers = [gr_1, gr_2] with mock.patch('bokeh.core.validation.check.log') as mock_logger: issues = check_integrity([legend_item]) process_validation_issues(issues) assert mock_logger.error.call_count == 0
def test_legend_item_with_field_label_and_different_data_sources_raises_a_validation_error() -> None: legend_item = LegendItem() gr_1 = GlyphRenderer(data_source=ColumnDataSource(data={'label': [1]})) gr_2 = GlyphRenderer(data_source=ColumnDataSource(data={'label': [1]})) legend_item.label = field('label') legend_item.renderers = [gr_1, gr_2] with mock.patch('bokeh.core.validation.check.log') as mock_logger: check_integrity([legend_item]) assert mock_logger.error.call_count == 1
def test_label_already_exists(self) -> None: legend = Legend(items=[LegendItem(label=dict(value="foo"))]) renderer = GlyphRenderer() bpl._handle_legend_label("foo", legend, renderer) assert len(legend.items) == 1 assert legend.items[0].label == dict(value="foo") assert legend.items[0].renderers == [renderer]
def test_legend_item_with_field_label_raises_error_if_field_not_in_cds(): legend_item = LegendItem() gr_1 = GlyphRenderer(data_source=ColumnDataSource()) legend_item.label = field('label') legend_item.renderers = [gr_1] with mock.patch('bokeh.core.validation.check.logger') as mock_logger: check_integrity([legend_item]) assert mock_logger.error.call_count == 1
def test_field_string(self) -> None: legend = Legend(items=[LegendItem(label=dict(field="foo"))]) renderer = GlyphRenderer(data_source=ColumnDataSource(data=dict(foo=[], bar=[]))) bpl._handle_legend_deprecated("foo", legend, renderer) assert len(legend.items) == 1 assert all("field" in item.label for item in legend.items) bpl._handle_legend_deprecated("bar", legend, renderer) assert len(legend.items) == 2 assert all("field" in item.label for item in legend.items)
def test_label_not_already_exists(self) -> None: legend = Legend(items=[LegendItem(label=dict(field="foo"))]) renderer = GlyphRenderer() bpl._handle_legend_field("bar", legend, renderer) assert len(legend.items) == 2 assert legend.items[0].label == dict(field="foo") assert legend.items[0].renderers == [] assert legend.items[1].label == dict(field="bar") assert legend.items[1].renderers == [renderer]
def test_value_dict(self) -> None: legend = Legend(items=[LegendItem(label=dict(value="foo"))]) renderer = GlyphRenderer(data_source=ColumnDataSource()) bpl._handle_legend_deprecated(dict(value="foo"), legend, renderer) assert len(legend.items) == 1 assert all("value" in item.label for item in legend.items) bpl._handle_legend_deprecated(dict(value="bar"), legend, renderer) assert len(legend.items) == 2 assert all("value" in item.label for item in legend.items)
def __init__(self, field_name='Value', highlight_fill_color='#79DCDE', highlight_line_color='#79DCDE', size=8, is_categorical=False, extent=None, agg=None, how='mean'): if how not in ('mean', 'sum', 'max', 'min', 'median', 'std', 'var', 'count'): raise ValueError("invalid 'how' downsample method") self.hover_data = ColumnDataSource(data=dict(x=[], y=[], value=[])) self.invisible_square = Square(x='x', y='y', fill_color=None, line_color=None, size=size) self.visible_square = Square(x='x', y='y', fill_color=highlight_fill_color, fill_alpha=.5, line_color=highlight_line_color, line_alpha=1, size=size) self.tooltips = [] code = "source.selected = cb_data['index'];" self._callback = CustomJS(args={'source': self.hover_data}, code=code) self.renderer = GlyphRenderer() self.renderer.data_source = self.hover_data self.renderer.glyph = self.invisible_square self.renderer.selection_glyph = self.visible_square self.renderer.nonselection_glyph = self.invisible_square self.tool = HoverTool(callback=self._callback, renderers=[self.renderer], mode='mouse') self.extent = extent self.is_categorical = is_categorical self.field_name = field_name self._agg = agg self._size = size or 8 self.how = how if self.agg is not None and self.extent is not None: self.compute()
def setUp(self): self.source = ColumnDataSource() self.xdr = Range1d() self.ydr = Range1d() self.glyph = GlyphRenderer() self._groups = [self.glyph] * 3 self.chart = Chart( title="title", xlabel="xlabel", ylabel="ylabel", legend="top_left", xscale="linear", yscale="linear", width=800, height=600, tools=True, responsive=True, xgrid=True, ygrid=False )
def large_plot(n): from bokeh.models import ( Plot, LinearAxis, Grid, GlyphRenderer, ColumnDataSource, DataRange1d, PanTool, ZoomInTool, ZoomOutTool, WheelZoomTool, BoxZoomTool, BoxSelectTool, SaveTool, ResetTool ) from bokeh.models.layouts import Column from bokeh.models.glyphs import Line col = Column() objects = set([col]) for i in xrange(n): source = ColumnDataSource(data=dict(x=[0, i + 1], y=[0, i + 1])) xdr = DataRange1d() ydr = DataRange1d() plot = Plot(x_range=xdr, y_range=ydr) xaxis = LinearAxis() plot.add_layout(xaxis, "below") yaxis = LinearAxis() plot.add_layout(yaxis, "left") xgrid = Grid(dimension=0) plot.add_layout(xgrid, "center") ygrid = Grid(dimension=1) plot.add_layout(ygrid, "center") tickers = [xaxis.ticker, xaxis.formatter, yaxis.ticker, yaxis.formatter] glyph = Line(x='x', y='y') renderer = GlyphRenderer(data_source=source, glyph=glyph) plot.renderers.append(renderer) pan = PanTool() zoom_in = ZoomInTool() zoom_out = ZoomOutTool() wheel_zoom = WheelZoomTool() box_zoom = BoxZoomTool() box_select = BoxSelectTool() save = SaveTool() reset = ResetTool() tools = [pan, zoom_in, zoom_out, wheel_zoom, box_zoom, box_select, save, reset] plot.add_tools(*tools) col.children.append(plot) objects |= set([ xdr, ydr, xaxis, yaxis, xgrid, ygrid, renderer, renderer.view, glyph, source, source.selected, source.selection_policy, plot, plot.x_scale, plot.y_scale, plot.toolbar, plot.title, box_zoom.overlay, box_select.overlay, ] + tickers + tools) return col, objects
def large_plot(n): from bokeh.models import (Plot, LinearAxis, Grid, GlyphRenderer, ColumnDataSource, DataRange1d, PanTool, ZoomInTool, ZoomOutTool, WheelZoomTool, BoxZoomTool, BoxSelectTool, ResizeTool, SaveTool, ResetTool) from bokeh.models.layouts import VBox from bokeh.models.glyphs import Line vbox = VBox() objects = set([vbox]) for i in xrange(n): source = ColumnDataSource(data=dict(x=[0, i + 1], y=[0, i + 1])) xdr = DataRange1d() ydr = DataRange1d() plot = Plot(x_range=xdr, y_range=ydr) xaxis = LinearAxis(plot=plot) yaxis = LinearAxis(plot=plot) xgrid = Grid(plot=plot, dimension=0) ygrid = Grid(plot=plot, dimension=1) tickers = [ xaxis.ticker, xaxis.formatter, yaxis.ticker, yaxis.formatter ] glyph = Line(x='x', y='y') renderer = GlyphRenderer(data_source=source, glyph=glyph) plot.renderers.append(renderer) pan = PanTool() zoom_in = ZoomInTool() zoom_out = ZoomOutTool() wheel_zoom = WheelZoomTool() box_zoom = BoxZoomTool() box_select = BoxSelectTool() resize = ResizeTool() save = SaveTool() reset = ResetTool() tools = [ pan, zoom_in, zoom_out, wheel_zoom, box_zoom, box_select, resize, save, reset ] plot.add_tools(*tools) vbox.children.append(plot) objects |= set([ source, xdr, ydr, plot, xaxis, yaxis, xgrid, ygrid, renderer, glyph, plot.toolbar, plot.tool_events, plot.title, box_zoom.overlay, box_select.overlay ] + tickers + tools) return vbox, objects
def __init__(self, field_name='Value', highlight_fill_color='#79DCDE', highlight_line_color='#79DCDE', size=8, is_categorical=False, extent=None, agg=None): self.hover_data = ColumnDataSource(data=dict(x=[], y=[], value=[])) self.invisible_square = Square(x='x', y='y', fill_color=None, line_color=None, size=size) self.visible_square = Square(x='x', y='y', fill_color=highlight_fill_color, fill_alpha=.5, line_color=highlight_line_color, line_alpha=1, size=size) self.tooltips = [] code = "source.set('selected', cb_data['index']);" self._callback = CustomJS(args={'source': self.hover_data}, code=code) self.renderer = GlyphRenderer() self.renderer.data_source = self.hover_data self.renderer.glyph = self.invisible_square self.renderer.selection_glyph = self.visible_square self.renderer.nonselection_glyph = self.invisible_square self.tool = HoverTool(callback=self._callback, renderers=[self.renderer], mode='mouse') self.extent = extent self.is_categorical = is_categorical self.field_name = field_name self._agg = agg self._size = size or 8 if self.agg is not None and self.extent is not None: self.compute()
def large_plot(n): from bokeh.models import (Plot, LinearAxis, Grid, GlyphRenderer, ColumnDataSource, DataRange1d, PanTool, WheelZoomTool, BoxZoomTool, BoxSelectTool, BoxSelectionOverlay, ResizeTool, PreviewSaveTool, ResetTool) from bokeh.models.widgets.layouts import VBox from bokeh.models.glyphs import Line vbox = VBox() objects = set([vbox]) for i in xrange(n): source = ColumnDataSource(data=dict(x=[0, i + 1], y=[0, i + 1])) xdr = DataRange1d() ydr = DataRange1d() plot = Plot(x_range=xdr, y_range=ydr) xaxis = LinearAxis(plot=plot) yaxis = LinearAxis(plot=plot) xgrid = Grid(plot=plot, dimension=0) ygrid = Grid(plot=plot, dimension=1) tickers = [ xaxis.ticker, xaxis.formatter, yaxis.ticker, yaxis.formatter ] glyph = Line(x='x', y='y') renderer = GlyphRenderer(data_source=source, glyph=glyph) plot.renderers.append(renderer) pan = PanTool(plot=plot) wheel_zoom = WheelZoomTool(plot=plot) box_zoom = BoxZoomTool(plot=plot) box_select = BoxSelectTool(plot=plot) box_selection = BoxSelectionOverlay(tool=box_select) plot.renderers.append(box_selection) resize = ResizeTool(plot=plot) previewsave = PreviewSaveTool(plot=plot) reset = ResetTool(plot=plot) tools = [ pan, wheel_zoom, box_zoom, box_select, resize, previewsave, reset ] plot.tools.extend(tools) vbox.children.append(plot) objects |= set([ source, xdr, ydr, plot, xaxis, yaxis, xgrid, ygrid, renderer, glyph, plot.tool_events, box_selection ] + tickers + tools) return vbox, objects
def mdsplot(): xdr = DataRange1d(sources=[mdssource.columns("x")]) ydr = DataRange1d(sources=[mdssource.columns("y")]) title = "Intertopic Distance Map (via multidimensional scaling)" plot = Plot(title=title, title_text_font_size="16px", x_range=xdr, y_range=ydr, plot_width=mdswidth, plot_height=mdsheight) circle1 = Circle(x="x", y="y", radius=dict(field="r", units="screen"), fill_color=base_color, fill_alpha=0.2) circle2 = Circle(x="x", y="y", radius=dict(field="r", units="screen"), fill_color=high_color, fill_alpha=0.6) circles = GlyphRenderer(data_source=mdssource, glyph=circle1, selection_glyph=circle2, nonselection_glyph=circle1) plot.renderers.append(circles) plot.add_glyph( mdssource, Text(x="x", y="y", text="text", text_font_style="bold", text_align="center", text_baseline="middle", text_font_size="11px")) plot.tools.append(TapTool(plot=plot, renderers=[circles])) #plot.add_layout(LinearAxis(axis_label="PC1"), "below") #plot.add_layout(LinearAxis(axis_label="PC2"), "left") return plot
def test_items(self) -> None: source = ColumnDataSource(data=dict(foo=[10,10,20,30,20,30,40])) renderer = GlyphRenderer(data_source=source) legend = Legend(items=[]) bpl._handle_legend_group("foo", legend, renderer) assert len(legend.items) == 4 assert legend.items[0].label == dict(value="10") assert legend.items[0].renderers == [renderer] assert legend.items[0].index == 0 assert legend.items[1].label == dict(value="20") assert legend.items[1].renderers == [renderer] assert legend.items[1].index == 2 assert legend.items[2].label == dict(value="30") assert legend.items[2].renderers == [renderer] assert legend.items[2].index == 3 assert legend.items[3].label == dict(value="40") assert legend.items[3].renderers == [renderer] assert legend.items[3].index == 6
def add_dots(self, sub, colour, suffix, line_colour, extra_tips=None): """ return the Hovertool object and renderer object for plotting sub-population corr dots with tooltips """ # reference example # https://github.com/bokeh/bokeh/blob/f76ccc44fb39007743ffbe71659b282759915653/examples/glyphs/data_tables.py # outer line colour indicates whether sup-population correlation pos or neg glyph = Circle( x=sub + suffix, y="y", fill_color=colour, line_color=line_colour, line_width=1, size=15, fill_alpha=1, line_alpha=1, ) renderer = GlyphRenderer(data_source=self.source, glyph=glyph) if extra_tips: return ( HoverTool( renderers=[renderer], tooltips=[(sub, "@{" + sub + "}" + extra_tips)], ), renderer, ) else: return ( HoverTool(renderers=[renderer], tooltips=[(sub, "@{" + sub + "}")]), renderer, )
node_indices = list(range(N)) plot = figure(title="Graph Layout Demonstration", x_range=(-1.1, 1.1), y_range=(-1.1, 1.1), plot_width=250, plot_height=250, tools="", toolbar_location=None) node_ds = ColumnDataSource(data=dict(index=node_indices, color=Spectral8), name="Node Renderer") edge_ds = ColumnDataSource(data=dict(start=[0] * N, end=node_indices), name="Edge Renderer") ### start of layout code circ = [i * 2 * math.pi / 8 for i in node_indices] x = [math.cos(i) for i in circ] y = [math.sin(i) for i in circ] graph_layout = dict(zip(node_indices, zip(x, y))) graph = GraphRenderer( node_renderer=GlyphRenderer(glyph=Oval(height=0.1, width=0.2, fill_color="color"), data_source=node_ds), edge_renderer=GlyphRenderer(glyph=MultiLine(), data_source=edge_ds), layout_provider=StaticLayoutProvider(graph_layout=graph_layout)) plot.renderers.append(graph) show(plot)
assert mock_run_notebook_hook.call_args[1] == {} @patch('bokeh.io.showing._show_with_state') def test_show_doesn_not_adds_obj_to_curdoc(m) -> None: curstate().reset() assert curstate().document.roots == [] p = Plot() bis.show(p) assert curstate().document.roots == [] p = Plot() bis.show(p) assert curstate().document.roots == [] @pytest.mark.parametrize('obj', [1, 2.3, None, "str", GlyphRenderer()]) @pytest.mark.unit def test_show_with_bad_object(obj) -> None: with pytest.raises(ValueError): bis.show(obj) #----------------------------------------------------------------------------- # Dev API #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Private API #-----------------------------------------------------------------------------
# >> Init. Bokeh GUI elements << # plot = Plot(x_range=Range1d(-PLOT_BOUNDARY, params['L'] + PLOT_BOUNDARY), y_range=Range1d(-PLOT_BOUNDARY, params['L'] + PLOT_BOUNDARY), height=VIEW_SIZE + 3 * COLORBAR_WIDTH, width=VIEW_SIZE, background_fill_color=FILL_COLOR) plot.background_fill_alpha = 1.0 # Cell renderer # cell_source = ColumnDataSource( dict(xs=[[0, params['L']], [0, params['L']], [0, 0], [params['L'], params['L']]], ys=[[0, 0], [params['L'], params['L']], [0, params['L']], [0, params['L']]])) cell_glyph = MultiLine(xs='xs', ys='ys', line_width=1, line_color='silver') cell = GlyphRenderer(data_source=cell_source, glyph=cell_glyph) # Mesh renderer # mesh_source = ColumnDataSource() mesh_glyph = MultiLine(xs='xs', ys='ys', line_width=0.7, line_dash=[2, 5], line_color='gold') mesh = GlyphRenderer(data_source=mesh_source, glyph=mesh_glyph) # Grid renderer # grid_colormap = linear_cmap('Is', cc.CET_L19, low=0, high=8.0,
def _make_graph_plot(self): """ Builds the graph portion of the final model. """ import networkx as nx nodes = nx.nx_pydot.graphviz_layout(self._graph, prog="dot") node_x, node_y = zip(*nodes.values()) models = [self._graph.nodes[x]["model"] for x in nodes] node_id = list(nodes.keys()) node_source = ColumnDataSource( {"x": node_x, "y": node_y, "index": node_id, "model": models} ) edge_x_coords = [] edge_y_coords = [] for start_node, end_node in self._graph.edges: edge_x_coords.extend([[nodes[start_node][0], nodes[end_node][0]]]) edge_y_coords.extend([[nodes[start_node][1], nodes[end_node][1]]]) edge_source = ColumnDataSource({"xs": edge_x_coords, "ys": edge_y_coords}) p2 = Plot(outline_line_alpha=0.0) xinterval = max(max(node_x) - min(node_x), 200) yinterval = max(max(node_y) - min(node_y), 200) p2.x_range = Range1d( start=min(node_x) - 0.15 * xinterval, end=max(node_x) + 0.15 * xinterval ) p2.y_range = Range1d( start=min(node_y) - 0.15 * yinterval, end=max(node_y) + 0.15 * yinterval ) node_renderer = GlyphRenderer( data_source=node_source, glyph=Circle(x="x", y="y", size=15, fill_color="lightblue"), nonselection_glyph=Circle(x="x", y="y", size=15, fill_color="lightblue"), selection_glyph=Circle(x="x", y="y", size=15, fill_color="green"), ) edge_renderer = GlyphRenderer( data_source=edge_source, glyph=MultiLine(xs="xs", ys="ys") ) node_hover_tool = HoverTool(tooltips=[("id", "@index"), ("model", "@model")]) node_hover_tool.renderers = [node_renderer] tap_tool = TapTool() tap_tool.renderers = [node_renderer] labels = LabelSet( x="x", y="y", text="model", source=node_source, text_font_size="8pt", x_offset=-20, y_offset=7, ) help = Label( x=20, y=20, x_units="screen", y_units="screen", text_font_size="8pt", text_font_style="italic", text="Click on a model to see its attributes", ) p2.add_layout(help) p2.add_layout(edge_renderer) p2.add_layout(node_renderer) p2.tools.extend( [node_hover_tool, tap_tool, BoxZoomTool(), ResetTool(), PanTool()] ) p2.renderers.append(labels) self._node_source = node_source self._edge_source = edge_source return p2
def main(): df = pd.read_csv('../../university_ranking.csv', index_col=0) df2016 = df.loc[df['year'] == 2016].head(200) df2017 = df.loc[df['year'] == 2017].head(200) df2018 = df.loc[df['year'] == 2018].head(200) dfs = [df2016, df2017, df2018] i = 2016 for df in dfs: data = { 'Ranking': df['ranking'], 'Male': df['male'], 'Female': df['female'], 'university': df['university_name'], 'midFemale': df['female'] / 2, 'midMale': df['male'] / 2 } source = ColumnDataSource(data=data) # Set up the ranges, plot, and axes bar_height = 0.8 max_value = 100 ydr = Range1d(0, 200) xdr_left = Range1d(max_value, 0) xdr_right = Range1d(0, max_value) plot_height = 400 plot_width = 400 hover = HoverTool(tooltips=[( 'Ranking', '@Ranking'), ('% male students', '@Male%'), ('% female students', '@Female%'), ('University', '@university')]) plot_left = figure(tools=[hover], title="male", x_range=xdr_left, y_range=ydr, plot_height=plot_height, plot_width=int(plot_width / 2)) plot_right = figure(tools=[hover], title="female", x_range=xdr_right, y_range=ydr, plot_height=plot_height, plot_width=int(plot_width / 2)) # plot_left.add_layout(CategoricalAxis(), 'left') plot_right.yaxis.visible = False # Set up the ranges, plot, and axes left_rect = Rect(y='Ranking', x='midMale', width='Male', height=bar_height, fill_color="#b3cde3", line_color=None) right_rect = Rect(y='Ranking', x='midFemale', width='Female', height=bar_height, fill_color="#fbb4ae", line_color=None) left_glyph = GlyphRenderer(data_source=source, glyph=left_rect) right_glyph = GlyphRenderer(data_source=source, glyph=right_rect) plot_left.renderers.extend([left_glyph]) plot_right.renderers.extend([right_glyph]) plot_left.min_border_right = 0 plot_right.min_border_left = 0 output_file('docs/male_female.html') g = gridplot([[plot_left, plot_right]], border_space=0) show(g)
assert mock_run_notebook_hook.call_args[0][0] == curstate().notebook_type assert mock_run_notebook_hook.call_args[0][1:] == ("app", app, curstate(), "baz") assert mock_run_notebook_hook.call_args[1] == {} @patch('bokeh.io.showing._show_with_state') def test_show_doesn_not_adds_obj_to_curdoc(m) -> None: curstate().reset() assert curstate().document.roots == [] p = Plot() bis.show(p) assert curstate().document.roots == [] p = Plot() bis.show(p) assert curstate().document.roots == [] @pytest.mark.parametrize('obj', [1, 2.3, None, "str", GlyphRenderer(data_source=ColumnDataSource())]) def test_show_with_bad_object(obj) -> None: with pytest.raises(ValueError): bis.show(obj) #----------------------------------------------------------------------------- # Dev API #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Private API #----------------------------------------------------------------------------- @patch('bokeh.io.showing.run_notebook_hook') @patch('bokeh.io.showing._show_file_with_state') @patch('bokeh.io.showing.get_browser_controller')
def plot_dist_box_by_cols(summary_df, measure_name, cols_to_plot, col_groupname, colnames=None, title=None, horizontal=True, cmap="Spectral", palette=None, bgcolor="#D9EEF1", plot_range=None, plot_size=None, linked_plot=None, out_html=None, nolegend=False): ''' Build boxplot ''' # We only need cols_to_plot # Note that it uses idx values and name to label scatter points df_toplot = summary_df[cols_to_plot] # default title if title is None: title = '%s by %s' % (measure_name, col_groupname) # Stack them to prepare for plotting stacked = stack_df(df_toplot, cols_to_plot, col_groupname, measure_name) # find the quartiles and IQR for each category groups = stacked.groupby(col_groupname) mean = groups.mean() count = groups.count() q1 = groups.quantile(q=0.25) q2 = groups.quantile(q=0.5) q3 = groups.quantile(q=0.75) iqr = q3 - q1 upper = q3 + 1.5 * iqr lower = q1 - 1.5 * iqr # find the outliers for each category def outliers(group): cat = group.name return group[(group[measure_name] > upper.loc[cat][measure_name]) | ( group[measure_name] < lower.loc[cat][measure_name])][measure_name] out = groups.apply(outliers).dropna() # if no outliers, shrink lengths of stems to be no longer than the minimums or maximums qmin = groups.quantile(q=0.00) qmax = groups.quantile(q=1.00) upper.loc[:, measure_name] = [ min([x, y]) for (x, y) in zip(list(qmax.loc[:, measure_name]), upper.loc[:, measure_name]) ] lower.loc[:, measure_name] = [ max([x, y]) for (x, y) in zip(list(qmin.loc[:, measure_name]), lower.loc[:, measure_name]) ] # Put them in a single df to create a datasource for box plots box_source = pd.concat([mean, count, q1, q2, q3, iqr, upper, lower], axis=1) box_source.columns = [ 'mean', 'count', '25p', '50p', '75p', 'IQR', 'upper', 'lower' ] box_source = ColumnDataSource(box_source) # if there are outliers, put them in a single df to create a datasource for # outlier scatter plots if not out.empty: out_dat = {} for cat in cols_to_plot: if not out.loc[cat].empty: num_out = len(out.loc[cat]) out_dat[col_groupname] = out_dat.get(col_groupname, []) + [cat] * num_out out_dat[out.loc[cat].index.name] = out_dat.get( out.loc[cat].index.name, []) + (out.loc[cat].index.tolist()) out_dat[measure_name] = out_dat.get( measure_name, []) + (out.loc[cat].values.tolist()) out_source = ColumnDataSource(pd.DataFrame(out_dat)) # Categorical color mapper # If palette is provided, it overrides cmap if palette is not None: my_palette = palette else: my_palette = get_bokehpalette(cmap, len(cols_to_plot)) color_mapper = CategoricalColorMapper(factors=cols_to_plot, palette=my_palette) # properties for color etc. style_d = dict(fill_color={ 'field': col_groupname, 'transform': color_mapper }, fill_alpha=0.5, line_color='slategray') hover_style_d = dict(fill_color={ 'field': col_groupname, 'transform': color_mapper }, fill_alpha=0.9, line_color='black') # Set the plot range on the measure dimension if plot_range is not given if plot_range is None: plot_range = get_lims(stacked[measure_name].values) measure_range = Range1d(plot_range[0], plot_range[1]) very_thin_range = 0.001 * (plot_range[1] - plot_range[0]) # plot top to bottom if horizontal if horizontal: y_range = cols_to_plot[::-1] if plot_size is None: plot_size = (800, 80 + 50 * len(y_range)) p = figure(plot_width=plot_size[0], plot_height=plot_size[1], x_range=measure_range, y_range=y_range, title=title, background_fill_color=bgcolor) # components for vertically arranged horizontal boxplots seg1_d = dict(x0='25p', y0=col_groupname, x1='lower', y1=col_groupname) seg2_d = dict(x0='75p', y0=col_groupname, x1='upper', y1=col_groupname) box = HBar(y=col_groupname, right='75p', left='25p', height=0.5, line_width=2, **style_d) box_h = HBar(y=col_groupname, right='75p', left='25p', height=0.5, line_width=2, **hover_style_d) whisk1_d = dict(x='lower', y=col_groupname, width=very_thin_range, height=0.2) whisk2_d = dict(x='upper', y=col_groupname, width=very_thin_range, height=0.2) whisk3_d = dict(x='mean', y=col_groupname, width=very_thin_range, height=0.5) whisk4_d = dict(x='50p', y=col_groupname, width=very_thin_range, height=0.5) scatter = Circle(x=measure_name, size=8, y=jitter(col_groupname, width=0.6, range=p.y_range), **style_d) scatter_h = Circle(x=measure_name, size=8, y=jitter(col_groupname, width=0.6, range=p.y_range), **hover_style_d) p.xaxis.axis_label = "%s" % measure_name else: x_range = cols_to_plot if plot_size is None: plot_size = (80 + 50 * len(x_range), 800) p = figure(plot_width=plot_size[0], plot_height=plot_size[1], x_range=x_range, y_range=measure_range, title=title, background_fill_color=bgcolor) # components for horizontally arranged vertical boxplots seg1_d = dict(x0=col_groupname, y0='25p', x1=col_groupname, y1='lower') seg2_d = dict(x0=col_groupname, y0='75p', x1=col_groupname, y1='upper') box = VBar(x=col_groupname, top='75p', bottom='25p', width=0.5, line_width=2, **style_d) box_h = VBar(x=col_groupname, top='75p', bottom='25p', width=0.5, line_width=2, **hover_style_d) whisk1_d = dict(x=col_groupname, y='lower', width=0.2, height=very_thin_range) whisk2_d = dict(x=col_groupname, y='upper', width=0.2, height=very_thin_range) whisk3_d = dict(x=col_groupname, y='mean', width=0.5, height=very_thin_range) whisk4_d = dict(x=col_groupname, y='50p', width=0.5, height=very_thin_range) scatter = Circle(x=jitter(col_groupname, width=0.6, range=p.y_range), y=measure_name, size=8, **style_d) scatter_h = Circle(x=jitter(col_groupname, width=0.6, range=p.y_range), y=measure_name, size=8, **hover_style_d) p.yaxis.axis_label = "%s" % measure_name # Now plot the box by each component p.segment(line_color='slategray', line_width=4, source=box_source, **seg1_d) p.segment(line_color='slategray', line_width=4, source=box_source, **seg2_d) p.rect(line_color='slategray', line_width=4, source=box_source, **whisk1_d) p.rect(line_color='slategray', line_width=4, source=box_source, **whisk2_d) p.rect(line_color='slategray', source=box_source, **whisk3_d) p.rect(line_color='slategray', line_width=4, source=box_source, **whisk4_d) box_glyph = GlyphRenderer(data_source=box_source, glyph=box, hover_glyph=box_h) # Make and add the hover tool box_tooltips = [(col_groupname, '@%s' % col_groupname), ('count', '@count'), ('mean', '@mean'), ('median', '@50p'), ('IQR', '@IQR'), ('upper', '@upper'), ('lower', '@lower')] box_hover = HoverTool(renderers=[box_glyph], tooltips=box_tooltips) p.add_tools(box_hover) p.renderers.extend([box_glyph]) # Plot outliers if any if not out.empty: out_scatter = GlyphRenderer(data_source=out_source, glyph=scatter, hover_glyph=scatter_h) scatter_tooltips = [(df_toplot.index.name, '@%s' % df_toplot.index.name), (col_groupname, '@%s' % col_groupname), ('%s value' % measure_name, '@%s' % measure_name)] scat_hover = HoverTool(renderers=[out_scatter], tooltips=scatter_tooltips) p.add_tools(scat_hover) p.renderers.extend([out_scatter]) p.min_border = 10 #5 #p.min_border_bottom = 100 if nolegend: p.yaxis.visible = False p.min_border_left = 60 p.min_border_right = 60 if out_html is not None: bokeh.io.save(p, filename=out_html, title=title) return p
yaxis = LinearAxis(plot=plot) ygrid = Grid(plot=plot, dimension=1, ticker=yaxis.ticker) plot.left.append(yaxis) cty_glyph = Circle(x="index", y="cty", fill_color="#396285", size=8, fill_alpha=0.5, line_alpha=0.5) hwy_glyph = Circle(x="index", y="hwy", fill_color="#CE603D", size=8, fill_alpha=0.5, line_alpha=0.5) cty = GlyphRenderer(data_source=source, glyph=cty_glyph) hwy = GlyphRenderer(data_source=source, glyph=hwy_glyph) tooltips = [ ("Manufacturer", "@manufacturer"), ("Model", "@model"), ("Displacement", "@displ"), ("Year", "@year"), ("Cylinders", "@cyl"), ("Transmission", "@trans"), ("Drive", "@drv"), ("Class", "@class"), ] cty_hover_tool = HoverTool(plot=plot, renderers=[cty], tooltips=tooltips + [("City MPG", "@cty")]) hwy_hover_tool = HoverTool(plot=plot,
p1.line(cu1_ids, 1.2, line_width=1, legend='Rejected: ' + str(cu1_rejected)) #daily rejected p1.line(cu1_ids, 1.2, line_width=2, line_color='green') p1.line(cu1_ids, 1.4, line_width=2, line_color='green') p1.background_fill = 'beige' p1.xaxis.axis_label = 'Grid Id' p1.yaxis.axis_label = 'Weights(g)' #Meco plot m_s = ColumnDataSource(data=dict(x=m_ids, y=m_weights)) p3 = figure(plot_width=780, plot_height=550, tools = "pan,box_select,box_zoom,xwheel_zoom,reset,save,resize", title="Meco Tool") p3.line('x', 'y', source=m_s, line_width=2) glyph = Circle(x='x',y='y', size=6, fill_color='white') rend = GlyphRenderer(data_source=m_s, glyph=glyph) hover = HoverTool( plot=p3, renderers=[rend], tooltips=[ ("GridId, Weight", "@x, @y"), ] ) p3.tools.extend([hover]) p3.renderers.extend([rend]) m_avg = ColumnDataSource(data=dict(y=[m_stats['avg'], m_stats['avg']])) m_lower = ColumnDataSource(data=dict(y=[m_stats['lcl'], m_stats['lcl']])) m_upper = ColumnDataSource(data=dict(y=[m_stats['ucl'], m_stats['ucl']])) p3.line(x=[m_ids[0], m_ids[len(m_ids)-1]], y='y', source=m_avg, line_width=2, line_color='red', line_dash=[4,4], legend='Mean = ' + str(round(m_stats['avg'], 3)))
def create(self): manufacturers = sorted(mpg["manufacturer"].unique()) models = sorted(mpg["model"].unique()) transmissions = sorted(mpg["trans"].unique()) drives = sorted(mpg["drv"].unique()) classes = sorted(mpg["class"].unique()) manufacturer_select = Select(title="Manufacturer:", value="All", options=["All"] + manufacturers) manufacturer_select.on_change('value', self.on_manufacturer_change) model_select = Select(title="Model:", value="All", options=["All"] + models) model_select.on_change('value', self.on_model_change) transmission_select = Select(title="Transmission:", value="All", options=["All"] + transmissions) transmission_select.on_change('value', self.on_transmission_change) drive_select = Select(title="Drive:", value="All", options=["All"] + drives) drive_select.on_change('value', self.on_drive_change) class_select = Select(title="Class:", value="All", options=["All"] + classes) class_select.on_change('value', self.on_class_change) columns = [ TableColumn(field="manufacturer", title="Manufacturer", editor=SelectEditor(options=manufacturers), formatter=StringFormatter(font_style="bold")), TableColumn(field="model", title="Model", editor=StringEditor(completions=models)), TableColumn(field="displ", title="Displacement", editor=NumberEditor(step=0.1), formatter=NumberFormatter(format="0.0")), TableColumn(field="year", title="Year", editor=IntEditor()), TableColumn(field="cyl", title="Cylinders", editor=IntEditor()), TableColumn(field="trans", title="Transmission", editor=SelectEditor(options=transmissions)), TableColumn(field="drv", title="Drive", editor=SelectEditor(options=drives)), TableColumn(field="class", title="Class", editor=SelectEditor(options=classes)), TableColumn(field="cty", title="City MPG", editor=IntEditor()), TableColumn(field="hwy", title="Highway MPG", editor=IntEditor()), ] data_table = DataTable(source=self.source, columns=columns, editable=True) xdr = DataRange1d() ydr = DataRange1d() plot = Plot(title=None, x_range=xdr, y_range=ydr, plot_width=800, plot_height=300) xaxis = LinearAxis(plot=plot) plot.below.append(xaxis) yaxis = LinearAxis(plot=plot) ygrid = Grid(plot=plot, dimension=1, ticker=yaxis.ticker) plot.left.append(yaxis) cty_glyph = Circle(x="index", y="cty", fill_color="#396285", size=8, fill_alpha=0.5, line_alpha=0.5) hwy_glyph = Circle(x="index", y="hwy", fill_color="#CE603D", size=8, fill_alpha=0.5, line_alpha=0.5) cty = GlyphRenderer(data_source=self.source, glyph=cty_glyph) hwy = GlyphRenderer(data_source=self.source, glyph=hwy_glyph) tooltips = [ ("Manufacturer", "@manufacturer"), ("Model", "@model"), ("Displacement", "@displ"), ("Year", "@year"), ("Cylinders", "@cyl"), ("Transmission", "@trans"), ("Drive", "@drv"), ("Class", "@class"), ] cty_hover_tool = HoverTool(plot=plot, renderers=[cty], tooltips=tooltips + [("City MPG", "@cty")]) hwy_hover_tool = HoverTool(plot=plot, renderers=[hwy], tooltips=tooltips + [("Highway MPG", "@hwy")]) select_tool = BoxSelectTool(plot=plot, renderers=[cty, hwy], dimensions=['width']) plot.tools.extend([cty_hover_tool, hwy_hover_tool, select_tool]) plot.renderers.extend([cty, hwy, ygrid]) controls = VBox(children=[ manufacturer_select, model_select, transmission_select, drive_select, class_select ], width=200) top_panel = HBox(children=[controls, plot]) layout = VBox(children=[top_panel, data_table]) return layout
last_date = last_items[1] + '-' + last_items[0] + '-' + last_items[2] if first_date == last_date: output_file(first_date + '.html', title=first_date) else: output_file(first_date + ' to ' + last_date + '.html', title=first_date + ' to ' + last_date) #Cu1 Plot cu1_s = ColumnDataSource(data=dict(x=cu1_ids, y=cu1_weights)) p1 = figure(plot_width=780, plot_height=550, tools = "pan,box_select,box_zoom,xwheel_zoom,reset,save,resize", title="Cu Tool 1") p1.line('x', 'y', source=cu1_s, line_width=2) p1.circle('x', 'y', source=cu1_s, fill_color='white', size=8) cu1_glyph = Circle(x='x',y='y', size=6, fill_color='white') cu1_rend = GlyphRenderer(data_source=cu1_s, glyph=cu1_glyph) cu1_hover = HoverTool( plot=p1, renderers=[cu1_rend], tooltips=[ ("GridId, Weight", "@x, @y"), ] ) p1.tools.extend([cu1_hover]) p1.renderers.extend([cu1_rend]) cu1_avg = ColumnDataSource(data=dict(y=[cu1_stats['avg'], cu1_stats['avg']], cl=cl)) cu1_lower = ColumnDataSource(data=dict(y=[cu1_stats['lcl'], cu1_stats['lcl']])) cu1_upper = ColumnDataSource(data=dict(y=[cu1_stats['ucl'], cu1_stats['ucl']]))