def _arc(self, df, line_alpha=CALENDAR_ALPHA, color=CALENDAR_COLOR): arc = Arc(x=CALENDAR_X, y=CALENDAR_Y, radius=CALENDAR_ARC_RADIUS, start_angle=CALENDAR_START, end_angle=CALENDAR_END, direction='anticlock', line_color=color, line_alpha=line_alpha) return self._plot.add_glyph( ColumnDataSource(df), arc, name='with_hover' if df is self._df else None)
def add_gauge(radius: float, max_value: float, length: float, direction: Literal[-1, 1], color: Any, major_step: int, minor_step: int) -> None: major_angles, minor_angles = [], [] total_angle = start_angle - end_angle major_angle_step = float(major_step) / max_value * total_angle minor_angle_step = float(minor_step) / max_value * total_angle major_angle = 0 while major_angle <= total_angle: major_angles.append(start_angle - major_angle) major_angle += major_angle_step minor_angle = 0 while minor_angle <= total_angle: minor_angles.append(start_angle - minor_angle) minor_angle += minor_angle_step major_labels = [major_step * i for i, _ in enumerate(major_angles)] n = major_step / minor_step minor_angles = [x for i, x in enumerate(minor_angles) if i % n != 0] glyph = Arc(x=0, y=0, radius=radius, start_angle=start_angle, end_angle=end_angle, direction="clock", line_color=color, line_width=2) plot.add_glyph(glyph) rotation = 0 if direction == 1 else -pi angles = [angle + rotation for angle in major_angles] source = ColumnDataSource(dict(major_angles=major_angles, angle=angles)) t = PolarTransform(radius=radius, angle="major_angles") glyph = Ray(x=expr(t.x), y=expr(t.y), length=data(length), angle="angle", line_color=color, line_width=2) plot.add_glyph(source, glyph) angles = [angle + rotation for angle in minor_angles] source = ColumnDataSource(dict(minor_angles=minor_angles, angle=angles)) t = PolarTransform(radius=radius, angle="minor_angles") glyph = Ray(x=expr(t.x), y=expr(t.y), length=data(length / 2), angle="angle", line_color=color, line_width=1) plot.add_glyph(source, glyph) text_angles = [angle - pi / 2 for angle in major_angles] source = ColumnDataSource( dict(major_angles=major_angles, angle=text_angles, text=major_labels)) t = PolarTransform(radius=radius + 2 * length * direction, angle="major_angles") glyph = Text(x=expr(t.x), y=expr(t.y), angle="angle", text="text", text_align="center", text_baseline="middle") plot.add_glyph(source, glyph)
inner_radius=screen(10), outer_radius=screen(20), start_angle=0.6, end_angle=4.1, fill_color="#8888ee")), ("annulus", Annulus(x="x", y="y", inner_radius=screen(10), outer_radius=screen(20), fill_color="#7FC97F")), ("arc", Arc(x="x", y="y", radius=screen(20), start_angle=0.6, end_angle=4.1, line_color="#BEAED4", line_width=3)), ("bezier", Bezier(x0="x", y0="y", x1="xp02", y1="y", cx0="xp01", cy0="yp01", cx1="xm01", cy1="ym01", line_color="#D95F02", line_width=2)), ("ellipse",
def add_gauge(plot, radius, max_value, length, direction, color, major_step, minor_step, offset = 0): ''' draw the gauge in plot area :param plot: :param radius: :param max_value: :param length: :param direction: :param color: :param major_step: :param minor_step: :param offset: :return: ''' start_angle = pi + pi / 4 end_angle = -pi / 4 major_angles, minor_angles = [], [] total_angle = start_angle - end_angle major_angle_step = float(major_step) / max_value * total_angle minor_angle_step = float(minor_step) / max_value * total_angle major_angle = 0 while major_angle <= total_angle: major_angles.append(start_angle - major_angle) major_angle += major_angle_step minor_angle = 0 while minor_angle <= total_angle: minor_angles.append(start_angle - minor_angle) minor_angle += minor_angle_step major_labels = [major_step * i + offset for i, _ in enumerate(major_angles)] n = major_step / minor_step minor_angles = [x for i, x in enumerate(minor_angles) if i % n != 0] glyph = Arc(x=0, y=0, radius=radius, start_angle=start_angle, end_angle=end_angle, direction="clock", line_color=color, line_width=2) plot.add_glyph(glyph) rotation = 0 if direction == 1 else -pi x, y = zip(*[polar_to_cartesian(radius, angle) for angle in major_angles]) angles = [angle + rotation for angle in major_angles] source = ColumnDataSource(dict(x=x, y=y, angle=angles)) glyph = Ray(x="x", y="y", length=data(length), angle="angle", line_color=color, line_width=2) plot.add_glyph(source, glyph) x, y = zip(*[polar_to_cartesian(radius, angle) for angle in minor_angles]) angles = [angle + rotation for angle in minor_angles] source = ColumnDataSource(dict(x=x, y=y, angle=angles)) glyph = Ray(x="x", y="y", length=data(length / 2), angle="angle", line_color=color, line_width=1) plot.add_glyph(source, glyph) x, y = zip(*[polar_to_cartesian(radius + 2 * length * direction, angle) for angle in major_angles]) text_angles = [angle - pi / 2 for angle in major_angles] source = ColumnDataSource(dict(x=x, y=y, angle=text_angles, text=major_labels)) glyph = Text(x="x", y="y", angle="angle", text="text", text_align="center", text_baseline="middle") plot.add_glyph(source, glyph)
x = np.linspace(-2, 2, N) y = x**2 r = x / 15.0 + 0.3 source = ColumnDataSource(dict(x=x, y=y, r=r)) plot = Plot(title=None, width=300, height=300, min_border=0, toolbar_location=None) glyph = Arc(x="x", y="y", radius="r", start_angle=0.6, end_angle=4.1, line_color="#beaed4", line_width=3) plot.add_glyph(source, glyph) xaxis = LinearAxis() plot.add_layout(xaxis, 'below') yaxis = LinearAxis() plot.add_layout(yaxis, 'left') plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker)) plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker)) curdoc().add_root(plot)
def helper(obs: Observable, plot=None): # Domain-specific rendering if isinstance(obs, GraphObservable): if plot is None: plot = figure(x_range=self.x_rng, y_range=self.y_rng, tooltips=[], width=self.plot_width, height=self.plot_height) plot.axis.visible = False plot.xgrid.grid_line_color = None plot.ygrid.grid_line_color = None renderer = from_networkx(G, layout) plot.renderers.append(renderer) plot.toolbar_location = None if obs.Gd is GraphDomain.nodes: plot.add_tools(HoverTool(tooltips=[('value', '@value'), ('node', '@node')])) plot.renderers[0].node_renderer.data_source.data['node'] = list(map(str, items[0].G.nodes())) plot.renderers[0].node_renderer.data_source.data['value'] = obs.y cmap = LinearColorMapper(palette=self.node_palette, low=self.node_rng[0], high=self.node_rng[1]) self.node_cmaps[obs.plot_id] = cmap if isinstance(obs, gds): plot.renderers[0].node_renderer.data_source.data['thickness'] = [3 if (x in obs.X_dirichlet or x in obs.X_neumann) else 1 for x in obs.X] plot.renderers[0].node_renderer.glyph = Ellipse(height=self.node_size, width=self.node_size, fill_color=field('value', cmap), line_width='thickness') else: plot.renderers[0].node_renderer.glyph = Ellipse(height=self.node_size, width=self.node_size, fill_color=field('value', cmap)) if self.colorbars: cbar = ColorBar(color_mapper=cmap, ticker=BasicTicker(), title='node') cbar.major_label_text_font_size = "15pt" plot.add_layout(cbar, 'right') elif obs.Gd is GraphDomain.edges: plot.add_tools(HoverTool(tooltips=[('value', '@value'), ('edge', '@edge')])) self.prep_layout_data(obs, G, layout) obs.arr_source.data['edge'] = list(map(str, items[0].G.edges())) self.draw_arrows(obs, obs.y) plot.renderers[0].edge_renderer.data_source.data['value'] = obs.arr_source.data['value'] cmap = LinearColorMapper(palette=self.edge_palette, low=self.edge_rng[0], high=self.edge_rng[1]) self.edge_cmaps[obs.plot_id] = cmap arrows = Patches(xs='xs', ys='ys', fill_color=field('value', cmap)) plot.add_glyph(obs.arr_source, arrows) if self.colorbars: cbar = ColorBar(color_mapper=cmap, ticker=BasicTicker(), title='edge') cbar.major_label_text_font_size = "15pt" plot.add_layout(cbar, 'right') if self.edge_colors: plot.renderers[0].edge_renderer.glyph = MultiLine(line_width=5, line_color=field('value', cmap)) elif isinstance(obs, gds): plot.renderers[0].edge_renderer.data_source.data['thickness'] = [3 if (x in obs.X_dirichlet or x in obs.X_neumann) else 1 for x in obs.X] plot.renderers[0].edge_renderer.glyph = MultiLine(line_width='thickness') elif obs.Gd is GraphDomain.faces: plot.add_tools(HoverTool(tooltips=[('value', '@value'), ('face', '@face')])) cmap = LinearColorMapper(palette=self.face_palette, low=self.face_rng[0], high=self.face_rng[1]) self.face_cmaps[obs.plot_id] = cmap obs.face_source = ColumnDataSource() xs = [[orig_layout[n][0] for n in f] for f in obs.faces] ys = [[orig_layout[n][1] for n in f] for f in obs.faces] if hasattr(obs.G, 'rendered_faces'): # Hacky xs = [xs[i] for i in obs.G.rendered_faces] ys = [ys[i] for i in obs.G.rendered_faces] obs.face_source.data['xs'] = xs obs.face_source.data['ys'] = ys obs.face_source.data['value'] = np.zeros(len(xs)) faces = Patches(xs='xs', ys='ys', fill_color=field('value', cmap), line_color='#FFFFFF', line_width=2) plot.add_glyph(obs.face_source, faces) if self.face_orientations: # TODO: only works for convex faces obs.centroid_x, obs.centroid_y = np.array([np.mean(row) for row in xs]), np.array([np.mean(row) for row in ys]) obs.radius = 0.3 * np.array([min([np.sqrt((xs[i][j] - obs.centroid_x[i])**2 + (ys[i][j] - obs.centroid_y[i])**2) for j in range(len(xs[i]))]) for i in range(len(xs))]) height = 2/5 * obs.radius arrows_ys = np.stack((obs.centroid_y-obs.radius, obs.centroid_y-obs.radius+height/2, obs.centroid_y-obs.radius-height/2), axis=1) obs.face_source.data['centroid_x'] = obs.centroid_x obs.face_source.data['centroid_y'] = obs.centroid_y obs.face_source.data['radius'] = obs.radius obs.face_source.data['arrows_ys'] = (arrows_ys + 0.01).tolist() self.draw_face_orientations(obs, cmap) arcs = Arc(x='centroid_x', y='centroid_y', radius='radius', start_angle=-0.9, end_angle=4.1, line_color=field('arrow_color', cmap)) arrows = Patches(xs='arrows_xs', ys='arrows_ys', fill_color=field('arrow_color', cmap), line_color=field('arrow_color', cmap)) plot.add_glyph(obs.face_source, arcs) plot.add_glyph(obs.face_source, arrows) if self.colorbars: cbar = ColorBar(color_mapper=cmap, ticker=BasicTicker(), title='face') cbar.major_label_text_font_size = "15pt" plot.add_layout(cbar, 'right') else: raise Exception('unknown graph domain.') elif isinstance(obs, PointObservable): plot = figure(width=self.plot_width, height=self.plot_height) plot.add_tools(HoverTool(tooltips=[('time', '@t'), ('value', '@value')])) plot.toolbar_location = None plot.x_range.follow = 'end' plot.x_range.follow_interval = 10.0 plot.x_range.range_padding = 0 plot.xaxis.major_label_text_font_size = "15pt" plot.xaxis.axis_label = 'Time' plot.yaxis.major_label_text_font_size = "15pt" plot.y_range.range_padding_units = 'absolute' plot.y_range.range_padding = obs.render_params['min_res'] / 2 obs.src = ColumnDataSource({'t': [], 'value': []}) glyph = Line(x='t', y='value') plot.add_glyph(obs.src, glyph) # plot.line('t', 'value', line_color='black', source=obs.src) elif isinstance(obs, VectorObservable): plot = figure(width=self.plot_width, height=self.plot_height, y_range=obs.domain) plot.add_tools(HoverTool(tooltips=[('time', '@t'), ('value', '@val'), ('y', '@y')])) plot.toolbar_location = None plot.x_range.follow = 'end' plot.x_range.follow_interval = 10.0 plot.x_range.range_padding = 0 # plot.xaxis.major_label_text_font_size = "15pt" # plot.xaxis.axis_label = 'Time' # plot.yaxis.major_label_text_font_size = "15pt" obs.src = ColumnDataSource({'t': [], 'y': [], 'w': [], 'val': []}) obs.cmap = LinearColorMapper(palette=self.vec_palette, low=0, high=1) obs.last_t = obs.t plot.rect(x='t', y='y', width='w', height=1, source=obs.src, line_color=None, fill_color=field('val', obs.cmap)) if self.colorbars: cbar = ColorBar(color_mapper=obs.cmap, ticker=BasicTicker(), title='value') cbar.major_label_text_font_size = "15pt" plot.add_layout(cbar, 'right') else: raise Exception('unknown observable type: ', obs) return plot
def __init__(self, lcolor='black', **kwargs): pl_wdt = pl_hgt = 1400 self.tooltips = kwargs.get('tooltips') if self.tooltips: self.p = figure( plot_width=pl_wdt, plot_height=pl_hgt, tooltips=self.tooltips, ) else: self.p = figure(plot_width=pl_wdt, plot_height=pl_hgt) self.left, self.right, self.bottom, self.top = -800, 800, -200, 1500 self.p.x_range = Range1d(self.left, self.right) self.p.y_range = Range1d(self.bottom, self.top) self.p.axis.visible = False self.p.grid.visible = False self.rectang = Rect(x="x", y="y", width="w", height="h", fill_color="fc") self.circle = Circle(x="x", y="y", radius="r", line_color=lcolor, fill_color='white') self.arc = Arc(x="x", y="y", radius="r", line_color=lcolor, start_angle="sa", end_angle="ea", end_angle_units="grad", line_dash="ld") # Main court self.main_court = ColumnDataSource({ 'x': [0], 'y': [621.25], 'w': [1500], 'h': [1400], 'fc': ["#f8f9f9"] }) self.p.add_glyph(self.main_court, self.rectang) # Rim self.rim = ColumnDataSource({'x': [0], 'y': [0], 'r': [23]}) self.p.add_glyph(self.rim, self.circle) # Backboard self.backboard = ColumnDataSource({ 'x': [0], 'y': [-37.5], 'w': [183], 'h': [1], 'fc': ["#0"] }) self.p.add_glyph(self.backboard, self.rectang) # The paint self.outer_paint = ColumnDataSource({ 'x': [0], 'y': [211.25], 'w': [490], 'h': [580], 'fc': ["#0"] }) self.p.add_glyph(self.outer_paint, self.rectang) # Free throw top arc self.ftt_arc = ColumnDataSource({ 'x': [0], 'y': [502.5], 'r': [180], 'sa': [0], 'ea': [200], 'ld': ["solid"] }) self.p.add_glyph(self.ftt_arc, self.arc) # Free throw bottomw arc self.ftb_arc = ColumnDataSource({ 'x': [0], 'y': [502.5], 'r': [180], 'sa': [600], 'ea': [0], 'ld': ["dashed"] }) self.p.add_glyph(self.ftb_arc, self.arc) # Corner 3pt self.corner_three_a = ColumnDataSource({ 'x': [663], 'y': [72], 'w': [-1], 'h': [300], 'fc': ["#0"] }) self.p.add_glyph(self.corner_three_a, self.rectang) self.corner_three_b = ColumnDataSource({ 'x': [-663], 'y': [72], 'w': [-1], 'h': [300], 'fc': ["#0"] }) self.p.add_glyph(self.corner_three_b, self.rectang) # 3pt Arc self.three_arc_src = ColumnDataSource({'x': [0], 'y': [0], 'r': [700]}) self.three_arc = Arc(x="x", y="y", radius="r", line_color=lcolor, start_angle=0.32, end_angle=2.825, direction='anticlock') self.p.add_glyph(self.three_arc_src, self.three_arc) # Center court arc self.center_court = ColumnDataSource({ 'x': [0], 'y': [1320], 'r': [180], 'sa': [600], 'ea': [0], 'ld': ["solid"] }) self.p.add_glyph(self.center_court, self.arc) # Restricted zone arc self.restricted = ColumnDataSource({ 'x': [0], 'y': [0], 'r': [125], 'sa': [0], 'ea': [200], 'ld': ["solid"] }) self.p.add_glyph(self.restricted, self.arc)