def scalebar_cropped(self, x_range, y_range): if x_range and y_range: x0, x1 = x_range y0, y1 = y_range x_span = x1 - x0 y_span = y1 - y0 y0 = y0 + int(y_span / 20) y1 = y0 + int(y_span / 50) ytext = y1 + int(y_span / 30) x0 = x1 - self.scalebar_size_cropped - int(x_span / 30) x1 = x1 - int(x_span / 30) rect = hv.Rectangles((x0, y0, x1, y1)).opts(color="w") text = hv.Text(x0, ytext, str(self.scalebar_size_cropped) + " um").opts( text_color="w", text_align="left", text_font="Helvetica" ) scalebar = rect * text return scalebar else: x0 = self.x_range[0] y0 = self.y_range[0] x1 = self.x_range[1] y1 = self.y_range[1] x_span = x1 - x0 y_span = y1 - y0 y0 = y0 + int(y_span / 20) y1 = y0 + int(y_span / 50) x0 = x1 - self.scalebar_size_cropped - int(x_span / 40) x1 = x1 - int(x_span / 30) ytext = y1 + int(y_span / 30) rect = hv.Rectangles((x0, y0, x1, y1)).opts(color="w") text = hv.Text(x0, ytext, str(self.scalebar_size_cropped) + " um").opts( text_color="w", text_align="left", text_font="Helvetica" ) scalebar = rect * text return scalebar
def scalebar(self, x_range, y_range): if x_range and y_range: x0, x1 = x_range y0, y1 = y_range x_span = x1 - x0 y_span = y1 - y0 y0 = y0 + int(y_span / 20) y1 = y0 + int(y_span / 50) ytext = y1 + int(y_span / 30) x0 = x1 - self.scalebar_size - int(x_span / 30) x1 = x1 - int(x_span / 30) rect = hv.Rectangles((x0, y0, x1, y1)).opts(color="w") text = hv.Text(x0, ytext, str(self.scalebar_size) + " um").opts( text_color="w", text_align="left", text_font="Helvetica" ) scalebar = rect * text return scalebar else: x0 = 0 y0 = 0 x1 = self.rendered_image.data["x"].size y1 = self.rendered_image.data["y"].size x_span = x1 - x0 y_span = y1 - y0 y0 = y0 + int(y_span / 20) y1 = y0 + int(y_span / 50) x0 = x1 - self.scalebar_size - int(x_span / 40) x1 = x1 - int(x_span / 30) ytext = y1 + int(y_span / 30) rect = hv.Rectangles((x0, y0, x1, y1)).opts(color="w") text = hv.Text(x0, ytext, str(self.scalebar_size) + " um").opts( text_color="w", text_align="left", text_font="Helvetica" ) scalebar = rect * text return scalebar
def plot_rect(data): if show_legend: opts = {} else: # If there is no legend, we are gonna plot all the rectangles at once so we use colormapping to distinguish the tasks opts = dict( color='pid', # Colormap from colorcet with a large number of color, so it is # suitable for plotting many tasks cmap='glasbey_hv', ) return hv.Rectangles( data, kdims=[ hv.Dimension('Time'), hv.Dimension('CPU'), hv.Dimension('x1'), hv.Dimension('y1'), ] ).options( show_legend=show_legend, alpha=alpha, **opts, ).options( backend='matplotlib', linewidth=0, ).options( backend='bokeh', line_width=0, tools=[self._BOKEH_TASK_HOVERTOOL], )
class RoiEditor(param.Parameterized): '''mixin class to add bounding box editor capabilities''' roi_plot = param.Parameter(hv.Rectangles([], group='ROIedit')) box_edit = param.Parameter(streams.BoxEdit(), instantiate=True) spacing = param.NumericTuple((1, 1), doc='2D pixel size') def __init__(self, *args, **kwargs): num_objects = kwargs.pop('num_objects', 1) super().__init__(*args, **kwargs) self.box_edit.num_objects = num_objects self.box_edit.source = self.roi_plot def img_slice(self): '''return image slice in px coordinates''' if self.box_edit.data is None or not self.box_edit.data['x0']: return None # repack dict of 4 lists as a list of (x0,x1,y0,y1) rois = list(zip(*self.box_edit.data.values())) loc = [(slice(max(0, round(y1 / self.spacing[0])), max(0, round(y0 / self.spacing[0]))), slice(max(0, round(x0 / self.spacing[1])), max(0, round(x1 / self.spacing[1])))) for x0, x1, y0, y1 in rois] return loc
def _timetable(self, x, y): if self.solutions.empty: return (hv.Points((0, 0)).opts(alpha=0) * hv.Text( 0, 0, 'No Journeys Found').opts(color='firebrick')).opts( xlim=(-1, 1), xaxis=None, yaxis=None, show_frame=False, toolbar=None) stop_time = self.stop_time * 10**3 time_delta = stop_time - self.solutions['start_time'].min() boxes_opts = { 'color': 'color', 'line_width': 0, 'tools': [ HoverTool( tooltips=[('From', '@station_name'), ('To', '@station_name_stop'), ('Departure Time', '@departure'), ('Arrival Time', '@arrival'), ('Travel Type', '@transport_type'), ( 'Line', '@line_text'), ('Trip', '@trip_id')]) ], } opts = { 'height': int(self.solutions['path'].max() + 3) * 50, 'width': 600, 'ylim': (-1, self.solutions['path'].max() + 2), 'xlim': (self.solutions['start_time'].min() - time_delta * 0.1, stop_time + time_delta * 0.1), 'hooks': [datetime_ticks], 'yaxis': None, 'show_frame': False, 'xlabel': '', 'toolbar': None, 'active_tools': [] } boxes = hv.Rectangles( self.line_aggregate, ['start_time', 'y_min', 'stop_time', 'y_max'], [ 'color', 'station_name', 'station_name_stop', 'departure', 'arrival', 'transport_type', 'trip_id', 'line_text' ]).opts(**boxes_opts) text = self._timetable_text() stop_line = hv.VLine(stop_time).opts(line_width=1, line_color='red') return (boxes * text * stop_line).opts(**opts)
def create_candle_stick(data: pd.DataFrame) -> hv.Layout: """Creates a candle stick plot Args: data (pd.DataFrame): A dataframe with columns time, open, high, low, close and volume Returns: hv.Layout: A candle stick plot """ data = data.copy(deep=True) t_delta = timedelta(hours=1) data["time_start"] = data.time - 9 * t_delta # rectangles start data["time_end"] = data.time + 9 * t_delta # rectangles end data["positive"] = ((data.close - data.open) > 0).astype(int) tooltips = [ ("Time", "@{time}{%F}"), ("Open", "@open"), ("High", "@high"), ("Low", "@{price}"), ("Close", "@close"), ("Volume", "@volume{0,0}"), ] hover = HoverTool(tooltips=tooltips, formatters={"@{time}": "datetime"}) candlestick = hv.Segments( data, kdims=["time", "low", "time", "high"]) * hv.Rectangles( data, kdims=["time_start", "open", "time_end", "close"], vdims=["positive", "high", "low", "time", "volume"], ) candlestick = candlestick.redim(low="price") candlestick.opts( hv.opts.Rectangles( color="positive", cmap=[RED, GREEN], responsive=True, tools=["box_zoom", "pan", "wheel_zoom", "save", "reset", hover], default_tools=[], active_tools=["box_zoom"], ), hv.opts.Segments( color=GRAY, height=400, responsive=True, tools=["box_zoom", "pan", "reset"], default_tools=[], active_tools=["box_zoom"], ), ) return candlestick
def get_plot(self, df): """ Dataframe df must have columns x0, y0, x1, y1 (in this order) for coordinates bottom-left (x0, y0) and top right (x1, y1). Optionally a fifth value-column can be provided for colors Parameters ---------- df Returns ------- """ # processed = {} # for k, v in self.kwargs.items(): # if k.endswith('formatter') and isinstance(v, str) and '%' not in v: # v = NumeralTickFormatter(format=v) # processed[k] = v # if self.streaming: # processed['stream'] = self._stream #hvplots stream? https://holoviews.org/user_guide/Streaming_Data.html # plot = hv.Rectangles([(0, 0, 1, 1), (2, 3, 4, 6), (0.5, 2, 1.5, 4), (2, 1, 3.5, 2.5)]) processed = {} for k, v in self.kwargs.items(): if k.endswith('formatter') and isinstance(v, str) and '%' not in v: v = NumeralTickFormatter(format=v) processed[k] = v if self.streaming: #processed['stream'] = self._stream plot = hv.DynamicMap(hv.Rectangles, streams=[self._stream]) plot = plot.apply.opts(**self.opts) if self.opts else plot else: plot = hv.Rectangles(df) plot.opts(**self.opts) if self.opts else plot if self.selection_group or 'selection_expr' in self._param_watchers: plot = self._link_plot(plot) return plot
# define which regions should be able to highlight # keep in mind that each option has to be implemented further below # highlights = ["None", "Pause", "Continuous Watch"] highlights = ["None", "Pauses", "Skips"] # instantiate the input text boxes where information can be added to enable uploading data to the database input_name = pn.widgets.TextInput( name="Name of Annotation", placeholder="Enter a name for the annotation") input_annotator_id = pn.widgets.TextInput( name="Annotator ID", placeholder="Enter your annotator ID (e.g. 'p1')") input_additional_info = pn.widgets.TextInput( name="Additional Information", placeholder="Optional additional information...") # instantiate the box edit tool boxes = hv.Rectangles([]) box_stream = streams.BoxEdit(source=boxes, num_objects=100, styles={'fill_color': ['red']}) boxes.opts(opts.Rectangles(active_tools=['box_edit'], fill_alpha=0.5)) # define and activate hover tool for box edits, so the index of the box is shown, when the mouse is hovering over boxes hover = HoverTool(tooltips=[ ("index", "$index"), ]) boxes.opts(tools=[hover]) ################################# # Fxns for making static raster # #################################
def view( self, *, channels, rscale=None, gscale=None, bscale=None, percentile=98, show_miniview=True, height=600, resolution=900, ): self.channels = channels self.resolution = resolution self.rscale = rscale or self.ds.display_interval( channels[0], percentile) self.gscale = gscale or self.ds.display_interval( channels[1], percentile) self.bscale = bscale or self.ds.display_interval( channels[2], percentile) self.setup_streams() self.setup_controller(channels=channels) self.setup_template(height=height) tooltips = [ ("x", "$x{(0)}"), ("y", "$y{(0)}"), ] hover = HoverTool(tooltips=tooltips) self.main = self.mainview().opts( clone=True, responsive=True, hooks=[remove_bokeh_logo], default_tools=[hover], title=f"Sample: {self.name}", ) boxes = hv.Rectangles([]) self.box_stream = streams.BoxEdit( source=boxes, styles={"fill_color": ["yellow", "red", "green", "blue", "cyan"]}, ) boxes = boxes.opts(hv.opts.Rectangles(active_tools=[], fill_alpha=0.5)) overlay = hd.regrid(hv.Image([]), streams=[self.pointer]) if show_miniview: mini = (self.miniview().clone(link=False).opts( width=200, height=200, xaxis=None, yaxis=None, default_tools=[], shared_axes=False, hooks=[remove_bokeh_logo], )) zoom = self.zoomview().opts( width=200, height=200, xaxis=None, yaxis=None, default_tools=[], shared_axes=False, hooks=[remove_bokeh_logo], ) RangeToolLink(mini, self.main, axes=["x", "y"]) self.tmpl.add_panel( "A", pn.Row( pn.panel(self.main * overlay * boxes), pn.Column(pn.panel(mini), pn.panel(zoom)), width=400, height=280, sizing_mode="scale_both", ), ) else: self.tmpl.add_panel("A", pn.Row(pn.panel(self.main))) self.tmpl.add_panel("C", self.controller) return self.tmpl