Visualization & Plotting

doetools returns interactive Plotly figures. In a notebook, return the figure from the final cell or call fig.show(). Use fig.write_html("plot.html") for a self-contained interactive file. Static image export through fig.write_image(...) requires Plotly’s static image export dependency.

Available plots

The table below lists every public plotting method. Methods inherited from GraphsMixin are shared by the design classes that expose the standard graph API; candidate-set and Pareto plots are available only on the classes that provide those workflows.

Method

Use and required state

Result

plot_design()

Inspect process or mixture design points. Requires a generated or imported design.

One 2D, 3D, ternary, or tetrahedral figure.

plot_candidate_set()

Inspect a new D-optimal design’s candidate set before optimization.

One 2D, 3D, ternary, or tetrahedral figure.

plot_leverage()

Explore model leverage. Requires model terms, but not fitted responses.

Contour and surface figures.

plot_response()

Explore a fitted response, optionally with a second response, conservative interval correction, or feasible region.

Contour and surface figures.

plot_interval()

Explore confidence or prediction half-width. Requires a fitted model and variance statistics.

Contour and surface figures.

plot_regression_coefficients()

Compare fitted coefficients and their confidence intervals.

One figure, optionally with a response selector.

plot_diagnostics()

Select an overview, observed-versus-predicted, residual, Q-Q, or histogram diagnostic.

One figure, optionally with a response selector.

plot_main_effects()

Compare fitted main-effect profiles for all non-mixture factors.

One multi-panel figure.

plot_interactions()

Compare all fitted two-factor interactions for a non-mixture design.

One figure with a factor-pair selector.

plot_mixture_trace()

Inspect fitted component traces through the centroid blend.

One figure.

plot_confirmation()

Select observed-versus-predicted or residual confirmation diagnostics.

One figure for one response.

plot_pareto_front()

Inspect non-dominated solutions after compute_pareto_front().

One 2D or 3D figure.

compute_d_optimal()

Run D-optimal selection and inspect the best log-determinant by run count.

One optimization-history figure.

The D-optimal computation methods also return an optimization-history figure. Because they run the optimization rather than only render existing data, they are documented with the D-optimal design and D-optimal augmentation workflows.

Design-space visualization

Design points

plot_design selects its geometry from the chosen factor types and number of axes. Two or three non-mixture factors produce Cartesian plots. Two mixture components produce a mixture-line plot, three produce a ternary plot, and four produce a tetrahedral plot. Mixture and non-mixture factors cannot be combined as axes, but continuous and categorical axes can be combined.

For mixture plots, domain="allowed" draws the domain covered by the design instead of the full simplex or tetrahedron. When omitted factors make multiple runs share the same plotted coordinates, projected points are aggregated by default and their replicate counts are retained.

GraphsMixin.plot_design(ax1, ax2, ax3=None, ax4=None, coded=False, *, show_title=True, show_summary=True, show_legend=True, show_grid=True, marker_color='#1971c2', show_hover=True, show_run_labels=False, show_replicate_count=True, aggregate_projected_points=True, axis_label_mode='symbol_unit', height=None, domain='full')[source]

Visualize an experimental design in factor space.

Two or three non-mixture factors produce a Cartesian scatter plot. Two mixture components produce a mixture-line plot, three produce a ternary plot, and four produce a tetrahedral plot.

Parameters:
  • ax1 (str) – First factor, used as the x-axis or first simplex vertex.

  • ax2 (str) – Second factor, used as the y-axis or second simplex vertex.

  • ax3 (str) – Third factor, used as the z-axis or third simplex vertex.

  • ax4 (str) – Fourth mixture component for a tetrahedral plot.

  • coded (bool) – Whether to display coded rather than actual units.

  • show_title (bool) – Whether to display the generated title.

  • show_summary (bool) – Whether to display the design summary.

  • show_legend (bool) – Whether to display the legend.

  • show_grid (bool) – Whether to display grid lines.

  • marker_color (str) – Plotly-compatible marker color.

  • show_hover (bool) – Whether to display point information on hover.

  • show_run_labels (bool) – Whether to label points with run numbers.

  • show_replicate_count (bool) – Whether to include replicate counts.

  • aggregate_projected_points (bool) – Whether points with identical plotted coordinates are combined when other factors are omitted.

  • axis_label_mode (str) – Axis-label format. Supported values are "symbol_unit", "symbol", and "name".

  • height (int | None) – Figure height in pixels.

  • domain (Literal['full', 'allowed']) – Mixture domain to draw. "full" draws the full simplex or tetrahedron; "allowed" draws the domain covered by the design points.

Returns:

Interactive design plot.

Return type:

plotly.graph_objects.Figure

Notes

Either all selected factors must be mixture components, or none of them may be mixture components. Continuous and categorical factors can be combined in a Cartesian plot.

figure = design.plot_design(
    ax1="Temperature",
    ax2="Pressure",
    ax3="Time",
    coded=False,
)
figure.show()

D-optimal candidate sets

Candidate-set plots are specific to D-optimal workflows. For augmentation, generate the candidate set before plotting it. The two methods have different state requirements, so both signatures are shown.

DOptDesign.plot_candidate_set(ax1, ax2, ax3=None, ax4=None, coded=False, *, show_title=True, show_summary=True, show_legend=True, show_grid=True, marker_color='#495057', show_hover=True, show_run_labels=False, show_replicate_count=True, aggregate_projected_points=True, axis_label_mode='symbol_unit', height=None, domain='full')[source]

Visualize the candidate set before selecting a design.

Parameters:
  • ax1 (str) – First factor shown in the plot.

  • ax2 (str) – Second factor shown in the plot.

  • ax3 (str | None) – Third plotted factor.

  • ax4 (str | None) – Fourth mixture component for a tetrahedral plot.

  • coded (bool) – Whether to display coded rather than actual units.

  • show_title (bool) – Whether to display the generated title.

  • show_summary (bool) – Whether to display the candidate-set summary.

  • show_legend (bool) – Whether to display the legend.

  • show_grid (bool) – Whether to display grid lines.

  • marker_color (str) – Plotly-compatible marker color.

  • show_hover (bool) – Whether to display point information on hover.

  • show_run_labels (bool) – Whether to label candidate points.

  • show_replicate_count (bool) – Whether to include counts for repeated candidate settings.

  • aggregate_projected_points (bool) – Whether candidates with identical plotted coordinates are combined when other factors are omitted.

  • axis_label_mode (str) – Axis-label format. Supported values are "symbol_unit", "symbol", and "name".

  • height (int | None) – Figure height in pixels.

  • domain (Literal['full', 'allowed']) – Mixture domain to draw. "full" draws the full simplex or tetrahedron; "allowed" draws the domain covered by the candidate points.

Returns:

Candidate-set visualization.

Return type:

Figure

Notes

Two or three non-mixture factors produce Cartesian plots. Two, three, or four mixture components produce mixture-line, ternary, or tetrahedral plots.

candidate_figure = design.plot_candidate_set(
    ax1="Temperature",
    ax2="Pressure",
    ax3="Time",
    coded=False,
)

Leverage and fitted surfaces

The surface methods return two figures in this order: (contour_figure, surface_figure). With two free process factors these are a Cartesian contour and a 3D surface. Supplying ax3 produces the corresponding mixture contour and surface.

For process factors, grid bounds are always supplied in coded units, even when coded=False controls the displayed labels. Factors not assigned to an axis must be supplied in constant_levels when the method cannot infer them.

Leverage

Leverage depends on the model matrix, not on observed response values. It can therefore be inspected after model terms are defined and before fitting a model. Use domain="allowed" to apply saved process-domain filters or limit mixture plots to their allowed hull.

GraphsMixin.plot_leverage(ax1, ax2, ax3=None, constant_levels=None, resolution=100, x_min=-1.0, x_max=1.0, y_min=-1.0, y_max=1.0, coded=False, show_title=True, show_legend=True, show_summary=True, colorscale=None, domain='full')[source]

Visualize leverage values across the design space.

Leverage measures the influence of design points on model predictions. High leverage points are candidates for replication to improve precision.

Parameters:
  • ax1 (str) – First free factor.

  • ax2 (str) – Second free factor.

  • ax3 (str) – Third free mixture component for a ternary plot.

  • constant_levels (dict[str, float]) – Actual-unit levels at which to hold all remaining factors.

  • resolution (int) – Number of grid points per process axis, or the mixture-grid resolution.

  • x_min (float) – Lower bound for ax1 in coded units.

  • x_max (float) – Upper bound for ax1 in coded units.

  • y_min (float) – Lower bound for ax2 in coded units.

  • y_max (float) – Upper bound for ax2 in coded units.

  • coded (bool) – Whether to display coded rather than actual units.

  • show_title (bool) – Whether to display the generated title.

  • show_legend (bool) – Whether to display the legend.

  • show_summary (bool) – Whether to display the fixed-level and leverage-range annotation.

  • colorscale (str | list | None) – Plotly colorscale applied to the contour and surface traces.

  • domain (Literal['full', 'allowed']) – Plotting domain. "allowed" applies saved process domain filters or restricts a mixture plot to its allowed hull.

Returns:

Contour and three-dimensional surface figures.

Return type:

tuple[Figure, Figure]

Notes

Leverage is computed as x.T @ (X.T @ X)^+ @ x, where + denotes the Moore-Penrose pseudoinverse. A model matrix must have been defined, but response results and a fitted model are not required.

contour, surface = design.plot_leverage(
    ax1="Temperature",
    ax2="Pressure",
    constant_levels={"Time": 30.0},
    coded=False,
    domain="allowed",
)

Response surfaces

plot_response requires a fitted model. Set second_response to overlay a second fitted response. feasible_region=True displays the region satisfying the limits previously configured with set_response_conditions(); it is different from domain="allowed", which controls which factor combinations are drawn.

Set interval="confidence" to apply a conservative confidence bound for the mean, or interval="prediction" for one new independent observation. With interval=None (the default), the uncorrected fitted mean is plotted. The selected half-width is subtracted for maximization and added for minimization, so response conditions are required. This applies to both responses and the feasible region. variance_source="residuals" uses residual mean square; variance_source="pure_error" uses pure error and its degrees of freedom, requiring valid replicated observations. There is no automatic fallback.

GraphsMixin.plot_response(ax1, ax2, response, constant_levels=None, second_response=None, feasible_region=False, ax3=None, x_min=-1.0, x_max=1.0, y_min=-1.0, y_max=1.0, resolution=300, alpha=0.05, coded=False, domain='full', *, interval=None, variance_source='residuals')[source]

Visualize a fitted response across the design space.

The surface can include a second response, a conservative interval correction, and the region satisfying configured response conditions.

Parameters:
  • ax1 (str) – First free factor.

  • ax2 (str) – Second free factor.

  • response (str) – Primary fitted response.

  • constant_levels (dict[str, float]) – Actual-unit levels at which to hold all remaining factors.

  • second_response (str) – Second fitted response to overlay.

  • interval (Optional[Literal['confidence', 'prediction']]) – None for fitted means (default), “confidence” for a conservative mean-confidence bound, or “prediction” for a conservative bound for one new observation.

  • variance_source (Literal['residuals', 'pure_error']) – “residuals” (default) or “pure_error”. Pure error requires valid replicated observations.

  • feasible_region (bool) – Whether to mark the region satisfying the response conditions configured with set_response_conditions().

  • ax3 (str) – Third free mixture component for a ternary plot.

  • x_min (float) – Lower bound for ax1 in coded units.

  • x_max (float) – Upper bound for ax1 in coded units.

  • y_min (float) – Lower bound for ax2 in coded units.

  • y_max (float) – Upper bound for ax2 in coded units.

  • resolution (int) – Number of grid points per process axis, or the mixture-grid resolution.

  • alpha (float) – Significance level used by the confidence correction; 0.05 gives a 95% confidence level.

  • coded (bool) – Whether to display coded rather than actual units.

  • domain (Literal['full', 'allowed']) – Plotting domain. "allowed" applies saved process domain filters or restricts a mixture plot to its allowed hull.

Returns:

Contour and three-dimensional surface figures.

Return type:

tuple[plotly.graph_objects.Figure, plotly.graph_objects.Figure]

Notes

A fitted model is required. Any interval correction requires response conditions; its half-width is subtracted for a response being maximized and added for one being minimized. The "pure_error" variance source also requires replicate-based lack-of-fit statistics. feasible_region=True likewise requires response conditions.

contour, surface = design.plot_response(
    ax1="Temperature",
    ax2="Pressure",
    response="Yield",
    second_response="Purity",
    constant_levels={"Time": 30.0},
    feasible_region=True,
    interval="prediction",
    variance_source="residuals",
    domain="allowed",
)

Interval half-width

plot_interval shows the half-width, not the full interval width. interval="confidence" (default) uses t * sqrt(MS * h) for the expected mean; interval="prediction" uses t * sqrt(MS * (1 + h)) for one new observation, including its experimental error. alpha=0.05 gives 95% pointwise, two-sided coverage, not simultaneous coverage across the surface. Both formulas use the selected variance and its degrees of freedom, under an adequate OLS model with independent homoscedastic normal errors.

These methods replace plot_confidence_interval, corrected and type without aliases. Graphs reject intervals when their variance cannot be estimated.

GraphsMixin.plot_interval(ax1, ax2, response, constant_levels=None, ax3=None, x_min=-1.0, x_max=1.0, y_min=-1.0, y_max=1.0, resolution=300, alpha=0.05, coded=False, domain='full', *, interval='confidence', variance_source='residuals')[source]

Visualize a confidence or prediction interval half-width.

“confidence” describes uncertainty in the fitted mean; “prediction” additionally includes the error of one new independent observation.

Parameters:
  • ax1 (str) – First free factor.

  • ax2 (str) – Second free factor.

  • response (str) – Fitted response.

  • constant_levels (dict[str, float]) – Actual-unit levels at which to hold all remaining factors.

  • interval (Literal['confidence', 'prediction']) – “confidence” for the mean (default), or “prediction” for one new observation.

  • variance_source (Literal['residuals', 'pure_error']) – “residuals” (default) or “pure_error”.

  • ax3 (str) – Third free mixture component for a ternary plot.

  • x_min (float) – Lower bound for ax1 in coded units.

  • x_max (float) – Upper bound for ax1 in coded units.

  • y_min (float) – Lower bound for ax2 in coded units.

  • y_max (float) – Upper bound for ax2 in coded units.

  • resolution (int) – Number of grid points per process axis, or the mixture-grid resolution.

  • alpha (float) – Significance level; 0.05 gives a 95% confidence level.

  • coded (bool) – Whether to display coded rather than actual units.

  • domain (Literal['full', 'allowed']) – Plotting domain. "allowed" applies saved process domain filters or restricts a mixture plot to its allowed hull.

Returns:

Contour and three-dimensional surface figures.

Return type:

tuple[plotly.graph_objects.Figure, plotly.graph_objects.Figure]

Notes

Half-widths are t * sqrt(MS * h) for confidence and t * sqrt(MS * (1 + h)) for prediction. The selected variance and its degrees of freedom are used throughout. These are two-sided pointwise intervals under independent homoscedastic normal errors and an adequate fitted model. Pure error requires valid replicates.

contour, surface = design.plot_interval(
    ax1="Temperature",
    ax2="Pressure",
    response="Yield",
    interval="prediction",  # or "confidence" for the mean
    variance_source="residuals",  # or "pure_error"
)

Model diagnostics

Diagnostic plots require a fitted model. plot_diagnostics selects the view through view; supported values are "overview", "observed_vs_predicted", "residuals_vs_fitted", "residuals_by_run", "qq", and "histogram". Set cv=True to use leave-one-out cross-validation predictions and residuals. Omitting response adds a response selector to every view.

GraphsMixin.plot_diagnostics(response=None, *, view='overview', cv=False, x_axis='exp_order')[source]

Plot model diagnostics in one consolidated entry point.

Parameters:
  • response (str | None) – Response to display. If omitted, the figure provides a response dropdown.

  • view (Literal['overview', 'observed_vs_predicted', 'residuals_vs_fitted', 'residuals_by_run', 'qq', 'histogram']) – Diagnostic view. "overview" shows experimental versus predicted, residuals versus fitted, normal Q-Q, and the residual histogram in a four-panel figure.

  • cv (bool) – Whether to use leave-one-out cross-validation predictions and residuals.

  • x_axis (Literal['exp_order', 'exp_idx', 'sequence']) – Run coordinate used by "residuals_by_run".

Returns:

Requested diagnostic figure.

Return type:

Figure

GraphsMixin.plot_regression_coefficients(response=None)[source]

Plot regression coefficients with confidence intervals.

Pass response to obtain a single dashboard-ready figure. If it is omitted, the figure keeps the response dropdown for compatibility.

Displays coefficient estimates as bars with error bars representing confidence intervals. Coefficients whose intervals do not cross zero are statistically significant.

Parameters:

response (str | None) – Response to display. If omitted, the figure provides a response dropdown.

Returns:

Interactive coefficient plot.

Return type:

plotly.graph_objects.Figure

Notes

A coefficient is significant at the plotted confidence level when its interval does not include zero.

diagnostics = design.plot_diagnostics(response="Yield", cv=True)
coefficients = design.plot_regression_coefficients(response="Yield")
residuals_by_run = design.plot_diagnostics(
    response="Yield",
    view="residuals_by_run",
    x_axis="exp_order",
)
normality = design.plot_diagnostics(response="Yield", view="qq")

Model effects

Process and categorical factors

Main-effect plots vary one factor while holding the others at their standard reference settings. Interaction plots vary a pair of factors; visibly non-parallel profiles indicate that the fitted effect of one factor depends on the other. These methods evaluate the fitted model and are not raw response summaries.

Omit factor or factors to build the complete dashboard. Supply one factor or one two-factor tuple to return a focused figure. Both methods reject mixture components; use plot_mixture_trace for mixture models.

GraphsMixin.plot_main_effects(response, factor=None, coded=True, n_points=50)[source]

Plot one or all fitted main-effect profiles.

Each factor varies across its range while all other process factors are held at their centers and categorical factors at their reference levels.

Parameters:
  • response (str) – Fitted response to display.

  • factor (str | None) – Factor to display. If omitted, all non-mixture factors are shown in a dashboard.

  • coded (bool) – Whether to display coded rather than actual units.

  • n_points (int) – Number of evaluation points for each continuous factor profile.

Returns:

Main-effect dashboard with one panel

per factor.

Return type:

Figure

Raises:

ValueError – If the design contains mixture components. Use plot_mixture_trace() for mixture models.

GraphsMixin.plot_interactions(response, factors=None, coded=True, n_points=50)[source]

Plot one or all fitted non-mixture factor interactions.

Parameters:
  • response (str) – Fitted response to display.

  • factors (tuple[str, str] | None) – Pair to display. If omitted, all available pairs are exposed through a selector.

  • coded (bool) – Whether to display coded rather than actual units.

  • n_points (int) – Number of evaluation points along the factor shown on each horizontal axis.

Returns:

Interaction figure with a factor-pair

selector.

Return type:

Figure

Raises:

ValueError – If the design contains mixture components. Use plot_mixture_trace() for mixture models.

Notes

Non-parallel profiles indicate that one factor’s fitted effect depends on the level of the other factor.

all_main_effects = design.plot_main_effects("Yield", coded=False)
temperature_effect = design.plot_main_effects(
    "Yield",
    factor="Temperature",
    coded=False,
)
selected_interaction = design.plot_interactions(
    "Yield",
    factors=("Temperature", "Pressure"),
)

Mixture traces

A mixture trace varies each component along a bound-respecting path through the centroid reference blend. The remaining mixture components are adjusted using their available capacity so that their bounds are respected and the mixture sum remains one. Any process or categorical factors are held at their standard reference settings.

GraphsMixin.plot_mixture_trace(response, reference='centroid', n_points=50)[source]

Plot fitted mixture traces through a centroid reference blend.

Each component is varied in turn while the other mixture components are adjusted using their available capacity. Component bounds and the mixture sum are preserved. Process and categorical factors remain at their standard reference levels.

Parameters:
  • response (str) – Fitted response to display.

  • reference (Literal['centroid']) – Reference blend. Currently only "centroid" is supported.

  • n_points (int) – Number of points on each feasible component path.

Returns:

Mixture trace plot.

Return type:

Figure

Raises:

ValueError – If fewer than two mixture components are available, the reference is unsupported, or n_points is less than two.

trace = design.plot_mixture_trace(
    response="Viscosity",
    reference="centroid",
    n_points=75,
)

Model-validation plots

These plots use grouped confirmation runs loaded through import_confirmation_results() and predictions from the fitted model. See Model validation for the complete workflow and the formulas used for validation intervals.

GraphsMixin.plot_confirmation(response, *, view)[source]

Plot one confirmation diagnostic for a fitted response.

Return type:

Figure

comparison = design.plot_confirmation(
    response="Yield", view="observed_vs_predicted"
)
residuals = design.plot_confirmation(response="Yield", view="residuals")

Pareto-front plots

Call compute_pareto_front() before plotting. The candidate grid uses every declared process-factor level by default. factor_levels can select exact continuous values in actual units and categorical values from their declared levels. Mixture resolution is configured with mixture_grid. Domain filters set with set_domain_filters() remove invalid candidates; response limits do not remove candidates and remain reference guides on 2D plots.

Omitting x and y uses the first two computed objectives. Adding z creates a 3D plot. Domain-valid dominated candidates are shown in grey; pass show_candidates=False for a front-only plot.

GraphsMixin.plot_pareto_front(x=None, y=None, z=None, *, show_candidates=True)[source]

Plot a previously computed Pareto front in two or three dimensions.

Domain-valid dominated candidates are shown as context by default. Response limits configured with set_response_conditions() are reference guides only and do not affect Pareto membership.

Return type:

Figure

design.compute_pareto_front(
    responses=["Yield", "Cost", "Purity"],
    factor_levels={
        "Temperature": [40, 50, 60],
        "Catalyst": ["A", "C"],
    },
    mixture_grid={"degree": 8},
)
front = design.get_pareto_front()
pareto_2d = design.plot_pareto_front(x="Yield", y="Cost")
pareto_3d = design.plot_pareto_front(
    x="Yield",
    y="Cost",
    z="Purity",
    show_candidates=False,
)