asreviewcontrib.simulation.api.plotting
Offers functionality for plotting a list of samples taken from the parameter space.
1""" 2Offers functionality for plotting a list of samples taken from the parameter space. 3""" 4from asreviewcontrib.simulation._private.lib.plotting.padding import Padding 5from asreviewcontrib.simulation._private.lib.plotting.trellis import plot_trellis 6from asreviewcontrib.simulation._private.lib.plotting.trellis import TrellisHandles 7 8 9__all__ = [ 10 "Padding", 11 "TrellisHandles", 12 "plot_trellis", 13]
class
Padding:
2class Padding: 3 """ 4 Class to keep track of padding length in 4 directions: `bottom`, `left`, `right`, `top`. 5 """ 6 7 def __init__(self, bottom: float = 0.1, left: float = 0.1, right: float = 0.1, top: float = 0.1): 8 """ 9 Synopsis: 10 11 Constructor method. 12 13 Example usage: 14 15 Use the default lengths of 0.1 all around: 16 ```python 17 from asreviewcontrib.simulation.api.plotting import Padding 18 19 20 padding = Padding() 21 ``` 22 23 Use 0.0 padding horizontally and 0.2 vertically: 24 25 ```python 26 from asreviewcontrib.simulation.api.plotting import Padding 27 28 29 padding = Padding(left=0.0, right=0.0, top=0.2, bottom=0.2) 30 ``` 31 """ 32 # define private attributes 33 self._bottom = None 34 self._left = None 35 self._right = None 36 self._top = None 37 38 # set private attributes via setters 39 self.bottom = bottom 40 self.left = left 41 self.right = right 42 self.top = top 43 44 @property 45 def bottom(self): 46 """ 47 The padding length at the bottom side. 48 """ 49 return self._bottom 50 51 @bottom.setter 52 def bottom(self, bottom): 53 """ 54 The padding length at the bottom side. 55 """ 56 self._bottom = bottom 57 58 @property 59 def left(self): 60 """ 61 The padding length at the left side. 62 """ 63 return self._left 64 65 @left.setter 66 def left(self, left): 67 """ 68 The padding length at the left side. 69 """ 70 self._left = left 71 72 @property 73 def right(self): 74 """ 75 The padding length at the right side. 76 """ 77 return self._right 78 79 @right.setter 80 def right(self, right): 81 """ 82 The padding length at the right side. 83 """ 84 self._right = right 85 86 @property 87 def top(self): 88 """ 89 The padding length at the top side. 90 """ 91 return self._top 92 93 @top.setter 94 def top(self, top): 95 """ 96 The padding length at the top side. 97 """ 98 self._top = top
Padding( bottom: float = 0.1, left: float = 0.1, right: float = 0.1, top: float = 0.1)
7 def __init__(self, bottom: float = 0.1, left: float = 0.1, right: float = 0.1, top: float = 0.1): 8 """ 9 Synopsis: 10 11 Constructor method. 12 13 Example usage: 14 15 Use the default lengths of 0.1 all around: 16 ```python 17 from asreviewcontrib.simulation.api.plotting import Padding 18 19 20 padding = Padding() 21 ``` 22 23 Use 0.0 padding horizontally and 0.2 vertically: 24 25 ```python 26 from asreviewcontrib.simulation.api.plotting import Padding 27 28 29 padding = Padding(left=0.0, right=0.0, top=0.2, bottom=0.2) 30 ``` 31 """ 32 # define private attributes 33 self._bottom = None 34 self._left = None 35 self._right = None 36 self._top = None 37 38 # set private attributes via setters 39 self.bottom = bottom 40 self.left = left 41 self.right = right 42 self.top = top
Synopsis:
Constructor method.
Example usage:
Use the default lengths of 0.1 all around:
from asreviewcontrib.simulation.api.plotting import Padding padding = Padding()Use 0.0 padding horizontally and 0.2 vertically:
from asreviewcontrib.simulation.api.plotting import Padding padding = Padding(left=0.0, right=0.0, top=0.2, bottom=0.2)
bottom
44 @property 45 def bottom(self): 46 """ 47 The padding length at the bottom side. 48 """ 49 return self._bottom
The padding length at the bottom side.
left
58 @property 59 def left(self): 60 """ 61 The padding length at the left side. 62 """ 63 return self._left
The padding length at the left side.
class
TrellisHandles:
53class TrellisHandles: 54 def __init__( 55 self, 56 axes_handles: List[List[Optional[plt.Axes]]], 57 show_params: List[str], 58 ): 59 """ 60 Args: 61 axes_handles: 62 TODO 63 show_params: 64 TODO 65 66 Synopsis: 67 68 TODO 69 """ 70 self._axes = axes_handles 71 self._show_params = show_params 72 73 def get_axes_by_row_name(self, row_name: str) -> List[plt.Axes]: 74 """ 75 Args: 76 row_name: 77 TODO 78 79 Returns: 80 TODO 81 """ 82 assert row_name is not None, "Need a name to identify the row of subaxes" 83 assert row_name in self.show_params[:-1], f"{row_name} is not a valid name for a row" 84 irow = self.show_params.index(row_name) 85 return [col for col in self.axes[irow] if col is not None] 86 87 def get_axes_by_col_name(self, col_name: str) -> List[plt.Axes]: 88 """ 89 Args: 90 col_name: 91 TODO 92 93 Returns: 94 TODO 95 """ 96 assert col_name is not None, "Need a name to identify the column of subaxes" 97 assert col_name in self.show_params[1:], f"{col_name} is not a valid name for a column" 98 icol = self.show_params.index(col_name) 99 return [row[icol] for row in self.axes if row[icol] is not None] 100 101 def get_axes_by_names(self, row_name: Optional[str] = None, col_name: Optional[str] = None) -> plt.Axes: 102 """ 103 Args: 104 row_name: 105 TODO 106 col_name: 107 TODO 108 109 Returns: 110 TODO 111 """ 112 assert row_name is not None, "Need a name to identify the row of subaxes" 113 assert row_name in self.show_params[:-1], f"{row_name} is not a valid name for a row" 114 assert col_name is not None, "Need a name to identify the column of subaxes" 115 assert col_name in self.show_params[1:], f"{col_name} is not a valid name for a column" 116 irow = self.show_params.index(row_name) 117 icol = self.show_params.index(col_name) 118 assert icol > irow, "No axes at that position." 119 return self._axes[irow][icol] 120 121 @property 122 def axes(self): 123 """ 124 TODO 125 """ 126 return self._axes 127 128 @property 129 def show_params(self): 130 """ 131 TODO 132 """ 133 return self._show_params
TrellisHandles( axes_handles: List[List[Optional[matplotlib.axes._axes.Axes]]], show_params: List[str])
54 def __init__( 55 self, 56 axes_handles: List[List[Optional[plt.Axes]]], 57 show_params: List[str], 58 ): 59 """ 60 Args: 61 axes_handles: 62 TODO 63 show_params: 64 TODO 65 66 Synopsis: 67 68 TODO 69 """ 70 self._axes = axes_handles 71 self._show_params = show_params
Arguments:
- axes_handles: TODO
- show_params: TODO
Synopsis:
TODO
def
get_axes_by_row_name(self, row_name: str) -> List[matplotlib.axes._axes.Axes]:
73 def get_axes_by_row_name(self, row_name: str) -> List[plt.Axes]: 74 """ 75 Args: 76 row_name: 77 TODO 78 79 Returns: 80 TODO 81 """ 82 assert row_name is not None, "Need a name to identify the row of subaxes" 83 assert row_name in self.show_params[:-1], f"{row_name} is not a valid name for a row" 84 irow = self.show_params.index(row_name) 85 return [col for col in self.axes[irow] if col is not None]
Arguments:
- row_name: TODO
Returns:
TODO
def
get_axes_by_col_name(self, col_name: str) -> List[matplotlib.axes._axes.Axes]:
87 def get_axes_by_col_name(self, col_name: str) -> List[plt.Axes]: 88 """ 89 Args: 90 col_name: 91 TODO 92 93 Returns: 94 TODO 95 """ 96 assert col_name is not None, "Need a name to identify the column of subaxes" 97 assert col_name in self.show_params[1:], f"{col_name} is not a valid name for a column" 98 icol = self.show_params.index(col_name) 99 return [row[icol] for row in self.axes if row[icol] is not None]
Arguments:
- col_name: TODO
Returns:
TODO
def
get_axes_by_names( self, row_name: Optional[str] = None, col_name: Optional[str] = None) -> matplotlib.axes._axes.Axes:
101 def get_axes_by_names(self, row_name: Optional[str] = None, col_name: Optional[str] = None) -> plt.Axes: 102 """ 103 Args: 104 row_name: 105 TODO 106 col_name: 107 TODO 108 109 Returns: 110 TODO 111 """ 112 assert row_name is not None, "Need a name to identify the row of subaxes" 113 assert row_name in self.show_params[:-1], f"{row_name} is not a valid name for a row" 114 assert col_name is not None, "Need a name to identify the column of subaxes" 115 assert col_name in self.show_params[1:], f"{col_name} is not a valid name for a column" 116 irow = self.show_params.index(row_name) 117 icol = self.show_params.index(col_name) 118 assert icol > irow, "No axes at that position." 119 return self._axes[irow][icol]
Arguments:
- row_name: TODO
- col_name: TODO
Returns:
TODO
def
plot_trellis( data: List[Tuple[asreviewcontrib.simulation._private.lib.config.Config, float]], show_params: Optional[List[str]] = None, outer_padding: Optional[Padding] = None, inner_padding: Optional[Padding] = None, scatter_kwargs: Optional[Dict[str, Any]] = None, show_response_surface: bool = True, show_text: bool = True) -> TrellisHandles:
289def plot_trellis( 290 data: List[Tuple[Config, float]], 291 show_params: Optional[List[str]] = None, 292 outer_padding: Optional[Padding] = None, 293 inner_padding: Optional[Padding] = None, 294 scatter_kwargs: Optional[Dict[str, Any]] = None, 295 show_response_surface: bool = True, 296 show_text: bool = True, 297) -> TrellisHandles: 298 """ 299 Args: 300 data: A list of tuples, where each tuple consists of an 301 `asreviewcontrib.simulation.api.Config` object and its associated objective score. 302 show_params: 303 The subset of the parameters that you want to plot. 304 outer_padding: 305 The padding around the trellis of axes. 306 inner_padding: 307 The padding around an individual axes. 308 scatter_kwargs: 309 `matplotlib`'s `scatter` keyword arguments, see 310 https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.scatter.html. 311 show_response_surface: 312 Whether to show an interpolation of objective function scores as a background 313 image in each axes. 314 show_text: 315 Whether to show the metadata for the list of parameterizations. 316 317 Returns: 318 The handles to the axes, to facilitate subsequent customization. 319 320 Synopsis: 321 322 Visualize each combination of 2 parameters out of a user-provided list of parameters using 323 a grid/trellis of axes. 324 325 Example usage: 326 327 ```python 328 from asreviewcontrib.simulation.api import Config 329 from asreviewcontrib.simulation.api import draw_sample 330 from asreviewcontrib.simulation.api import get_pyll 331 from asreviewcontrib.simulation.api import OneModelConfig 332 from asreviewcontrib.simulation.api.plotting import plot_trellis 333 from matplotlib import pyplot as plt 334 335 336 # retrieve the sampling spaces for the double balancer model 337 # and the TF-IDF feature extraction model, respectively. 338 pyll = { 339 "bal": get_pyll("bal-double"), 340 "fex": get_pyll("fex-tfidf"), 341 } 342 343 n_samples = 100 344 results = [] 345 346 for _ in range(n_samples): 347 348 # use pyll programs to draw a parameterization for 'bal' and 'fex' 349 drawn = draw_sample(pyll) 350 351 # construct an all-model config from one-model configs -- implicitly use 352 # default model choice and parameterization for models not included as 353 # argument 354 config = Config(**fixed, **drawn) 355 356 # emulate calculating objective scores with random(), naturally the 357 # results are not meaningful 358 results.append((config, random())) 359 360 plt.figure() 361 plot_trellis(results, sorted(drawn.keys())) 362 plt.show() 363 ``` 364 """ 365 366 assert len(data) >= 1, "Need at least one sample" 367 expected_params = data[0][0].flattened().keys() 368 for irow, row in enumerate(data): 369 actual_params = row[0].flattened().keys() 370 # verify that all the data rows are samples in the same parameter space 371 assert set(actual_params) == set(expected_params), f"Data row {irow} has unexpected key set" 372 373 # verify that the parameters selected for plotting are in fact all present 374 show_params = show_params or sorted(expected_params) 375 assert set(show_params).issubset(set(expected_params)), "The data doesn't include all the parameters you wanted to plot" 376 377 data_dict, scores = _calc_data_dict(data, show_params) 378 379 # assign defaults 380 outer = outer_padding or Padding(left=0.14, right=0.01, top=0.01, bottom=0.14) 381 inner = inner_padding or Padding(left=0.05, right=0.05, top=0.05, bottom=0.05) 382 scatter_kwargs = scatter_kwargs or {} 383 384 # prepare the grid of axes 385 axes_handles = _prep_axes(data_dict, inner=inner, outer=outer) 386 387 trellis_handles = TrellisHandles(axes_handles, show_params) 388 389 # visualize the data 390 _plot_scatter(axes_handles, data_dict, scatter_kwargs) 391 392 if show_response_surface: 393 _plot_response_surface(axes_handles, data_dict, scores) 394 395 if show_text: 396 _plot_text(data_dict, trellis_handles) 397 398 return trellis_handles
Arguments:
- data: A list of tuples, where each tuple consists of an
asreviewcontrib.simulation.api.Configobject and its associated objective score. - show_params: The subset of the parameters that you want to plot.
- outer_padding: The padding around the trellis of axes.
- inner_padding: The padding around an individual axes.
- scatter_kwargs:
matplotlib'sscatterkeyword arguments, see https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.scatter.html. - show_response_surface: Whether to show an interpolation of objective function scores as a background image in each axes.
- show_text: Whether to show the metadata for the list of parameterizations.
Returns:
The handles to the axes, to facilitate subsequent customization.
Synopsis:
Visualize each combination of 2 parameters out of a user-provided list of parameters using a grid/trellis of axes.
Example usage:
from asreviewcontrib.simulation.api import Config from asreviewcontrib.simulation.api import draw_sample from asreviewcontrib.simulation.api import get_pyll from asreviewcontrib.simulation.api import OneModelConfig from asreviewcontrib.simulation.api.plotting import plot_trellis from matplotlib import pyplot as plt # retrieve the sampling spaces for the double balancer model # and the TF-IDF feature extraction model, respectively. pyll = { "bal": get_pyll("bal-double"), "fex": get_pyll("fex-tfidf"), } n_samples = 100 results = [] for _ in range(n_samples): # use pyll programs to draw a parameterization for 'bal' and 'fex' drawn = draw_sample(pyll) # construct an all-model config from one-model configs -- implicitly use # default model choice and parameterization for models not included as # argument config = Config(**fixed, **drawn) # emulate calculating objective scores with random(), naturally the # results are not meaningful results.append((config, random())) plt.figure() plot_trellis(results, sorted(drawn.keys())) plt.show()