Skip to content

API Reference: FastPlot

Hannes Suhr edited this page Mar 9, 2026 · 9 revisions

API Reference: FastPlot

The core plotting class. Manages data lines, thresholds, bands, shadings, fills, and markers with automatic downsampling on zoom/pan. Inherits from handle.


Constructor

fp = FastPlot();
fp = FastPlot('Parent', axHandle);
fp = FastPlot('Theme', 'dark', 'LinkGroup', 'sensors');
fp = FastPlot('YScale', 'log', 'DefaultDownsampleMethod', 'lttb');
fp = FastPlot('LiveInterval', 1.0, 'Verbose', true);

Creates a new FastPlot instance. All options are name-value pairs. Defaults are loaded from FastPlotDefaults (via getDefaults) and can be overridden per-instance.

Constructor Parameters

Parameter Type Default Description
Parent axes handle [] Target axes handle. If empty, render() creates a new figure and axes
LinkGroup char '' Synchronization group ID. Plots sharing the same LinkGroup have linked zoom/pan
Theme char, struct, or FastPlotTheme (from FastPlotDefaults) Theme preset name ('default', 'dark', 'light', 'industrial', 'scientific'), partial override struct, or FastPlotTheme object
Verbose logical false Print diagnostic messages to the console during render, zoom, and live updates
MinPointsForDownsample double 5000 Lines with fewer points than this are plotted raw without downsampling
DownsampleFactor double 2 Points per pixel. Higher values render more points per pixel column
PyramidReduction double 100 Compression factor per pyramid level. Controls the ratio between successive LOD levels
DefaultDownsampleMethod char 'minmax' Default downsampling algorithm: 'minmax' (preserves extremes) or 'lttb' (preserves visual shape)
XScale char 'linear' X-axis scale: 'linear' or 'log'
YScale char 'linear' Y-axis scale: 'linear' or 'log'
LiveInterval double 2.0 Polling interval in seconds for live mode

Properties

Public Configurable Properties

Set these before calling render(). Some can be changed after rendering (noted below).

Property Type Default Description
ParentAxes handle [] Target axes handle. Empty means render() creates a new figure
LinkGroup char '' String ID for linked zoom/pan across multiple FastPlot instances
Theme struct (from FastPlotDefaults) Active theme struct. Change after render via reapplyTheme()
Verbose logical false Print diagnostics to the console
DeferDraw logical false Skip drawnow calls during render. Used by FastPlotFigure for batch rendering of dashboard tiles
ShowProgress logical true Show ConsoleProgressBar during render
XScale char 'linear' X-axis scale. Change after render via setScale()
YScale char 'linear' Y-axis scale. Change after render via setScale()
ViolationsVisible logical true Global toggle for violation marker visibility. Change after render via setViolationsVisible()
LiveViewMode char '' View behavior during live updates: 'preserve' (keep current view), 'follow' (scroll to latest), 'reset' (show all). Empty means no view mode applied
LiveFile char '' Path to .mat file for live polling
LiveUpdateFcn function_handle [] Callback f(fp, data) called on each live poll when the file changes
LiveIsActive logical false Whether live polling is currently running
LiveInterval double 2.0 Polling interval in seconds for live mode
MetadataFile char '' Path to .mat file containing metadata
MetadataVars cell {} Cell array of variable names to extract from the metadata file
MetadataLineIndex double 1 Which line index receives metadata loaded from MetadataFile

Performance Tuning Properties

These are public and can be set before render() or via the constructor.

Property Type Default Description
MinPointsForDownsample double 5000 Lines with fewer points are plotted raw. Also determines the IsStatic flag on each line
DownsampleFactor double 2 Target points per pixel (min + max). Higher values produce denser traces
PyramidReduction double 100 Reduction factor per pyramid level. Each level stores N/R points from the level above
DefaultDownsampleMethod char 'minmax' 'minmax' preserves per-bucket min/max extremes; 'lttb' (Largest-Triangle-Three-Buckets) preserves visual shape

Read-Only / Private-Set Properties

These are set internally by FastPlot. Read access is public.

Property Type Description
Lines struct array Added data lines. Fields: X, Y, Options, DownsampleMethod, hLine, Pyramid, HasNaN, Metadata, IsStatic
Thresholds struct array Added thresholds. Fields: Value, X, Y, Direction, ShowViolations, Color, LineStyle, Label, hLine, hMarkers
Bands struct array Added bands. Fields: YLow, YHigh, FaceColor, FaceAlpha, EdgeColor, Label, hPatch
Markers struct array Added markers. Fields: X, Y, Marker, MarkerSize, Color, Label, hLine
Shadings struct array Added shaded regions. Fields: X, Y1, Y2, FaceColor, FaceAlpha, EdgeColor, DisplayName, hPatch, CacheX, CacheY1, CacheY2
IsRendered logical true after render() has been called
hFigure handle Figure handle (created by render() if no Parent was given)
hAxes handle Axes handle
XType char 'numeric' or 'datenum' (auto-detected from data)
IsDatetime logical true if X data was MATLAB datetime (auto-converted to datenum internally)

Internal Private Properties

Not accessible externally. Listed for architecture reference.

Property Type Description
Listeners array Event listeners (XLim, resize)
hRefineTimer timer One-shot timer for deferred MinMax/LTTB refinement after stride preview
IsRefined logical false while showing coarse stride preview, true after refinement
CachedXLim 1x2 double Last known XLim for lazy skip of unchanged zoom events
CachedViolationLim 1x5 double [xmin xmax ymin ymax pixelWidth] dirty-flag for violation skip
FullXLim 1x2 double Full data X range stored at render time for Home button restore
FullYLim 1x2 double Full data Y range stored at render time for Home button restore
PixelWidth double Cached axes width in pixels (minimum 100)
IsPropagating logical Guard against re-entrant link propagation
HasLimitRate logical Cached: does drawnow support 'limitrate'? (MATLAB yes, Octave no)
DeferredTimer timer Timer for deferred Home button re-downsample via scheduleDeferredXLimCheck
ColorIndex double Tracks auto color cycling position across addLine calls
LiveTimer timer Timer object for live polling
LiveFileDate double Last known file modification datenum for change detection
MetadataFileDate double Last known metadata file modification datenum

Public Methods

addLine(x, y, ...)

Add a data line for downsampled rendering. Must be called before render().

fp.addLine(x, y);
fp.addLine(x, y, 'DisplayName', 'Pressure', 'Color', [0 0.4 0.8], 'LineWidth', 1.5);
fp.addLine(x, y, 'DownsampleMethod', 'lttb');
fp.addLine(x, y, 'XType', 'datenum');
fp.addLine(dt, y);              % MATLAB datetime auto-detected
fp.addLine(x, y, 'Metadata', metaStruct);
fp.addLine(x, y, 'AssumeSorted', true, 'HasNaN', false);

Parameters:

Parameter Type Default Description
x 1xN double or datetime (required) Monotonically increasing X values. Datetime objects are auto-converted to datenum
y 1xN double (required) Y values. NaN allowed for gaps
DownsampleMethod char (from constructor DefaultDownsampleMethod) Per-line override: 'minmax' or 'lttb'
Metadata struct [] Struct with a .datenum field for forward-fill tooltip lookup via lookupMetadata
AssumeSorted logical false Skip the monotonicity check on X. Use when you guarantee X is sorted to save time on very large arrays
HasNaN logical [] (auto-detect) Override NaN detection. When [], FastPlot scans Y with any(isnan(y)). Set explicitly to skip the scan on large arrays
XType char 'numeric' Set to 'datenum' for datenum X values. Auto-set when datetime X is detected
Color 1x3 RGB or char (auto-cycled from theme LineColorOrder) Line color
LineStyle char '-' Line style: '-', '--', ':', '-.'
LineWidth double (from theme LineWidth) Line width in points
DisplayName char '' Legend label

Any additional name-value pairs not listed above (e.g., 'MarkerSize', 'MarkerEdgeColor') are passed through to the MATLAB line() object as graphics properties.

Behavior:

  • X must be monotonically increasing. Validated in chunks of 1M elements unless AssumeSorted is true
  • Column vectors are silently converted to row vectors
  • NaN values in Y create visual gaps -- each contiguous non-NaN segment is downsampled independently
  • Colors auto-cycle from the theme's LineColorOrder palette when Color is not specified
  • Lines with fewer than MinPointsForDownsample points are flagged as static and skip re-downsampling on zoom/pan
  • Errors if called after render()

Example -- Multiple sensor lines:

fp = FastPlot('Theme', 'scientific');
x = linspace(0, 10, 5e6);
fp.addLine(x, sin(x), 'DisplayName', 'Channel A');
fp.addLine(x, cos(x), 'DisplayName', 'Channel B', 'LineStyle', '--');
fp.addLine(x, sin(2*x) * 0.5, 'DisplayName', 'Channel C', 'LineWidth', 1.5);
fp.render();

Example -- Data with NaN gaps:

y = sin(x);
y(1000:2000) = NaN;  % Sensor dropout
y(5000:5500) = NaN;
fp.addLine(x, y, 'DisplayName', 'Sensor');

addThreshold(value, ...) / addThreshold(thX, thY, ...)

Add a constant or time-varying threshold line with optional violation markers. Must be called before render().

The calling convention is auto-detected: if the first two arguments are both numeric vectors and the first has more than one element, the call is treated as time-varying.

Constant threshold (scalar):

fp.addThreshold(4.5);
fp.addThreshold(4.5, 'Direction', 'upper', 'ShowViolations', true, 'Color', 'r', 'Label', 'High Limit');
fp.addThreshold(-2.0, 'Direction', 'lower', 'ShowViolations', true, 'Color', 'b', 'Label', 'Low Limit');

Time-varying threshold (step function):

fp.addThreshold(thX, thY, 'Direction', 'upper', 'ShowViolations', true, 'Label', 'Dynamic Limit');

Parameters:

Parameter Type Default Description
value double (scalar) (required) Constant threshold value (scalar form)
thX 1xN double (required) Time-varying threshold X coordinates (vector form)
thY 1xN double (required) Time-varying threshold Y coordinates (vector form)
Direction char 'upper' 'upper' (violation when y > threshold) or 'lower' (violation when y < threshold)
ShowViolations logical false Render violation markers where data crosses the threshold
Color 1x3 RGB or char (theme ThresholdColor) Line and marker color
LineStyle char (theme ThresholdStyle) Line style
Label char '' Legend/display label

Behavior:

  • Scalar thresholds draw a horizontal line spanning the full X range of all data lines
  • Time-varying thresholds draw a piecewise-constant or piecewise-linear line from the provided X/Y vectors
  • Threshold lines are rendered with LineWidth of 1.5 and HandleVisibility off (hidden from legend)
  • Violation markers are rendered as '.' markers with MarkerSize 6, colored to match the threshold
  • Markers are pixel-culled on zoom via violation_cull -- only one marker per pixel column is rendered to avoid overdraw
  • Violations are computed against all data lines (not just the first)
  • Errors if called after render()

Example -- Industrial alarm levels:

fp = FastPlot('Theme', 'industrial');
fp.addLine(x, y, 'DisplayName', 'Temperature');
fp.addThreshold(95, 'Direction', 'upper', 'ShowViolations', true, 'Color', [1 0 0], 'Label', 'HH Alarm');
fp.addThreshold(85, 'Direction', 'upper', 'ShowViolations', false, 'Color', [1 0.5 0], 'Label', 'H Warning');
fp.addThreshold(15, 'Direction', 'lower', 'ShowViolations', false, 'Color', [0 0.5 1], 'Label', 'L Warning');
fp.addThreshold(5, 'Direction', 'lower', 'ShowViolations', true, 'Color', [0 0 1], 'Label', 'LL Alarm');
fp.render();

addBand(yLow, yHigh, ...)

Add a horizontal band (shaded zone spanning the full X range). Bands are rendered as patches behind data lines and are not re-downsampled on zoom. Must be called before render().

fp.addBand(85, 95, 'FaceColor', [1 0.3 0.3], 'FaceAlpha', 0.15, 'Label', 'High Alarm Zone');
fp.addBand(-95, -85, 'FaceColor', [0.3 0.3 1], 'FaceAlpha', 0.15, 'Label', 'Low Alarm Zone');

Parameters:

Parameter Type Default Description
yLow double (required) Lower Y bound
yHigh double (required) Upper Y bound
FaceColor 1x3 RGB (theme ThresholdColor) Fill color
FaceAlpha double (theme BandAlpha) Fill transparency (0 = invisible, 1 = opaque)
EdgeColor char or RGB 'none' Edge line color
Label char '' Legend label

Example -- 4-level alarm bands:

fp.addBand(90, 100, 'FaceColor', [1 0 0], 'FaceAlpha', 0.12, 'Label', 'HH');
fp.addBand(80, 90, 'FaceColor', [1 0.6 0], 'FaceAlpha', 0.10, 'Label', 'H');
fp.addBand(10, 20, 'FaceColor', [0 0.6 1], 'FaceAlpha', 0.10, 'Label', 'L');
fp.addBand(0, 10, 'FaceColor', [0 0 1], 'FaceAlpha', 0.12, 'Label', 'LL');

addShaded(x, y1, y2, ...)

Add a shaded region between two curves. The shading is dynamically re-downsampled on zoom/pan just like data lines. Must be called before render().

fp.addShaded(x, y_upper, y_lower, 'FaceColor', [0.3 0.7 1], 'FaceAlpha', 0.2, 'DisplayName', 'Envelope');

Parameters:

Parameter Type Default Description
x 1xN double (required) Monotonically increasing X values
y1 1xN double (required) Upper boundary curve
y2 1xN double (required) Lower boundary curve
FaceColor 1x3 RGB [0 0.45 0.74] Fill color
FaceAlpha double 0.15 Fill transparency
EdgeColor char or RGB 'none' Edge line color
DisplayName char '' Legend label

Behavior:

  • X must be monotonically increasing. Validated the same way as addLine
  • All three arrays must have the same number of elements
  • For datasets larger than 20,000 points, a pre-downsampled cache (CacheX, CacheY1, CacheY2) of 10,000 points is built during render to speed up zoom updates
  • The shading is rendered as a patch with vertices [x, fliplr(x)] / [y1, fliplr(y2)]
  • Column vectors are silently converted to row vectors
  • Errors if called after render()

Example -- Confidence envelope:

fp.addLine(x, y_mean, 'DisplayName', 'Mean');
fp.addShaded(x, y_mean + 2*y_std, y_mean - 2*y_std, ...
    'FaceColor', [0.3 0.7 1], 'FaceAlpha', 0.2, 'DisplayName', '2-sigma');

addFill(x, y, ...)

Area fill from a curve to a constant baseline. Convenience wrapper around addShaded. Must be called before render().

fp.addFill(x, y, 'FaceColor', [0 0.5 1], 'Baseline', 0, 'DisplayName', 'Energy');

Parameters:

Parameter Type Default Description
x 1xN double or datetime (required) X values. Datetime auto-converted to datenum
y 1xN double (required) Y values
Baseline double 0 Constant Y value for the fill bottom
FaceColor 1x3 RGB [0 0.45 0.74] Fill color
FaceAlpha double 0.15 Transparency
EdgeColor char or RGB 'none' Edge line color
DisplayName char '' Legend label

Behavior:

  • Internally calls addShaded(x, y, baseline_vector, ...) where baseline_vector is a constant array of the Baseline value
  • Datetime X is auto-converted to datenum

Example -- Shaded area under a curve:

x = linspace(0, 2*pi, 1000);
fp.addFill(x, sin(x), 'Baseline', 0, ...
    'FaceColor', [0.2 0.6 1], 'FaceAlpha', 0.3, 'DisplayName', 'Signal');

addMarker(x, y, ...)

Add custom event markers at specific data points. Markers are drawn as a line object with LineStyle='none', rendered in front of data lines. They are not downsampled. Must be called before render().

fp.addMarker([50 150 250], [3 3 3], 'Marker', 'v', 'MarkerSize', 10, 'Color', [1 0 0], 'Label', 'Faults');

Parameters:

Parameter Type Default Description
x 1xN double (required) Marker X positions
y 1xN double (required) Marker Y positions
Marker char 'o' Marker shape: 'o', 'v', '^', 's', 'd', 'x', '+', '*', '.', etc.
MarkerSize double 6 Marker size in points
Color 1x3 RGB or char (theme ThresholdColor) Marker color
Label char '' Legend label

Behavior:

  • Column vectors are silently converted to row vectors
  • Markers are not downsampled -- provide only the points you want drawn
  • Rendered with HandleVisibility off (hidden from legend)
  • Errors if called after render()

addSensor(sensor, ...)

Add a resolved Sensor object's data line, threshold lines, and violation markers in one call. Must be called before render().

fp.addSensor(sensor);
fp.addSensor(sensor, 'ShowThresholds', true);
fp.addSensor(sensor, 'ShowThresholds', false);

Parameters:

Parameter Type Default Description
sensor Sensor (required) Resolved Sensor object. Must have fields: X, Y, Name, Key, ResolvedThresholds
ShowThresholds logical true Display threshold step-function lines and enable violation markers

Behavior:

  • Calls addLine for the sensor's X/Y data, using sensor.Name (or sensor.Key as fallback) as the DisplayName
  • When ShowThresholds is true, calls addThreshold for each entry in sensor.ResolvedThresholds with ShowViolations set to true
  • Threshold color and line style from the sensor are resolved against the theme via resolveThresholdStyle (empty color/style falls back to theme defaults)
  • Errors if called after render()

Example:

s = sensorLib.resolve('temperature');
fp.addSensor(s);
fp.render();

render()

Render the plot: create figure/axes, downsample all data, draw graphics objects, install zoom/pan listeners. Can only be called once per FastPlot instance.

fp.render();
fp.render(progressBar);  % Use an existing ConsoleProgressBar (for dashboard batch rendering)

Parameters:

Parameter Type Default Description
progressBar ConsoleProgressBar [] Optional external progress bar handle. If empty and ShowProgress is true, creates one internally

Render Pipeline (in order):

  1. Creates a figure and axes (or uses ParentAxes). Sets PositionConstraint to 'innerposition'
  2. Applies the theme (background, grid, font) via applyTheme
  3. Sets axis scale (XScale, YScale)
  4. Computes the full X range from all lines' endpoints
  5. Renders bands as patches spanning the full X range (back layer)
  6. Renders shaded regions. For datasets >20k points, builds a pre-downsampled cache (10k points) for fast zoom updates
  7. Downsamples and renders all data lines:
    • When DeferDraw is true: full synchronous MinMax/LTTB downsample
    • When DeferDraw is false: fast stride preview (every K-th point), followed by async refinement via timer
  8. Renders threshold lines (scalar as horizontal lines, time-varying as step functions) with LineWidth 1.5
  9. Computes and renders violation markers via violation_cull (pixel-culled, one per pixel column)
  10. Renders custom markers (front layer)
  11. Sets axis limits with 5% additive padding (linear) or 10% multiplicative padding (log Y)
  12. Auto-formats datetime X ticks via datetick when XType is 'datenum'
  13. Shows legend when there are multiple data lines
  14. Creates an invisible anchor line spanning the full X range for correct resetplotview behavior
  15. Installs XLim PostSet listener for re-downsampling on zoom/pan
  16. Installs XLimMode PostSet listener to catch resetplotview (Home button)
  17. Installs ButtonDownFcn for double-click loupe (on axes and all children)
  18. Installs ResizeFcn (only when FastPlot owns the figure)
  19. Enables zoom mode (only when FastPlot owns the figure)
  20. Stores FullXLim/FullYLim and calls resetplotview('SaveCurrentView')
  21. Registers in LinkGroup if set
  22. Schedules async refinement timer (10ms delay) for stride-previewed lines
  23. Makes figure visible and calls drawnow (unless DeferDraw is true)

Errors:

  • FastPlot:alreadyRendered if called more than once
  • FastPlot:noLines if no lines have been added

setScale(...)

Change axis scale ('linear' or 'log') before or after render.

fp.setScale('YScale', 'log');
fp.setScale('XScale', 'log', 'YScale', 'log');

Parameters:

Parameter Type Default Description
XScale char (current value) 'linear' or 'log'
YScale char (current value) 'linear' or 'log'

Behavior:

  • Before render: stores the values for use during render()
  • After render: applies the new scale to the axes and re-downsamples all lines, shadings, and violations
  • When XScale changes: all pyramid caches are invalidated (log-space bucketing differs from linear)
  • When only YScale changes: only LTTB pyramids are invalidated (MinMax is order-invariant along Y)
  • Errors on invalid scale values

setViolationsVisible(visible)

Toggle violation marker visibility programmatically.

fp.setViolationsVisible(false);  % Hide all markers
fp.setViolationsVisible(true);   % Show markers and recompute

Parameters:

Parameter Type Description
visible logical true to show violation markers, false to hide

Behavior:

  • Sets the global ViolationsVisible flag
  • When set to true: clears the violation cache, recomputes violations via updateViolations, and sets Visible='on' only on thresholds that have ShowViolations=true
  • When set to false: sets Visible='off' on all violation marker handles without recomputing

setLineMetadata(lineIdx, meta)

Attach or replace a metadata struct on a rendered line for tooltip display.

fp.setLineMetadata(1, struct('datenum', [1 5 10], 'batch', {{'A','B','C'}}));

Parameters:

Parameter Type Description
lineIdx double Integer index of the data line (1-based)
meta struct Metadata struct. Should contain a .datenum field with sorted timestamps for forward-fill lookup

Behavior:

  • Silently does nothing if lineIdx is out of range
  • Primarily used by FastPlotFigure to attach metadata loaded from a separate file after render

lookupMetadata(lineIdx, xValue)

Get active metadata at a given X value using forward-fill (last-observation-carried-forward) logic.

result = fp.lookupMetadata(1, 7.5);

Parameters:

Parameter Type Description
lineIdx double Integer index of the data line (1-based)
xValue double Scalar X position (datenum or numeric)

Returns: Struct with one value per metadata field at the matching timestamp, or [] if no metadata is available.

Behavior:

  • Binary-searches the metadata's .datenum field for the largest value <= xValue
  • Returns all fields except .datenum at the found index
  • Cell array fields return the cell element; numeric fields return the scalar
  • Returns [] if: lineIdx is out of range, no metadata attached, or xValue precedes all timestamps

Example:

meta = struct('datenum', [1 5 10], 'operator', {{'A','B','C'}});
fp.addLine(1:20, randn(1,20), 'Metadata', meta);
fp.render();
info = fp.lookupMetadata(1, 7);  % returns struct with operator='B'

reapplyTheme()

Re-apply the current Theme to axes, figure, and line widths. Call this after changing the Theme property on an already-rendered plot.

fp.Theme = FastPlotTheme('dark');
fp.reapplyTheme();

Behavior:

  • Has no effect before render() has been called
  • Calls applyTheme() to refresh background, foreground, grid, and font
  • Updates all existing line widths to Theme.LineWidth

resetColorIndex()

Reset the auto color cycling counter to zero.

fp.resetColorIndex();
fp.addLine(x, y);  % Uses first palette color again

Behavior:

  • Sets ColorIndex to 0
  • The next addLine() call without an explicit Color option will use the first color from Theme.LineColorOrder

openLoupe()

Open a standalone enlarged copy of this plot in a new figure.

fp.openLoupe();  % Also triggered by double-clicking on the axes

Behavior:

  • Creates a new FastPlot instance and deep-copies all lines, thresholds, bands, shadings, and markers
  • Preserves the current zoom state (XLim/YLim) from the source
  • Datetime data is converted back from datenum to datetime before adding to the new plot
  • The new figure is offset by [+30, -30] pixels from the source figure
  • A FastPlotToolbar is created on the new figure
  • Uses DeferDraw=true during render so the figure appears at the correct zoom rather than flashing at full range first
  • The source tile's axes title is used as the loupe figure name

updateData(lineIdx, newX, newY, ...)

Replace data for a line and re-downsample. Must be called after render(). This is the primary method for live data updates.

fp.updateData(1, newX, newY);
fp.updateData(1, newX, newY, 'Metadata', newMeta);
fp.updateData(1, newX, newY, 'SkipViewMode', true);
fp.updateData(1, newX, newY, true);  % Legacy positional boolean for SkipViewMode

Parameters:

Parameter Type Default Description
lineIdx double (required) Integer index of the data line (1-based)
newX 1xN double (required) New X data (monotonic)
newY 1xN double (required) New Y data (same length as newX)
Metadata struct [] Replace line metadata
SkipViewMode logical false Skip LiveViewMode adjustments

Behavior:

  1. Replaces raw X/Y data and clears the pyramid cache
  2. Updates HasNaN and IsStatic flags
  3. Applies LiveViewMode (follow/preserve/reset) unless SkipViewMode is true
  4. Re-downsamples all lines, shadings, and violations via updateLines, updateShadings, updateViolations
  5. Flushes the display via drawnow limitrate

Errors:

  • FastPlot:notRendered if called before render()
  • FastPlot:indexOutOfRange if lineIdx is out of range
  • FastPlot:sizeMismatch if X and Y have different lengths

Live Mode Methods

startLive(filepath, updateFcn, ...)

Start live mode -- poll a .mat file for changes. Must be called after render().

fp.startLive('data.mat', @(fp, s) fp.updateData(1, s.x, s.y));
fp.startLive('data.mat', @updateFcn, 'Interval', 1, 'ViewMode', 'follow');
fp.startLive('data.mat', @updateFcn, 'MetadataFile', 'meta.mat', ...
    'MetadataVars', {'batch', 'operator'}, 'MetadataLineIndex', 1);

Parameters:

Parameter Type Default Description
filepath char (required) Path to a .mat file to poll
updateFcn function_handle (required) Callback @(fp, data) called when the file changes. data is the result of load(filepath)
Interval double (from LiveInterval) Polling period in seconds
ViewMode char 'preserve' 'preserve', 'follow', or 'reset'
MetadataFile char '' Path to a separate metadata .mat file
MetadataVars cell {} Variable names to extract from the metadata file
MetadataLineIndex double 1 Which line index receives metadata

Behavior:

  • Stops any existing live mode first
  • Records the current file modification date for change detection
  • Creates a MATLAB timer with fixedSpacing execution mode
  • Installs a cleanup callback on the figure's DeleteFcn so the timer stops when the figure is closed
  • On Octave (where timer is unavailable), use runLive() after this method for a blocking poll loop
  • Errors if called before render()

stopLive()

Stop live mode polling.

fp.stopLive();

Behavior:

  • Stops and deletes the live timer and deferred timer
  • Stops the refinement timer
  • Sets LiveIsActive to false
  • Safe to call even if live mode is not active

refresh()

Manual one-shot reload from LiveFile.

fp.refresh();

Behavior:

  • Loads the current LiveFile and calls LiveUpdateFcn(fp, data)
  • Updates LiveFileDate timestamp
  • Also reloads MetadataFile if configured
  • Errors if LiveFile or LiveUpdateFcn have not been set
  • Warns if the file does not exist

setViewMode(mode)

Change the live view mode at runtime.

fp.setViewMode('follow');
fp.setViewMode('preserve');
fp.setViewMode('reset');

Parameters:

Parameter Type Description
mode char 'preserve' (keep current zoom), 'follow' (scroll to track latest data), or 'reset' (fit full X range)

runLive()

Blocking poll loop for live mode (Octave compatibility).

fp.startLive('data.mat', @updateFcn);
fp.runLive();  % Blocks on Octave, no-op on MATLAB

Behavior:

  • On MATLAB: no-op (the timer is already running)
  • On Octave: enters a blocking loop that polls LiveFile for changes at LiveInterval. Blocks until the figure is closed or Ctrl+C
  • Installs an onCleanup guard to call stopLive() when the loop exits

onLiveTimerPublic()

Public wrapper for testing the live timer callback directly.

fp.onLiveTimerPublic();

Behavior:

  • Delegates to the private onLiveTimer method
  • Exists solely for unit tests to invoke the timer callback without relying on real timers

delete()

Clean up timers and release resources. Called automatically when the FastPlot object is destroyed (cleared from workspace or figure closed).

% Implicit -- called by MATLAB when fp goes out of scope
clear fp;

Behavior:

  • Stops the refinement timer
  • Stops the live timer via stopLive()

Static Methods

FastPlot.distFig(...)

Distribute figure windows across the screen in a grid layout.

FastPlot.distFig();                      % Auto-arrange all open figures
FastPlot.distFig('Rows', 2, 'Cols', 3); % Arrange in a 2x3 grid

Parameters:

Parameter Type Default Description
Rows double (auto) Number of grid rows
Cols double (auto) Number of grid columns

Behavior:

  • Delegates to the vendored distFig function (in vendor/distFig/)
  • Automatically adds the vendor directory to the MATLAB path if not already present
  • Figures are sorted by number and tiled left-to-right, top-to-bottom

FastPlot.resetDefaults()

Force reload of FastPlotDefaults on next constructor call.

FastPlot.resetDefaults();
fp = FastPlot();  % Picks up new defaults

Behavior:

  • Calls clearDefaultsCache() to clear the persistent variable in getDefaults
  • Useful after editing FastPlotDefaults.m in a running MATLAB session

Internal Architecture

Zoom/Pan Pipeline

When the user zooms or pans, the following chain executes:

  1. XLim PostSet listener fires onXLimChanged
  2. onXLimChanged guards against re-entrancy (IsPropagating) and unchanged limits (CachedXLim)
  3. Calls updateLines -- for each non-static line:
    • Binary-searches raw X for the visible index range
    • Selects the coarsest pyramid level with enough resolution via selectPyramidLevel
    • Lazy-builds missing pyramid levels via buildPyramidLevel
    • MinMax/LTTB downsamples the visible slice to screen pixel width
    • Updates the line handle's XData/YData
  4. Calls updateShadings -- binary-search + MinMax downsample for each shaded region
  5. Calls updateViolations -- dirty-flag check, then violation_cull per threshold per line
  6. Updates datetime tick formatting if applicable
  7. Propagates XLim to all members of the LinkGroup
  8. Flushes via drawnow limitrate

Pyramid Cache

Each line maintains a multi-level pyramid cache (Lines(i).Pyramid):

  • Level 1: MinMax downsample of raw data by PyramidReduction (100x)
  • Level 2: MinMax downsample of Level 1 by another 100x
  • Level N: Continues until levelSize < target (2 * pixelWidth)
  • Levels are built lazily on first access during zoom
  • The coarsest level with sufficient resolution for the visible range is selected
  • Cache is invalidated when: X scale changes (all levels), Y scale changes (LTTB levels only), or updateData is called

Home Button / resetplotview

MATLAB's resetplotview (Home button) defers its XLim update, bypassing the XLim PostSet listener. FastPlot handles this via:

  1. XLimMode PostSet listener fires onXLimModeChanged
  2. If XLimMode is 'auto': immediately restores FullXLim/FullYLim and re-downsamples
  3. Otherwise: schedules a 10ms deferred timer (scheduleDeferredXLimCheck) that reads the new XLim after MATLAB's deferred update completes

Stride Preview + Async Refinement

During render() (when DeferDraw is false):

  1. Large lines display a fast stride preview (every K-th point) for instant figure visibility
  2. A 10ms one-shot timer schedules refineLines()
  3. refineLines() replaces the stride preview with proper MinMax/LTTB downsampled data
  4. On Octave or when timer is unavailable, refinement happens synchronously

Usage Patterns

Minimal plot

fp = FastPlot();
fp.addLine(x, y);
fp.render();

Themed plot with thresholds

fp = FastPlot('Theme', 'dark');
fp.addLine(x, y, 'DisplayName', 'Sensor');
fp.addThreshold(0.8, 'Direction', 'upper', 'ShowViolations', true, 'Label', 'HI');
fp.render();
tb = FastPlotToolbar(fp);

Datetime X-axis

dt = datetime(2024,1,1) + hours(0:1e5-1);
fp = FastPlot();
fp.addLine(dt, randn(1, 1e5), 'DisplayName', 'Sensor');
fp.render();

Log-scale plot

fp = FastPlot('XScale', 'log', 'YScale', 'log');
fp.addLine(logspace(0, 6, 1e6), logspace(-1, 3, 1e6));
fp.render();

LTTB downsampling

fp = FastPlot('DefaultDownsampleMethod', 'lttb');
fp.addLine(x, y);
fp.render();

Embedded in existing axes

fig = figure;
ax = axes('Parent', fig);
fp = FastPlot('Parent', ax);
fp.addLine(x, y);
fp.render();

Linked zoom/pan

fp1 = FastPlot('LinkGroup', 'group1');
fp1.addLine(x, y1, 'DisplayName', 'Temp');
fp1.render();
fp2 = FastPlot('LinkGroup', 'group1');
fp2.addLine(x, y2, 'DisplayName', 'Pressure');
fp2.render();
% Zooming fp1 automatically zooms fp2

Live polling

fp = FastPlot();
fp.addLine(x, y);
fp.render();
fp.startLive('data.mat', @(fp, d) fp.updateData(1, d.x, d.y), ...
    'Interval', 1, 'ViewMode', 'follow');

Shaded confidence envelope

fp = FastPlot();
fp.addLine(x, y_mean, 'DisplayName', 'Mean');
fp.addShaded(x, y_mean + 2*sigma, y_mean - 2*sigma, ...
    'FaceColor', [0.3 0.7 1], 'FaceAlpha', 0.2, 'DisplayName', '2-sigma');
fp.render();

Full industrial dashboard tile

fp = FastPlot('Theme', 'industrial');
fp.addLine(x, y, 'DisplayName', 'Temperature');
fp.addBand(90, 100, 'FaceColor', [1 0 0], 'FaceAlpha', 0.1, 'Label', 'HH');
fp.addThreshold(95, 'Direction', 'upper', 'ShowViolations', true, ...
    'Color', [1 0 0], 'Label', 'HH Alarm');
fp.addMarker(event_x, event_y, 'Marker', 'v', 'Color', [1 0 0], 'Label', 'Trips');
fp.render();

See Also

Clone this wiki locally