Source code for emat.analysis.visual_distribution


from emat.viz import scatter_graphs, scatter_graphs_2
from emat.viz.scatter import ScatterMass
from IPython.display import HTML, display, display_html


def _shorten_category_names(scope, experiment_results, original_cats):
	for k in scope.get_all_names():
		abbrev = getattr(scope[k], 'abbrev', {})
		if k in experiment_results.columns:
			try:
				is_cat = experiment_results[k].dtype == 'category'
			except TypeError:
				is_cat = False
			if is_cat:
				original_cats[k] = experiment_results[k].cat.categories
				experiment_results[k].cat.categories = [abbrev.get(i, i) for i in experiment_results[k].cat.categories]
	return experiment_results, original_cats


def _restore_category_names(experiment_results, original_cats):
	for k, v in original_cats.items():
		try:
			experiment_results[k].cat.categories = v
		except:
			print(k)
			print(experiment_results[k].cat.categories)
			print(v)
			raise


[docs]def display_experiments( scope, experiment_results=None, db=None, render='png', rows='measures', columns='infer', mass=1000, use_gl=True, return_figures=False, ): """ Render a visualization of experimental results. This function will display the outputs in a jupyter notebook, but does not actually return any values. Parameters ---------- scope : emat.Scope The scope to use in identifying parameters and performance measures. experiment_results : pandas.DataFrame or str The complete results from a set of experiments, including parameter inputs and performance measure outputs. Give a string to name a design in the database. db : emat.Database, optional When either of the `experiments` arguments is given as a string, the experiments are loaded from this database using the scope name as well as the given string as the design name. render : str or dict or None, default 'png' If given, the graph[s] will be rendered to a static image using `plotly.io.to_image`. For default settings, pass 'png', or give a dictionary that specifies keyword arguments to that function. If no rendering is done (by setting `render` to None), the raw plotly figures are returned -- this may result in a very large number of javascript figures and may slow down your browser. rows : {'measures', 'levers', 'uncertainties'} or Collection, default 'measures' Give a named group to generate a row of figures for each item in that group, or give a collection of individual names to generate a row of figures for each named item. columns : {'infer', 'measures', 'levers', 'uncertainties'} or Collection, default 'infer' Give a named group to generate a column of plots for each item in that group, or give a collection of individual names to generate a column of plots for each named item. The default 'infer' value will select all parameters when the row is a measure, and all measures otherwise. mass : int or emat.viz.ScatterMass, default 1000 The target number of rendered points in each figure. Setting to a number less than the number of experiments will make each scatter point partially transparent, which will help visually convey relative density when there are a very large number of points. return_figures : bool, default False Set this to True to return the FigureWidgets instead of simply displaying them. """ if isinstance(experiment_results, str): if db is None: raise ValueError("must give experiments or db and design_name") experiment_results = db.read_experiment_all( scope_name=scope.name, design_name=experiment_results, ) if rows == 'measures': rows = scope.get_measure_names() elif rows == 'levers': rows = scope.get_lever_names() elif rows == 'uncertainties': rows = scope.get_uncertainty_names() original_cats = {} try: experiment_results, original_cats = _shorten_category_names(scope, experiment_results, original_cats) figures = {} for row in rows: try: fig = scatter_graphs( row, experiment_results, scope=scope, render=render, use_gl=use_gl, mass=mass, contrast=columns, ) except KeyError: continue try: fig.update_layout(height=250) except KeyboardInterrupt: raise except: pass if return_figures: figures[row] = fig else: display_html(f'<h4 title="{scope.get_description(row)}">{scope.shortname(row)}</h4>', raw=True) display(fig) if return_figures: return figures finally: _restore_category_names(experiment_results, original_cats)
[docs]def contrast_experiments( scope, experiments_1, experiments_2, db=None, render='png', rows='measures', columns='infer', mass=1000, use_gl=True, return_figures=False, ): """ Render a visualization of two sets of experimental results. This function will display the outputs in a Jupyter notebook, but does not actually return any values. Args: scope (emat.Scope): The scope to use in identifying parameters and performance measures. experiments_1, experiments_2 (str or pandas.DataFrame): The complete results from a set of experiments, including parameter inputs and performance measure outputs. Give a string to name a design in the database instead of passing results explicitly as a DataFrame. db (emat.Database, optional): When either of the `experiments` arguments is given as a string, the experiments are loaded from this database using the scope name as well as the given string as the design name. render (str or dict or None, default 'png'): If given, the graph[s] will be rendered to a static image using `plotly.io.to_image`. For default settings, pass 'png', or give a dictionary that specifies keyword arguments to that function. If no rendering is done (by setting `render` to None), the raw plotly figures are returned -- this may result in a very large number of javascript figures and may slow down your browser. rows (str or Collection, default 'measures'): Give a named group {'measures', 'levers', 'uncertainties'} to generate a row of figures for each item in that group, or give a collection of individual names to generate a row of figures for each named item. columns (str or Collection, default 'infer'): Give a named group {'infer', 'measures', 'levers', 'uncertainties'} to generate a column of plots for each item in that group, or give a collection of individual names to generate a column of plots for each named item. The default 'infer' value will select all parameters when the row is a measure, and all measures otherwise. mass (int or emat.viz.ScatterMass, default 1000): The target number of rendered points in each figure. Setting to a number less than the number of experiments will make each scatter point partially transparent, which will help visually convey relative density when there are a very large number of points. return_figures (bool, default False): Set this to True to return the figures instead of simply displaying them within a Jupyter notebook. """ if isinstance(experiments_1, str): if db is None: raise ValueError("must give experiments or db and design_name") experiments_1 = db.read_experiment_all( scope_name=scope.name, design_name=experiments_1, ) if isinstance(experiments_2, str): if db is None: raise ValueError("must give experiments or db and design_name") experiments_2 = db.read_experiment_all( scope_name=scope.name, design_name=experiments_2, ) # check that categories align with scope scope.ensure_cat_ordering(experiments_1) scope.ensure_cat_ordering(experiments_2) if rows == 'measures': rows = scope.get_measure_names() elif rows == 'levers': rows = scope.get_lever_names() elif rows == 'uncertainties': rows = scope.get_uncertainty_names() # if measures is None: # measures = scope.get_measure_names() original_cats1 = {} original_cats2 = {} try: experiments_1, original_cats1 = _shorten_category_names(scope, experiments_1, original_cats1) experiments_2, original_cats2 = _shorten_category_names(scope, experiments_2, original_cats2) figures = {} for row in rows: if not return_figures: display_html(f'<h4 title="{scope.get_description(row)}">{scope.shortname(row)}</h4>', raw=True) fig = scatter_graphs_2( row, [experiments_1, experiments_2], scope=scope, render=render, use_gl=use_gl, mass=mass, contrast=columns, ) if return_figures: figures[row] = fig else: display(fig) if return_figures: return figures finally: _restore_category_names(experiments_1, original_cats1) _restore_category_names(experiments_2, original_cats2)