def dist_compare_grid( df1, df2, columns=None, max_bar_categories: int = 40, grid_size: Tuple[int, int] = (900, 900), ): if columns is None: columns = [c for c in df1.columns if c in df2.columns] else: for c in columns: if c not in df1.columns: raise ValueError("%s is not in df1.columns" % str(c)) if c not in df2.columns: raise ValueError("%s is not in df2.columns" % str(c)) grid_cols = int(np.ceil(np.sqrt(len(columns)))) grid_rows = int(np.ceil(len(columns) / grid_cols)) plots = [ dist_compare_plot(df1[c], df2[c], max_bar_categories).opts(title=c) for c in columns ] grid = hv.Layout(plots).opts(shared_axes=False, normalize=False) grid.cols(grid_cols) # set sizes subplot_size = (int(grid_size[0] / grid_cols), int(grid_size[1] / grid_rows)) grid.opts( opts.Histogram(width=subplot_size[0], height=subplot_size[1]), opts.Bars(width=subplot_size[0], height=subplot_size[1]), ) return grid
def get_pbars(Week): abbrev_labels = ['GBM', 'LR', 'NB', 'RF'] mean = round(np.mean([week_probs[i][Week] for i in range(4)])*100,2) res = hv.Bars([(abbrev_labels[i], week_probs[i][Week]) for i in range(4)], label='Rain Probability: '+ str(mean)+'%').opts(width=500, height=500) res.opts(xlabel='Models', ylabel='Probability', \ legend_position='top_right').redim(x=hv.Dimension('x', range=(0.0, 1)), \ y=hv.Dimension('y', range=(0.0, 1))) res = res.opts(opts.Bars(alpha=0.5)) return res
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 get_split(complete_df): # preprocessing df = complete_df.copy() df['Leves'] = abs(df['Casos'] - (df['Hospitalizados'] + df['UCI'])) df = df[[ 'Comunidad Autónoma', 'Fecha', 'Leves', 'Hospitalizados', 'UCI', 'Fallecidos' ]] df = pd.melt(df, id_vars=df.columns[:2], var_name='Estado', value_name='Número') # plot key_dimensions = ['Fecha', 'Estado'] value_dimensions = ['Número'] # for better date representation df.Fecha = df.loc[:, 'Fecha'].dt.strftime('%d-%m') macro = hv.Table(df, key_dimensions, value_dimensions) bars = macro.to.bars(key_dimensions, value_dimensions, 'Comunidad Autónoma') # color_cycle = hv.Cycle(['#FEE5AD', '#F7A541', '#F45D4C', '#2E2633']) color_cycle = hv.Palette('Inferno', reverse=True) bars.opts( opts.Bars(color=color_cycle, show_legend=True, stacked=True, width=900, height=450, shared_axes=False, ylabel='', xlabel='Fecha', responsive=True, tools=['hover'], title='Desglose por estado', legend_position='top_left', xrotation=90, active_tools=['pan', 'wheel_zoom']), ) return bars
def plot_segregation(adata, save=False, filename=None): """Plot gabaergic and glutamaterig cell populations""" import holoviews as hv from holoviews import opts import pandas as pd hv.extension("matplotlib") df = pd.DataFrame(adata.uns["ligands"]).loc[["GABA", "L-glutamic acid" ]].stack().reset_index() df.columns = ["ligand", "cluster", "value"] df = df.sort_values(by="cluster", axis=0) opts.defaults( opts.Bars(stacked=True, xrotation=90, legend_position="right", ylabel="Ligand score")) bars = hv.Bars(df, kdims=["cluster", "ligand"]) if save is True: hv.save(bars, filename) return bars
def get_sens_spec(thingers): abbrev_labels = ['GBM', 'LR', 'NB', 'RF'] tp = [thingers[i][0,0] for i in range(4)] fp = [thingers[i][0,1] for i in range(4)] tn = [thingers[i][1,1] for i in range(4)] fn = [thingers[i][1,0] for i in range(4)] sens = np.array([tp[i]/(tp[i]+fn[i]) for i in range(4)]) spec = np.array([tn[i]/(tn[i]+fp[i]) for i in range(4)]) hist1 = hv.Bars([(abbrev_labels[i], sens[i]) for i in range(4)], \ label='Sensitivity').opts(width=500, height=500) hist2 = hv.Bars([(abbrev_labels[i], spec[i]) for i in range(4)], \ label='Specificity').opts(width=500, height=500) both = (hist1*hist2).opts(xlabel='Models', ylabel='Rates', \ legend_position='top_right').redim(x=hv.Dimension('x', range=(0.0, 1)), \ y=hv.Dimension('y', range=(0.0, 1))) both = both.opts(opts.Bars(alpha=0.5)).redim(x=hv.Dimension('x', range=(0.0, 1)), \ y=hv.Dimension('y', range=(0.0, 1))) return sens, spec, both
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
for i in open(base_dir + 'kyoto-train.en', 'r').readlines() ] df = pd.DataFrame({"ja": ja, "en": en}).iloc[0:3000, :] # Japanese PreProcessing df['ja_preprocessed'] = df['ja'].apply(lambda x: ja_preprocess(x)) # English PreProcessing df['en_preprocessed'] = df['en'].apply(lambda x: en_preprocess(x)) # English tfidf / bow features en_bow = bow_features(df['en_preprocessed'], _max_features=10, _max_ngrams=1) en_tfidf = tfidf_features(df['en_preprocessed'], _max_features=10, _max_ngrams=1) # English Ngram Count en_ngram = ngram_count(df['en_preprocessed'], ngram=1, common_num=30) # Ngram Count Bar Plot en_ngram_graph = hv.Bars(en_ngram[::-1]) \ .opts(opts.Bars(title="Ngram Count", color="red", xlabel="Unigrams", ylabel="Count", width=400, height=600, show_grid=True, invert_axes=True)) hv.save(en_ngram_graph, 'en_graph.html') # Japanese WordCloud wordCloud(df['ja_preprocessed'], _font_path='NotoSansCJKjp-Regular.otf', _output_file='wordCloud_ja.png') # English WordCloud wordCloud(df['en_preprocessed'], _output_file='wordCloud_en.png')
def bars_defaults(cls, **kwargs): """ Set defaults for holoviews Points class. Use kwargs to overwrite elvis defaults and set user-specific defaults """ return opts.defaults(opts.Bars(**_dict_merge(kwargs, cls.DEFAULT_BARS_OPTS)))
from bokeh.models import HoverTool from .average_water_thread import AverageWaterThread from .plot_average_data import PlotAverageData from .bokeh_plot_manager import BokehPlotManager 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)
def seriesToHistogram(data, fileName='histogram', graphTitle='Distribution', sortedAscending=True, logScale=False, xlbl='Value', ylbl='Frequency'): data2 = data.replace(' ', np.nan) data2.dropna(inplace=True) # data2.sort_values(inplace=True) try: histData = pd.to_numeric(data2, errors='raise') numericData = True except: histData = data2 numericData = False if numericData: # frequencies, edges = np.histogram(gpas, int((highest - lowest) / 0.1), (lowest, highest)) dataList = histData.tolist() frequencies, edges = np.histogram(dataList, (int(math.sqrt(len(dataList))) if (len(dataList) > 30) else (max(len(dataList) // 3, 1))), (min(dataList), max(dataList))) #print('Values: %s, Edges: %s' % (frequencies.shape[0], edges.shape[0])) if logScale: frequencies = [ math.log10(freq) if freq > 0 else freq for freq in frequencies ] ylbl += ' (log 10 scale)' histo = hv.Histogram((edges, frequencies)) histo.opts( opts.Histogram(xlabel=xlbl, ylabel=ylbl, title=graphTitle, fontsize={ 'title': 40, 'labels': 20, 'xticks': 20, 'yticks': 20 })) subtitle = 'mean: ' + str(round(sum(dataList) / len(dataList), 3)) + ', n = ' + str(len(dataList)) hv.output(size=250) graph = hv.render(histo) graph.add_layout( Title(text=subtitle, text_font_style="italic", text_font_size="30pt"), 'above') output_file(outDir + fileName + '.html', mode='inline') save(graph) show(graph) # JH: Adds some specific display components when not in a graphical program. # JH: Consider a separate function for the two cases. if not edmApplication: hv.output(size=300) histo.opts(toolbar=None) graph = hv.render(histo) graph.add_layout( Title(text=subtitle, text_font_style="italic", text_font_size="30pt"), 'above') export_png(graph, filename=outDir + fileName + '.png') else: barData = histData.value_counts(dropna=False) dictList = sorted(zip(barData.index, barData.values), key=lambda x: x[sortedAscending]) # print(dictList) bar = hv.Bars(dictList) bar.opts(opts.Bars(xlabel=xlbl, ylabel=ylbl, title=graphTitle)) subtitle = 'n = ' + str(len(dictList)) hv.output(size=250) graph = hv.render(bar) graph.add_layout( Title(text=subtitle, text_font_style="italic", text_font_size="30pt"), 'above') output_file(outDir + fileName + '.html', mode='inline') save(graph) show(graph) # JH: Consider a bool exportPng=True when calling from outside edmAppliation if not edmApplication: hv.output(size=300) bar.opts(toolbar=None) graph2 = hv.render(bar) graph2.add_layout( Title(text=subtitle, text_font_style="italic", text_font_size="30pt"), 'above') export_png(graph2, filename=outDir + fileName + '.png') hv.output(size=125)
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
def holoviews_bar_small(self): """ holoviews_bar_small :- Plot the Categorical Cols. Plot Cat Cols with Max and Min Categories. """ try: import pandas as pd import holoviews as hv from holoviews import opts from bokeh.plotting import figure, show, output_file from bokeh.embed import components from bokeh.resources import CDN from holoviews.core.options import Store df_for_bokeh = pd.read_pickle("./df_holoviewPlots.pkl") col_names_fromPSQL = list(df_for_bokeh) ls_SeriesName = [] ls_SeriesUnqCnts = [] for k in range(len(col_names_fromPSQL)): series_name = str(col_names_fromPSQL[k]) ls_SeriesName.append(series_name) unq_values_list = df_for_bokeh[series_name].unique() ls_SeriesUnqCnts.append(len(unq_values_list)) df_calcUnq = pd.DataFrame({ 'ls_SeriesName': ls_SeriesName, 'ls_SeriesUnqCnts': ls_SeriesUnqCnts }) # ls_SeriesUnqCnts -- is COUNT of SUB_CATEGORIES within the CATEGORY = ls_SeriesName min_valIndex = df_calcUnq['ls_SeriesUnqCnts'].idxmin() # min_valIndex -- is INDEX of SERIES with LEAST NUMBER of UNIQUE VALUES max_valIndex = df_calcUnq['ls_SeriesUnqCnts'].idxmax() # max_valIndex -- is INDEX of SERIES with MAX NUMBER of UNIQUE VALUES colA_with_CategoricalValues = df_calcUnq.iloc[min_valIndex][ 'ls_SeriesName'] unq_values_listA = df_for_bokeh[ colA_with_CategoricalValues].unique() #print("----------unq_values_listA-------------",unq_values_listA) #key_dimensions = [('businesstravel', 'BUSINESS_TRAVEL'), ('dailyrate', 'DAILY_RATE')] key_dimensions = [('businesstravel', 'BUSINESS_TRAVEL')] value_dimensions = [('dailyrate', 'DAILY_RATE')] macro = hv.Table(df_for_bokeh, key_dimensions, value_dimensions) bars = macro.to.bars(['businesstravel', 'dailyrate'], 'department', []) print("---------type(bars)----1----", type(bars)) ## <class 'holoviews.element.chart.Bars'> ##### Below line Commented for TESTING bars.opts( opts.Bars(color=hv.Cycle('Category20'), show_legend=False, stacked=True, tools=['hover'], width=600, xrotation=90)) #### ERROR == AttributeError: type object 'opts' has no attribute 'Bars' # /dc_dash/dc_holoviews.py", line 65, in holoviews_bar_small # bokeh_renderer = Store.renderers['bokeh'] # KeyError: 'bokeh' # bokeh_renderer = Store.renderers['bokeh'] # bokeh_plot = bokeh_renderer.get_plot(bars).state # hv.renderer('bokeh').get_plot(bars).state print("---------type(bars)----2----", type(bars)) ## <class 'holoviews.element.chart.Bars'> #print("---------type(bokeh_plot)-------",type(bokeh_plot)) #bars.toolbar.logo = None #bars.toolbar_location = None # FOO_Issue = https://github.com/pyviz/holoviews/issues/1975 js_holo_bar, div_holo_bar = components(bokeh_plot) cdn_js_holo_bar = CDN.js_files[0] # NOT REQD ?? cdn_css_holo_bar = CDN.css_files[0] # NOT REQD ?? return js_holo_bar, div_holo_bar, cdn_js_holo_bar, cdn_css_holo_bar except Exception as e: print( "--Exception as e:---File=>>-dc_holoviews.py-=--def holoviews_bar_small(self)------", e)
def run(self): """Runs the script""" from forge.tools import plainPlot # some elusive error in debugger it works while running it does not, but only here # Do some grouping and sanatizing groupedcountries = self.data["All"].groupby( self.data["All"]["Country/Region"]) # Data grouped by country self.countries = list(groupedcountries.groups) self.PlotDict["All"] = None prekeys = self.data["keys"] for items in self.config["COVID19"]["Countries"]: countryName = list(items.keys())[0] inhabitants = list(items.values())[0] countrycasegrouped = groupedcountries.get_group( countryName).groupby( "Name") # Grouped for death, confirmed, recovered seldata = { } # a dict containing all data from one country grouped by death, confirmed, recovered for i, key in enumerate( prekeys): # The three groups: death, confirmed, recovered rawdata = countrycasegrouped.get_group(key).sum( ) # Some countries have region information (I combine them to a single one) seldata[self.keys_basenames[i]] = rawdata[ self.measurements].reindex(self.measurements) # Now do the anlysis growth = {} relgrowth = {} for key, dat in seldata.items(): growth[key] = dat.diff() # Calculate the relative growth gr = growth[key].reindex(self.measurements) absc = dat.reindex(self.measurements) relgrowth[key] = gr.shift( periods=-1, fill_value=np.nan).divide( absc.replace(0, np.nan)).shift( periods=1, fill_value=np.nan ) * self.config["COVID19"]["GrowingRateMulti"] # Replace the data in the data structure newkeys = [ "Accumulated", "Growth", "RelativeGrowth*{}".format( self.config["COVID19"]["GrowingRateMulti"]) ] self.data["keys"] = newkeys self.data["columns"] = self.keys_basenames units = ["#" for i in self.keys_basenames] for key, dat in zip(newkeys, [seldata, growth, relgrowth]): self.data[key] = { "analysed": False, "plots": False, "header": "" } self.data[key]["measurements"] = self.keys_basenames self.data[key]["units"] = units #self.data[key]["units"][-2] = "%" # The last one is percent dat["Date"] = pd.to_datetime(pd.Series(self.measurements, name="Date", index=pd.Index( self.measurements)), infer_datetime_format=True) dat["Date"] = dat["Date"].dt.to_period('d') dat["Name"] = pd.Series([key for i in self.measurements], name="Name", index=pd.Index(self.measurements)) self.data[key]["measurements"].append("Date") self.data[key]["units"].append("") self.data[key]["data"] = pd.DataFrame(dat) # Start plotting # All individual donts = ["Date"] individual = plot_all_measurements( self.data, self.config, "Date", "COVID19", keys=[ "Accumulated", "Growth", "RelativeGrowth*{}".format( self.config["COVID19"]["GrowingRateMulti"]) ], do_not_plot=donts, PlotLabel="{}".format(countryName)) if self.Plots: self.Plots += individual else: self.Plots = individual self.relgrowth_all_countries(countryName) if self.config["COVID19"]["Normalize"] == True: self.accumulated_all_countries_normalizes( countryName, inhabitants) elif self.config["COVID19"]["Normalize"] == False: self.accumulated_all_countries(countryName) # Cases vs growth if not self.GrowthvsCases: self.GrowthvsCases = plainPlot( "Curve", self.data["Accumulated"]["data"]["confirmed"], self.data["Growth"]["data"]["confirmed"], label=countryName, ylabel="New Cases", **self.config['COVID19']['General'], **self.config['COVID19']['GvC']["PlotOptions"]) else: self.GrowthvsCases *= plainPlot( "Curve", self.data["Accumulated"]["data"]["confirmed"], self.data["Growth"]["data"]["confirmed"], label=countryName, ylabel="New Cases", **self.config['COVID19']['General'], **self.config['COVID19']['GvC']["PlotOptions"]) # Death vs growth if not self.DeathvsCases: self.DeathvsCases = plainPlot( "Curve", self.data["Accumulated"]["data"]["confirmed"], self.data["Accumulated"]["data"]["deaths"], label=countryName, ylabel="Total Deaths", **self.config['COVID19']['General'], **self.config['COVID19']['GvC']["PlotOptions"]) else: self.DeathvsCases *= plainPlot( "Curve", self.data["Accumulated"]["data"]["confirmed"], self.data["Accumulated"]["data"]["deaths"], label=countryName, ylabel="Total Deaths", **self.config['COVID19']['General'], **self.config['COVID19']['GvC']["PlotOptions"]) # Relabel the plots self.GrowthvsCases = relabelPlot( self.GrowthvsCases.opts(xlim=(1, None), ylim=(1, None)), "New Cases vs. Total Cases") self.DeathvsCases = relabelPlot( self.DeathvsCases.opts(xlim=(1, None), ylim=(1, None)), "Total Death vs. Total Cases") if not self.config["COVID19"]["Normalize"]: self.cases = relabelPlot(self.cases, "Confirmed Cases not normalized") self.recovered = relabelPlot(self.recovered, "Recovered Cases not normalized") self.deaths = relabelPlot(self.deaths, "Deaths not normalized") self.casesrelgrowth = relabelPlot(self.casesrelgrowth, "Confirmed Cases relative growth") self.recoveredrelgrowth = relabelPlot( self.recoveredrelgrowth, "Recovered Cases relative growth") self.deathsrelgrowth = relabelPlot(self.deathsrelgrowth, "Deaths relative growth") if self.config["COVID19"]["Normalize"]: self.casesNorm = relabelPlot(self.casesNorm, "Confirmed Cases normalized") self.recoveredNorm = relabelPlot(self.recoveredNorm, "Recovered Cases normalized") self.deathsNorm = relabelPlot(self.deathsNorm, "Deaths normalized") # Define Plotting order self.plottingOrder = [ self.GrowthvsCases, self.DeathvsCases, self.casesNorm, self.recoveredNorm, self.deathsNorm, self.casesrelgrowth, self.recoveredrelgrowth, self.deathsrelgrowth, self.cases, self.recovered, self.deaths, self.Plots ] for plot in self.plottingOrder: if plot: if self.PlotDict["All"]: self.PlotDict["All"] += plot else: self.PlotDict["All"] = plot # Reconfig the plots to be sure self.PlotDict["All"].opts(opts.Bars(stacked=True)) self.PlotDict["All"] = config_layout( self.PlotDict["All"], **self.config.get(self.analysisname, {}).get("Layout", {})) return self.PlotDict
def plot_sankey(G, notebook=False): """ render an interactive sankey plot of the graph. If notebook is False, starts an bokeh app in a browser window, if True, renders the plot directly in the cell. """ import scConnect as cn import holoviews as hv from holoviews import opts, dim import networkx as nx import pandas as pd import numpy as np # instantiate the bokeh renderer renderer = hv.renderer('bokeh') hv.extension("bokeh") hv.output(size=100) # set visuals opts.defaults( opts.Sankey(cmap='Category20', edge_cmap='Category20', edge_color=dim("receptorfamily"), labels='cluster', node_color=dim('cluster'), inspection_policy="edges", selection_policy="edges", colorbar=True, toolbar="above"), opts.Bars(invert_axes=False, xrotation=70, toolbar="above")) # Create values to be used for filtering of the graph edges = nx.to_pandas_edgelist(G) percentiles = [0, 20, 40, 60, 80, 90, 95, 99] th_values = np.percentile(edges["weighted_score"], percentiles) nodes_list = list(G.nodes()) node = hv.Dimension(("node", "Focus cluster"), default=nodes_list[0]) th = hv.Dimension(('th', 'Weighted score threshold'), default=th_values[0]) # Filter data on node and threshold, and return a sankey element def sankey_graph(node, th): # Find all interactions where node is target or source node G_s = nx.MultiDiGraph() for n, nbrs in G.adj.items(): for nbr, edict in nbrs.items(): if n == node: for e, d in edict.items(): # append dash after the target node G_s.add_edge(n, nbr + "_", **d) if nbr == node: for e, d in edict.items(): # append dash before the source node G_s.add_edge("_" + n, nbr, **d) # create the dataset used to build the sankey graph. # Sort values on weight to get ordered representation on plot. edges = nx.to_pandas_edgelist(G_s) links = hv.Dataset(edges, ["source", "target"], ["weighted_score", "interaction", "receptorfamily" ]).sort("weighted_score") nodes = hv.Dataset(list(G_s.nodes), 'cluster') sankey = hv.Sankey((links, nodes)).select(weighted_score=(th, None)) # calculate bars ligands = hv.Dataset(edges, ["ligand", "source"], ["score"]).select( source=node).aggregate(function=np.mean).sort("score", reverse=True) receptors = hv.Dataset(edges, ["receptor", "target"], ["score"]).select(target=node).aggregate( function=np.mean).sort("score", reverse=True) bars = (hv.Bars(ligands, "ligand") + hv.Bars(receptors, "receptor")).cols(2) # calculate table ligands = hv.Dataset((G.node[node]["ligands"]), "ligand", "score").sort("score", reverse=True) receptors = hv.Dataset((G.node[node]["receptors"]), "receptor", "score").sort("score", reverse=True) table = hv.Layout(hv.Table(ligands) + hv.Table(receptors)).cols(2) return (bars + table + sankey).cols(2) sankey = hv.DynamicMap(sankey_graph, kdims=[node, th]).redim.values(node=nodes_list, th=th_values) layout = sankey # Run the server if not in notebook if notebook == False: server = renderer.app(layout, show=True, new_window=True) if notebook == True: return layout