def generateHoloview(self, df, SSC, FSC, type, counter_max=50): renderer = hv.renderer('bokeh') body_points = hv.Scatter(df, SSC, FSC).opts(color='r', title='SSC vs FSC Default Gating') body_hist = body_points.hist(num_bins=50, dimension=[SSC, FSC]) body = body_hist counter = 0 for index in range(len(df.columns)): for index2 in range(index+1, len(df.columns)): col = df.columns[index] col2 = df.columns[index2] if col2 != col and col not in (SSC, FSC) and col2 not in (SSC, FSC) and counter < counter_max: points = hv.Scatter(df, col, col2) hist = points.hist(num_bins=50, dimension=[col, col2]) body += hist counter += 1 print(counter) try: body = body.opts( opts.Scatter(tools=['box_select', 'lasso_select']), opts.Layout(shared_axes=True, shared_datasource=True)).cols(2) except: body = body.opts( opts.Scatter(tools=['box_select', 'lasso_select']), opts.Layout(shared_axes=True, shared_datasource=True)) renderer.save(body, os.path.join(self.directory, str(type)+"gating"))
def _getOptions(library): if (library == 'bokeh'): options = [ opts.Scatter(size='bSize', color='color', show_legend=False) ] else: options = [opts.Scatter(s='mSize', color='color', show_legend=True)] return options
def load_indices(Index): #scatter = hv.Scatter(multi_df[Index], kdims = ['JDK_RS_ratio', 'JDK_RS_momentum']) scatter = hv.Scatter(multi_df[Index], kdims = ['JDK_RS_momentum']) ##Colors explicit_mapping = {'Leading': 'green', 'Lagging': 'yellow', 'Weakening': 'red', 'Improving': 'blue'} ##Plot Joining all together scatter = scatter.opts(opts.Scatter(tools=['hover'], height = 500, width=500, size = 10, xlim = x_range, ylim = y_range, color = 'Quadrant', cmap=explicit_mapping, )) ##Line connecting the dots #curve = hv.Curve(multi_df[Index], kdims = ['JDK_RS_ratio', 'JDK_RS_momentum']) curve = hv.Curve(multi_df[Index], kdims = [ 'JDK_RS_momentum']) curve = curve.opts(opts.Curve(color = 'black', line_width = 1)) ##Vertical and Horizontal Lines vline = hv.VLine(100).opts(color = 'black', line_width = 1) hline = hv.HLine(100).opts(color = 'black', line_width = 1) #All Together full_scatter = scatter * vline * hline * curve full_scatter = full_scatter.opts(legend_cols= True) return full_scatter
def investigateOptimalAlgorithms(kmerId, kmerPca): plot.setLibrary('bokeh') pca = kmerPca.loc[:, PCA_DATA_COL_NAMES] plots = {} algos = ( ('Elliptic', EllipticEnvelope()), ('SVM', OneClassSVM()), ('Forest', IsolationForest()), ('Local', LocalOutlierFactor())) ## Visualise data and manually determine which algorithm will be good for i, (name, algo) in enumerate(algos, 1): labels = _getLabels(algo, pca) labels = pd.DataFrame(labels, columns=[OLABEL_COL_NAME]) kmerDf = pd.concat([kmerId, pca, labels], axis=1) dataset = hv.Dataset(kmerDf, PCA_DATA_COL_NAMES) scatter = dataset.to(hv.Scatter, PCA_DATA_COL_NAMES, groupby=OLABEL_COL_NAME).overlay() scatter.opts(opts.Scatter(size=10, show_legend=True)) plots[name] = scatter plots = hv.HoloMap(plots, kdims='algo') plots = plots.collate() return plots
def investigateOptimalAlgorithms(kmerId, kmerCount): plot.setLibrary('bokeh') plots = {} params = {'n_components':N_PCA_COMPONENTS, 'random_state':42} algos = ( ('PCA', decomposition.PCA(**params)), ('LLE', manifold.LocallyLinearEmbedding(method='standard', **params)), ('LTSA', manifold.LocallyLinearEmbedding(method='ltsa', **params)), ('Hessian LLE', manifold.LocallyLinearEmbedding(method='hessian', n_neighbors=10, **params)), ('Modified LLE', manifold.LocallyLinearEmbedding(method='modified', **params)), ('tSNE', manifold.TSNE(**params)), ('Isomap', manifold.Isomap(n_components=N_PCA_COMPONENTS)), ('MDS', manifold.MDS(**params)), ('SE', manifold.SpectralEmbedding(**params))) ## Visualise data and manually determine which algorithm will be good for i, (name, algo) in enumerate(algos, 1): com = _getComponents(algo, kmerCount) com = pd.DataFrame(com, columns=PCA_DATA_COL_NAMES) kmerDf = pd.concat([kmerId, com], axis=1) dataset = hv.Dataset(kmerDf, PCA_DATA_COL_NAMES) scatter = dataset.to(hv.Scatter, PCA_DATA_COL_NAMES) scatter.opts(opts.Scatter(size=10, show_legend=True)) plots[name] = scatter plots = hv.HoloMap(plots, kdims='algo') plots = plots.collate() return plots
def _get_linked_plots(backend: str = "plotly") -> Tuple: """Returns a tuple (scatter, hist) of linked plots Args: backend (str, optional): "plotly" or "bokeh". Defaults to "plotly". Returns: [Tuple]: Returns a tuple (scatter, hist) of linked plots """ dataset = hv.Dataset(IRIS_DATASET) scatter = hv.Scatter(dataset, kdims=["sepal_length"], vdims=["sepal_width"]) hist = hv.operation.histogram(dataset, dimension="petal_width", normed=False) # pylint: disable=no-value-for-parameter selection_linker = hv.selection.link_selections.instance() scatter = selection_linker(scatter).opts( opts.Scatter(**OPTS["all"]["scatter"], **OPTS[backend]["scatter"])) hist = selection_linker(hist).opts( opts.Histogram(**OPTS["all"]["hist"], **OPTS[backend]["hist"])) return scatter, hist
def investigateOptimalAlgorithms(kmerId, kmerPca): plot.setLibrary('bokeh') pca = kmerPca.loc[:, PCA_DATA_COL_NAMES] plots = {} algos = (('KMeans', cluster.KMeans()), ('Affinity', cluster.AffinityPropagation()), ('MeanShift', cluster.MeanShift()), ('Spectral', cluster.SpectralClustering()), ('Agglomerative', cluster.AgglomerativeClustering(linkage='average')), ('Agglomerative', cluster.AgglomerativeClustering(linkage='ward')), ('DBSCAN', cluster.DBSCAN()), ('Gaussian', GaussianMixture())) ## Visualise data and manually determine which algorithm will be good for i, (name, algo) in enumerate(algos, 1): labels = _getLabels(algo, pca) labels = pd.DataFrame(labels, columns=[CLABEL_COL_NAME]) kmerDf = pd.concat([kmerId, pca, labels], axis=1) dataset = hv.Dataset(kmerDf, PCA_DATA_COL_NAMES) scatter = dataset.to(hv.Scatter, PCA_DATA_COL_NAMES, groupby=CLABEL_COL_NAME).overlay() scatter.opts(opts.Scatter(size=10, show_legend=True)) plots[name] = scatter plots = hv.HoloMap(plots, kdims='algo') plots = plots.collate() return plots
def plot_curve(): df = download_data(index.value) future_df = download_data_predicted(index.value) title = index.value + " Exchange Rate" # Create stock curve past_label = "Past " + title future_label = "Predicted Future " + title df['label'] = past_label future_df['label'] = future_label new_df = pd.concat([df, future_df], axis=0) curve = hv.Curve(df, 'Date', ('Close', 'label')) curve_pred = hv.Curve(future_df, 'Date', ('Close', 'Price')) # Labels and layout tgt = curve.relabel("Past " + title).opts( #width=width, height=600, show_grid=True, labelled=['y'], default_tools=[hover], hooks=[set_tools], title=title, responsive=True) tgt_pred = curve_pred.relabel("Future " + title).opts( #width=width, height=600, show_grid=True, labelled=['y'], default_tools=[hover], hooks=[set_tools], title=title, responsive=True) src = curve.opts(height=100, yaxis=None, default_tools=[], color='green', responsive=True) src_pred = curve_pred.opts(height=100, yaxis=None, default_tools=[], color='green', responsive=True) circle = hv.Scatter(df, 'Date', ('Close', 'Price')).opts(color='green') circle_pred = hv.Scatter(future_df, 'Date', ('Close', 'Price')).opts(color='blue') RangeToolLink(src, tgt) # Merge rangetool layout = ((tgt * tgt_pred * circle * circle_pred) + (src * src_pred)).cols(1) layout.opts(opts.Layout(shared_axes=False, merge_tools=False), opts.Curve(toolbar=None), opts.Scatter(size=3)) print("kepanggil nih viz") print(df["Close"][0]) print(index.value) return layout
def generateCombined(self, decimated, SSC, FSC, cachebust, counter_max=20): renderer = hv.renderer('bokeh') body = None points = None point_collect = [] for key in decimated.keys(): print(key) point = hv.Scatter(decimated[key], SSC, FSC, label=key) point_collect.append(point) if points is None: points = point else: points *= point if body is None: body = points.opts(title='Default {0}: SSC vs FSC'.format("Combined"), height=450, width=450) else: body += points.opts(title='Default {0}: SSC vs FSC'.format("Combined")) for dim in (SSC, FSC): hists = None for point in point_collect: hist = histogram(point, dimension=dim) if hists is None: hists = hist else: hists *= hist body += hists potentialCols = [c for c in decimated[list(decimated.keys())[0]].columns if c != SSC and c != FSC] for i in range(len(potentialCols)): for j in range(i+1, len(potentialCols)): points = None point_collect = [] for key in decimated.keys(): point = hv.Scatter(decimated[key], potentialCols[i], potentialCols[j], label=key) point_collect.append(point) if points is None: points = point else: points *= point body += points.opts(title='Combined: {0} vs {1}'.format(potentialCols[i], potentialCols[j]), height=450, width=450) for dim in (potentialCols[i], potentialCols[j]): hists = None for point in point_collect: hist = histogram(point, dimension=dim) if hists is None: hists = hist else: hists *= hist body += hists body = body.opts( opts.Scatter(alpha=0.9), opts.Histogram(alpha=0.9, height=450), opts.Layout(shared_axes=True, shared_datasource=True)).cols(3) renderer.save(body, os.path.join(self.directory, cachebust+"combined_gating"))
def concatenated_summary_curve_factory( cdf, kdims="Cycle_Index", vdims="Charge_Capacity(mAh/g)", title="Summary Curves", fill_alpha=0.8, size=12, width=800, legend_position="right", colors=None, markers=None, ): # TODO: missing doc-string if not hv_available: print("This function uses holoviews. But could not import it." "So I am aborting...") return if colors is None: colors = hv.Cycle("Category10") if markers is None: markers = hv.Cycle(["circle", "square", "triangle", "diamond"]) groups = [] curves_opts = [] curves = {} for indx, new_df in cdf.groupby(level=0, axis=1): g = indx.split("_")[1] groups.append(g) n = hv.Scatter(data=new_df[indx], kdims=kdims, vdims=vdims, group=g, label=indx).opts(fill_alpha=fill_alpha, size=size) curves[indx] = n ugroups = set(groups) max_sub_group = max([groups.count(x) for x in ugroups]) markers = markers[max_sub_group] colors = colors[len(ugroups)] for g, c in zip(ugroups, colors.values): curves_opts.append(opts.Scatter(g, color=c, marker=markers)) curves_overlay = hv.NdOverlay(curves, kdims="cell id").opts( opts.NdOverlay(width=800, legend_position=legend_position, title=title), *curves_opts, ) return curves_overlay
def visualize_time_series(self, stats:List[str], rename_cols:Dict[str, str]=dict(), options:opts=opts()): """ Plots the given stats over a period of a time :param stats: names of statistics to plot :param rename_cols: any human readable names for the statistics :param options: plotting options for holoviews """ df = pd.DataFrame(self.trend).fillna(0) stats = list(map(lambda s: rename_cols.get(s, s), df.columns & stats)) df = df.rename(columns=rename_cols) point_curves = [hv.Scatter(df[["date", statistic]], label=statistic) for statistic in stats] line_curves = [hv.Curve(points) for points in point_curves] return (hv.Overlay(line_curves + point_curves)). opts(opts.Scatter(tools=["hover"], size=6)). opts(padding=0.05, height=375, legend_position="bottom", title=""). opts(options)
def setLibrary(library='bokeh'): ## Use Bokeh by default if (library == 'bokeh'): hv.extension('bokeh') hv.archive.auto(filename_formatter="{obj:.7}") ## For notebooks opts.defaults( opts.Scatter(tools=['hover'], width=700, height=700, padding=0.05), opts.HeatMap(tools=['hover'], width=700, height=700, labelled=[], xrotation=45, colorbar=True, cmap=('Blues'))) # opts.HeatMap(tools=['hover'], width=700, height=700, labelled=[], # xrotation=45, colorbar=True, cmap=('Blues'))) ## The library that Bokeh uses to export to SVG is not longer supported ## and so cannot be exported to SVG elif (library == 'matplotlib'): hv.extension('matplotlib') hv.output(fig='svg') opts.defaults( opts.Scatter(fig_size=300, padding=0.05), opts.HeatMap(fig_size=300, labelled=[], xrotation=45, colorbar=True, cmap=('Blues'))) else: raise NotImplementedError("Unknown plotting library.")
def __init__(self, path, ping_file_path, speed_test_file_path): self.path = path self.ping_file_path = ping_file_path self.speed_test_file_name = speed_test_file_path # Define default layout of graphs hv.extension('bokeh') opts.defaults( opts.Bars(xrotation=45, tools=['hover']), opts.BoxWhisker(width=700, xrotation=30, box_fill_color=Palette('Category20')), opts.Curve(width=700, tools=['hover']), opts.GridSpace(shared_yaxis=True), opts.Scatter(width=700, height=500, color=Palette('Category20'), size=dim('growth')+5, tools=['hover'],alpha=0.5, cmap='Set1'), opts.NdOverlay(legend_position='left')) if os.path.isdir(os.path.join(self.path, "webpage","figures")) is False: os.mkdir(os.path.join(self.path, "webpage","figures")) print("Path 'figures' created successfully") else: print("Path 'figures' initialized") # Load basic configurations config = configparser.ConfigParser() try: config.read('./modules/config_a.ini') # Get values from configuration file self.upper_acceptable_ping_bound = float(config['DEFAULT']['upper_acceptable_ping_bound']) self.upper_ping_issue_bound = float(config['DEFAULT']['upper_ping_issue_bound']) self.acceptable_network_speed = float(config['DEFAULT']['acceptable_network_speed']) except: # In case no config-file is found or another reading error occured print("Configuration file not found/readable.") print("Creating a new configuration file.") # Creating new file with standard values config['DEFAULT'] = {'upper_acceptable_ping_bound': '10', 'upper_ping_issue_bound': '99999', 'acceptable_network_speed': '16'} with open('config_a.ini', 'w') as configfile: config.write(configfile) print("New configuration file was created. Running on default parameters, please restart for changes.") #set default values to continue with program self.upper_acceptable_ping_bound = float(config['DEFAULT']['upper_acceptable_ping_bound']) self.upper_ping_issue_bound = float(config['DEFAULT']['upper_ping_issue_bound']) self.acceptable_network_speed = float(config['DEFAULT']['acceptable_network_speed'])
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 scatter(data, x, y, hue=None): key_dimensions = [(xi, xi) for xi in [x, hue]] value_dimensions = [(y, y)] macro = hv.Table(data, key_dimensions, value_dimensions) scatter = macro.to.scatter(x, y).overlay(hue) scatter.opts( opts.Scatter(color=hv.Cycle('Category20'), line_color='k', size=10, show_grid=True, width=700, height=400), opts.NdOverlay(legend_position='left', show_frame=False)) return scatter
def generate_graph_ping_times_with_extreme_outliers(self): fig_all_max_ping = hv.Curve((self.df_ping["date"], self.df_ping["max"]), "Date", "Ping in ms", label="All messured pings") fig_dot_over_upper_bound = hv.Scatter( (self.df_ping["date"][self.df_ping["max"] > self.upper_acceptable_ping_bound], self.df_ping["max"][self.df_ping["max"] > self.upper_acceptable_ping_bound]), "Date", "Max_Ping_Time", label="Highlight pings over {} ms".format( str(self.upper_acceptable_ping_bound))).opts(opts.Scatter(color="red", size=10)) fig_ping_times_with_extreme_outliers = (fig_all_max_ping * fig_dot_over_upper_bound).opts( legend_position="top_left", title="All Max. Ping Times in ms", padding=0.05) # Safe newly generated plot hv.save(fig_ping_times_with_extreme_outliers, os.path.join(self.path, "webpage", "figures", "fig_ping_times_with_extreme_outliers.html"), backend='bokeh')
def investigateOptimalParameters(kmerId, kmerCount): ## TO FIX import holoviews as hv from holoviews import dim ## Requires python 3.7; not 3.5 from holoviews import opts hv.extension('bokeh') kmerId = updateDuplicates(kmerId, kmer.ID_COL_NAME) cond = ((kmerId[kmer.ID_COL_NAME].str.contains('Wuhan-Hu-1')) | (kmerId[kmer.ID_COL_NAME].str.match('Australia')) | (kmerId[kmer.ID_COL_NAME].str.match('Sydney')) | (kmerId[kmer.ID_COL_NAME].str.match('C6'))) kmerId.loc[cond, kmer.FILE_COL_NAME] = kmerId.loc[cond, kmer.ID_COL_NAME] labels = [] # algos = investigatePCAParameters(kmerId, kmerCount) # algos = investigateMDSParameters(kmerId, kmerCount) algos = investigateTSNEParameters(kmerId, kmerCount) plots = {} for p, a in algos: print(p) pca = getPca(a, kmerCount) kmerPca = joinColumns(kmerId, PCA_DATA_COL_NAMES, pca) dataset = hv.Dataset(kmerPca, PCA_DATA_COL_NAMES) scatter = dataset.to(hv.Scatter, PCA_DATA_COL_NAMES, groupby=kmer.FILE_COL_NAME) \ .overlay() scatter.opts(opts.Scatter(tools=['hover'], height=700, width=700, size=10, show_legend=True)) plots[tuple(p.values())] = scatter labels = p.keys() ## Create the map of plots plots = hv.HoloMap(plots, kdims=[*labels]) plots = plots.collate() hv.save(plots, 'plot.html')
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_experiments(src, experiments, attr=None, n_samples=10000, single_mode=False, width=550, n_cols=3, cmap=None): if type(experiments) == int: experiments = [experiments] if src == 'mnist' or src == 'fmnist': attr = 'labels' cmap = 'Category10' df = pd.read_feather( os.path.join(META_PATH, src, src + '_meta.feather')) df = df.loc[:n_samples] elif src == 'cartoon' or src == 'cartoon10k': n_file = int(np.ceil(n_samples / 10000)) df, attr_dict = load_cartoon_meta(n_file=n_file, src=src) df = df.loc[:n_samples] if attr is None: print('TODO: implement DynamicMap for src=cartoon and attr=None') attr = 'nhair' if cmap is None: if attr == 'nhair': cmap = 'Category20' else: cmap = 'viridis' df = add_experiments(experiments, src, df) if n_samples > 10000: scatter_options = opts.Scatter(width=width, aspect=1, xaxis=None, yaxis=None, colorbar=False, cmap=cmap, nonselection_alpha=0.01, nonselection_color='black') return hv.Layout([ dynspread( datashade(hv.Scatter(df, 'x_' + str(e), ['y_' + str(e), attr], label=get_label( e, src)).opts(scatter_options), aggregator=ds.count_cat(attr))) for e in experiments ]) else: str_tooltips = "\ <div> \ <img src=\"@path\" width=\"100\" height=\"100\"></img> \ </div> \ <div> \ <span style=\"font-size: 12px;\">label: @labels</span> \ </div> \ " hover = bokeh.models.HoverTool(tooltips=str_tooltips) scatter_options = opts.Scatter( width=width, aspect=1, xaxis=None, yaxis=None, colorbar=False, cmap=cmap, nonselection_alpha=0.01, nonselection_color='black', tools=[hover, 'box_select', 'lasso_select']) if single_mode: raise ValueError( 'Implement single_mode (no layout just DynamicMap)' ) # TODO: single_mode scatter_list = [ hv.Scatter(df, 'x_' + str(e), ['y_' + str(e), attr, 'path', 'labels'], label=get_label( e, src)).opts(scatter_options).opts(color=hv.dim(attr)) for e in experiments ] if len(scatter_list) > 2: [ DataLink(scatter1, scatter2) for scatter1, scatter2 in combinations(scatter_list, 2) ] DataLink(scatter_list[0], scatter_list[1]) return hv.Layout(scatter_list).cols(n_cols).relabel(src + ' plotting ' + str(n_samples) + ' datapoints')
df = iris() dataset = hv.Dataset(df) # Build selection linking object selection_linker = hv.selection.link_selections.instance() scatter = selection_linker( hv.Scatter(dataset, kdims=["sepal_length"], vdims=["sepal_width"])) hist = selection_linker( hv.operation.histogram(dataset, dimension="petal_width", normed=False)) # Use plot hook to set the default drag mode to box selection def set_dragmode(plot, element): fig = plot.state fig['layout']['dragmode'] = "select" if isinstance(element, hv.Histogram): # Constrain histogram selection direction to horizontal fig['layout']['selectdirection'] = "h" scatter.opts(opts.Scatter(hooks=[set_dragmode])) hist.opts(opts.Histogram(hooks=[set_dragmode])) app = dash.Dash(__name__) components = to_dash(app, [scatter, hist], reset_button=True) app.layout = html.Div(components.children) if __name__ == "__main__": app.run_server(debug=True)
def plot_countries(df, col, round_val=1, col_tooltip='', nr_countries=10, reverse=False): ''' Plot the overview for the top x (default 10) countries and for the overall countries as well. Returns a HoloViews plot layout. Arguments: df - Dataframe to process, must have the columns 'Country' and 'Year' within. col - Column in Dataframe where values are evaluated for the plotting process round_val (optional) - single numeric value to set the y axis limit on max found within col col_tooltip (optional) - tooltip to be set in the plots for the col values nr_countries (int) (optional) - number of countries to plot in the top views reverse (bool) (optional) - if True the bottom countries are listed ''' max_y = np.ceil(np.nanmax(df[col].values)) max_y = max_y - max_y % round_val + 2 * round_val if col_tooltip == '': col_tooltip = '@{' + col.replace( " ", "_" ) + '}{0,0.000}' # Holoviews auto-replaces spaces with underscores years_list = list(df['Year'].unique()) if reverse == True: label = 'Bottom' + str(nr_countries) plot_df = df[-nr_countries * len(years_list):] else: label = 'Top' + str(nr_countries) plot_df = df[:nr_countries * len(years_list)][::-1] plot_df_invert = plot_df[::-1].copy() df_invert = df[::-1].copy() # Plot settings and parameters top_hover = HoverTool(tooltips=[('Country', '@Country'), ('Year', '@Year'), (col, col_tooltip)]) country_hover = HoverTool(tooltips=[("Year", "@Year"), (col, col_tooltip)]) year_hover = HoverTool(tooltips=[("Country", "@Country"), (col, col_tooltip)]) top_plot_arguments = dict(x='Year', y=col, by='Country', tools=[top_hover]) options_shared = dict(height=700, ylim=(0, max_y), hooks=[set_bokeh_plot], active_tools=['wheel_zoom'], padding=(0.1, 0.1)) options = [ opts.Bars(width=700, show_grid=True, **options_shared), opts.Scatter(xticks=years_list, marker='o', size=10, **options_shared), opts.NdOverlay(width=650, xticks=years_list, **options_shared), opts.Layout(tabs=True) ] # Create the multiplot layout = ( plot_df_invert.hvplot( kind='barh', label=label + 'BarPlot', **top_plot_arguments) + plot_df.hvplot( kind='line', label=label + 'LinePlot', **top_plot_arguments) * plot_df.hvplot( kind='scatter', label=label + 'LinePlot', **top_plot_arguments) + df.hvplot(kind='bar', x='Year', y=col, groupby='Country', label='SingleCountryDropdown', tools=[country_hover]) + df_invert.hvplot(kind='barh', x='Country', y=col, groupby='Year', label='AllCountriesYearSlider', tools=[year_hover])).opts(options) return layout
import pandas as pd import numpy as np import holoviews as hv from holoviews import opts, dim hv.extension('bokeh') macro_df = pd.read_csv('http://assets.holoviews.org/macro.csv', '\t') key_dimensions = [('year', 'Year'), ('country', 'Country')] value_dimensions = [('unem', 'Unemployment'), ('capmob', 'Capital Mobility'), ('gdp', 'GDP Growth'), ('trade', 'Trade')] macro = hv.Table(macro_df, key_dimensions, value_dimensions) gdp_curves = macro.to.curve('Year', 'GDP Growth') gdp_unem_scatter = macro.to.scatter('Year', ['GDP Growth', 'Unemployment']) annotations = hv.Arrow(1973, 8, 'Oil Crisis', 'v') * hv.Arrow(1975, 6, 'Stagflation', 'v') *\ hv.Arrow(1979, 8, 'Energy Crisis', 'v') * hv.Arrow(1981.9, 5, 'Early Eighties\n Recession', 'v') composition=(gdp_curves * gdp_unem_scatter* annotations) composition.opts( opts.Curve(color='k'), opts.Scatter(cmap='Blues', color='Unemployment', line_color='k', size=dim('Unemployment')*1.5), opts.Text(text_font_size='13px'), opts.Overlay(height=400, show_frame=False, width=700)) hv.save(composition, 'holomap.html')
import pandas as pd import sys import os import holoviews as hv from holoviews import opts, dim, Palette import configparser # Define default layout of graphs hv.extension('bokeh') opts.defaults( opts.Bars(xrotation=45, tools=['hover']), opts.BoxWhisker(width=700, xrotation=30, box_fill_color=Palette('Category20')), opts.Curve(width=700, tools=['hover']), opts.GridSpace(shared_yaxis=True), opts.Scatter(width=700, height=500, color=Palette('Category20'), size=dim('growth')+5, tools=['hover'],alpha=0.5, cmap='Set1'), opts.NdOverlay(legend_position='left')) # Initializes the figures path in webpage for the diagram output if os.path.isdir(os.path.join("webpage","figures")) is False: os.mkdir(os.path.join("webpage","figures")) print("Path 'figures' created successfully") else: print("Path 'figures' initialized") class InteractivePlots: def __init__(self):
def plot_perforacion(): elementos_perforacion=serie_resumen[['dias_perforacion','Qi_hist','estado_actual']] tabla_perforacion = hv.Table(elementos_perforacion,'pozo') tabla_perforacion.opts(height=500,width=400,fontscale=20) dist = hv.Distribution(serie_resumen.dias_perforacion, label='Dias de perforacion - Función de Probabilidad') hist=serie_resumen.dias_perforacion.dropna() hist=np.histogram(hist) plot_hist = hv.Histogram(hist) #kde = univariate_kde(dist, # bin_range=(0, serie_resumen.dias_perforacion.max()), # bw_method='scott', # n_samples=1000) #kde scatter = hv.Scatter(serie_resumen, kdims=['dias_perforacion','profundidad_total'], label='Dias de perforacion vs Profundidad total') #dist = dists.redim.label(dias_perforacion='Dias de perforacion') scatter = scatter.redim.label(dias_perforacion='Dias de perforacion', profundidad_total='Profundidad total') tiempos = tabla_perforacion + dist + scatter tiempos.opts( opts.Distribution(height=500, width=700, xaxis=True, xlabel='Dias de Perforacion', xlim=(0,serie_resumen.dias_perforacion.max()), line_width=1.00, color='grey', alpha=0.5, fontscale=1.5, tools=['hover']), opts.Scatter(height=500, width=700, xaxis=True, yaxis=True, size=dim('Qi_hist')*50, line_width=0.25, color='estado_actual', cmap='Set1', fontscale=1.5, legend_position='bottom_right')) #fill_color=factor_cmap('estado_actual', palette=Spectral6, factors=elementos_tipos['tipo'])) tiempos hv.output(tiempos, backend='bokeh', fig='html') hv.save(tiempos, 'curvas_tipo.html') #hv.save(tiempos, 'tiempos.html') return
import math from . import average_water_view from rti_python.Post_Process.Average.AverageWaterColumn import AverageWaterColumn import pandas as pd import holoviews as hv from holoviews import opts, dim, Palette hv.extension('bokeh') import panel as pn pn.extension() from bokeh.plotting import figure, ColumnDataSource opts.defaults( opts.Bars(xrotation=45, tools=['hover']), opts.BoxWhisker(width=800, xrotation=30, box_fill_color=Palette('Category20')), opts.Curve(width=600, tools=['hover']), opts.GridSpace(shared_yaxis=True), opts.Scatter(width=800, height=400, color=Palette('Category20'), size=dim('growth')+5, tools=['hover']), opts.NdOverlay(legend_position='left')) class AverageWaterVM(average_water_view.Ui_AvgWater, QWidget): increment_ens_sig = pyqtSignal(int) reset_avg_sig = pyqtSignal() avg_taken_sig = pyqtSignal() def __init__(self, parent, rti_config): average_water_view.Ui_AvgWater.__init__(self) QWidget.__init__(self, parent) self.setupUi(self) self.parent = parent
default_fontsizes = dict(title=8, labels=8, ticks=7, minor_ticks=7, legend=7) fig_opts = [ opts.Layout(aspect_weight=1, fig_inches=(3.42, None), sublabel_size=10, fontsize=8), opts.Overlay(fontsize=default_fontsizes, ), opts.Area(fontsize=default_fontsizes), opts.Arrow(textsize=default_fontsizes), opts.Curve(fontsize=default_fontsizes), opts.HexTiles(fontsize=default_fontsizes), opts.Histogram(fontsize=default_fontsizes), opts.Raster(fontsize=default_fontsizes), opts.Scatter(fontsize=default_fontsizes), opts.Text(fontsize=default_fontsizes), opts.QuadMesh(fontsize=default_fontsizes), opts.Violin(fontsize=default_fontsizes), opts.VLine(fontsize=default_fontsizes), ] # hv hooks class Suptitle: def __init__(self, suptitle, color, y=1.175): self.suptitle = suptitle self.color = color self.y = y
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
tiempos tiempos.opts( opts.Distribution(height=400, width=800, xaxis=True, xlabel='Dias de Perforacion', xlim=(0, serie_resumen.dias_perforacion.max()), line_width=1.00, color='grey', alpha=0.5, tools=['hover']), opts.Scatter(height=400, width=800, xaxis=True, yaxis=True, size=10, line_width=0.25, color='orange')).cols(1) hv.save(tiempos, 'output_tiempos.html', backend='bokeh') ###### HV Plot import panel as pn tiempo_perf = serie_resumen.hvplot.scatter(x='dias_perforacion', y='profundidad_total', by='trayectoria', alpha=0.5) tiempo_perf
right_viterbi = 100 * np.count_nonzero( gen_states == model.states(series)) / series.size print(f"Right states with Viterbi: {right_states:.2f}%\n" f"Right states with gamma argmax: {right_viterbi:.2f}%") mt = hv.Scatter((model.matrix.flat, np.genfromtxt("gen_param/A.txt").flat)) avg = hv.Scatter( (model.distr.mean, np.log(np.genfromtxt("gen_param/b.txt")[:, 0]))) std = hv.Scatter((model.distr.std, np.genfromtxt("gen_param/b.txt")[:, 1])) pi = hv.Scatter((model.init_distr, np.genfromtxt("gen_param/pi.txt"))) ze = hv.Scatter( (model.zero_distr, np.genfromtxt("gen_param/zero_distr.txt")[:, 0])) param_max = ( np.array([model.matrix.max(), model.init_distr.max(), model.zero_distr.max()]).max() + 0.02 ) # yapf: disable fit = hv.Curve((*[[0, param_max]] * 2, )) layout = (mt * std * pi * ze * fit).redim(x="Inferred", y="Simulated") layout.opts(opts.Scatter(size=7, tools=["hover"]), opts.Curve(color="green")) # %% cProfile.run("model.baum_welch(series, 5)", sort="cumtime") # %% lp = line_profiler.LineProfiler(model.baum_welch) lp.run("model.baum_welch(series, 3)").print_stats() # %%
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()