Matlab Fit Curve
MathWorksOfficialCreated by MathWorks
- Skill
- Tool integration
- Data and AI
- BSD-2-Clause
- Low risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured, no-code workflow for fitting curves and surfaces to data using the MATLAB Curve Fitter app. It supports the entire lifecycle of a fitting project, from initial data selection and model exploration to iterative refinement, outlier exclusion, and final export of results to the workspace, figures, or Simulink.
What it does
- Launches the Curve Fitter app with specified data or session files
- Enables interactive selection of regression, interpolation, and smoothing models
- Provides tools for visual and numerical inspection of fit results
- Supports iterative refinement through point-and-click outlier exclusion
- Facilitates comparison of multiple fit models within a single session
- Exports results to the MATLAB workspace, figures, or Simulink lookup tables
When to use it
- When you need to fit models to data without writing manual code
- When you want to explore multiple fit types to determine the best model
- When you need to visually identify and exclude outliers from your dataset
- When you require a visual comparison of different fitting approaches
- When you need to generate Simulink lookup tables from your fitted data
Advantages
- Provides a complete, intuitive graphical interface for complex fitting tasks
- Allows for rapid iteration and visual feedback during model development
- Maintains session state for easy collaboration and reproducibility
- Supports seamless transition from interactive exploration to generated code
Usage examples
- “Open the Curve Fitter app with my x and y variables.”
- The agent launches the Curve Fitter app and loads the specified workspace variables for fitting.
- “Compare a polynomial fit and a smoothing spline for my data.”
- The agent creates two separate fits in the app, allowing you to compare their goodness-of-fit metrics and visual plots.
- “Exclude the outliers in the current plot.”
- The agent enables interactive exclusion mode, allowing you to select and remove specific data points from the fit.
- “Export my current fit to the workspace.”
- The agent exports the fit object and goodness-of-fit statistics to your MATLAB workspace.
Install
2 of its files are not mirrored here, so install it from its source:
https://github.com/matlab/matlab-agentic-toolkit/tree/2a7f215e965597acf6ed495beb9e7b8aff45a3be/skills-catalog/ai-and-statistics/matlab-fit-curve
Documentation by MathWorks
Interactive Curve and Surface Fitting
Guides interactive curve and surface fitting through the Curve Fitter app as part of the Curve Fitting Toolbox. Covers the full in-app workflow of selecting data, exploring fit types, modifying with fit options, inspecting fits visually and numerically, then exporting results.
When to Use
No-code fitting
Users who want to fit curves or surfaces without writing code
Users who want to start interactively and generate code later to continue in the command line
Interactive exploration
Exploring fit types when the best model is unknown
Iterating on fits with visual feedback
Maintaining and comparing multiple fits in a single session
Discovering available fit types, options, and features
App-specific features
Exporting fits to Simulink lookup tables (only available through the app)
Excluding data points or regions iteratively with visual feedback
Loading or continuing a saved session (
.sfit) for convenience or collaboration
When NOT to Use
CLI workflows (no app involvement)
User is already writing code and does not want the app involved
Using
fit(),fittype(),fitoptions()directly in their own scripts/functionsThe desired fit type, data, and options are already known and the user wants code
Many fits that would be difficult to manage in the app
Spline workflows
Spline CLI functions (
csapi,csaps,fnbrk, etc.)splinetoolorbspliguiapps
Other tools and domains
Base MATLAB functions —
interp1,pchip,scatteredInterpolant,griddedInterpolant,spline,smoothdataBasic Fitting tool — polynomials, spline interpolant, pchip interpolant; built into MATLAB figures
Statistics and Machine Learning Toolbox — statistical modeling, cross-validation, dataset partitioning, separate test data (
fitlm,fitnlm,cvpartition)Optimization Toolbox — any workflow using Optimization Toolbox functions (
lsqnonlin,fmincon,lsqcurvefit,lsqlin)
If CLI is the better approach, do not suggest app workflows. If neither section clearly applies, use these signals to disambiguate:
| Signal | Recommendation | Why |
|---|---|---|
| User says "compare" fits | Depends | Visual curve comparison -> CLI (overlaid on same axes). Comparing goodness of fit metrics -> App (Table of Fits). Interactive adjustment -> App. |
| User just wants to visualize a single fit | CLI | CLI plotting handles this well |
| User wants to overlay multiple fits on same axes | CLI | App shows fits in separate figures only |
| User needs to exclude outliers by visual inspection | App | Point-and-click exclusion is easier than computing indices |
| User needs formal validation data | App | The app has explicit validation data support |
User instructions always take precedence. If the user explicitly asks for CLI code — even mid-app-workflow — write CLI code. The agent may also offer CLI as an alternative when the controller cannot fulfill a request.
Do not spontaneously switch between app and CLI mid-workflow. If the user's intent is still unclear after consulting the table above, ask whether they prefer working interactively in the app or with code.
If the user asks how to perform a workflow themselves, where to find a feature in the UI, or whether a capability is available in the app, see references/curve-fitter-layout.md for the full layout and feature locations.
Must-Follow Rules
Release Compatibility
Use
cftoolfor R2021b and earlier;curveFitterfor R2022a+ — never instruct the user to use both in the same workflow. Users often say "cftool" out of habit on R2022a+ — still usecurveFitteror the controller regardless of user terminology.CurveFitterAppController(scripts/CurveFitterAppController) requires R2022a+ — it will error on earlier releases. On R2021b and earlier, the agent CANNOT read or write app state programmatically. The only programmatic interaction iscftoolinput arguments (cftool(x, y),cftool(x, y, z), etc.). All other actions (changing fit types, excluding points, exporting) must be performed by the user through the app UI — guide them using general knowledge of cftool, don't promise action.getFittypeTable()still works independently for discovering fit types. On R2022a+, prefer the controller'sopen*methods to launch the app (they handle version checking internally). On pre-R2022a, set expectations upfront: everything besides launching the app or launching the app with data is unsupported for agentic workflows on this release — you can guide the user through the UI but cannot perform actions for them. Offer CLI fitting as an alternative path. Don't let users discover limitations one by one.Critical for pre-R2022a: On these releases, ALL of the following apply:
Refer to the app ONLY as "cftool" or "the Curve Fitting Tool" — never "Curve Fitter"
Do not mention ANY controller method names (setExclusionRule, setFittype, etc.) — they do not exist on this release
Do not imply you can perform actions inside the app — you cannot
If the user says "Curve Fitter" on R2021b or earlier, say "The Curve Fitter app isn't available in [release]. I'll use cftool instead."
API Usage
Drive the app workflow via the controller API — do not spontaneously switch to CLI — once the app is open or the user is working in the app, fitting, comparison, and exclusion work goes through the controller. Do not spontaneously generate CLI
fit()code as a substitute for app actions. Do not pause and instruct users to click UI elements. Exceptions:The user explicitly requests CLI code (user instructions always take precedence)
The controller has no API for the requested action — guide the user through the app UI via
references/curve-fitter-layout.mdfirst. Only offer CLI as an alternative if the feature isn't available in the app or the workflow is trending toward the ambiguous signals in "When NOT to Use"The user explicitly says they want to perform actions themselves in the UI
Internal CLI execution is permitted for efficiency — the agent can internally execute
fit(),fittype(),fitoptions(), etc. for quick lookups (e.g., surveying multiple fit types, checking available fit options) without generating user-facing code or mentioning it in responses. This is distinct from generating code for the user.If a controller method errors, read the error and react — the messages are informative and will guide you to fix the syntax or inform the user.
Use
getFittypeTable()(scripts/getFittypeTable) to discover available fit types — do not guess or assume the availability of fit type names or prioritize custom equations when a built-in one exists. To inspect a specific fit type, create afittypeobject and use its methods (formula,coeffnames,islinear, etc.) —fittypeobjects have no public properties. Never assume or state that data "looks like" or "is suitable for" a specific model — ask the user about their data characteristics or goals instead.Read the minimum relevant state before taking actions that depend on it — do not blindly execute commands without checking prerequisites (e.g., check dimensionality before setting a curve-only fit type, check that a fit exists before exporting). Do not read the full app state for every action — only what the specific action requires.
Reporting Results
Never make subjective value judgments on fit quality — but factual interpretation is allowed — report all relevant goodness-of-fit metrics (not just R²) and let the user interpret. Factual, objective statements about statistical properties and tradeoffs are permitted and encouraged — these are distinct from subjective quality judgments. Do not suggest alternative fit types or approaches unless the user explicitly asks. See
references/interpreting-fit-results.mdfor the full list of prohibited terms, permitted factual statements, and guidance on how to handle direct quality questions.
Agent Behavior
Load references before acting (silently) — these are mandatory, not optional. Load liberally — when in doubt about whether you need a reference, load it. Never narrate or mention loading references in user-facing text (see Rule 10):
Load
references/api-reference.mdbefore calling any controller method for the first time in a sessionLoad
references/interpreting-fit-results.mdbefore reporting, comparing, or explaining fit resultsLoad
references/curve-fitter-layout.mdbefore answering questions about app features, UI locations, or when the controller has no API for a requested actionScope:
curve-fitter-layout.mdcovers R2022a+ (Curve Fitter) ONLY. It can indicate what features exist in cftool, but NOT where they are located in the UI. For cftool UI locations: rely on general knowledge, and when unsure say so rather than guessing.Never describe UI elements not documented in references — if you don't know what an icon looks like or where a button is, say "I'm not certain of the exact location" rather than inventing details.
The controller is invisible to the user — everything about the controller, API, and reference files is an internal implementation detail. In user-facing responses:
CRITICAL — most common violations: "let me add the controller scripts to the path", "using the controller", "the controller's X method", "programmatically". These MUST NOT appear in any user-facing text including narration, status updates, and thinking-aloud.
Never mention controller class names, method names, or API syntax (e.g., don't say "I'll use setExclusionRule" — say "I'll exclude those points")
Never narrate internal implementation steps — don't say "let me add the controller scripts to the path", "the controller is available", "I'll use the controller to set the fit type", or "using the controller's openAppWithData method." These are invisible mechanics. From the user's perspective, you are simply performing actions in the Curve Fitter app.
Never mention reference file names or loading (e.g., don't say "let me check the API reference")
The act of loading references is itself invisible — do not say "let me check", "let me read", or "let me look up" before loading a reference file. Just load it silently and proceed.
Never mention the concept of a "controller" or explain that one exists or doesn't exist for a given release
Never mention "programmatic" control of the app — just offer actions naturally (e.g., "Would you like me to change the fit type?" not "I can programmatically set the fit type")
Never explain internal release reasoning (e.g., don't say "since the controller isn't available on this release" — just guide the user appropriately)
When no controller API exists for a requested action, guide the user through the app UI using
references/curve-fitter-layout.mdDo not invent programmatic workarounds
Ask before acting on ambiguity — when a user's request is vague or underspecified (e.g., "take care of that point", "fix this", "clean up the data"), ask the user to clarify what they want before acting. For example, if excluding points, ask which points or what criteria to use. Never apply an arbitrary exclusion criterion (2σ,
isoutlier, etc.) without user confirmation. When the user asks generically about handling or dealing with outliers (not specifically asking to exclude), present the relevant options: exclusion (interactive or rule-based) removes points from fitting, while robust fitting down-weights outliers without removing them. When the user specifically asks to exclude points, only present exclusion methods — don't suggest robust fitting as an alternative. When app state changes unexpectedly (fits disappear, session resets), describe what you observe and ask how to proceed rather than taking corrective action autonomously.Use release-appropriate terminology in responses — for R2022a+, always refer to the app as "Curve Fitter" (not "cftool"). If the user says "cftool" on R2022a+, acknowledge their term and clarify that cftool isn't available in this release and that you'll be using Curve Fitter. For R2021b and earlier, refer to the app as "cftool" or "the Curve Fitting Tool" — never "Curve Fitter" or "Curve Fitter app." If the user asks to open "Curve Fitter" or "curveFitter" on R2021b or earlier, clarify that it isn't available in this release and that you'll be using cftool.
Use display names, not library model names, in user-facing text — library model names (
exp1,poly2,rat11,lowess,loess,smoothingspline) are for programmatic use only (controller calls, scripts). In user-facing responses, use the display names from the Fit Type Gallery: "Exponential (1 term)", "Polynomial (degree 2)", "Rational (1/1)", "Smoothing Spline", "Lowess (Linear)", etc.Trust live app state over conversation memory — always trust getter call results over what was true earlier in the conversation. Read state before acting on it. If state conflicts with what the user described, report the actual state factually. Don't diagnose unexpected state changes as bugs — the user can change the app between turns.
Report WARNING states and convergence messages — after completing a fit action, if the fit has a WARNING state or convergence messages, report them to the user and ask if they want to address them. Don't silently ignore, and don't automatically "fix" them. Exception: if the user has already acknowledged or explicitly dismissed warnings.
Confirm with the user before importing or exporting — any action that moves data into or out of the app requires explicit user confirmation before execution. State what you plan to do (file name, variable names, breakpoint values, etc.) and why you're asking (what's ambiguous or what choices you made), then wait for approval. Specific scenarios:
Saving a session — state the session name and file path before saving (e.g., "I'll save the session as
myfit.sfitatC:\Users\.... OK?")Loading a session — if exactly one
.sfitfile is detected, it can be loaded directly. If multiple exist and the user's request is ambiguous, state what you found and propose your selection (e.g., "There are multiple session files — isanalysis.sfitthe correct one?"). Do not load until confirmed.Selecting fitting/validation data — if the correct variables are unambiguous from the prompt or workspace, proceed. If multiple candidate variables exist (e.g.,
x,x2,y,y2), explain the ambiguity, propose your selection, and confirm before acting (e.g., "There are several numeric variables in the workspace — I'll usexandyas the fitting data. Is that correct?"). Do NOT launch the app or select data until confirmed.Exporting variables to workspace — propose variable names and explain what will be exported before acting (e.g., "I'll export the fit object as
fitresultand goodness of fit asgofto the workspace. OK?")Exporting to Simulink LUT — state the breakpoint values/scheme you plan to use and confirm before executing. If the user didn't specify breakpoints, propose reasonable values and wait for approval.
Rule 16 does NOT apply to: exporting to a figure, generating code from the app, or starting a new session — these are non-destructive or already have built-in app-level dialogs.
Workflow
Fitting Workflow:
- [ ] Step 1: Select data
- [ ] Step 2: Choose a fit type
- [ ] Step 3: Choose fit options
- [ ] Step 4: Fit
- [ ] Step 5: Evaluate and visualize results
- [ ] Step 6: Iterate and compare
- [ ] Step 7: Export, save, or share resultsThis workflow applies per fit. Most sessions involve one or a few fits, but additional fits can be created at Step 6 to compare approaches.
Entry Points
Select Curve Fitter from the Apps gallery under the Apps tab in the MATLAB Toolstrip
For R2021b and earlier releases:
cftool(...)(do not usecurveFitter)For R2022a and later releases:
curveFitter(...)(do not usecftool)
Both commands share the same input argument syntax:
curveFitter()— launch the app with no data, or bring an already-open app to focuscurveFitter(x, y, z, w)— launch with data, or create a new fit in an already-open app. Provide[]to omit an argument (e.g., use(x, y, [], w)for weighted curve fitting)curveFitter('file.sfit')— load a saved session (must be a.sfitfile)
Note: In agentic workflows (R2022a+), use the controller's
openAppWithData()andopenSession()methods instead of callingcurveFitter(...)directly. They automatically detect and dismiss startup alert dialogs and return the alert text for reporting to the user.
Programmatic Control
Instantiate CurveFitterAppController (scripts/CurveFitterAppController) for read/write API access in agentic workflows. Only supported in R2022a and later. See references/api-reference.md for the full API — all controller methods referenced in the steps below are documented there.
Launching the app: Use openAppWithData() or openSession() to launch the app with data or a session file. These handle launch waiting, app handle management, and automatic dismissal of any alert dialogs. Always capture the returned alertText — if non-empty, report it to the user before proceeding.
Relevant controller methods:
openApp(),openAppWithData(),openSession(),closeApp()
Step 1: Select Data
Assign fitting data from workspace variables. Optionally add validation data for independent fit assessment, and define exclusion rules or exclude individual points.
Relevant controller methods:
selectFittingXData(),selectFittingYData(),selectFittingZData(),selectFittingWData()selectFittingXDataFromTable(),selectFittingYDataFromTable(),selectFittingZDataFromTable(),selectFittingWDataFromTable()getFittingDataVariableNames(),isSurfaceFit()selectValidationXData(),selectValidationYData(),selectValidationZData()selectValidationXDataFromTable(),selectValidationYDataFromTable(),selectValidationZDataFromTable()getValidationDataVariableNames()setExclusionRule(),getExclusionRules(),clearAllExclusionRules()toggleInteractiveExclusions(),getInteractiveExclusions(),clearAllInteractiveExclusions()
Step 2: Choose a Fit Type
Choose a fit type based on the selected data. Built-in library models include Regression (Polynomial, Exponential, Power, Fourier, Gaussian, etc.), Interpolants, and Smoothing fit types. Custom linear and nonlinear equations are also supported, including equations defined in separate files.
To discover all available built-in fit types for the current release, run getFittypeTable() (scripts/getFittypeTable). Pass "curve" or "surface" to filter by dimensionality if known. The returned table includes a category column — the category "library" specifically refers to regression fit types. To inspect a specific fit type, create a fittype object and use its methods (formula, coeffnames, islinear, etc.) — fittype objects have no public properties.
Relevant controller methods:
setFittype(),getFittype()getFittypeTable()(utility script)
Step 3: Choose Fit Options
Optional unless the user wants to adjust fit quality or behavior. To discover which options are available for a given fit type, call fitoptions(fittypeString) in MATLAB — this returns a fitoptions object showing all settable properties and their current/default values.
Relevant controller methods:
setFitOptions(),getFitOptions()
Step 4: Fit
If auto-fit is enabled (default), fitting occurs automatically when data or fit type changes. If manual mode is selected, explicitly execute the fit.
Relevant controller methods:
runFit()setAutoFit(),getAutoFit()
Step 5: Evaluate and Visualize Results
After fitting, check the fit status for errors, warnings, or convergence issues. Review goodness of fit metrics and inspect the fit visually — add residuals plots, contour plots, or prediction bounds if applicable and relevant.
Relevant controller methods:
getFitState(),getFitStatusMessages()getGoodnessOfFit(),getGoodnessOfValidation()getFormula(),getCoefficientNames(),getCoefficientValues(),getCoefficientConfidenceIntervals()getResultsPanelText()getFitInformation()setResidualsPlotVisibility(),getResidualsPlotVisibility()setContourPlotVisibility(),getContourPlotVisibility()setPredictionBoundConfidenceLevel(),getPredictionBoundConfidenceLevel(),clearPredictionBounds()setFitPlotVisibility(),getFitPlotVisibility()setLegendVisibility(),getLegendVisibility()setGridVisibility(),getGridVisibility()
Step 6: Iterate and Compare
If unsatisfied, iterate on the current fit by adjusting the fit type, options, or exclusions (repeat steps 2-5). To compare multiple approaches, create additional fits — each maintains its own data, fit type, options, and results independently.
Relevant controller methods:
createNewFit(),duplicateFit()selectFit(),renameFit(),deleteFit()getAllFitNames(),getFitName()getAllFitInformation()
Step 7: Export, Save, or Share Results
Export results to transition to other workflows (Simulink, CLI scripts), save the session for later use, or share it with others.
Relevant controller methods:
exportFitToWorkspace()exportToFigure()generateCode()exportToSimulinkLUT(),exportToSimulinkLUTEvenSpacing(),launchOptimizedLookupTableWizard()saveSession(),saveSessionAs()hasUnsavedChanges(),getSessionInfo()openSession(),startNewSession()
Efficiency Patterns
Prefer
duplicateFit()overcreateNewFit()+ re-selecting data — when creating a comparison fit that uses the same data, duplicate preserves everything about the current fit: name (with "copy N" appended, incrementing), fitting data, validation data, fit type, fit options, exclusions, and visualization settings — not just the dataRead current state before making changes — before switching fit types or modifying options, read the current metrics and settings so results can be compared to the previous state
Proactive state reads prevent error-recovery cycles — check prerequisites (data dimensionality, fit existence, fit state) before attempting actions that will error without them
Conventions
Reporting Results
Report all relevant goodness of fit metrics (SSE, R-square, Adjusted R-square, RMSE, DFE)
Include validation metrics when validation data is present
When reporting FitState, translate: GOOD → "Complete", WARNING → "Warning", ERROR → "Error", INCOMPLETE → "Incomplete". Never use "Good" as a fit state label — users will interpret it as a quality judgment.
Never characterize fit quality subjectively — present numbers and context
See
references/interpreting-fit-results.mdfor how to present, compare, and explain metrics to users
Workflow Approach
For multi-step or complex actions, understand the current state first, identify the commands and inputs needed, then execute sequentially
Improving a fit is a multidimensional problem — when the user wants to improve a fit or address issues, the main levers are: fit type selection (or trying multiple fit types), fit options (start points, bounds, algorithm, robust fitting), and exclusions. All should be considered, not just one. Typically: exclusions and data cleaning come first, then fit type selection, then fit options — but the user may approach in any order
Inspect data before fitting when the goal is ambiguous — if the user hasn't specified a fit type or approach, silently analyze the data (dimensions, range, distribution, obvious patterns) to inform suggestions. Scale inspection effort to ambiguity: clear requests ("fit a polynomial") need no inspection; open-ended requests ("find the best fit") benefit from it
Agent Behavior
Report consequences, not elaborations — after completing an action, explain what happened as a result (including side effects like a fit completing due to auto-fit), but do not add further detail or analysis beyond the direct consequences. For example, if loading data triggers a default fit, mention that a fit completed — but don't report metrics, coefficients, or quality assessments unless the action itself was about fitting or the user asked. If a visualization is toggled, report that it is now showing — but don't analyze or summarize its content unless asked. Keep responses proportional to the action taken.
Per-fit scope — unless specified, app controls and controller methods apply to the currently selected fit only. Some actions may reasonably apply to multiple fits — selecting fitting/validation data or applying exclusion rules could apply to all fits with the same data. If the user's request doesn't explicitly state scope and the action could plausibly affect one or all fits, ask whether it should apply to the current fit or all fits before proceeding.
Never fabricate technical explanations — if an unexpected error arises that you don't recognize or know how to resolve, report the observable behavior factually. Never invent internal implementation details, diagnose bugs in the app code, name internal methods/classes, or speculate about access permissions or configuration issues. When an error has no immediate or clear programmatic fix, fall back to the UI: consult the layout reference and guide the user through achieving the action manually in the app. This applies to ALL unexpected errors, not just known limitations.
Let the user drive the workflow — don't suggest or assume their next step. Present results and wait for direction.
Follow user instructions precisely — don't add extra actions beyond what was requested without confirming first.
Don't explain internal release reasoning or implementation details to users — they know their own release.
Copyright 2026 The MathWorks, Inc.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.0 KiB
- LICENSELicence file added by AutoGineer1.4 KiB
- SKILL.md26.6 KiB
- manifest.yaml504 B
- references/api-reference.md26.1 KiB
- references/curve-fitter-layout.md24.1 KiB
- references/interpreting-fit-results.md12.4 KiB
- scripts/CurveFitterAppController.p(opens on GitHub)Not mirrored: opens on GitHub14.3 KiB
- scripts/getFittypeTable.p(opens on GitHub)Not mirrored: opens on GitHub567 B
references/api-reference.md
CurveFitterAppController — API Reference
Complete API for reading and writing the Curve Fitter app state.
Controller location: scripts/CurveFitterAppController.m
Creating the controller:
controller = CurveFitterAppController();The controller requires R2022a or later. Methods that access functionality only available in newer releases will throw an error with a clear message indicating what went wrong and suggesting corrective action.
Version Convention
All methods documented here are available in R2022a and later unless an "Available" column indicates otherwise in the method table.
Quick Start
controller = CurveFitterAppController();
controller.openApp();
controller.selectFittingXData('xdata');
controller.selectFittingYData('ydata');
controller.setFittype('poly2');
% Auto-fit fires automatically — check results:
gof = controller.getGoodnessOfFit();
controller.exportFitToWorkspace(FitVariable="myFit")Per-fit scope: Unless otherwise specified, all controller methods that read or write app state operate on the currently selected fit only. This includes fitting data, validation data, fit type, fit options, exclusions, and visualization settings. To apply changes across multiple fits, select each fit individually and call the methods on each.
App Lifecycle
| Method | Signature | Description |
|---|---|---|
openApp | controller.openApp() | Opens the app if not already running; brings the app into focus if already open |
openAppWithData | alertText = controller.openAppWithData(x, y) or alertText = controller.openAppWithData(x, y, z) or alertText = controller.openAppWithData(x, y, z, w) | Opens app and sets fitting data. z and w are optional — omit them for curve data. If the app is already open, creates a new fit with the provided data. Dismisses any alert dialog and returns its text (empty char if none). |
closeApp | controller.closeApp() | Closes the app. If unsaved changes exist, a save dialog appears that requires user interaction. |
Always use the controller's open methods to launch the app rather than calling curveFitter(...) directly. Always capture the returned alertText from openAppWithData and openSession — if non-empty, report it to the user before proceeding.
Session Overview (Read)
| Method | Signature | Returns |
|---|---|---|
getAllFitInformation | fitInfo = controller.getAllFitInformation() | Struct array with full information for every fit in the session |
getFitInformation | fitInfo = controller.getFitInformation() | Struct with full information for the currently selected fit (same fields as one element of getAllFitInformation) |
getAllFitNames | names = controller.getAllFitNames() | String array of all fit names |
getFitName | fitName = controller.getFitName() | Name of the currently selected fit |
getFitState | state = controller.getFitState() | Fit state: "INCOMPLETE", "GOOD", "WARNING", or "ERROR" |
hasUnsavedChanges | tf = controller.hasUnsavedChanges() | true if session has unsaved modifications |
getSessionInfo | [name, path] = controller.getSessionInfo() | Session name and file path (path empty if never saved) |
FitState Values
| State | Report to User As | Meaning |
|---|---|---|
INCOMPLETE | Incomplete | Insufficient data to fit (e.g., missing Y data for curves, mismatched X/Y sizes without Z data) or auto-fit is disabled and runFit() has not been called |
GOOD | Complete | Fit completed without errors or warnings. Does not indicate fit quality — only that no warnings were thrown. A convergence message may still be present. Never report as "Good". |
WARNING | Warning | Fit completed but warnings were thrown during fitting |
ERROR | Error | Fit failed with an error (e.g., incompatible data, Inf/NaN computed during fitting) |
fitInfo Struct Fields
Each element returned by getAllFitInformation (or the single struct from getFitInformation) contains:
| Field | Type | Description |
|---|---|---|
FitName | char | Display name (e.g., 'fit 1') |
XDataName | char | X data variable name (empty if unset) |
YDataName | char | Y data variable name (empty if unset) |
ZDataName | char | Z data variable name (empty if unset) |
WDataName | char | W (weights) variable name (empty if unset) |
Fittype | char | Fit type string (e.g., 'poly1', 'exp2') |
ExclusionRules | cell | Active exclusion rule descriptions |
ResidualsPlotVisible | logical | Whether residuals plot is shown |
CoefficientBounds | table | Table with Lower/Upper columns, indexed by coefficient name |
CoefficientValues | double vector | Coefficient values, or [] if not computed |
CoefficientNames | cell | Coefficient names, or {} if not computed |
Goodness | struct | Goodness-of-fit struct (sse, rsquare, dfe, adjrsquare, rmse) |
FitState | enum | INCOMPLETE, GOOD, WARNING, or ERROR |
ErrorString | char | Error message (empty if none) |
WarningString | char | Warning message (empty if none) |
ConvergenceString | char | Convergence info (empty if none) |
AutoFitEnabled | logical | Whether auto-fit is enabled for this fit |
Formula | char | Formula string for the fit type |
ValidationGoodness | struct | Goodness-of-fit struct (sse, rmse) against validation data (empty if no validation data) |
InteractiveExclusions | logical vector | Points excluded interactively; true = excluded (empty if none) |
FitOptions | fitoptions | The fitoptions object for this fit |
ContourPlotVisible | logical | Whether contour plot is shown |
PredictionBoundConfidenceLevel | double | Confidence level for prediction bounds (0 if off) |
FitPlotVisible | logical | Whether fit plot is shown |
Session Management (Write)
| Method | Signature | Description |
|---|---|---|
openSession | alertText = controller.openSession(filepath) | Opens a saved session. filepath must end in .sfit. If omitted, opens a file browser for the user to select. Clears the existing session; if unsaved changes exist, a save dialog appears that requires user interaction. Dismisses any alert dialog and returns its text (empty char if none). |
startNewSession | controller.startNewSession() | Discards current session and starts fresh. If unsaved changes exist, a save dialog appears that requires user interaction. |
saveSession | controller.saveSession() | Saves to the existing session file path. Errors if no path exists (use saveSessionAs instead). |
saveSessionAs | controller.saveSessionAs(filepath) | Saves to specified .sfit file. If filepath omitted/empty, opens a file browser for the user to select. |
Confirm before saving or loading: Before calling saveSessionAs, confirm the file path and name with the user. Before calling openSession with a specific file, confirm which session file to load if multiple .sfit files exist or the user's request is ambiguous (see SKILL.md Rule 16).
Fit Management
| Method | Signature | Description |
|---|---|---|
createNewFit | fitName = controller.createNewFit() | Creates a new blank fit. Always capture the returned name. |
duplicateFit | newFitName = controller.duplicateFit() | Duplicates the currently selected fit. Always capture the returned name. |
selectFit | controller.selectFit(fitName) | Selects (displays) the named fit |
renameFit | controller.renameFit(fitName, newName) | Renames a fit |
deleteFit | controller.deleteFit(fitName) | Permanently deletes the named fit. A confirmation dialog appears that requires user interaction. |
createNewFit behavior: Creates a completely blank fit — no data, no fit type, auto-fit enabled. It inherits nothing from the current fit. Use duplicateFit() when you want a copy that preserves data, fit type, and options.
What duplicateFit copies: Duplicating a fit copies everything — name (with "copy N" appended, incrementing), fitting data, validation data, fit type, fit options, exclusions, and visualization settings.
Default naming: Newly created fits are named "untitled fit N" (e.g., "untitled fit 1", "untitled fit 2"). Do not assume shortened names like "fit 1". Always capture the return value of createNewFit() or duplicateFit() to get the actual name.
openAppWithData when app is already open: Creates a new fit with the provided data — it does not replace the session or modify existing fits.
Multi-Fit Workflow Pattern
When operating across multiple fits, work sequentially per fit: select → modify → verify → move to next. Do not batch modifications across all fits and verify after — this leads to stale state, redundant selection, and missed errors.
Data Selection — Fitting Data
Read
| Method | Signature | Returns |
|---|---|---|
getFittingDataVariableNames | [xName, yName, zName, wName] = controller.getFittingDataVariableNames() | Variable name strings; empty '' if unset |
isSurfaceFit | tf = controller.isSurfaceFit() | true if Z data is assigned (surface fit) |
Write — From workspace arrays
The variableName argument is the name of a numeric variable in the workspace.
| Method | Signature | Description |
|---|---|---|
selectFittingXData | controller.selectFittingXData(variableName) | Sets X fitting data |
selectFittingYData | controller.selectFittingYData(variableName) | Sets Y fitting data |
selectFittingZData | controller.selectFittingZData(variableName) | Sets Z fitting data (surface fits) |
selectFittingWData | controller.selectFittingWData(variableName) | Sets W (weights) fitting data |
Confirm when ambiguous: If multiple candidate variables exist in the workspace and the user's request doesn't clearly identify which to use, propose variable assignments and confirm before calling these methods (see SKILL.md Rule 16).
Write — From table columns
The tableName argument is the name of a table variable in the workspace. The columnName argument is the name of a numeric column in that table.
| Method | Signature | Description |
|---|---|---|
selectFittingXDataFromTable | controller.selectFittingXDataFromTable(tableName, columnName) | Sets X fitting data from table column |
selectFittingYDataFromTable | controller.selectFittingYDataFromTable(tableName, columnName) | Sets Y fitting data from table column |
selectFittingZDataFromTable | controller.selectFittingZDataFromTable(tableName, columnName) | Sets Z fitting data from table column (surface fits) |
selectFittingWDataFromTable | controller.selectFittingWDataFromTable(tableName, columnName) | Sets W (weights) fitting data from table column |
Write — Clearing
| Method | Signature | Description |
|---|---|---|
clearFittingXData | controller.clearFittingXData() | Clears X |
clearFittingYData | controller.clearFittingYData() | Clears Y |
clearFittingZData | controller.clearFittingZData() | Clears Z |
clearFittingWData | controller.clearFittingWData() | Clears W |
clearAllFittingData | controller.clearAllFittingData() | Clears all (X, Y, Z, W) |
Data Selection — Validation Data
Read
| Method | Signature | Returns |
|---|---|---|
getValidationDataVariableNames | [xName, yName, zName] = controller.getValidationDataVariableNames() | Variable name strings; empty '' if unset |
Write — From workspace arrays
The variableName argument is the name of a numeric variable in the workspace.
| Method | Signature | Description |
|---|---|---|
selectValidationXData | controller.selectValidationXData(variableName) | Sets X validation data |
selectValidationYData | controller.selectValidationYData(variableName) | Sets Y validation data |
selectValidationZData | controller.selectValidationZData(variableName) | Sets Z validation data (surface fits) |
Confirm when ambiguous: If multiple candidate variables exist in the workspace and the user's request doesn't clearly identify which to use, propose variable assignments and confirm before calling these methods (see SKILL.md Rule 16).
Write — From table columns
The tableName argument is the name of a table variable in the workspace. The columnName argument is the name of a numeric column in that table.
| Method | Signature | Description |
|---|---|---|
selectValidationXDataFromTable | controller.selectValidationXDataFromTable(tableName, columnName) | Sets X validation data from table column |
selectValidationYDataFromTable | controller.selectValidationYDataFromTable(tableName, columnName) | Sets Y validation data from table column |
selectValidationZDataFromTable | controller.selectValidationZDataFromTable(tableName, columnName) | Sets Z validation data from table column (surface fits) |
Write — Clearing
| Method | Signature | Description |
|---|---|---|
clearValidationXData | controller.clearValidationXData() | Clears X |
clearValidationYData | controller.clearValidationYData() | Clears Y |
clearValidationZData | controller.clearValidationZData() | Clears Z |
clearAllValidationData | controller.clearAllValidationData() | Clears all validation data |
Exclusion Rules
| Method | Signature | Description |
|---|---|---|
getExclusionRules | exclusionRules = controller.getExclusionRules() | Returns cell array of active rule descriptions |
setExclusionRule | controller.setExclusionRule(variable, operator, value) | Adds a rule. Replaces conflicting rule on same variable+direction. |
clearAllExclusionRules | controller.clearAllExclusionRules() | Removes all rules |
Scope: clearAllExclusionRules() only affects the currently selected fit. To clear rules across multiple fits, select each fit individually and call it on each.
Parameters for setExclusionRule:
variable:'X','Y','Z', or'W'operator:'<','<=','>','>='value: numeric scalar threshold
Each variable supports at most one upper-bound rule (< or <=) and one lower-bound rule (> or >=). Setting a new rule replaces any existing rule in the same direction for that variable.
Interactive Point Exclusions
| Method | Signature | Description |
|---|---|---|
getInteractiveExclusions | excluded = controller.getInteractiveExclusions() | Returns logical vector; true = excluded point |
toggleInteractiveExclusions | controller.toggleInteractiveExclusions(indices) | Toggles exclusion for points at given indices |
clearAllInteractiveExclusions | controller.clearAllInteractiveExclusions() | Re-includes all excluded points |
Fit Type
| Method | Signature | Description |
|---|---|---|
getFittype | fittypeString = controller.getFittype() | Returns current fit type string |
setFittype | controller.setFittype(fittypeInput) | Sets fit type (see syntax below) |
setFittype | controller.setFittype(fittypeInput, Independent=..., Dependent=...) | Sets fit type with custom variable names |
setFittype Syntax
Library model names:
controller.setFittype('poly2')
controller.setFittype('exp1')Custom nonlinear equations:
controller.setFittype('a*exp(b*x)+c')Custom linear equations (cell array of terms):
controller.setFittype({'1', 'x', 'x^2'})File-based equations (M-file name, must include all function inputs):
controller.setFittype('myFitFunction(a, b, x)')Custom variable names (optional name-value arguments):
Independent— string or cell array of strings; defaults to"x"for curves or{"x", "y"}for surfacesDependent— string; defaults to"y"for curves or"z"for surfaces
controller.setFittype('a*exp(b*t)+c', Independent="t", Dependent="voltage")
controller.setFittype('a*x+b*y+c', Independent={"x", "y"})Fitting
| Method | Signature | Description |
|---|---|---|
getAutoFit | tf = controller.getAutoFit() | Returns true if auto-fit is enabled |
setAutoFit | controller.setAutoFit(tf) | Enable/disable auto-fit |
runFit | controller.runFit() | Manually trigger fit. Errors if auto-fit is enabled. |
Auto-fit on new fits: New fits (from createNewFit() or openAppWithData() on an already-open app) start with auto-fit enabled. If you need manual mode, call setAutoFit(false) after creation.
When to use manual mode: setAutoFit(false) is useful when batching multiple changes (fit type, options, exclusions, data) before fitting, or when fitting is slow and the user doesn't want to wait between each change. Once in manual mode, call runFit() when ready. Do not automatically re-enable auto-fit after calling runFit() — the user chose manual mode for a reason.
Fit Options
| Method | Signature | Description |
|---|---|---|
getFitOptions | options = controller.getFitOptions() | Returns the fitoptions object for the current fit |
setFitOptions | controller.setFitOptions(options) | Sets the fitoptions object for the current fit |
Use the standard fitoptions API to inspect and modify the options object. Inspect the output of getFitOptions() to discover which properties are available and their current values.
Example:
opts = controller.getFitOptions();
opts.Robust = 'Bisquare';
opts.StartPoint = [1 0.5 0];
controller.setFitOptions(opts);Note: Some
fitoptionsproperties are release-gated and do not exist in earlier MATLAB releases (e.g.,ExtrapolationMethodin R2023a+,ConstraintPointsandAlgorithm='Interior-Point'in R2025a+).ConstraintPointsandAlgorithm='Interior-Point'require Optimization Toolbox.
Results
| Method | Signature | Returns |
|---|---|---|
getFitStatusMessages | messages = controller.getFitStatusMessages() | Struct with fields: Error, Warning, Convergence (each a char; empty if no issues) |
getFormula | formulaStr = controller.getFormula() | Formula string (e.g., 'p1*x+p2'); empty if no fit type set |
getCoefficientNames | coeffNames = controller.getCoefficientNames() | Cell array of coefficient names; {} if no fit result |
getCoefficientValues | coeffValues = controller.getCoefficientValues() | Numeric vector of coefficient values; [] if no fit result |
getCoefficientConfidenceIntervals | ci = controller.getCoefficientConfidenceIntervals() | 2-by-N matrix [lower; upper] for each coefficient; errors if no fit result |
getGoodnessOfFit | gof = controller.getGoodnessOfFit() | Struct: sse, rsquare, dfe, adjrsquare, rmse; empty if no fit |
getGoodnessOfValidation | gov = controller.getGoodnessOfValidation() | Struct: sse, rmse; empty if no fit or no validation data |
getResultsPanelText | text = controller.getResultsPanelText() | Formatted results text matching the Results panel display; includes fit type, formula, coefficients with confidence bounds, GOF, validation GOF |
Visualization
| Method | Signature | Description |
|---|---|---|
getFitPlotVisibility | tf = controller.getFitPlotVisibility() | Returns fit plot visibility |
setFitPlotVisibility | controller.setFitPlotVisibility(tf) | Show/hide fit plot |
getResidualsPlotVisibility | tf = controller.getResidualsPlotVisibility() | Returns residuals visibility |
setResidualsPlotVisibility | controller.setResidualsPlotVisibility(tf) | Show/hide residuals |
getContourPlotVisibility | tf = controller.getContourPlotVisibility() | Returns contour plot visibility (false for curve fits) |
setContourPlotVisibility | controller.setContourPlotVisibility(tf) | Show/hide contour plot |
getPredictionBoundConfidenceLevel | level = controller.getPredictionBoundConfidenceLevel() | Returns confidence level as a percentage on (0, 100) exclusive, or 0 if bounds are off |
setPredictionBoundConfidenceLevel | controller.setPredictionBoundConfidenceLevel(level) | Set level as a percentage on (0, 100) exclusive (e.g., 95 for 95%). Use clearPredictionBounds() to hide. |
clearPredictionBounds | controller.clearPredictionBounds() | Hide prediction bounds |
getLegendVisibility | tf = controller.getLegendVisibility() | Returns legend visibility |
setLegendVisibility | controller.setLegendVisibility(tf) | Show/hide legend |
getGridVisibility | tf = controller.getGridVisibility() | Returns grid visibility |
setGridVisibility | controller.setGridVisibility(tf) | Show/hide grid |
getResiduals | residuals = controller.getResiduals() | Returns the residual vector (observed minus fitted) for the current fit |
Prediction bounds: Only supported for parametric (regression) fit types — not interpolant or smoothing fit types.
Constraint point incompatibility: setPredictionBoundConfidenceLevel will error if constraint points are active on the current fit. Remove constraint points before setting prediction bounds.
Export
| Method | Signature | Description | Available |
|---|---|---|---|
exportFitToWorkspace | controller.exportFitToWorkspace(FitVariable=..., GoodnessVariable=..., OutputVariable=...) | Exports fit object, GOF struct, and/or output struct to workspace variables | R2022a+ |
exportToFigure | controller.exportToFigure() | Creates a standalone MATLAB figure from current fit figure | R2022a+ |
generateCode | controller.generateCode() | Generates a MATLAB function reproducing the session; opens in Editor | R2022a+ |
generateCode behavior: Opens the generated code in the MATLAB Editor. Has no return value — do not assign output.
Default name derivation: When exporting with true (default names), the variable name is derived from the fit name using matlab.lang.makeValidName. For example, a fit named "untitled fit 1" exports as untitledFit1. The export happens directly — no dialog appears. Consider renaming fits to meaningful names before exporting so that workspace variables are easy to identify.
Confirm before exporting: Before calling exportFitToWorkspace, confirm the variable names with the user (e.g., "I'll export as fitresult and gof — OK?"). Before calling exportToSimulinkLUT or exportToSimulinkLUTEvenSpacing, confirm the breakpoint values/scheme. After exporting, report what was exported. See SKILL.md Rule 16.
| exportToSimulinkLUT | modelName = controller.exportToSimulinkLUT(xBreakpoints) | Exports curve fit as Simulink LUT with explicit X breakpoints (requires Simulink) | R2022b+ |
| exportToSimulinkLUT | modelName = controller.exportToSimulinkLUT(xBreakpoints, yBreakpoints) | Exports surface fit as Simulink LUT with explicit X and Y breakpoints (requires Simulink) | R2022b+ |
| exportToSimulinkLUTEvenSpacing | modelName = controller.exportToSimulinkLUTEvenSpacing(xFirst, xSpacing, xNum) | Exports curve fit as Simulink LUT with even-spacing specification (requires Simulink) | R2022b+ |
| exportToSimulinkLUTEvenSpacing | modelName = controller.exportToSimulinkLUTEvenSpacing(xFirst, xSpacing, xNum, yFirst, ySpacing, yNum) | Exports surface fit as Simulink LUT with X and Y even-spacing specifications (requires Simulink) | R2022b+ |
| launchOptimizedLookupTableWizard | controller.launchOptimizedLookupTableWizard() | Launches the Lookup Table Optimizer wizard (requires Simulink and Fixed-Point Designer) | R2024a+ |
exportFitToWorkspace Details
Exports the fit result objects for the currently selected fit to the MATLAB base workspace. Each parameter controls one object:
| Parameter | Controls | Default when true |
|---|---|---|
FitVariable | cfit/sfit fit object | <fitName> (e.g., fit1) |
GoodnessVariable | Goodness-of-fit struct | <fitName>_gof |
OutputVariable | Output struct | <fitName>_output |
The UI convention uses "fittedmodel", "goodness", and "output" as default names.
Parameter values:
true(default) — export using the auto-generated default name derived from the fit name"customName"— export using the specified namefalse— do not export this object
Examples:
% Export all three with default names
controller.exportFitToWorkspace()
% Export only the fit object with a custom name
controller.exportFitToWorkspace(FitVariable="myModel", GoodnessVariable=false, OutputVariable=false)
% Export all with custom names
controller.exportFitToWorkspace(FitVariable="expFit", GoodnessVariable="expGof", OutputVariable="expOut")exportToSimulinkLUT / exportToSimulinkLUTEvenSpacing Details
Both methods accept no arguments to use default breakpoints (11 evenly-spaced points from data range). Provide explicit breakpoints or spacing parameters for custom control.
Utility Scripts
These are standalone functions shipped alongside the controller (in scripts/), not controller methods.
| Function | Signature | Description |
|---|---|---|
getFittypeTable | t = getFittypeTable() | Returns a table of all built-in fit types with columns: fittype, category, displayName, dimension |
getFittypeTable | t = getFittypeTable("curve") | Filters to curve-only and both-dimension types |
getFittypeTable | t = getFittypeTable("surface") | Filters to surface-only and both-dimension types |
Use this to discover valid fittypeString values for setFittype(). Custom equations (e.g., 'a*exp(b*x)+c') are not listed — pass them directly as strings.
Error Handling
Controller error messages are informative and include guidance on corrective action. If a method throws an error:
Read the error message — it will indicate what went wrong and suggest a fix
If the corrective action is clear, take it (e.g., call
openApp()first, set data before fit type)If the error is unclear, report it to the user for guidance
Copyright 2026 The MathWorks, Inc.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
What our scanner noticed· Low risk
- Phrasing that asks for actions without confirmation
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- MathWorks
- Publisher
- MathWorks (Official)
- Source
- matlab/matlab-agentic-toolkit · skills-catalog/ai-and-statistics/matlab-fit-curve · commit 2a7f215
- Licence
- BSD 2-Clause License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.md)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by MathWorks.
Get it from the source
2 of this skill’s files are not mirrored here, so there is no ZIP. Get the complete skill from its source: matlab/matlab-agentic-toolkit