Skip to content

Feature Request: Selective Plotting of State Variables vs Derivatives #3867

@ChrisRackauckas-Claude

Description

@ChrisRackauckas-Claude

Feature Request: Selective Plotting of State Variables vs Derivatives

Summary

Add support for plotting only state variables (without their derivatives) when calling plot(sol) on ModelingToolkit solutions. This would provide a cleaner visualization for complex models where derivative plots can be overwhelming.

Motivation

Currently, when using plot(sol) on a ModelingToolkit solution, all variables including derivatives are plotted. For models with many state variables, this can result in cluttered plots with 2x the number of series (state + derivative for each variable).

Users often want to quickly visualize just the "primary" state variables without derivatives. The current workaround requires manually specifying idxs with individual variables, which defeats the convenience of plot(myanalysis()).

Proposed Solution

Extend SymbolicIndexingInterface (SII) with functionality to distinguish between state variables and their derivatives, allowing syntax like:

# Option 1: Using SII interface
plot(sol, idxs=SII.STATE_VARIABLES)  # Only state variables
plot(sol, idxs=SII.ALL_DERIVATIVES)  # Only derivatives

# Option 2: Plotting keyword argument  
plot(sol, plot_derivs=false)  # Exclude derivatives

This would integrate with the existing plotting infrastructure while providing users more control over what gets visualized.

Minimal Working Example

using ModelingToolkit, OrdinaryDiffEqDefault, Plots
using ModelingToolkit: t_nounits as t, D_nounits as D

# Simple cartesian pendulum example
@parameters g = 9.81 L = 1.0  # gravity, length
@variables x(t) y(t)  # cartesian coordinates

# Pendulum equations with constraint x² + y² = L²
eqs = [
    D(D(x)) ~ -x/L^2 * g * y/L,
    D(D(y)) ~ -y/L^2 * g * y/L - g,
    0 ~ x^2 + y^2 - L^2  # constraint
]

@mtkbuild sys = ODESystem(eqs, t)

# Initial conditions: pendulum starts at 30° from vertical
θ₀ = π/6
u0 = [
    x => L * sin(θ₀),
    y => -L * cos(θ₀),
    D(x) => 0.0,
    D(y) => 0.0
]

# Solve the system
prob = ODEProblem(sys, u0, (0.0, 3.0), [])
sol = solve(prob)

# Current behavior: plots ALL variables including derivatives
plot(sol)  # Shows x(t), y(t), D(x)(t), D(y)(t), etc.

# Desired behavior:
plot(sol, idxs=SII.STATE_VARIABLES)  # Only x(t), y(t)
# or
plot(sol, plot_derivs=false)  # Only x(t), y(t)

Current Workaround

Users must manually specify which variables to plot:

state_variables = [x, y]  # Manually list state variables
plot(sol, idxs=state_variables)

This approach doesn't scale well for models with many state variables and requires users to know which variables are "primary" vs derivatives.

Related Issues

This relates to issue #3555 about plotting unknowns and observables, but focuses specifically on the state/derivative distinction rather than the unknown/observable distinction.

Implementation Notes

This would likely involve:

  1. Extending SymbolicIndexingInterface to categorize variables by type (state vs derivative)
  2. Adding plotting keywords or SII constants for selective plotting
  3. Updating the default plotting behavior to optionally filter variable types

The implementation should maintain backward compatibility while providing users with more intuitive control over visualization complexity.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions