1. User API
This section describes the main API users are expected to interact with.
1.1. Functions
- ipysensitivityprofiler.profiler(models: list[Callable], xmin: list[float] | ndarray, xmax: list[float] | ndarray, ymin: list[float] | ndarray, ymax: list[float] | ndarray, x0: list[float] | ndarray | None = None, resolution: int = 25, width: int = 300, height: int | None = None, xlabels: list[str] | None = None, ylabels: list[str] | None = None, colors: list[str] | None = None, line_styles: list[str] | None = None, model_labels: list[str] | None = None, show_legend: bool | None = None) Profiler[source]
Create sensitivity profilers for given models.
- Example:
import ipysensitivityprofiler as isp def f1(x): return -0.1 * x[:, 0] ** 3 - 0.5 * x[:, 1] ** 2 def f2(x): return -0.2 * x[:, 0] ** 3 - 0.25 * x[:, 1] ** 2 isp.profiler( models=[f1, f2], xmin=[-5, -5], xmax=[5, 5], ymin=[-10], ymax=[10], x0=[1, 1], resolution=100, xlabels=["x1", "x2"], ylabels=["y"], )
- Args:
- models: List[callable]
List of callable functions with the same signature y = f(x). There will be one profile per model. x must be a numpy array of shape (-1, nx) and y an array of shape (-1, ny).
- xmin: Union[List[float], np.ndarray]
Lower bounds of inputs.
- xmax: Union[List[float], np.ndarray]
Upper bounds of inputs.
- ymin: Union[List[float], np.ndarray]
Lower bounds of outputs.
- ymax: Union[List[float], np.ndarray]
Upper bounds of outputs.
x0: Union[List[float], np.ndarray] Defaults to use for initial x0 (red dot in plots). Default is None (which turns into mean of range).
- resolution: int, optional
Line resolution. Default is 25 points.
- width: int, optional
Width of each plot. Default is 300 pixels.
- height: int, optional
Height of each plot. Default is None (match width).
- xlabels: List[str]
Labels to use for inputs. Default is None (which becomes x1, x2, …)
- ylabels: Union[List[float], np.ndarray]
Labels to use for outputs. Default is None (which becomes y1, y2, …)
- colors: List[str], optional
Line color per model, by position, as any CSS color. Cycled if shorter than models. Default is None, which uses a colorblind-safe categorical palette. Pass ipysensitivityprofiler._utils.DARK_COLORS under a dark theme.
- line_styles: List[str], optional
Line style per model, by position: one of “solid”, “dashed”, “dotted”, “dash_dotted”. Cycled if shorter than models. Default is None, which cycles all four so models stay distinguishable without relying on color alone.
- model_labels: List[str], optional
Legend label per model. Default is None, which uses each model’s function name.
- show_legend: bool, optional
Show a legend keying models to their color and stroke. Default is None, which shows one when there is more than one model.
- Returns:
Profiler: Jupyter Widget.
- Note:
The models are evaluated exactly once here, after the widget has been fully built. A slow model therefore shows an empty set of axes while it runs rather than blocking the widget from rendering at all.
1.2. Classes
- class ipysensitivityprofiler.Profiler(*args: t.Any, **kwargs: t.Any)[source]
Bases:
VBoxProfiler Widget.
- Attributes:
- view:
View Profiler widget controlled by controller.
- controller:
Controller Widget to control profilers
- view:
- __init__(view: View, controller: Controller, **kwargs: Any) None[source]
Public constructor
- class ipysensitivityprofiler.Controller(*args: t.Any, **kwargs: t.Any)[source]
Bases:
VBoxControl panel for profiler.
- Attributes:
- range_sliders: Dict[str, List[W.FloatRangeSlider]]:
Range sliders to control axis limits of inputs and outputs:
range_sliders = { "x": [...], # list of range sliders associated with inputs "y": [...], # list of range sliders associated with outputs }
- sliders: List[W.FloatSlider]
Sliders to control input values (and automatically update view).
- class ipysensitivityprofiler.View(*args: t.Any, **kwargs: t.Any)[source]
Bases:
BoxWidget to display grid of sensivity profiles.
Construction builds the whole figure grid but does not evaluate the models: the curves start flat and the first evaluation happens on
refresh(). Seerefresh().- predict: Callable
Callable function with signature y = f(x) where x must be a numpy array of shape (-1, n_x) and y an array of shape (-1, n_y).
- xmin: ndarray
An array of shape (n_x,) representing the lower bound on the inputs
- xmax: ndarray
An array of shape (n_x,) representing the upper bound on the inputs
- ymin: ndarray
An array of shape (n_y,) representing the lower bound on the outputs
- ymax: ndarray
An array of shape (n_y,) representing the upper bound on the outputs
- width: int
The width of each figure in pixels. Default is 300.
- height: int
The height of each figure in pixels. Default is 300.
- resolution: int
The number of point in each curve. Default is 25.
- x0: ndarray
The point about which to compute the sensitivities
- y0: ndarray
The value of the outputs evaluates at x0
- xlabels: list[str]
The name of each input
- ylabels: list[str]
The name of each output
- n_models: int
Number of models being profiled, i.e. the number of curves per figure.
- grid: GridspecLayout
Grid containing all figures
- colors: list[str]
Line color per model, by position. Cycled if shorter than the number of models. Defaults to a colorblind-safe categorical palette.
- line_styles: list[str]
Line style per model, by position. Cycled if shorter than the number of models. One of solid, dashed, dotted, dash_dotted.
- model_labels: list[str]
Legend label per model
- show_legend: bool
Show a legend keying models to their style
- refresh() None[source]
Evaluate the models and redraw.
Construction draws flat placeholder curves rather than evaluating, so that every widget exists before a slow model is allowed to block (#6).
ipysensitivityprofiler.profiler()calls this once the whole widget tree has been assembled; call it yourself when building aViewdirectly.
- save_png(xlabel: str, ylabel: str, filename: str | None = None) None[source]
Save figure as PNG.
- Args:
- xlabel: str
The label of the input shown in the figure.
- ylabel: str
The label of the output shown in the figure.
- filename: str, optional
File name to save to. Default is “profiler_{xlabel}_vs_{ylabel}.png”
2. Core API
This section describes backend support functions and classes. It is intended for developers.
- class ipysensitivityprofiler._data.Data(*args: t.Any, **kwargs: t.Any)[source]
Bases:
HasTraitsAutomatically evaluate outputs whenever inputs change.
This class is in charge of managing source data and calling user prediction models as needed.
Construction deliberately does not evaluate: y starts as a placeholder of the right shape and the models run only once
refresh()is called. Seerefresh().- xlabels: list[str]
An instance of a Python list.
- ylabels: list[str]
An instance of a Python list.
- n_models: int
Number of models, i.e. the number of curves in each figure.
- predict: Callable
Callback that calls user provided models to update data as needed.
- x: NDArray
A numpy array trait type.
- y: NDArray
A numpy array trait type.
- property n_x: int
Number of inputs.
- property n_y: int
Number of outputs.
- property N: int
Number of models (i.e. number of lines on plot).
- ipysensitivityprofiler._utils.grid_size(n_x: int, resolution: int) int[source]
Number of rows in a grid built by
create_grid().Callers that must pre-size buffers for a fixed number of evaluation points (such as an OpenMDAO problem’s
num_nodes) should size them with this.
- ipysensitivityprofiler._utils.create_grid(x0: NDArray, xmin: NDArray, xmax: NDArray, resolution: int = 10) NDArray[source]
Generate grid data for sensitivity profilers.
- Args:
- x0: NDArray
Local point about which to plot sensivities. Array of shape (n,) where n is the number of input variables.
- xmin: NDArray
Min bound for plotting sensitivities. Array of shape (n,)
- xmax: NDArray
Max bound for plotting sensitivities. Array of shape (n,)
- resolution: int, optional
Number of points between xmin and xmax. Default is 10.
- Returns:
- NDArray
Array of shape (resolution * n + 1, n). The first
resolution * nrows sweep one input at a time; the final row isx0itself.
- Example:
x = create_grid( x0=[ 0, 1, 2], xmin=[-5, -5, -5], xmax=[ 5, 5, 5], resolution=10, ) >> x = [[-5, 1, 2], [-3, 1, 2], [-2, 1, 2], [-1, 1, 2], [ 0, 1, 2], [ 0, 1, 2], [ 1, 1, 2], [ 2, 1, 2], [ 3, 1, 2], [ 5, 1, 2], [ 0, -5, 2], [ 0, -3, 2], [ 0, -2, 2], [ 0, -1, 2], [ 0, 0, 2], [ 0, 0, 2], [ 0, 1, 2], [ 0, 2, 2], [ 0, 3, 2], [ 0, 5, 2], [ 0, 1, -5], [ 0, 1, -3], [ 0, 1, -2], [ 0, 1, -1], [ 0, 1, 0], [ 0, 1, 0], [ 0, 1, 1], [ 0, 1, 2], [ 0, 1, 3], [ 0, 1, 5], [ 0, 1, 2]] # <- x0
- ipysensitivityprofiler._utils.batch_slice(index: int, resolution: int) slice[source]
Return the rows of a grid that sweep input index.
Grids from
create_grid()lay out one contiguous sweep per input, so the rows for a given input are a plain slice. Using a slice rather than a list of indices keeps the lookup a view instead of a copy, which matters because this sits in the redraw path.- Args:
- index: int
Index of the input variable.
- resolution: int
Number of points per sweep.
- Returns:
- slice
Row slice corresponding to one grid permutation.
- ipysensitivityprofiler._utils.make_figure(N: int, num_x_ticks: int = 3, num_y_ticks: int = 3, tick_style: dict | None = None, xmin: float | None = None, xmax: float | None = None, ymin: float | None = None, ymax: float | None = None, xs: LinearScale | None = None, ys: LinearScale | None = None, colors: list[str] | None = None, line_styles: list[str] | None = None, labels: list[str] | None = None, show_legend: bool = False) Figure[source]
Create initial figure for profiler trait (data will be replaced).
Pass xs / ys to share a scale with the other figures in the same column / row; omit them and the figure owns a private scale built from the bounds.
colors and line_styles are assigned to models by position and cycled if shorter than N, so each model is distinguishable by hue and by stroke.
- ipysensitivityprofiler._utils.make_grid(n_x: int, n_y: int, N: int, width: int | None = None, height: int | None = None, xscales: list[LinearScale] | None = None, yscales: list[LinearScale] | None = None, colors: list[str] | None = None, line_styles: list[str] | None = None, labels: list[str] | None = None, show_legend: bool = False) GridspecLayout[source]
Create grid layout of specified width and height.
Every figure in column j shows the same input and every figure in row i the same output, so xscales / yscales let one scale per column / row be shared across the whole grid rather than each cell owning a private pair.