def covid_viewer_v2(ds): ''' covid viewer, for actives_vs_beds ''' opts.defaults( opts.Curve(tools=['hover'], width=800, height = 600, ylabel='') ) logtog = pn.widgets.Toggle(name='Log (Y-axis)', button_type='default', value=False) xlim=(np.datetime64('2020-03-01'), np.datetime64('2020-03-25')) hv_ds = hv.Dataset(ds, ['date', 'place'], ['active_per_beds']) avb = hv_ds.to(hv.Curve, 'date', 'active_per_beds').overlay('place').opts( legend_position='top_left', shared_axes=True, ylim=(0, 0.13), xlim=xlim, title='Severe Cases per Open Hospital Bed') avb_log = hv_ds.to(hv.Curve, 'date', 'active_per_beds').overlay('place').opts( legend_position='top_left', shared_axes=True, logy=True, ylim=(1e-6, 10), xlim=xlim, title='Severe Cases per Open Hospital Bed (Log Scale)') max_line = hv.HLine(1).opts( opts.HLine(color='red', line_width=6), opts.Points(color='#D3D3D3')) # layout = (avb_log) # layout.opts( # opts.Curve(width=400, height=300, framewise=True)) # pn_layout = pn.pane.HoloViews(layout) # return pn.Row(logtog, pn_layout) return avb
def view(self): data = self.data xmin, xmax = np.min(data), np.max(data) x1_dim = hv.Dimension('x₁', range=(xmin, xmax)) x2_dim = hv.Dimension('x₂', range=(xmin, xmax)) samples_map = self.maps["samples"] samples_map = samples_map.opts(width=600, height=350, show_grid=True, padding=(0, 0.1), toolbar=None) samples_map = samples_map.opts(opts.Path(color=blue, framewise=True)) samples_map = samples_map.redim.label(y="f(x)", x="x") control_vline_map = self.maps["vlines_control"] control_vline_map = control_vline_map.redim(x=x1_dim, y=x2_dim) control_vline_map = control_vline_map.opts(show_grid=True) control_vline_map = control_vline_map.opts( opts.HLine(line_width=2), opts.VLine(line_width=2), opts.Points(color="white", marker="s", size=8), opts.Image(cmap="viridis")) vlines_map = self.maps["vlines"] vlines_map = vlines_map.opts(toolbar=None) vlines_map = vlines_map.opts(opts.VLine(line_width=2), opts.Points(size=6)) scatter_map = self.maps["scatter"] scatter_map = scatter_map.redim.label(y="f(x₂)", x="f(x₁)") scatter_map = scatter_map.opts(padding=(0.5, 0.5), show_grid=True, toolbar=None) scatter_map = scatter_map.opts( opts.Scatter(size=7, framewise=True, fill_color=orange1, line_color=orange2)) title = pn.pane.Markdown("## GP samples visualization", max_height=25) descr = pn.pane.Markdown( "_For moving x₁ and x₂ bars: 1. turn off **pan** tool, 2. click and move the orange squared point on the covariance matrix_" ) row0 = pn.Row(pn.Spacer(width=25), self.kernels_controller.view()) row1 = samples_map * vlines_map row2 = pn.Row(control_vline_map, scatter_map) return pn.Column(title, descr, row0, row1, row2)
def candy_buttons(name, cmap=None, size=450, **kwargs): if cmap is None: cmap = palette[name][:100] name = get_aliases(name) options = opts.Points(color='color', size=size/13.0, tools=['hover'], yaxis=None, xaxis=None, height=size, width=size, cmap=cmap, **kwargs) return hv.Points(data, vdims='color').opts(options).relabel(name)
def __init__(self, directory, selected_cols, columns, files): self.db_file = os.path.join(directory, "experiment.db") self.directory = directory self.all_cols = columns self.columns = [] self.selected = list(selected_cols) self.files = files self.exps = {} opts.defaults(opts.Points(fontsize={'title': 18, 'labels': 18}))
def plot_linpos_flat(self): plt = hv.Points(self.linpos_flat['linpos_flat'], kdims=[('samples', 'Samples'), ('pos', 'Position (cm)')], label='Synthetic position data for UnitGenerator and encoding algorithm'). \ opts(opts.Points(bgcolor='black', marker='o')) if hv.Store.current_backend == 'matplotlib': return plt.opts(fig_size=400, aspect=2) elif hv.Store.current_backend == 'bokeh': return plt.opts(aspect=2, frame_width=600)
def display(self): points = hv.Points( (self.df['X'], self.df['Y'], np.log10(self.df['flux_25'])), vdims='z') res = points.opts(size=0.25) # dynspread(datashade(points)) res.opts(aspect='equal').opts(opts.Points(color='z')).opts( {'Points': { 'frame_height': self.height }}) return res
def hv_adjust_image_landmarks(image, landmarks, landmarks_match=None, bregma_offset=None, resolution=0.0194, msize=40): ''' TODO: merge part of this with the one for the landmarks landmarks are in allen reference space ''' h, w = image.shape if bregma_offset is None: # then it is the center of the image bregma_offset = np.array([int(w / 2), int(h / 2) ]) # place bregma in the center of the image landmarks_im = allen_landmarks_to_image_space(landmarks.copy(), bregma_offset, resolution) if landmarks_match is None: landmarks_match = landmarks_im import holoviews as hv from holoviews import opts, streams from holoviews.plotting.links import DataLink bounds = np.array([0, 0, w, h]) im = hv.Image(image[::-1, :], bounds=tuple(bounds.tolist())).opts(invert_yaxis=True, cmap='gray') points = hv.Points(landmarks_match, vdims='color').opts(marker='+', size=msize) point_stream = streams.PointDraw(data=points.columns(), add=False, num_objects=4, source=points, empty_value='black') table = hv.Table(points, ['x', 'y', 'name'], 'color').opts(title='Annotation location') DataLink(points, table) from bokeh.models import HoverTool hoverpts = HoverTool(tooltips=[("i", "$index")]) widget = (im * points + table).opts( opts.Layout(merge_tools=False), opts.Points(invert_yaxis=True, active_tools=['point_draw'], color='color', tools=[hoverpts], width=int(w), height=int(h)), opts.Table(editable=True)) return widget, point_stream, landmarks_im
def _create_hvplot(): # Generate some data cl1 = np.random.normal(loc=2, scale=0.2, size=(200, 200)) cl2x = np.random.normal(loc=-2, scale=0.6, size=200) cl2y = np.random.normal(loc=-2, scale=0.1, size=200) cl3 = np.random.normal(loc=0, scale=1.5, size=(400, 400)) # Create an overlay of points and ellipses clusters = (hv.Points(cl1).opts(color="blue") * hv.Points( (cl2x, cl2y)).opts(color="green") * hv.Points(cl3).opts(color="#FDDC22")).opts( opts.Points(tools=["hover"])) plot = (clusters * hv.Ellipse(2, 2, 2).opts(line_width=3, color=ACCENT_REST) * hv.Ellipse(-2, -2, (4, 2)).opts(line_width=3, color=ACCENT_REST)) return plot
def __init__(self, adh_mod, **params): super(InterpolateMesh, self).__init__(adh_mod=adh_mod, **params) # set defaults for initialized example self.display_range.param.color_range.bounds = (10, 90) self.display_range.color_range = (10, 90) self.cmap_opts.colormap = cc.rainbow self.scatter_projection.set_crs(ccrs.GOOGLE_MERCATOR) self.adh_mod.wmts.source = gv.tile_sources.EsriImagery # print(self.projection.param.UTM_zone_hemi.constant, self.projection.crs_label) self.opts = (opts.Curve(height=self.map_height, width=self.map_width, xaxis=None, line_width=1.50, color='red', tools=['hover']), opts.Path(height=self.map_height, width=self.map_width, line_width=3, color='black'), opts.Image(height=self.map_height, width=self.map_width, cmap=self.cmap_opts.param.colormap, clim=self.display_range.param.color_range, colorbar=True, clipping_colors={ 'NaN': 'transparent', 'min': 'transparent' }, axiswise=True), opts.RGB(height=self.map_height, width=self.map_width), opts.Points(height=self.map_height, width=self.map_width, color_index='z', cmap=self.cmap_opts.param.colormap, clim=self.display_range.param.color_range, size=10, tools=['hover'], padding=(0.1, 0.1), colorbar=True), opts.TriMesh(height=self.map_height, width=self.map_width, color_index='z', cmap=self.cmap_opts.param.colormap, clim=self.display_range.param.color_range, tools=['hover'], padding=(0.1, 0.1), colorbar=True), opts.VLine(color='black'))
def initialize_loc_history_replay(self): self._loc_hist_replay_stream = Buffer(pd.DataFrame({ "x": pd.Series([], dtype=float), "y": pd.Series([], dtype=float), "Name": pd.Series([], dtype=str), "Date": pd.Series([], dtype=str) }), length=100, index=False) loc_dmap = hv.DynamicMap(partial(hv.Points, vdims=["Name", "Date"]), streams=[self._loc_hist_replay_stream]) trace_dmap = hv.DynamicMap(partial(hv.Curve), streams=[self._loc_hist_replay_stream]) # title_dmap = hv.DynamicMap(partial(hv.Text, x=13, y=13, text="Hello", vdims=["Date", "Name", "timestamp"], streams=[self._loc_hist_replay_stream])) print("Now call start_loc_history_replay() whenever you are ready") return (loc_dmap * trace_dmap). opts(ylim=(0, self.cc.breadth + 2), xlim=(0, self.cc.length + 2), show_legend=False).\ opts(opts.Points(size=6, tools=["hover"], color="Date", cmap="Blues"))
def coordinate_gating(self, df, col1, col2, xlimit, ylimit, type): renderer = hv.renderer('bokeh') d = {col1: df[col1], col2: df[col2], "category": 0} xycols = pd.DataFrame(data=d) set1 = [] set2 = [] set3 = [] set4 = [] for index in range(len(xycols)): x = float(xycols[col1][index]) y = float(xycols[col2][index]) xlimit = float(xlimit) ylimit = float(ylimit) if x < xlimit and y > ylimit: #xycols["category"][index] = 1 set1.append((xycols[col1][index], xycols[col2][index])) elif x > xlimit and y > ylimit: #xycols["category"][index] = 2 set2.append((xycols[col1][index], xycols[col2][index])) elif x < xlimit and y < ylimit: #xycols["category"][index] = 3 set3.append((xycols[col1][index], xycols[col2][index])) elif x > xlimit and y < ylimit: #xycols["category"][index] = 4 set4.append((xycols[col1][index], xycols[col2][index])) categories = {} categories["upper left"] = np.around(100*len(set1)/len(xycols), decimals=2) categories["upper right"] = np.around(100*len(set2)/len(xycols), decimals=2) categories["bottom left"] = np.around(100*len(set3)/len(xycols), decimals=2) categories["bottom right"] = np.around(100*len(set4)/len(xycols), decimals=2) linex = hv.VLine(xlimit) liney = hv.HLine(ylimit) body = linex * liney * hv.Points(set1, label=str("upper left: " + str(categories["upper left"]) + "%")) * \ hv.Points(set2, label=str("upper right: " + str(categories["upper right"]) + "%")) * \ hv.Points(set3, label=str("bottom left: " + str(categories["bottom left"]) + "%")) * \ hv.Points(set4, label=str("bottom right: " + str(categories["bottom right"]) + "%")) body = body.opts(plot=dict(width=800, height=600)) body = body.opts(opts.Points(tools=['box_select', 'lasso_select', 'hover'], size=6, fill_alpha=0.6)) body = body.redim.label(x=col1, y=col2) if os.path.isfile(os.path.join(self.directory, str("coordinate_gating_"+str(type)))): os.remove(os.path.join(self.directory, str("coordinate_gating_"+str(type)))) renderer.save(body, os.path.join(self.directory, str("coordinate_gating_"+str(type))))
def hv_adjust_reference_landmarks(landmarks, ccf_regions, msize=40): ''' landmarks = {'x': [-1.95, 0, 1.95, 0], 'y': [-3.45, -3.45, -3.45, 3.2], 'name': ['OB_left', 'OB_center', 'OB_right', 'RSP_base'], 'color': ['#fc9d03', '#0367fc', '#fc9d03', '#fc4103']} landmarks = pd.DataFrame(landmarks) # adjust landmarks wid,landmark_wid = hv_adjust_reference_landmarks(landmarks,ccf_regions) wid # to display # use the following to retrieve (on another cell) landmarks = pd.DataFrame(landmark_wid.data)[['x','y','name','color']] ''' import holoviews as hv from holoviews import opts, streams from holoviews.plotting.links import DataLink referenceplt = hv_plot_allen_regions(ccf_regions).options( {'Curve': { 'color': 'black', 'width': 600 }}) points = hv.Points(landmarks, vdims='color').opts(marker='+', size=msize) point_stream = streams.PointDraw(data=points.columns(), add=False, num_objects=4, source=points, empty_value='black') table = hv.Table(points, ['x', 'y', 'name'], 'color').opts(title='Landmarks location') DataLink(points, table) widget = (referenceplt * points + table).opts( opts.Layout(merge_tools=False), opts.Points(invert_yaxis=True, active_tools=['point_draw'], color='color', height=500, tools=['hover'], width=500), opts.Table(editable=True)) return widget, point_stream
def plot_pointer(self): if not self.zoom_initialized: self.monitor_zoom_level() self.zoom_initialized = True pos_x = self.pointer_pos.x if pos_x is None: pos_x = 0. pos_y = self.pointer_pos.y if pos_y is None: pos_y = 0. pt = hv.Points((pos_x, pos_y)) pt.opts( opts.Points( size=self.tool_width * self.zoom_level, color=self.cmap[self.dataset.drawing_label], shared_axes=True, )) return pt
def config_layout(PlotItem, **kwargs): """Configs the layout of the output""" for key, value in kwargs.items(): try: getattr(PlotItem, key)(value) except AttributeError as err: log.warning( "Option '{}' for plot not possible with error: {}".format( key, err)) try: TOOLTIPS = [("File", "@Name"), ("index", "$index"), ("(x,y)", "($x, $y)")] hover = HoverTool(tooltips=TOOLTIPS) PlotItem.opts( opts.Curve(tools=[hover], toolbar="disable"), opts.Scatter(tools=[hover], toolbar="disable"), opts.Histogram(tools=[hover], toolbar="disable"), opts.Points(tools=[hover], toolbar="disable"), opts.BoxWhisker(tools=[hover], toolbar="disable"), opts.Bars(tools=[ HoverTool(tooltips=[('Value of ID:', ' $x'), ('Value:', '$y')]) ], toolbar="disable"), opts.Violin(tools=[hover], toolbar="disable")) except AttributeError as err: log.error( "Nonetype object encountered while configuring final plots layout. This should not happen! Error: {}" .format(err)) except ValueError as err: if "unexpected option 'tools'" in str(err).lower( ) or "unexpected option 'toolbar'" in str(err).lower(): pass else: raise return PlotItem
def plot_scatter(df, x, y, x_round_val=1, y_round_val=1, x_tooltip='', y_tooltip=''): ''' Returns a HoloViews plot layout. Arguments: df - Dataframe to process, must have the column 'Country' adn the columns x and y within. x - Column in Dataframe where values are evaluated for the x-axis y - Column in Dataframe where values are evaluated for the y-axis x_round_val (optional) - single numeric value to set the x axis limits on max found within x y_round_val (optional) - single numeric value to set the y axis limits on max found within y x_tooltip (optional) - tooltip to be set in the plots for the x values y_tooltip (optional) - tooltip to be set in the plots for the y values ''' max_y = np.ceil(np.nanmax(df[y].values)) max_y = max_y - max_y % y_round_val + 2 * y_round_val max_x = np.ceil(np.nanmax(df[x].values)) max_x = max_x - max_x % x_round_val + 2 * x_round_val ''' if max_x > max_y: max_y = max_x else: max_x=max_y ''' if x_tooltip == '': x_tooltip = '@{' + x + '}{0,0.0}' if y_tooltip == '': y_tooltip = '@{' + y + '}{0,0.0}' # Plot settings and parameters hover = HoverTool(tooltips=[('Country', '@Country'), (x, x_tooltip), (y, y_tooltip)]) padding = dict(x=(-1.2, 1.2), y=(-1.2, 1.2)) options_shared = dict(width=700, height=700, xlim=(0, max_x), ylim=(0, max_y), hooks=[axis_not_scientific], active_tools=['wheel_zoom'], padding=(0.1, 0.1), show_grid=True, show_legend=True, legend_position='bottom', legend_cols=3) options = [ opts.Scatter(marker='o', size=10, fill_alpha=0.6, tools=[hover], color=hv.Palette('Set2'), **options_shared), opts.Points(color='Country', cmap=cc.cm.fire, size=8, tools=[hover], **options_shared), opts.Labels(text_font_size='8pt', yoffset=y_round_val / 5), opts.Overlay(**options_shared) ] ds = hv.Table(df) # Create the plot layout = ( #hv.Scatter(df, kdims=[x], vdims=[y, 'Country'])* ds.to(hv.Scatter, x, y, 'Country').overlay() * hv.Labels(ds, kdims=[x, y], vdims=['Country'])).opts(options) return layout
# Define annotations text = gapminder_ds.clone({ yr: hv.Text(1.2, 25, str(int(yr)), fontsize=30) for yr in gapminder_ds.keys() }) # In[20]: hvgapminder = (gapminder_ds * text).opts( opts.Points( alpha=0.5, color='ScoreClass', cmap=l, line_color='black', size=np.sqrt((dim('cod_pz')) * 20), width=1200, height=800, tools=['hover'], title= 'Graph of the correlation between age and blod pressure, grouped by degeneration of the disease.' ), opts.Text(text_font_size='52pt', text_color='lightgray')) # In[21]: # Define custom widgets def animate_update(): year = slider.value + 1 if year > end: year = start slider.value = year
# -*- coding: utf-8 -*- """Tools to work with images. """ import circle_fit as cf import holoviews as hv import numpy as np import pandas as pd from astropy.io import fits from holoviews import opts from skimage.exposure import equalize_adapthist as equalize from skimage.exposure import rescale_intensity hv.extension("bokeh") opts.defaults( opts.Image(tools=["hover"], cmap="gray"), opts.Points(color="red", marker="x", size=20), ) class Image: def __init__(self, path): self.path = path self.data, self.header = fits.getdata(path, header=True) @property def name(self): return self.path.name @property def wavelength(self): return self.header["FILTER"]
def points_defaults(cls, **kwargs): """ Set defaults for holoviews Points class. Use kwargs to overwrite elvis defaults and set user-specific defaults """ return opts.defaults(opts.Points(**_dict_merge(kwargs, cls.DEFAULT_POINT_OPTS)))
kdims = ['MappedFixationPointX', 'MappedFixationPointY'] vdims = ['FixationIndex', 'user'] trackData = hv.Dataset(calc_animation()) hvtracking = trackData.to(hv.Points, kdims, vdims, 'user_index') opts.defaults( opts.Points(alpha=0.8, line_color='black', cmap='Set1', height=450, width=600, color='user', size=dim('FixationIndex') * 0.03, tools=['hover'], title='Animation', invert_yaxis=True, show_grid=True) #opts.Text() ) # Define custom widgets def animate_update(): user_index = animation_slider.value + 1 if user_index > end: user_index = start animation_slider.value = user_index
def __call__(self, dset, **params): self.p = ParamOverrides(self, params) if self.p.vdim is None: vdim = dset.vdims[0].name else: vdim = self.p.vdim ra_range = (ra0, ra1) = dset.range("ra") if self.p.ra_sampling: xsampling = (ra1 - ra0) / self.p.ra_sampling else: xsampling = None dec_range = (dec0, dec1) = dset.range("dec") if self.p.dec_sampling: ysampling = (dec1 - dec0) / self.p.dec_sampling else: ysampling = None if self.p.aggregator == "mean": aggregator = ds.mean(vdim) elif self.p.aggregator == "std": aggregator = ds.std(vdim) elif self.p.aggregator == "count": aggregator = ds.count() sky_range = RangeXY() if self.p.range_stream: def redim(dset, x_range, y_range): ranges = {} if x_range and all(isfinite(v) for v in x_range): ranges["ra"] = x_range if y_range and all(isfinite(v) for v in x_range): ranges["dec"] = y_range return dset.redim.range(**ranges) if ranges else dset dset = dset.apply(redim, streams=[self.p.range_stream]) link_streams(self.p.range_stream, sky_range) streams = [sky_range, PlotSize()] pts = dset.apply(skypoints, streams=[self.p.filter_stream]) reset = PlotReset(source=pts) reset.add_subscriber(partial(reset_stream, None, [self.p.range_stream])) rasterize_inst = rasterize.instance(aggregator=aggregator, streams=streams, x_sampling=xsampling, y_sampling=ysampling) raster_pts = apply_when( pts, operation=rasterize_inst, predicate=lambda pts: len(pts) > self.p.max_points) return raster_pts.opts( opts.Image( bgcolor="black", colorbar=True, cmap=self.p.cmap, min_height=100, responsive=True, tools=["hover"], symmetric=True, ), opts.Points( color=vdim, cmap=self.p.cmap, framewise=True, size=self.p.decimate_size, tools=["hover"], symmetric=True, ), opts.Overlay(hooks=[ partial(reset_hook, x_range=ra_range, y_range=dec_range) ]), )
def __call__(self, dset, **params): self.p = ParamOverrides(self, params) if self.p.xdim not in dset.dimensions(): raise ValueError("{} not in Dataset.".format(self.p.xdim)) if self.p.ydim not in dset.dimensions(): raise ValueError("{} not in Dataset.".format(self.p.ydim)) if ("ra" not in dset.dimensions()) or ("dec" not in dset.dimensions()): raise ValueError("ra and/or dec not in Dataset.") # Compute sampling ra_range = (ra0, ra1) = dset.range("ra") if self.p.ra_sampling: ra_sampling = (ra1 - ra0) / self.p.x_sampling else: ra_sampling = None dec_range = (dec0, dec1) = dset.range("dec") if self.p.dec_sampling: dec_sampling = (dec1 - dec0) / self.p.y_sampling else: dec_sampling = None x_range = (x0, x1) = dset.range(self.p.xdim) if self.p.x_sampling: x_sampling = (x1 - x0) / self.p.x_sampling else: x_sampling = None y_range = (y0, y1) = dset.range(self.p.ydim) if self.p.y_sampling: y_sampling = (y1 - y0) / self.p.y_sampling else: y_sampling = None # Set up scatter plot scatter_range = RangeXY() if self.p.scatter_range_stream: def redim_scatter(dset, x_range, y_range): ranges = {} if x_range and all(isfinite(v) for v in x_range): ranges[self.p.xdim] = x_range if y_range and all(isfinite(v) for v in x_range): ranges[self.p.ydim] = y_range return dset.redim.range(**ranges) if ranges else dset dset_scatter = dset.apply(redim_scatter, streams=[self.p.scatter_range_stream]) link_streams(self.p.scatter_range_stream, scatter_range) else: dset_scatter = dset scatter_pts = dset_scatter.apply(filterpoints, streams=[self.p.filter_stream], xdim=self.p.xdim, ydim=self.p.ydim) scatter_streams = [scatter_range, PlotSize()] scatter_rasterize = rasterize.instance(streams=scatter_streams, x_sampling=x_sampling, y_sampling=y_sampling) cmap = (process_cmap(self.p.scatter_cmap)[:250] if self.p.scatter_cmap == "fire" else self.p.scatter_cmap) scatter_rasterized = apply_when( scatter_pts, operation=scatter_rasterize, predicate=lambda pts: len(pts) > self.p.max_points ).opts( opts.Image(clim=(1, np.nan), clipping_colors={"min": "transparent"}, cmap=cmap), opts.Points(clim=(1, np.nan), clipping_colors={"min": "transparent"}, cmap=cmap), opts.Overlay( hooks=[partial(reset_hook, x_range=x_range, y_range=y_range)]), ) # Set up sky plot sky_range = RangeXY() if self.p.sky_range_stream: def redim_sky(dset, x_range, y_range): ranges = {} if x_range and all(isfinite(v) for v in x_range): ranges["ra"] = x_range if y_range and all(isfinite(v) for v in x_range): ranges["dec"] = y_range return dset.redim.range(**ranges) if ranges else dset dset_sky = dset.apply(redim_sky, streams=[self.p.sky_range_stream]) link_streams(self.p.sky_range_stream, sky_range) else: dset_sky = dset sky_pts = dset_sky.apply(filterpoints, xdim="ra", ydim="dec", set_title=False, streams=[self.p.filter_stream]) skyplot_streams = [sky_range, PlotSize()] sky_rasterize = rasterize.instance( aggregator=ds.mean(self.p.ydim), streams=skyplot_streams, x_sampling=ra_sampling, y_sampling=dec_sampling, ) sky_rasterized = apply_when( sky_pts, operation=sky_rasterize, predicate=lambda pts: len(pts) > self.p.max_points).opts( opts.Image(bgcolor="black", cmap=self.p.sky_cmap, symmetric=True), opts.Points(bgcolor="black", cmap=self.p.sky_cmap, symmetric=True), opts.Overlay(hooks=[ partial(reset_hook, x_range=ra_range, y_range=dec_range) ]), ) # Set up BoundsXY streams to listen to box_select events and notify FilterStream scatter_select = BoundsXY(source=scatter_pts) scatter_notifier = partial(notify_stream, filter_stream=self.p.filter_stream, xdim=self.p.xdim, ydim=self.p.ydim) scatter_select.add_subscriber(scatter_notifier) sky_select = BoundsXY(source=sky_pts) sky_notifier = partial(notify_stream, filter_stream=self.p.filter_stream, xdim="ra", ydim="dec") sky_select.add_subscriber(sky_notifier) # Reset reset = PlotReset(source=sky_pts) reset.add_subscriber( partial(reset_stream, self.p.filter_stream, [self.p.sky_range_stream, self.p.scatter_range_stream])) raw_scatterpts = filterpoints(dset, xdim=self.p.xdim, ydim=self.p.ydim) raw_scatter = datashade( raw_scatterpts, cmap=list(Greys9[::-1][:5]), streams=scatter_streams, x_sampling=x_sampling, y_sampling=y_sampling, ) scatter_p = raw_scatter * scatter_rasterized if self.p.show_rawsky: raw_skypts = filterpoints(dset, xdim=self.p.xdim, ydim=self.p.ydim) raw_sky = datashade( rawskypts, cmap=list(Greys9[::-1][:5]), streams=skyplot_streams, x_sampling=ra_sampling, y_sampling=dec_sampling, ) sky_p = raw_sky * sky_rasterized else: sky_p = sky_rasterized if self.p.show_table: table = dset.apply(summary_table, ydim=self.p.ydim, streams=[self.p.filter_stream]) table = table.opts() layout = table + scatter_p + sky_p else: layout = (scatter_p + sky_p).opts(sizing_mode="stretch_width") return layout.opts( opts.Image(colorbar=True, responsive=True, tools=["box_select", "hover"]), opts.Layout(sizing_mode="stretch_width"), opts.Points(color=self.p.ydim, tools=["hover"]), opts.RGB(alpha=0.5), opts.Table(width=200), )
'Life expectancy': dict(label='Life expectancy at birth (years)', range=(15, 100)), 'Population': ('population', 'Population') } # Create Points plotting fertility vs life expectancy indexed by Year gapminder_ds = ds.redim(**dimensions).to(hv.Points, kdims, vdims, 'Year') # Define annotations text = gapminder_ds.clone({yr: hv.Text(1.2, 25, str(int(yr)), fontsize=30) for yr in gapminder_ds.keys()}) # Define options # Combine Points and Text hvgapminder = (gapminder_ds * text).opts( opts.Points(alpha=0.6, color='Group', cmap='Set1', line_color='black', size=np.sqrt(dim('Population'))*0.005, width=1000, height=600, tools=['hover'], title='Gapminder Demo'), opts.Text(text_font_size='52pt', text_color='lightgray')) # Define custom widgets def animate_update(): year = slider.value + 1 if year > end: year = start slider.value = year # Update the holoviews plot by calling update with the new year. def slider_update(attrname, old, new): hvplot.update((new,))
f1 + f2 + f3 + f4 + f5 + f6 #%% import holoviews as hv from holoviews import opts hv.extension('bokeh') from holoviews.operation import gridmatrix from bokeh.sampledata.iris import flowers from bokeh.palettes import brewer import bokeh.models as bmod counts = pd.read_csv(ippath) colors = brewer["Spectral"][len(counts.Genotype.unique()) + 1] colormap = { counts.Genotype.unique()[i]: colors[i] for i in range(len(counts.Genotype.unique())) } colors = [colormap[x] for x in counts.Genotype] print(colormap) iris_ds = hv.Dataset(counts).groupby('Genotype').overlay() point_grid = gridmatrix(iris_ds, chart_type=hv.Points) (point_grid).opts(opts.Bivariate(bandwidth=0.5, cmap=hv.Cycle(values=colors)), opts.Points(size=5, alpha=0.5), opts.NdOverlay(batched=False)) #%%
def animationFunction(trackData): hvData = hv.Dataset(trackData) kdims = ['MappedFixationPointX', 'MappedFixationPointY'] vdims = ['FixationDuration', 'user', 'StimuliName'] hvtracking = hvData.to(hv.Points, kdims, vdims, 'user_index') opts.defaults( opts.Points(alpha=0.8, line_color='black', cmap='Set1', width=600, height=450, color='user', size=dim('FixationDuration') * 0.03, tools=['hover'], title='DBL Animation', invert_yaxis=True, show_grid=True)) # Define custom widgets def animate_update(): user_index = animation_slider.value + 1 if user_index > end: user_index = start animation_slider.value = user_index # Update the holoviews plot by calling update with the user index. def slider_update(attrname, old, new): hvplot.update((new, )) callback_id = None def animate(): global callback_id print('animate() ', trackData.head()) # This always shows the old stimuli if button.label == '► Play': button.label = '❚❚ Pause' callback_id = doc.add_periodic_callback(animate_update, 600) else: button.label = '► Play' callback_id = doc.remove_periodic_callback(callback_id) start, end = hvData.range('user_index') animation_slider = Slider(start=start, end=end, value=0, step=1, title="User Index") animation_slider.on_change('value', slider_update) button = Button(label='► Play Animation', width=80) button.on_click(animate) doc = curdoc() hvplot = renderer.get_plot(hvtracking, doc) hvplot.update((1, )) plot = layout([[hvplot.state], [button, animation_slider]]) return plot
gapminder_ds = ds.redim(**dimensions).to(hv.Points, kdims, vdims, 'Year') # Define annotations text = gapminder_ds.clone({ yr: hv.Text(1.2, 25, str(int(yr)), fontsize=30) for yr in gapminder_ds.keys() }) # Define options # Combine Points and Text hvgapminder = (gapminder_ds * text).opts( opts.Points(alpha=0.6, color='Group', cmap='Set1', line_color='black', size=np.sqrt(dim('Population')) * 0.005, tools=['hover'], title='Gapminder Demo', responsive=True, show_grid=True), opts.Text(text_font_size='52pt', text_color='lightgray')) # Define custom widgets def animate_update(): year = slider.value + 1 if year > end: year = int(start) slider.value = year
class BasemapModule: """ NAME ---- BasemapModule DESCRIPTION ----------- Blueprint for Basemap objects. Plots seismic survey elements such as polygon, wells, lines and the intersection of these lines while providing interactive tools to improve the experience between data and users. These plots are not images but objects that can be modified by the user and exported as images. ATTRIBUTES ---------- basemap_dataframe : (Pandas)DataFrame Matrix compounded by the coordinates and lines of the seismic survey's corners. Empty by default. wells_dataframe : (Pandas)DataFrame Matrix compounded by wells related information. Empty by default. polygon : Holviews element [Curve] Plot of the seismic survey polygon. wells : Holviews element [Scatter] Plot of the wells inside the seismic survey. seismic_lines : Holviews element [Overlay] Plot of the seismic lines (Inline referred as iline and Crossline referred as xline) and its intersection. basemap : Holviews element [Overlay] Combination of the plots: polygon, wells and seismic_lines. METHODS ------- polygon_plot(**kwargs) Constructs the polygon attribute. wells_plot(**kwargs) Constructs the wells attribute. seismic_line_plot(**kwargS) Constructs the seismic_lines attribute. get_basemap(**kwargs) Constructs the Basemap attribute and provides interactive methods to inspect the plotted data. LIBRARIES --------- Holoviews: BSD open source Python library designed to simplify the visualization of data. More information available at: http://holoviews.org/ Numpy: BSD licensed package for scientific computing with Python. More information available at: https://numpy.org/ Pandas: BSD 3 licensed open source data analysis and manipulation tool, built on top of the Python programming language. More information available at: https://pandas.pydata.org/ Panel: BSD open source Python library that allows to create custom interactive dashboards by connecting user defined widgets to plots. More information available at: https://panel.holoviz.org/index.html ON PROGRESS ----------- Include a GIS element into plots. """ # Holoviews default config plot_tools = ['pan', 'wheel_zoom', 'reset'] font_s = {"title": 16, "labels": 14, "xticks": 10, "yticks": 10} opts.defaults(opts.Curve(tools=plot_tools, default_tools=[], xformatter='%.0f', yformatter='%.0f', fontsize=font_s, height=400, width=400, padding=0.1, toolbar='right'), opts.Scatter(tools=plot_tools, default_tools=[], xformatter='%.0f', yformatter='%.0f', fontsize=font_s, height=400, width=400, padding=0.1, toolbar='right', framewise=True, show_grid=True), opts.GridSpace(fontsize=font_s, shared_yaxis=True, plot_size=(120, 380), toolbar="left"), opts.Overlay(xformatter='%.0f', yformatter='%.0f', fontsize=font_s, toolbar="left", show_grid=True), opts.Points(tools=['box_select', 'lasso_select'], default_tools=[], active_tools=["box_select"], size=3, width=500, height=400, padding=0.01, fontsize={ 'title': 16, 'ylabel': 14, 'xlabel': 14, 'ticks': 10 }, framewise=True, show_grid=True), toolbar="left") def __init__(self, basemap_dataframe, wells_dataframe): """ DESCRIPTION ----------- Instantiates BasemapModule's attributes. For more information, please refer to BasemapModule's docstring. """ self.basemap_dataframe = basemap_dataframe self.wells_dataframe = wells_dataframe self.iline_step = 1 self.xline_step = 1 self.hover_format = [("Utmx", "$x{(0.00)}"), ("Utmy", "$y{(0.00)}")] self.hover_attributes = { "show_arrow": True, "point_policy": "follow_mouse", "anchor": "bottom_right", "attachment": "above", "line_policy": "none" } def polygon_plot(self): """ NAME ---- polygon_plot DESCRIPTION ----------- Constructs the polygon attribute. Plots the boundaries of the seismic survey using Holoviews and bokeh as backend. ARGUMENTS --------- BasemapModule.basemap_dataframe : (Pandas)DataFrame Matrix compounded by the coordinates and lines of the seismic survey's corners. RETURN ------ BasemapModule.polygon : Holviews element [Curve] instance attribute Plot of the seismic survey polygon. """ #Plotting the boundaries of the Seismic Survey. Holoviews Curve element BasemapModule.polygon = hv.Curve(self.basemap_dataframe, ["utmx", "utmy"], label="Polygon") BasemapModule.polygon.opts(line_width=2, color="black") return BasemapModule.polygon def wells_plot(self): """ NAME ---- wells_plot DESCRIPTION ----------- Constructs the wells attribute Plots the wells inside the Seismic Survey's polygon using Holoviews and bokeh as backend. ARGUMENTS --------- BasemapModule.wells_dataframe : (Pandas)DataFrame Matrix compounded by wells related information. RETURN ------ BasemapModule.wells : Holviews element [Scatter] instance attribute Plot of the wells inside the seismic survey. """ # Declaring the Hover tools (each line will use one) wells_hover = HoverTool(tooltips=[("Well", "@name")] + self.hover_format + [("Depth", "@depth{(0)}")]) # Plotting Wells. Holoviews Scatter element BasemapModule.wells = hv.Scatter( self.wells_dataframe, ["utmx", "utmy"], ["name", "cdp_iline", "cdp_xline", "depth"], label="Wells") BasemapModule.wells.opts(line_width=1, color="green", size=10, marker="^") return (BasemapModule.wells) def seismic_line_plot(self, iline_number, xline_number): """ NAME ---- seismic_line_plot DESCRIPTION ----------- Constructs the seismic_lines attribute. Plots seismic lines (given a set of inline and crossline numbers) and the intersection of these using Holoviews and bokeh as backend. ARGUMENTS --------- iline_number : int Number of the chosen inline. The value can be given manually or by Panel's slider widget. xline_number : int Number of the chosen crossline. The value can be given manually or by Panel's slider widget. RETURN ------ BasemapModule.seismic_lines : Holviews element [Overlay] instance attribute Plot of the seismic lines and its intersection. FUNCTIONS --------- seismic_lines_dataframe(**kwargs) Builds a DataFrame for the first line either along inline or crossline direction. seismic_intersection(**kwargs) Computes the coordinates and tracf of the intersection between two seismic lines. REFERENCES ---------- bokeh.pydata.org. Change the attributes of the hover tool. Online document: https://bokeh.pydata.org/en/latest/docs/reference/models/tools.html#bokeh.models.tools.HoverTool.point_policy """ def seismic_lines_dataframe(line_direction, perpendicular_direction): """ NAME ---- seismic_lines_dataframe DESCRIPTION ----------- Builds a DataFrame for the first line either along inline or crossline direction. The coordinates represent the lower end of a seismic line; therefore, these shall be used to draft seismic lines after the computation of the higher end. If the users want to plot a line along inline direction, the code will compute the coordinates of the traces within the first crossline and vice versa. ARGUMENTS --------- basemap_dataframe : (Pandas)DataFrame Matrix compounded by the coordinates and lines of the seismic survey's corners. line_direction : str Seismic line direction. perpendicular_direction : str Direction in which the points are going to be calculated. Is perpendicular to line_direction argument. RETURN ------ dlines : (Pandas)DataFrame Contains the trace coordinates within the first seismic line. """ # Less stresful to read the code df, ld, p_d = self.basemap_dataframe, line_direction, perpendicular_direction #Measure the amount of perpendicular lines within line_direction dif_lines = abs( int(df[f"{perpendicular_direction}"].min() - df[f"{perpendicular_direction}"].max())) + 1 #Computing the coordinates of each utmx = np.linspace( float(df[(df[ld] == df[ld].min()) & (df[p_d] == df[p_d].min())]["utmx"].unique()), float(df[(df[ld] == df[ld].min()) & (df[p_d] == df[p_d].max())]["utmx"].unique()), num=dif_lines, endpoint=True) utmy = np.linspace( float(df[(df[ld] == df[ld].min()) & (df[p_d] == df[p_d].min())]["utmy"].unique()), float(df[(df[ld] == df[ld].min()) & (df[p_d] == df[p_d].max())]["utmy"].unique()), num=dif_lines, endpoint=True) #Array of perpendiculars array = np.arange(df[f"{p_d}"].min(), df[f"{p_d}"].max() + 1, 1) # Making dataframes to ease further calculations dlines = pd.DataFrame({ ld: df[f"{ld}"].min(), p_d: array, "utmx": utmx, "utmy": utmy }) return (dlines) def seismic_intersection(iline_df, xline_df, iline_number, xline_number): """ NAME ---- seismic_intersection DESCRIPTION ----------- Computes the coordinates and tracf of the intersection between two seismic lines. The computation of the intersection uses vector differences. ARGUMENTS --------- iline_df : (Pandas)DataFrame Coordinates of the traces within the first crossline. xline_df : (Pandas)DataFrame Coordinates of the traces within the first inline. iline_number : int Number of the chosen inline. xline_number : int Number of the chosen crossline. RETURN ------ list List of tracf and coordinates of the intersection. """ # Amount of CDP within crosslines dif_lines = abs(self.basemap_dataframe["xline"].max() - self.basemap_dataframe["xline"].min()) + 1 # tracf tracf = (iline_number - self.basemap_dataframe["iline"].min()) * dif_lines + ( xline_number - self.basemap_dataframe["xline"].min()) + 1 # vector diferences. Formula utm = b - a + c tutmx = float( xline_df[xline_df["xline"] == xline_number] ["utmx"]) - xline_df["utmx"].iloc[0] + float( iline_df[iline_df["iline"] == iline_number]["utmx"]) tutmy = float( xline_df[xline_df["xline"] == xline_number] ["utmy"]) - xline_df["utmy"].iloc[0] + float( iline_df[iline_df["iline"] == iline_number]["utmy"]) return [int(tracf), tutmx, tutmy] df = self.basemap_dataframe # Assigning a variable for each dataframe in seismic_lines_dataframe ilines, xlines = seismic_lines_dataframe( df.keys()[1], df.keys()[0]), seismic_lines_dataframe(df.keys()[0], df.keys()[1]) # Extracting the intersection coordinates intersection = seismic_intersection(ilines, xlines, iline_number, xline_number) # Computing the second point to plot the seismic lines (By using vector differences) ## This can be refactored iutmx = float(xlines["utmx"].iloc[-1] - xlines["utmx"].iloc[0] + ilines[ilines["iline"] == iline_number]["utmx"]) iutmy = float(xlines["utmy"].iloc[-1] - xlines["utmy"].iloc[0] + ilines[ilines["iline"] == iline_number]["utmy"]) xutmx = float(ilines["utmx"].iloc[-1] - ilines["utmx"].iloc[0] + xlines[xlines["xline"] == xline_number]["utmx"]) xutmy = float(ilines["utmy"].iloc[-1] - ilines["utmy"].iloc[0] + xlines[xlines["xline"] == xline_number]["utmy"]) # hovers for lines and interception iline_hover = HoverTool(tooltips=[("Inline", f"{iline_number}")] + self.hover_format) xline_hover = HoverTool(tooltips=[("Crossline", f"{xline_number}")] + self.hover_format) int_hover = HoverTool( tooltips=[("Intersection", f"({iline_number}/{xline_number})")] + self.hover_format) #Updating hover attributes for item in [iline_hover, xline_hover, int_hover]: item._property_values.update(self.hover_attributes) # Plotting the Inline. Holoviews Curve element iline = hv.Curve( [(float(ilines[ilines["iline"] == iline_number]["utmx"]), float(ilines[ilines["iline"] == iline_number]["utmy"])), (iutmx, iutmy)], label="I-Line") # Plotting the Crossline. Holoviews Curve element xline = hv.Curve( [(float(xlines[xlines["xline"] == xline_number]["utmx"]), float(xlines[xlines["xline"] == xline_number]["utmy"])), (xutmx, xutmy)], label="C-Line") # Plot the intersection. Holovies Scatter element. intersection = hv.Scatter((intersection[1], intersection[2]), label="Intersection") # Adding the hover tool in to the plots iline.opts(line_width=2, color="red", tools=self.plot_tools + [iline_hover]) xline.opts(line_width=2, color="blue", tools=self.plot_tools + [xline_hover]) intersection.opts(size=7, line_color="black", line_width=2, color="yellow", tools=self.plot_tools + [int_hover]) # Making the overlay of the seismic plot to deploy BasemapModule.seismic_lines = iline * xline * intersection return BasemapModule.seismic_lines def get_basemap(self): """ NAME ---- get_basemap DESCRIPTION ----------- Constructs the basemap attribute and provides interactive methods to inspect the plotted data. Merges polygon, wells and seismic_lines attributes into one object using Holoviews and bokeh as backend. It also includes Panel's widgets and methods to add elements that ease data management. ARGUMENTS --------- BasemapModule.basemap_dataframe : (Pandas)DataFrame Matrix compounded by the coordinates and lines of the seismic survey's corners. Survey.survey_name : str Name of the seismic survey. RETURN ------ Panel Layout [Row] Container of the following indexed elements: [0] WidgetBox [0] Markdown for Survey.survey_name [1] IntSlider for inline number selection [2] IntSlider for crossline number selection [3] Select for well selection [1] basemap attribute FUNCTIONS --------- basemap_plot(**kwargs) Constructs the basemap attribute. update_plot(**kwargs) Links Panel's selection widgets to the basemap attribute. """ df = self.basemap_dataframe # Widgets iline_number = pn.widgets.IntSlider(name="Inline number", start=int(df["iline"].min()), end=int(df["iline"].max()), step=self.iline_step, value=int(df["iline"].min())) xline_number = pn.widgets.IntSlider(name="Crossline number", start=int(df["xline"].min()), end=int(df["xline"].max()), step=self.xline_step, value=int(df["xline"].min())) select_well = pn.widgets.Select(name="Select the well to inspect", options=["None"] + list(self.wells_dataframe["name"]), value="None") @pn.depends(iline_number.param.value, xline_number.param.value, select_well.param.value) def basemap_plot(iline_number, xline_number, select_well): """ NAME ---- basemap_plot DESCRIPTION ----------- Constructs the basemap attribute. Merges seismic survey related plots using Holoviews and bokeh as backend. ARGUMENTS --------- Arguments are given by Panel's widgets through the panel's depend decorator: iline_number : int Number of the chosen inline. xline_number : int Number of the chosen crossline. select_well : str Automatically gives well's line numbers when selected. RETURN ------ basemap : Holviews element [Overlay] instance attribute Combination of the plots: polygon, wells and seismic_lines. """ #new attributes WiggleModule.inline_number = iline_number WiggleModule.crossline_number = xline_number # First element BasemapModule.polygon = BasemapModule.polygon_plot(self) # Second element BasemapModule.wells = BasemapModule.wells_plot(self) # Third element BasemapModule.seismic_lines = BasemapModule.seismic_line_plot( self, iline_number, xline_number) # Final Overlay BasemapModule.basemap = BasemapModule.polygon * BasemapModule.wells * BasemapModule.seismic_lines BasemapModule.basemap.opts(legend_position='top', height=600, width=600) return (BasemapModule.basemap) widgets = pn.WidgetBox(f"## {Survey.survey} Basemap", iline_number, xline_number, select_well) def update_plot(event): """ NAME ---- update_plot DESCRIPTION ----------- Links Panel's selection widgets to the basemap attribute. Modifies the target plot when a well is selected through Panel's selector widget. ARGUMENTS --------- event : str Panel's selector widget value. RETURN ------ basemap : Holviews element [Overlay] instance attribute Combination of the plots: polygon, wells and seismic_lines. """ if select_well.value != "None": iline_number.value = int( self.wells_dataframe["cdp_iline"].loc[str( select_well.value)]) xline_number.value = int( self.wells_dataframe["cdp_xline"].loc[str( select_well.value)]) WiggleModule.inline_number = iline_number.value WiggleModule.crossline_number = xline_number.value select_well.param.watch(update_plot, 'value') return pn.Row(widgets, basemap_plot).servable()
def point_defaults(cls, **kwargs): return opts.defaults( opts.Points(**_dict_merge(kwargs, cls.DEFAULT_POINT_OPTS)))
#hv.save(hv.render(test3), '/Users/matthew/Desktop/IDW_test.png', fmt='png') show(hv.render(test3)) #show(hv.render(background)) #%% np.random.seed(9) data = np.random.rand(10, 2) points = hv.Points(data) labels = hv.Labels({('x', 'y'): data, 'text': [chr(65+i) for i in range(10)]}, ['x', 'y'], 'text') overlay = (points * labels).redim.range(x=(-0.2, 1.2), y=(-.2, 1.2)) overlay.opts( opts.Labels(text_font_size='10pt', xoffset=0.08), opts.Points(color='black', size=5)) test4 = (overlay + points).cols(2) #show(hv.render(test4)) #%% import imgkit imgkit.from_file('/Users/matthew/Desktop/IDW/DIDW_test2019_10_01_23_45.html', '/Users/matthew/Desktop/IDW/test.jpg') #%% import pdfkit #%% path_wkhtmltopdf = r'C:\Program Files (x86)\wkhtmltopdf\bin\wkhtmltopdf.exe' config = pdfkit.configuration(wkhtmltopdf=path_wkhtmltopdf)
np.random.multivariate_normal((0, 0), [[1, 0.1], [0.1, 1]], (1000, ))) points2 = hv.Points( np.random.multivariate_normal((3, 3), [[1, 0.1], [0.1, 1]], (1000, ))) # Declare two selection streams and set points and points2 as the source of each sel1 = streams.Selection1D(source=points) sel2 = streams.Selection1D(source=points2) # Declare DynamicMaps to show mean y-value of selection as HLine hline1 = hv.DynamicMap(lambda index: hv.HLine(points['y'][index].mean() if index else -10), streams=[sel1]) hline2 = hv.DynamicMap(lambda index: hv.HLine(points2['y'][index].mean() if index else -10), streams=[sel2]) # Combine points and dynamic HLines layout = (points * points2 * hline1 * hline2).opts( opts.Points(height=400, width=400)) # Create App app = dash.Dash(__name__) # Dash display components = to_dash(app, [layout], reset_button=True) app.layout = html.Div(components.children) if __name__ == '__main__': app.run_server(debug=True)
y=(bounds[1], bounds[3])), streams=[box]) # Compute histograms of selection along x-axis and y-axis yhist = hv.operation.histogram(dmap, bin_range=points.range('y'), dimension='y', dynamic=True, normed=False) xhist = hv.operation.histogram(dmap, bin_range=points.range('x'), dimension='x', dynamic=True, normed=False) layout = datashade(points).opts( opts.Points(size=6)) * mean_sel * bounds << yhist << xhist # Create App app = dash.Dash(__name__) components = to_dash( app, [layout], reset_button=True, use_ranges=False, ) app.layout = html.Div(components.children) if __name__ == "__main__": app.run_server(debug=True)