Fit Plotting

Fitting, profiles, diagnostics, and text reports do not require Makie; the plotting methods are activated by CairoMakie:

using ScientificFitting
using CairoMakie

Without using CairoMakie, every plotting entry point raises an ArgumentError that names the missing optional extension.

Choose The Plotting Entry Point

TaskFunctionReturn valueRuns an optimizer?
Fit arrays and plot immediatelyfitplot(result, figure)yes
Plot an existing x-y fitplot_fitFigureno
Add content to the data axisfit_axis, add_*!Axis or Makie plot objectno
Compose a custom themed figureplot_theme, plot_palette, plot_info_panel!, resize_plot_to_layout!Theme, token NamedTuple, GridLayout, or the resized Figureno

Complete composition examples live in Plotting And Customization; this page is the argument and failure contract.

Fit And Plot In One Call

fitplot(model, x, y; p0, show_panel=true, print_report=false, kwargs...)
fitplot(x, y; p0=nothing, show_panel=true, print_report=false, kwargs...)
fitplot(result::FitResult; show_panel=true, print_report=false, kwargs...)

All methods return (result=result, figure=figure). The two-array method fits the straight line $y=p_1x+p_2$, deriving initial slope and intercept from the first and last observations unless p0 is given. The FitResult method only renders and never repeats the fit.

Output selection

show_panel::Bool controls the right/inside numerical panel; print_report::Bool prints report_text(result) to the terminal and exists only on fitplot. The two are independent.

Keyword routing

For methods that perform a fit, the following keywords are sent to fit_model:

ConcernFitting keywords
Observation uncertaintysigma_y, sigma_x, cov_y, cov_x, whitening, error_components
Parameter informationbounds, constraints, parameter_priors, parameter_constraints, fixed_parameters
Derivatives and model evaluationjacobian, x_derivative, inplace, derivatives
Solver and covariance behaviorsolver, cost, maxiters, tol, scale_covariance, initial_guesses, multistart

All remaining keywords are sent to plot_fit; a misspelled fitting keyword does not disappear silently but fails there as an unsupported keyword.

Plot An Existing Result

plot_fit(result::FitResult; kwargs...) -> Figure

plot_fit draws the observations, available x/y error bars, fitted model, optional uncertainty band, and optional result panel, without modifying result or rerunning the optimizer.

Output, style, and appearance

KeywordDefaultContract
filenamenothingSave during construction when a path is supplied.
format:pdfExtension appended only when filename has no extension.
theme:sansMaintained visual style: :sans or :tex.
appearance:auto:light, :dark, or :auto; :auto currently resolves to light.
theme_overrideTheme()Makie theme merged after the selected ScientificFitting style.
styleFitPlotStyle()Per-figure visual token overrides — colors, markers, line widths, figure_size, panel and stats-box styling. See FitPlotStyle.
tight_layouttrueRemove empty layout rows and columns before the automatic fit-to-content pass.

The former names :analysis, :presentation, :screen, :lab, :workbench, :modern, :clean, :minimal, and :showcase map to :sans; :article, :publication, :paper, and :latex map to :tex; new code should use the maintained names. Unknown styles and appearances raise ArgumentError.

Labels, units, model domain, and limits

KeywordDefaultContract
titlenothingFigure title; nothing produces no title.
model_labelautomatic for the built-in lineModel expression shown in the right panel.
xlabel, ylabel"x", "y"Axis quantity labels.
xunit, yunitnothingAppended as label / unit (quantity-calculus notation: a tick value 2 on an axis labeled t / s means t = 2 s); units are never inferred.
latex_labelsfalseConvert suitable labels to Makie LaTeXString content. Pass explicit L"..." strings for mathematical notation.
xgridnothingExplicit finite model-sampling coordinates; authoritative when supplied.
fit_range:data:data samples from the smallest to the largest measured x, so the drawn curve never extrapolates silently; :axis extends the sampling over the data x range padded by limit_padding.
auto_limitstrueInclude data, errors, model, and displayed band in both axis limits.
limit_padding0.08Finite non-negative fractional padding around automatic content limits.
plot_aspectnothingOptional numeric AxisAspect; leave unset unless geometry carries meaning.
axis_kwargsNamedTuple()Makie Axis attributes applied after ScientificFitting's title/label defaults.

With auto_limits=false, set limits through axis_kwargs or on fit_axis(figure) after construction. Manual limits do not resample the model; pass a matching xgrid for intentional extrapolation.

Uncertainty band

KeywordDefaultContract
band:confidence:confidence, :prediction, or :none.
nsigma1.0Finite positive multiplier for the displayed standard-deviation scale.
band_labelnothingLegend text. nothing derives "<nsigma>-sigma band" from nsigma, e.g. "2-sigma band" for nsigma=2. The derived label does not name the band type; set the label explicitly when the meaning should be named, e.g. band_label="2-sigma prediction band" with band=:prediction.
band_kwargsNamedTuple()Makie band! attributes applied last.

Band color and opacity are the band_color and band_alpha fields of FitPlotStyle.

band=:confidence propagates the local parameter covariance to the fitted mean; band=:prediction adds pointwise observation uncertainty in y and the effective contribution from x uncertainty. Both are local covariance constructions.

A matrix-free WhiteningOperator can define the fit without exposing pointwise marginal errors; band=:prediction then requires marginal_sigma and raises ArgumentError otherwise. band=:confidence remains available.

Result panel and legend

KeywordDefaultContract
show_paneltrueShow the structured right panel or compact in-axis panel. Independent of visual style.
stats_position:right:right or :inside.
inside_stats_position:lt:lt/:lefttop, :lb/:leftbottom, :rt/:righttop, :rb/:rightbottom.
stats_panel_width:autoNatural Makie width, a fraction 0 < w <= 1, or a positive wrapping width. Fractions are clamped to 300–560 px; unbreakable TeX or legend content may expand the panel.
stats_mode:compact:compact or :full.
stats_sigdigits5Significant digits used only for displayed values.
parameter_namesnothingDisplay names; length must equal the total number of model parameters, including fixed ones (fixed parameters are marked (fixed) in the panel).
stats_titlenothingOptional title above the structured right panel.
latex_statsfalseRender structured right-panel symbols and numbers as LaTeX; requires stats_position=:right (the inside box renders plain text and rejects the combination with ArgumentError).
show_legendtrueShow data, fit, and band labels. With a right panel, the legend is placed above the report.
legend_position:rtIn-axis Makie legend position when no right-side panel owns the legend.
legend_kwargsNamedTuple()Makie legend attributes applied last.

Panel gap, panel text size, and the in-axis box background and border are the panel_gap, stats_fontsize, and stats_box_* fields of FitPlotStyle.

In the right panel, stats_mode=:full adds cost, AIC, and BIC to the compact parameter, chi-square, chi-square/ndf, p-value, and ndf rows; the in-axis box gains the raw chi-square. AIC and BIC are displayed values; their comparison rules are in Results And Diagnostics.

Data, fit, and error-bar styling

Per-layer visual tokens are FitPlotStyle fields, passed as one style keyword; a field left at nothing keeps the selected style's role default. Label keywords stay top-level, and each layer's Makie keyword container is merged last and has final authority.

LayerFitPlotStyle fieldsLabel keywordFinal Makie container
Observationsdata_color, data_marker, data_markersize, data_strokecolor, data_strokewidthdata_labelscatter_kwargs
Fit curvefit_color, fit_linewidthfit_labelline_kwargs
Bandband_color, band_alphaband_labelband_kwargs
X errorsxerr_color, error_linewidth, error_whiskerwidth—xerrorbars_kwargs
Y errorsyerr_color, error_linewidth, error_whiskerwidth—yerrorbars_kwargs

Every *_kwargs container accepts a NamedTuple, AbstractDict, or nothing; other container types raise ArgumentError. Explicit overrides affect only their layer.

Extend A Finished Figure

fig = plot_fit(result; show_legend=false)
ax = fit_axis(fig)

add_vline!(ax, threshold; color=:black, linestyle=:dash)
add_vband!(ax, threshold_low, threshold_high; color=(:gray50, 0.15))
add_points!(ax, [derived_x], [derived_y]; marker=:star5)
FunctionArguments and defaultsReturn valueValidation
fit_axis(figure; index=1)One-based axis indexMakie AxisIndex must exist.
add_curve!(axis, f; xgrid=nothing, xspan=nothing, n=400, label=nothing, kwargs...)Sample on xgrid, xspan, or current x limitsMakie line plotAt least two finite x values, finite curve values, n >= 2.
add_curve!(axis, x, y; label=nothing, kwargs...)Precomputed curveMakie line plotEqual-length finite vectors with at least two points.
add_points!(axis, x, y; label=nothing, kwargs...)Scalar or vector coordinatesMakie scatter plotEqual-length finite coordinates.
add_vline!, add_hline!Scalar or vector coordinate, optional labelMakie line collectionCoordinates must be finite.
add_vband!(axis, xmin, xmax; label=nothing, kwargs...)Ordered finite x boundsMakie axis-relative spanRequires xmin <= xmax.
add_hband!(axis, ymin, ymax; label=nothing, kwargs...)Ordered finite y boundsMakie axis-relative spanRequires ymin <= ymax.

Axis-relative bands do not inject artificial values into the orthogonal data limits; none of these helpers changes or reruns the fit, and their kwargs... are ordinary Makie plot attributes.

Reuse The Visual Contract

theme = plot_theme(:sans; appearance=:dark)
style = plot_palette(:sans; appearance=:dark)

plot_theme(theme; appearance, theme_override) returns the Makie Theme used by ScientificFitting; plot_palette(style; appearance) returns the corresponding named tuple of visual tokens, from data/fit/band and multi-series colors and marker and line sizes to typography, grids and spines, panel spacing, and default figure sizes.

plot_info_panel! adds the same left-aligned information hierarchy used by plot_fit:

plot_info_panel!(
    fig[1, 2];
    theme=:sans,
    appearance=:light,
    legend_plots=[data_plot, fit_plot],
    legend_labels=["data", "fit"],
    title="Fit summary",
    model_label="damped oscillator",
    parameter_lines=["A = ...", "lambda = ..."],
    statistic_lines=["chi2/ndf = ..."],
)

legend_source=axis builds the legend from labeled axis content instead. fontsize, color, muted_color, and legend_kwargs override style defaults. width=nothing reports the panel's natural Makie width; an explicit width wraps long plain-text lines. tellwidth=true reports that width to the parent layout, tellheight=true lets a long report enlarge its row. The function returns its GridLayout.

After adding every custom layout block, fit the canvas once:

resize_plot_to_layout!(
    fig;
    minimum_axis_size=(420, nothing), # keep width; retain compound row ratios
)

Existing explicit axis sizes remain authoritative, the current figure size is a lower bound, and additional width goes to the first graph column. When graph axes occupy other top-level columns, pass flexible_columns=(...): each listed Auto column is measured and pinned with Makie's Auto(false, ratio) mode so labels and legends cannot shrink it. Explicit Fixed and Relative tracks remain authoritative.

Diagnostic Figures

Residual, pull, ratio, profile, contour, and profile-matrix figures are listed in Diagnostic Plotting.

Export Semantics

Every high-level plot function returns its Figure even when filename is provided; a filename extension takes precedence over format, and without one .$(format) is appended. For explicit resolution control, save the returned figure with Makie:

fig = plot_fit(result; theme=:tex)
save("fit.svg", fig)
save("fit.png", fig; px_per_unit=2)

FitPlotStyle(figure_size=...) requests the minimum logical layout size: fixed-width content grows the canvas instead of clipping, and additional requested width widens the flexible data axis. Raster density is controlled by px_per_unit; enlarging figure_size and scaling the image down also scales down its text.

Failure Summary

FailureResult
CairoMakie extension not loadedArgumentError naming the required extension
Invalid style, appearance, band, stats position, stats mode, or fit rangeArgumentError
latex_stats=true with stats_position=:insideArgumentError
Non-positive/non-finite nsigmaDomainError
Unordered band bounds or n < 2 curve samplesDomainError
Negative/non-finite limit_paddingArgumentError
Prediction band without matrix-free marginal errorsArgumentError with the required remedy
Wrong number of parameter_namesDimensionMismatch
Non-finite annotation dataArgumentError
Dimensionally inconsistent annotation lengthsDimensionMismatch
Non-positive/non-finite layout dimensionsDomainError

API Documentation

ScientificFitting.fitplot — Function
fitplot(model, x, y; p0, kwargs...)
fitplot(x, y; kwargs...)
fitplot(result; kwargs...)

Convenience entry point for the common notebook workflow: fit data and return a plot in one call. Every method returns the named tuple (result::FitResult, figure::Figure). Obtain the primary axis with fit_axis(output.figure) when adding custom Makie content.

The two-array method fitplot(x, y) fits the straight line p[1] * x + p[2]; when p0 is not supplied, the initial slope and intercept are derived from the first and last observations. Pass a model function explicitly for any other model.

show_panel (default true) controls the fit-statistics panel; print_report=true additionally prints the text report.

ScientificFitting.plot_fit — Function
plot_fit(result; kwargs...)

Create and return a Makie Figure from an existing FitResult. The default layout shows data, fitted model, uncertainty band, and an optional right-side report without requiring manual margin tuning. Use fitplot(model, x, y; ...) when fitting and plotting should happen in one call.

The band is the pointwise nsigma-standard-error band of the fitted curve, propagated from the parameter covariance (band=:confidence, default nsigma=1, pointwise 68.3%, not a simultaneous band). band=:prediction adds the observation uncertainty in y and the first-order contribution of the x uncertainty; band=:none draws no band. The default legend label states the level. The full keyword contract (labels, units, limits, result panel, legend, *_kwargs escape hatches) is on the Fit Plotting documentation page; visual tokens are fields of FitPlotStyle.

The default fit_range=:data stops the fitted curve at the first and last measured x. Use fit_range=:axis to extend it over the padded axis range, or pass xgrid when the curve should stop at a specific domain boundary.

Plotting is provided by the optional CairoMakie extension. Load it with using CairoMakie before calling plot functions. Fitting and text reports work without CairoMakie.

ScientificFitting.fit_axis — Function
fit_axis(figure; index=1)

Return axis number index from a Makie Figure. The default returns the first axis, which is the primary data axis of a standard ScientificFitting fit figure. Invalid indices raise ArgumentError. This is the stable hook for adding custom Makie content after plot_fit without rebuilding the fit.

ScientificFitting.add_curve! — Function
add_curve!(axis, f; xgrid=nothing, xspan=nothing, n=400, label=nothing, kwargs...)
add_curve!(axis, x, y; label=nothing, kwargs...)

Add a function-valued or precomputed curve to an existing fit axis. A function is sampled on xgrid (a vector of sample positions), on xspan (an (xmin, xmax) interval sampled at n points), or on the current visible axis range at n points; xgrid takes precedence when both are given. Style defaults follow the active ScientificFitting plot contract unless Makie keyword arguments such as color or linewidth are explicitly supplied.

ScientificFitting.add_points! — Function
add_points!(axis, x, y; label=nothing, kwargs...)

Add extra points or derived markers to an existing fit axis. This is intended for thresholds, calibration anchors, extrapolated intersections, and other scientific annotations that should share the plot layout.

ScientificFitting.add_vline! — Function
add_vline!(axis, x; label=nothing, kwargs...)

Add vertical reference line(s) to an existing fit axis.

ScientificFitting.add_hline! — Function
add_hline!(axis, y; label=nothing, kwargs...)

Add horizontal reference line(s) to an existing fit axis.

ScientificFitting.add_vband! — Function
add_vband!(axis, xmin, xmax; label=nothing, kwargs...)

Add a vertical uncertainty band, acceptance region, excluded region, or physical threshold to an existing fit axis.

ScientificFitting.add_hband! — Function
add_hband!(axis, ymin, ymax; label=nothing, kwargs...)

Add a horizontal uncertainty band, acceptance region, excluded region, or physical threshold to an existing fit axis.

ScientificFitting.plot_theme — Function
plot_theme(theme=:sans; appearance=:auto, theme_override=Theme())

Return the Makie Theme used by ScientificFitting plots. The maintained visual styles are :sans (sans-serif typography, open axes, grid) and :tex (TeX typography, full frame, no grid); appearance is :light, :dark, or :auto. Use this when composing a custom Makie figure that should remain visually consistent with plot_fit. Axis text, legend entries and legend headings share the light/dark foreground color; explicit Makie attributes or theme_override take precedence.

ScientificFitting.FitPlotStyle — Type
FitPlotStyle(; kwargs...)

Reusable visual tokens for every ScientificFitting plot function. Each field overrides the corresponding token of the selected theme preset; a nothing field keeps the theme value. Pass one style object to plot_fit, fitplot, plot_residuals, plot_diagnostics, plot_profile, plot_contour, and plot_profile_matrix via their style keyword to keep figures visually consistent. Content and layout choices (what is plotted, labels, panels, legends) remain keywords of the individual plot functions; Makie-level escape hatches remain available through their *_kwargs arguments.

Fields: figure_size, panel_gap, data_color, data_marker, data_markersize, data_strokecolor, data_strokewidth, fit_color, fit_linewidth, band_color, band_alpha, xerr_color, yerr_color, error_linewidth, error_whiskerwidth, secondary_color, reference_color, stats_fontsize, stats_box_color, stats_box_alpha, stats_box_strokecolor, stats_box_strokewidth.

ScientificFitting.plot_palette — Function
plot_palette(theme=:sans; appearance=:auto)

Return the visual tokens used by a ScientificFitting plot style. Besides data, fit, uncertainty-band, and error-bar defaults, the result exposes typography, layout, and color-safe multi-series tokens for custom Makie figures.

ScientificFitting.plot_info_panel! — Function
plot_info_panel!(cell; theme=:sans, appearance=:auto,
                 legend_source=nothing, legend_plots=nothing,
                 legend_labels=nothing, model_label=nothing,
                 parameter_lines=Any[], statistic_lines=Any[], kwargs...)

Add a compact, left-aligned information panel to a Makie layout cell and return its GridLayout. theme and appearance use the same readable panel defaults as plot_fit; explicit keywords override them. Supply either legend_source or matching legend_plots/legend_labels, plus already formatted model, parameter, and statistic lines. This low-level helper lets compound figures follow ScientificFitting's information hierarchy without coupling the panel to one FitResult. width sets a wrapping width for plain text; legends and unbreakable TeX expressions retain their natural Makie width rather than being clipped.

ScientificFitting.resize_plot_to_layout! — Function
resize_plot_to_layout!(figure; axes=nothing, flexible_columns=(1,),
                       minimum_axis_size=(420, 300),
                       preferred_size=size(figure.scene))

Resize a completed Makie figure to its natural layout without sacrificing a readable data area. preferred_size is a lower bound, so requesting a wider figure widens flexible plot columns after fixed-size labels, legends, and panels have the room they need. Automatic axes receive minimum_axis_size only while Makie measures the layout; explicit axis widths and heights remain authoritative. Columns listed in flexible_columns are measured with their current Auto ratio and then changed to Auto(false, ratio), so labels and legends cannot shrink the plot after the final canvas is known. Explicit Fixed and Relative column sizes remain unchanged. Pass nothing for either minimum axis dimension when composing stacked or otherwise constrained axes.

plot_fit applies this step automatically. Call it after adding custom layout content to a figure built with plot_theme and plot_info_panel!.