def wtrack_linear_plot_polygons(arm, direction, pos_time, w_coor): time_range = (pos_time[0], pos_time[-1]) y_range = (w_coor[arm][direction].x1, w_coor[arm][direction].x2) time_total = time_range[1] - time_range[0] time_center = time_total / 2 + time_range[0] y_total = y_range[1] - y_range[0] y_center = y_total / 2 + y_range[0] box = hv.Box(time_center, y_center, (time_total, y_total)) init_hooks = [ functools.partial( WtrackLinposVisualizer.wtrack_linear_plot_init_hook, arm=arm, direction=direction) ] hooks = [ functools.partial(WtrackLinposVisualizer.wtrack_linear_plot_hook, arm=arm, direction=direction) ] if hv.Store.current_backend == 'bokeh': poly = hv.Polygons(box).opts(hooks=hooks) elif hv.Store.current_backend == 'matplotlib': poly = hv.Polygons(box).opts(initial_hooks=init_hooks) return poly
def __post_init__(self): """ :return: """ data = self.spectral_cube.data self.ds = hv.Dataset((np.arange(data.shape[2]), np.arange( data.shape[1]), np.arange(data.shape[0]), data), [self.spectral_axis_name, 'x', 'y'], 'Cube') # maybe PolyEdit as well # polys = hv.Polygons([hv.Box(int(self.image_width / 2), int(self.image_height / 2), int(self.image_height / 2))]) # self.box_stream = streams.PolyEdit(source=polys) polys = hv.Polygons([]) self.box_stream = streams.BoxEdit(source=polys) hlines = hv.HoloMap({i: hv.VLine(i) for i in range(data.shape[2])}, 'wavelengths') dmap = hv.DynamicMap(self.roi_curves, streams=[self.box_stream]) im = self.ds.to(hv.Image, ['x', 'y'], dynamic=True) self.layout = (im * polys + dmap * hlines).opts( opts.Image(cmap=self.color_map, width=self.image_width, height=self.image_height), opts.Curve(width=650, height=450, framewise=True), opts.Polygons(fill_alpha=0.2, line_color='white'), opts.VLine(color='black'))
def __init__(self, data, configs): '''removes wrong data''' for file in list(data.keys()): if "contact chain" not in data[file]["header"][3].lower(): data.pop(file) self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False) self.config = configs self.df = [] self.basePlots = None self.analysisname = "Contact_Chain" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"] self.sort_parameter = self.config["Contact_Chain"]["Bar_chart"][ "CreateBarChart"] self.Substrate_Type = ["Polysilicon", "N+", "P+"] self.filename_df = pd.DataFrame(columns=[ "Filename", "Substrate Type", "_", "Batch", "Wafer No.", "_", "HM location", "Test structure", "Resistance", "Standard deviation" ]) self.PlotDict["All"] = None self.limits = {"Polysilicon": 4 * 10**7, "N+": 10**5, "P+": 8 * 10**4} self.files_to_fit = self.config["files_to_fit"] hvtext = hv.Text(0, 0, self.analysisname, fontsize=20).opts(color="black", xlabel='', ylabel='') box = hv.Polygons(hv.Box(0, 0, 1).opts(color="black")).opts(color="white") self.PlotDict["All"] = box * hvtext
def ngon_ring(x=0, y=0, specs=[(1, 1), (.9, .9)], arc=(0, 2 * np.pi), orientation=0, npoints=40, line_color='k', line_alpha=1, fill_color='k', fill_alpha=0., label=''): ''' an ngon outline with finite width ''' l = ngon_data(x, y, specs=specs, arc=arc, orientation=orientation, npoints=npoints) d = (np.hstack([l[0][:, 0], l[1][::-1, 0]]), np.hstack([l[0][:, 1], l[1][::-1, 1]])) o_b = { 'Polygons': dict(color=fill_color, alpha=fill_alpha, line_alpha=0), 'Path': dict(line_color=line_color, line_alpha=line_alpha) } o_m = { 'Polygons': dict(color=fill_color, alpha=fill_alpha), 'Path': dict(color=line_color, alpha=line_alpha) } return (hv.Polygons([d], label=label) * hv.Path([l[0], l[1]])).opts( o_b, backend='bokeh') #.opts( o_m, backend='matplotlib ')
def index(): mystates = States.query.order_by(States.state) states_list = pickle.load(open(f'data/states_geo.pkl', "rb")) choropleth = hv.Polygons(states_list, ['lons', 'lats'], ['state', 'tot', 'unemployed']) choropleth.opts( opts.Polygons(logz=True, tools=['hover'], xaxis=None, yaxis=None, show_grid=False, show_frame=False, width=830, height=500, color_index='tot', cmap='Oranges', colorbar=True, toolbar='above', line_color='white')) return render_template('index.html', title='Health Care by the Numbers', mystates=mystates)
def highlight_ripples(self, time=None, plt_range=None, x_range=None, y_range=None): if time is None: time = self.posteriors.get_time_start() if plt_range is None: plt_range = self.posteriors.get_time_total() if x_range is None: x_range = (time, time + plt_range) if y_range is None: y_range = self.posteriors.get_pos_range() def rect(starttime, endtime, pos_min, pos_max): return { ('x', 'y'): [(starttime, pos_min), (endtime, pos_min), (endtime, pos_max), (starttime, pos_max)] } boxes = [ rect(entry.starttime, entry.endtime, self.enc_settings.pos_bins[0], self.enc_settings.pos_bins[-1]) for entry in self.riptimes.itertuples() ] poly = hv.Polygons(boxes, group='events', label='ripples') poly.extents = (time, self.enc_settings.pos_bins[0], time + plt_range, self.enc_settings.pos_bins[-1]) return poly
def ROI_plot(reference,region_names,stretch): #Define parameters for plot presentation nobjects = len(region_names) #get number of objects to be drawn #Make reference image the base image on which to draw image = hv.Image((np.arange(reference.shape[1]), np.arange(reference.shape[0]), reference)) image.opts(width=int(reference.shape[1]*stretch['width']), height=int(reference.shape[0]*stretch['height']), invert_yaxis=True,cmap='gray', colorbar=True, toolbar='above', title="Draw Regions: "+', '.join(region_names)) #Create polygon element on which to draw and connect via stream to PolyDraw drawing tool poly = hv.Polygons([]) poly_stream = streams.PolyDraw(source=poly, drag=True, num_objects=nobjects, show_vertices=True) poly.opts(fill_alpha=0.3, active_tools=['poly_draw']) def centers(data): try: x_ls, y_ls = data['xs'], data['ys'] except TypeError: x_ls, y_ls = [], [] xs = [np.mean(x) for x in x_ls] ys = [np.mean(y) for y in y_ls] rois = region_names[:len(xs)] return hv.Labels((xs, ys, rois)) dmap = hv.DynamicMap(centers, streams=[poly_stream]) return (image * poly * dmap), poly_stream
def plot_record_polygons( record_points, center_time=True, scaling=10**-3, ): """ Plots record hv.Points as polygons for record matrix. :param record_points: Holoviews Points generated with _records_to_points. :param center_time: If true treats specified times as center times. :param scaling: Scale times scale by this factor. E.g. if times should be in µs use 10**-3. :returns: hv.Polygons """ import holoviews as hv df = record_points.data.copy() if not center_time: df.loc[:, 'time'] = df.loc[:, 'time'] + (df.loc[:, 'length'] / 2 * df.loc[:, 'dt']) data = _make_polys(df, scaling=scaling) polys = hv.Polygons(data, kdims=['time', 'channel'], vdims=list(data[0].keys())[1:]).opts( color='area', aspect=4, responsive='width', line_width=0, cmap='viridis', ) return polys
def load_district_shapefile(district_type, **kwargs): district_type = '_'.join([part.lower() for part in district_type.split()]) shape_path = 'data/{0}/{0}.shp'.format(shapefile[district_type]) districts = gv.Shape.from_shapefile(shape_path, crs=crs.PlateCarree()) districts = gv.operation.project_shape(districts) districts = hv.Polygons([gv.util.geom_to_array(dist.data) for dist in districts]) # districts.opts(plot=dict(fill_color=None, line_width=1.5)) return districts
def plot_stimulus(obj, **args): spatial = args.get('spatial', False) bin = args.get('bin', float('Inf')) if np.isinf(bin): bins = np.array([0, obj.duration]) num = 1 else: bins = np.r_[0:obj.duration + bin / 1000.:bin / 1000.] num = bins.size - 1 if not spatial: grid = args.get('grid', False) hm = dict() tmin = np.min(obj.trace) tmax = np.max(obj.trace) for t in range(num): if num == 1: d = {i:hv.Curve((obj.time,obj.trace[i]))\ for i in range(obj.trace.shape[0])} else: d = {i:hv.Curve((obj.time,obj.trace[i]))*\ hv.Curve([(bins[t+1],tmin),(bins[t+1],tmax)]) for i in range(obj.trace.shape[0])} if grid: hvobj = hv.NdLayout(d) else: hvobj = hv.NdOverlay(d) hm[t] = hvobj hvobj = hv.HoloMap(hm, kdims='Time bin [' + str(bin) + ' ms]').collate() else: sur = args.get('surface', hand_surface) mid = (bins[1:] + bins[:-1]) / 2. d = np.array([np.interp(mid,obj.time,obj.trace[i])\ for i in range(obj.trace.shape[0])]) d = (d - np.min(d)) d = 1 - d / np.max(d) hm = dict() locs = sur.hand2pixel(obj.location) rad = obj.pin_radius * sur.pxl_per_mm for t in range(num): p = hv.Polygons( [{ ('x', 'y'): hv.Ellipse(locs[l, 0], locs[l, 1], 2 * rad).array(), 'z': d[l, t] } for l in range(obj.location.shape[0])], vdims='z').opts( plot=dict(color_index='z', aspect='equal'), style=dict(linewidth=0., line_width=0.01)).options(cmap='fire') hm[t] = p hvobj = hv.HoloMap(hm, kdims='Time bin [' + str(bin) + ' ms]') return hvobj
def highlight_ripples(self, time, x_range=None, y_range=None, plt_range=10): def rect(starttime, endtime, pos_min, pos_max): return {('x', 'y'): [(starttime, pos_min), (endtime, pos_min), (endtime, pos_max), (starttime, pos_max)]} boxes = [rect(entry.starttime, entry.endtime, self.enc_settings.pos_bins[0], self.enc_settings.pos_bins[-1]) for entry in self.riptimes.itertuples()] poly = hv.Polygons(boxes, group='events', label='ripples') poly.extents = (time, self.enc_settings.pos_bins[0], time+plt_range, self.enc_settings.pos_bins[-1]) return poly
def test_Line2d_get_normal_band_2(): from shapely.geometry import Polygon p0 = vec(0, 0) p1 = vec(2, 1) l = Line2d(p0, p1) band = l.get_normal_band(1) overlay = (l.hvplot() * l.unit_normal().hvplot(color='r', size=10) * hv.Polygons([Polygon(band)]).opts(alpha=0.1)) display(overlay)
def text_box(text, xpos, ypos, boxsize, fontsize=30, fontcolor="black", bgcolor="white"): """Generates a box with text in it""" hvtext = hv.Text(xpos, ypos, text).opts(fontsize=fontsize, color=fontcolor) box = hv.Polygons(hv.Box(xpos, ypos, boxsize).opts(color="black")).opts(color=bgcolor) return box * hvtext
def ROI_plot(directory, fnames, file, region_names=None): #Get image try: Image_Current_File = os.path.join(os.path.normpath(directory), fnames[file]) img = cv2.imread(Image_Current_File, cv2.IMREAD_GRAYSCALE) print(Image_Current_File) print('file: {}'.format(file)) except IndexError: print('Max file index exceeded. All images in folder drawn.') return None, None, None #get number of objects to be drawn nobjects = len(region_names) if region_names else 0 #Make reference image the base image on which to draw image_title = "No Regions to Draw" if nobjects == 0 else "Draw Regions: " + ', '.join( region_names) image = hv.Image((np.arange(img.shape[1]), np.arange(img.shape[0]), img)) image.opts(width=int(img.shape[1]), height=int(img.shape[0]), invert_yaxis=True, cmap='gray', colorbar=True, toolbar='below', title=image_title) #Create polygon element on which to draw and connect via stream to PolyDraw drawing tool poly = hv.Polygons([]) poly_stream = streams.PolyDraw(source=poly, drag=True, num_objects=nobjects, show_vertices=True) poly.opts(fill_alpha=0.3, active_tools=['poly_draw']) def centers(data): try: x_ls, y_ls = data['xs'], data['ys'] except TypeError: x_ls, y_ls = [], [] xs = [np.mean(x) for x in x_ls] ys = [np.mean(y) for y in y_ls] rois = region_names[:len(xs)] return hv.Labels((xs, ys, rois)) if nobjects > 0: dmap = hv.DynamicMap(centers, streams=[poly_stream]) return (image * poly * dmap), poly_stream, img.shape else: return (image), None, img.shape
def ngon(x=0,y=0, spec=(1,1), orientation=0., arc=(0,2*np.pi), npoints=40,\ line_color='k', line_alpha=1., color='k', alpha=0., label=''): ''' an ngon ''' e = ngon_data(x, y, specs=[spec], arc=arc, orientation=orientation, npoints=npoints) return hv.Polygons(e, label=label).opts(line_color=line_color, line_alpha=line_alpha, color=color, alpha=alpha)
def __init__(self, data, configs): '''removes wrong data''' for file in list(data.keys()): if "Linewidth".lower() not in data[file]["header"][3].lower(): data.pop(file) self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False) self.config = configs self.df = [] self.basePlots = None self.analysisname = "Linewidth" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"] self.PlotDict["All"] = None self.sort_parameter = self.config["Linewidth"]["Bar_chart"][ "CreateBarChart"] self.Substrate_Type = ["P+", "N+", "P-stop"] self.filename_df = pd.DataFrame(columns=[ "Filename", "Substrate Type", "_", "Batch", "Wafer No.", "_", "HM location", "Test structure", "Linewidth [um]", "Standard deviation" ]) self.limits = {"P+": 0.05, "N+": 0.00001, "P-stop": 0.0005} self.files_to_fit = self.config["files_to_fit"] self.sheet_dic = { "P+": self.config["Linewidth"]["parameter"]["sheet_r_p+"], "N+": self.config["Linewidth"]["parameter"]["sheet_r_N+"], "P-stop": self.config["Linewidth"]["parameter"]["sheet_r_ps"] } self.std_dic = { "P+": self.config["Linewidth"]["parameter"]["std_p+"], "N+": self.config["Linewidth"]["parameter"]["std_N+"], "P-stop": self.config["Linewidth"]["parameter"]["std_ps"] } hvtext = hv.Text(0, 0, self.analysisname, fontsize=25).opts(color="black", xlabel='', ylabel='') box = hv.Polygons(hv.Box(0, 0, 300).opts(color="black")).opts(color="white") self.PlotDict["All"] = box * hvtext
def __init__(self, data, configs): '''removes wrong data''' for file in list(data.keys()): if "van-der-pauw" not in data[file]["header"][3].lower( ) and "bulk cross" not in data[file]["header"][3].lower(): data.pop(file) self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False) self.config = configs self.df = [] self.basePlots = None self.analysisname = "Van_der_Pauw" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"] self.PlotDict["All"] = None self.sort_parameter = self.config["Van_der_Pauw"]["Bar_chart"][ "CreateBarChart"] self.Substrate_Type = [ "P-stop", "Polysilicon", "N+", "P+", "Metal", "bulk" ] '''columns have to be fitted according to sample_name + sample_type layout''' self.filename_df = pd.DataFrame(columns=[ "Filename", "Substrate Type", "_", "Batch", "Wafer No.", "_", "HM location", "Test structure", "_", "Sheet Resistance [Ohm/sq]", "Standard deviation" ]) self.limits = { "P-stop": 25000, "Polysilicon": 3000, "N+": 50, "P+": 1300, "Metal": 0.03, "bulk": 70000 } self.files_to_fit = self.config["files_to_fit"] hvtext = hv.Text(0, 0, self.analysisname, fontsize=13).opts(color="black", xlabel='', ylabel='') box = hv.Polygons(hv.Box(0, 0, 2).opts(color="black")).opts(color="white") self.PlotDict["All"] = box * hvtext
def __init__(self, data, configs): '''removes wrong data''' for file in list(data.keys()): if "meander" not in data[file]["header"][3]: data.pop(file) self.log = logging.getLogger(__name__) self.data = convert_to_df( data, abs=False ) ## funktioniert nicht komplet da metal und poly andere messungen haben self.complete_df(data) self.config = configs self.df = [] self.basePlots = None self.analysisname = "Meander" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"] self.sort_parameter = self.config["Meander"]["Bar_chart"][ "CreateBarChart"] self.Substrate_Type = ["Polysilicon", "Metal"] self.filename_df = pd.DataFrame(columns=[ "Filename", "Substrate Type", "_", "Batch", "Wafer No.", "_", "HM location", "Test structure", "_", "Resistivity", "Standard deviation", "specific Resistivity [Ohm/sq]" ]) self.PlotDict["All"] = None self.limits = {"Polysilicon": 2 * 10**6, "Metal": 450} self.files_to_fit = self.config["files_to_fit"] self.squares = { "Polysilicon": self.config["Meander"]["parameter"]["squares_poly"], "Metal": self.config["Meander"]["parameter"]["squares_m"] } hvtext = hv.Text(0, 0, self.analysisname, fontsize=13).opts(color="black", xlabel='', ylabel='') box = hv.Polygons(hv.Box(0, 0, 2).opts(color="black")).opts(color="white") self.PlotDict["All"] = box * hvtext
def interactive_crop( video_path, frame=0, ): """ Loads and displays a frame for a video to be used for cropping. Cropping automatically updated using holoviews stream object. Args: video_path (str): Path to the video frame (int): The index of the frame to be used for cropping Returns: image, stream """ hv.notebook_extension("bokeh") cap = cv2.VideoCapture(video_path) cap.set(cv2.CAP_PROP_POS_FRAMES, frame) _, frame = cap.read() print(frame.shape) frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # frame = frame[::-1, :] # inverse y axis for plotting cap.release() image = hv.Image( (np.arange(frame.shape[1]), np.arange(frame.shape[0]), frame)) image.opts( width=frame.shape[1], height=frame.shape[0], cmap="gray", colorbar=True, toolbar="below", title="First Frame. Crop if Desired", ) box = hv.Polygons([]) box.opts(alpha=0.5) box_stream = streams.BoxEdit(source=box, num_objects=1) return (image * box), box_stream
def Batch_Process(video_dict, tracking_params, bin_dict, region_names, stretch, crop, poly_stream, poly_stream_1, scale=None): #get polygon if poly_stream != None: lst = [] for poly in range(len(poly_stream.data['xs'])): x = np.array(poly_stream.data['xs'][poly]) #x coordinates y = np.array(poly_stream.data['ys'][poly]) #y coordinates lst.append([(x[vert], y[vert]) for vert in range(len(x))]) poly = hv.Polygons(lst).opts(fill_alpha=0.1, line_dash='dashed') heatmaps = [] # Batch process for file in video_dict['FileNames']: if file[-8: -5] == 'Box': # exclude 'EmptyBox' video from processing list continue try: video_dict[ 'file'] = file #used both to set the path and to store filenames when saving video_dict['fpath'] = os.path.join( os.path.normpath(video_dict['dpath']), file) print('Processing File: {f}'.format(f=file), video_dict['fpath']) # Track location and save a LocationOutput file reference = lt.Reference(video_dict, crop, num_frames=100) location = lt.TrackLocation(video_dict, tracking_params, reference, crop) if region_names != None: location = lt.ROI_Location(reference, poly_stream, region_names, location) location.to_csv( os.path.splitext(video_dict['fpath'])[0] + '_LocationOutput.csv') # Choices: 'ABFG','BCEG','ACDF','BDFH' baited = file.split('_')[4] config = va.specify_configuration(baited) # Scatter plot velocity-time va.velocity_distribution_show(video_dict, poly_stream_1, region_names, config, scale) referenceMemError, workingMemError = va.arm_retrieve_errors( video_dict, baited) file_summary = lt.Summarize_Location(location, video_dict, bin_dict=bin_dict, region_names=region_names) file_summary.to_csv( os.path.splitext(video_dict['fpath'])[0] + '_SummaryStats.csv') try: #Add summary info for individual file to larger summary of all files summary_all = pd.concat([summary_all, file_summary]) except NameError: #to be done for first file in list, before summary_all is created summary_all = file_summary #Plot Heat Map image = hv.Image( (np.arange(reference.shape[1]), np.arange(reference.shape[0]), reference)).opts( width=int(reference.shape[1] * stretch['width']), height=int(reference.shape[0] * stretch['height']), invert_yaxis=True, cmap='gray', toolbar='below', title=file + ": Motion Trace") points = hv.Scatter(np.array([location['X'], location['Y']]).T).opts(color='navy', alpha=.2) heatmaps.append( image * poly * points) if poly_stream != None else heatmaps.append(image * points) print('--------------------------') except: print('--------Error:' + file + '--------\n') pass #Write summary data to csv file sum_pathout = os.path.join(os.path.normpath(video_dict['dpath']), 'BatchSummary.csv') summary_all.to_csv(sum_pathout) layout = hv.Layout(heatmaps) return layout
def LoadAndCrop(video_dict,stretch={'width':1,'height':1},cropmethod='none'): #if batch processing, set file to first file to be processed if 'file' not in video_dict.keys(): video_dict['file'] = video_dict['FileNames'][0] print(video_dict['file']) #Upoad file and check that it exists video_dict['fpath'] = os.path.join(os.path.normpath(video_dict['dpath']), video_dict['file']) if os.path.isfile(video_dict['fpath']): print('file: {file}'.format(file=video_dict['fpath'])) cap = cv2.VideoCapture(video_dict['fpath']) else: raise FileNotFoundError('{file} not found. Check that directory and file names are correct'.format( file=video_dict['fpath'])) #Get maxiumum frame of file. Note that max frame is updated later if fewer frames detected cap_max = int(cap.get(7)) #7 is index of total frames print('total frames: {frames}'.format(frames=cap_max)) #Set first frame cap.set(1,video_dict['start']) #first index references frame property, second specifies next frame to grab ret, frame = cap.read() frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cap.release() print('dimensions: {x}'.format(x=frame.shape)) #Make first image reference frame on which cropping can be performed image = hv.Image((np.arange(frame.shape[1]), np.arange(frame.shape[0]), frame)) image.opts(width=int(frame.shape[1]*stretch['width']), height=int(frame.shape[0]*stretch['height']), invert_yaxis=True,cmap='gray', colorbar=True, toolbar='below', title="First Frame. Crop if Desired") #Create polygon element on which to draw and connect via stream to poly drawing tool if cropmethod=='none': image.opts(title="First Frame") return image,None,video_dict if cropmethod=='Box': box = hv.Polygons([]) box.opts(alpha=.5) box_stream = streams.BoxEdit(source=box,num_objects=1) return (image*box),box_stream,video_dict if cropmethod=='HLine': points = hv.Points([]) points.opts(active_tools=['point_draw'], color='white',size=1) pointerXY_stream = streams.PointerXY(x=0, y=0, source=image) pointDraw_stream = streams.PointDraw(source=points,num_objects=1) def h_track(x, y): #function to track pointer y = int(np.around(y)) text = hv.Text(x, y, str(y), halign='left', valign='bottom') return hv.HLine(y) * text track=hv.DynamicMap(h_track, streams=[pointerXY_stream]) def h_line(data): #function to draw line try: hline=hv.HLine(data['y'][0]) return hline except: hline=hv.HLine(0) return hline line=hv.DynamicMap(h_line,streams=[pointDraw_stream]) def h_text(data): #function to write ycrop value center=frame.shape[1]//2 try: y=int(np.around(data['y'][0])) htext=hv.Text(center,y+10,'ycrop: {x}'.format(x=y)) return htext except: htext=hv.Text(center,10, 'ycrop: 0') return htext text=hv.DynamicMap(h_text,streams=[pointDraw_stream]) return image*track*points*line*text,pointDraw_stream,video_dict
def hv_polygons(a, b, c, d): return hv.Polygons([ np.c_[loop.values[a, :], loop.values[b, :], loop.values[c, :], loop.values[d, :]].T ]).options(**opts_rectangle)
opts_poly = { 'Polygons': dict(line_width=1.5, color='white', xaxis=None, yaxis=None, show_frame=False) } opts_rectangle = dict(color=col_rect, fill_alpha=0.8) opts_point_1 = {'Points': dict(color=col_path_1, size=6.0)} opts_point_2 = {'Points': dict(color=col_path_2, size=6.0)} opts_path_1 = {'Path': dict(color=col_path_1, line_width=3)} opts_path_2 = {'Path': dict(color=col_path_2, line_width=3)} ## create HV loop object hv_loop = hv.Polygons((x, y)).options(opts_poly).redim.range(x=(50, 1250), y=(75, 1150)) # create polygons and paths def hv_polygons(a, b, c, d): return hv.Polygons([ np.c_[loop.values[a, :], loop.values[b, :], loop.values[c, :], loop.values[d, :]].T ]).options(**opts_rectangle) def hv_paths(a, b, c, d): diag_1 = hv.Path([np.c_[loop.values[a, :], loop.values[c, :]].T]).options(opts_path_1) diag_2 = hv.Path([np.c_[loop.values[b, :], loop.values[d, :]].T]).options(opts_path_2)
def LoadAndCrop(video_dict, stretch={ 'width': 1, 'height': 1 }, cropmethod=None, fstfile=False): """ ------------------------------------------------------------------------------------- Loads video and creates interactive cropping tool from first frame. In the case of batch processing, the first frame of the first video is used. Additionally, when batch processing, the same cropping parameters will be appplied to every video. Care should therefore be taken that the region of interest is in the same position across videos. ------------------------------------------------------------------------------------- Args: video_dict:: [dict] Dictionary with the following keys: 'dpath' : directory containing files [str] 'file' : filename with extension, e.g. 'myvideo.wmv' [str] 'fps' : frames per second of video files to be processed [int] 'start' : frame at which to start. 0-based [int] 'end' : frame at which to end. set to None if processing whole video [int] 'ftype' : (only if batch processing) video file type extension (e.g. 'wmv') [str] 'FileNames' : (only if batch processing) List of filenames of videos in folder to be batch processed. [list] stretch:: [dict] Dictionary with the following keys: 'width' : proportion by which to stretch frame width [float] 'height' : proportion by which to stretch frame height [float] cropmethod:: [str] Method of cropping video. cropmethod takes the following values: None : No cropping 'Box' : Create box selection tool for cropping video fstfile:: [bool] Dictates whether to use first file in video_dict['FileNames'] to generate reference. True/False ------------------------------------------------------------------------------------- Returns: image:: [holoviews.Image] Holoviews hv.Image displaying first frame stream:: [holoviews.streams.stream] Holoviews stream object enabling dynamic selection in response to cropping tool. `stream.data` contains x and y coordinates of crop boundary vertices. video_dict:: [dict] Dictionary with the following keys: 'dpath' : directory containing files [str] 'file' : filename with extension, e.g. 'myvideo.wmv' [str] 'fps' : frames per second of video file/files to be processed [int] 'start' : frame at which to start. 0-based [int] 'end' : frame at which to end. set to None if processing whole video [int] 'ftype' : (only if batch processing) video file type extension (e.g. 'wmv') [str] 'FileNames' : (only if batch processing) List of filenames of videos in folder to be batch processed. [list] ------------------------------------------------------------------------------------- Notes: - in the case of batch processing, video_dict['file'] is set to first video in file - prior cropping method HLine has been removed """ #if batch processing, set file to first file to be processed video_dict[ 'file'] = video_dict['FileNames'][0] if fstfile else video_dict['file'] #Upoad file and check that it exists video_dict['fpath'] = os.path.join(os.path.normpath(video_dict['dpath']), video_dict['file']) if os.path.isfile(video_dict['fpath']): print('file: {file}'.format(file=video_dict['fpath'])) cap = cv2.VideoCapture(video_dict['fpath']) else: raise FileNotFoundError( '{file} not found. Check that directory and file names are correct' .format(file=video_dict['fpath'])) #Get maxiumum frame of file. Note that max frame is updated later if fewer frames detected cap_max = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) print('total frames: {frames}'.format(frames=cap_max)) #Set first frame. try: cap.set(cv2.CAP_PROP_POS_FRAMES, video_dict['start']) except: cap.set(cv2.CAP_PROP_POS_FRAMES, 0) ret, frame = cap.read() frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cap.release() #Make first image reference frame on which cropping can be performed image = hv.Image( (np.arange(frame.shape[1]), np.arange(frame.shape[0]), frame)) image.opts(width=int(frame.shape[1] * stretch['width']), height=int(frame.shape[0] * stretch['height']), invert_yaxis=True, cmap='gray', colorbar=True, toolbar='below', title="First Frame. Crop if Desired") #Create polygon element on which to draw and connect via stream to poly drawing tool if cropmethod == None: image.opts(title="First Frame") return image, None, video_dict if cropmethod == 'Box': box = hv.Polygons([]) box.opts(alpha=.5) box_stream = streams.BoxEdit(source=box, num_objects=1) return (image * box), box_stream, video_dict
def update(*_): poly2 = hv.Polygons([[(randint(2, 5), randint(6, 9)), (4, 4), (8, 2)]]) poly_stream.source = poly2 plot_pane.object = get_plot(path, poly2)
ds = hv.Dataset(ds_sel[['coefs']], kdims=['ens', 'x', 'y']) vmax = 40 vmin = -vmax f_width = 300 hvc_opts = dict(logy = True, cmap = 'RdBu_r', symmetric=True, colorbar = True, \ tools = ['hover'], invert_yaxis=True, frame_width = f_width) im = ds.to(hv.QuadMesh, ['x', 'y'], dynamic=True).redim.range(coefs=(vmin, vmax)).opts(**hvc_opts) im2 = ds.aggregate(['x', 'y'], np.mean).to(hv.QuadMesh, ['x', 'y'], dynamic=True) im2 = im2.redim.range(coefs=(vmin, vmax)).opts(**hvc_opts) # ## Create Room-of-interest-function # + polys = hv.Polygons([]) box_stream = streams.BoxEdit(source=polys) def roi_curves(data): if not data or not any(len(d) for d in data.values()): return hv.NdOverlay({0: hv.Curve([], 'ens', 'coefs')}) curves = {} data = zip(data['x0'], data['x1'], data['y0'], data['y1']) for i, (x0, x1, y0, y1) in enumerate(data): selection = ds.select(x=(x0, x1), y=(y1, y0)) # swap y0 and y1 when inverted y-axis curves[i] = hv.Spread(selection.aggregate('ens', np.mean, np.std)) return hv.NdOverlay(curves)
from random import randint import holoviews as hv import panel as pn from holoviews import opts, streams LINE = "red" FILL1 = "green" FILL2 = "fulvous" FILL3 = "blue" hv.extension("bokeh") path = hv.Path([[(1, 5), (9, 5)]]) poly = hv.Polygons([[(2, 2), (5, 8), (8, 2)]]) path_stream = streams.PolyDraw(source=path, drag=True, show_vertices=True) poly_stream = streams.PolyDraw( source=poly, drag=True, num_objects=4, show_vertices=True, styles={"fill_color": [FILL1, FILL2, FILL3]}, ) def get_plot(path, poly): return (path * poly).opts( opts.Polygons(fill_alpha=0.3, active_tools=["poly_draw"]), opts.Path(color=LINE, height=400, line_width=5, width=400), )
def plot(self): """plot pane""" # get the tract list tract_list = self.tracts_in_widget() # extract the filter from the original data self.df_filter = self.df[self.df['filter'] == self.filter_] # extract only the provided metric self.df_extracted = self.df_filter[['tract','geometry', self.metric, 'x0','x1','y0','y1']] # rename the metric column (necessary abstraction for plotting) self.df_extracted = self.df_extracted.rename(columns={self.metric: 'metric'}) if self.df.empty: return pn.Spacer() else: if self.geoviews: self.polys = gv.Polygons(gpd.GeoDataFrame(self.df_extracted).set_geometry('geometry'), vdims=['metric', 'tract']).opts( tools=['hover', 'tap'], width=self.plot_width, height=self.plot_height, line_width=0, active_tools=['wheel_zoom', 'tap'], colorbar=True, title=self.metric, color='metric') else: def create_dict(row): """create a dictionary representation of a df row""" d = {('x','y'): np.array(row.geometry.exterior.coords), 'tract': row['tract'], 'metric': row['metric'] } return d # create a dictionary reprresentation of the dataframe data = list(self.df_extracted.apply(create_dict, axis=1)) # declare polygons self.polys = hv.Polygons(data, vdims=['metric', 'tract']).opts( tools=['hover', 'tap'], line_width=0, active_tools=['wheel_zoom', 'tap'], colorbar=True, title=self.metric, color='metric') # Declare Tap stream with polys as source and initial values self.stream.source = self.polys # Define a RangeXY stream linked to the image (preserving ranges from the previous image) self.rangexy = hv.streams.RangeXY( source=self.polys, x_range=self.rangexy.x_range, y_range=self.rangexy.y_range, ) # set padding (degrees) padding = 0 # get the limits of the selected filter/metric data xmin = self.df_extracted.x0.min() - padding xmax = self.df_extracted.x1.max() + padding ymin = self.df_extracted.y0.min() - padding ymax = self.df_extracted.y1.max() + padding # convert to google mercator if using geoviews # TODO this produces reasonable, but incorrect results if self.geoviews: xmin, ymin = ccrs.GOOGLE_MERCATOR.transform_point(xmin, ymin, ccrs.PlateCarree()) xmax, ymax = ccrs.GOOGLE_MERCATOR.transform_point(xmax, ymax, ccrs.PlateCarree()) # create hook for reseting to full extent def reset_range_hook(plot, element): plot.handles['x_range'].reset_start = xmin plot.handles['x_range'].reset_end = xmax plot.handles['y_range'].reset_start = ymin plot.handles['y_range'].reset_end = ymax # Define function to compute selection based on tap location def tap_histogram(index, x_range, y_range): (x0, x1), (y0, y1) = x_range, y_range # if nothing is selected if index == list(): # select all index = list(self.df_extracted.index) return self.polys.iloc[index].opts(opts.Polygons(xlim=(x0, x1), ylim=(y0, y1))) tap_dmap = hv.DynamicMap(tap_histogram, streams=[self.stream, self.rangexy]) # set up the plot to match the range stream if not self.rangexy.x_range and not self.rangexy.y_range: (x0, x1, y0, y1) = (None, None, None, None) else: (x0, x1), (y0, y1) = self.rangexy.x_range, self.rangexy.y_range return self.polys.opts(opts.Polygons(xlim=(x0, x1), ylim=(y0, y1), hooks=[reset_range_hook], responsive=True, bgcolor='black')) # TODO: responsive=True isn't changing the width
from os.path import abspath import webbrowser import holoviews as hv from holoviews import opts hv.extension('bokeh') from bokeh.sampledata.us_counties import data as counties from bokeh.sampledata.unemployment import data as unemployment counties = [dict(county, Unemployment=unemployment[cid]) for cid, county in counties.items() if county["state"] == "tx"] choropleth = hv.Polygons(counties, ['lons', 'lats'], [('detailed name', 'County'), 'Unemployment']) choropleth.opts(opts.Polygons(logz=True, tools=['hover'], xaxis=None, yaxis=None, show_grid=False, show_frame=False, width=500, height=500, color_index='Unemployment', colorbar=True, toolbar='above', line_color='white')) hv.save(choropleth, 'texas.html', backend='bokeh') url = abspath('texas.html') webbrowser.open(url)
def hv_squares(a_est, b_est): hv_polygons = hv.Polygons([{('x', 'y'): rectangle(x, y, w, w)} for x, y, w in np.c_[x,y,predictions(a_est, b_est)[1]]]) return hv_polygons