Plot arbitrary time-series data (non-calendar x-axis) into self-contained HTML using uPlot, with a pluggable parser system and expression-based derived traces.
- Loads one or more input files via auto-discovered parser plugins.
- Converts all data to base units and aligns traces to a common time grid.
- Evaluates derived traces from expressions (
expr[...]), including chained expressions. - Renders interactive offline HTML plots with summary statistics and input/source metadata.
- Supports dual y-axes (up to two distinct y-units per plot).
- Opens the result in your browser automatically.
- Python
>=3.14 uv
Install as a user tool (recommended):
uv tool install git+https://github.com/smprather/time-plotThen run anywhere:
time_plot --helpRender a single input file:
time_plot path/to/data.csvRender file + derived expressions:
time_plot path/to/sine.csv 'sum:expr[sine+sine]' 'r:expr[ddt(sum)]'Running with no positional sources opens the built-in sine.csv example.
time_plot [OPTIONS] [SOURCES]...
Options:
-o, --output FILE: output HTML path. Defaults to./plots/<input-stem>.html.--open-browser / --no-open-browser: open the output in the default browser after writing (default:--open-browser).--plugins-dir DIRECTORY: plugin directory override.--parser-options TEXT: comma-separatedkey=valuepairs passed to plugins.
Positional SOURCES can be:
- File path:
data.csv - Named file:
my_name:data.csv - Expression:
expr[sine+sine] - Named expression:
sum:expr[sine+sine]
Quote expressions in the shell to avoid interpretation of [ and ].
- Default output path for a single input source:
./plots/<input-stem>.html - Default output path for multiple sources:
./plots/combined.html - Plot HTML is self-contained (inlines
uPlotJS/CSS assets) — works offline. - Interactive chart with mousewheel zoom.
- Summary statistics table (
Peak |y|,Average,RMS). - Source table showing input file paths or expression text per trace.
- Plugin ID:
voltage-or-current-vs-time - File type:
.csv - Two-column header:
time(<unit>),voltage(<unit>)ortime(<unit>),current(<unit>)
time(ns),voltage(mv)
0,0
1,0.5- Plugin ID:
spice-pwl - Parses SPICE netlists containing
pwlvoltage or current sources. - Supports line continuations with leading
+. - Each PWL source becomes one dataset.
- Parser option
naming_method:element_name(default) orpositive_node_name.
time_plot spice_pwl.spi --parser-options naming_method=positive_node_name- Plugin ID:
cadence-dynamic-power-totalcurrent - File type:
.totalcurrent - Three tab-separated columns: row index, time (seconds, scientific notation), current (amps).
time_plot VDD.peak.totalcurrentSyntax: expr[<expression>] or <name>:expr[<expression>]
References use dataset names (flat namespace, valid Python identifiers).
Operators: +, -, *, /
Functions:
average(x)— mean over the time gridrms(x)— RMS over the time gridabs(x)— element-wise absolute valueddt(x)— finite-difference derivative
time_plot sine.csv 'sum:expr[sine+sine]' 'rate:expr[ddt(sum)]'Rules:
- Unnamed expressions auto-name as
e1,e2, ... - Circular references and unknown names are errors.
+/-require matching units;*//produce composed unit strings.
- File-backed dataset names default to file stem (
sine.csv→sine). - Explicit name:
my_name:/path/to/file.csv - Auto-generated name collisions are bumped:
foo,foo_1,foo_2, ... - Multi-series name collisions are prefixed:
<source>__<series> expris a reserved name.
Plugins are discovered from time_plot/plugins/ in deterministic sorted order. The first plugin whose identify(path) returns True handles the file.
A plugin must provide:
identify(path: Path) -> boolparse(path: Path, options: dict[str, str]) -> list[SeriesData]- Optional
plugin_name() -> str
Override the search directory with --plugins-dir.
git clone https://github.com/smprather/time-plot
cd time-plot
uv sync --group devRun tests:
uv run pytest -qLint and type check:
uv run ruff check .
uv run ty checkRegenerate example data:
uv run python scripts/generate_example_data.pyValidation:
uv run pytest -q
uv run time_plot --no-open-browser time_plot/example_data/sine.csv
uv run time_plot --no-open-browser time_plot/example_data/sine.csv 'sum:expr[sine+sine]' 'r:expr[ddt(sum)]'time_plot/: CLI, processing, plotting, units, plugin system.time_plot/plugins/: parser plugins.time_plot/example_data/: bundled sample files.scripts/: developer utilities.tests/: automated tests.doc/: architecture and plugin docs.
Input file not found: check the path; generate sample files withuv run python scripts/generate_example_data.py.No plugin recognized file: check file format and suffix against supported plugins.Unknown dataset referenced in expression: verify the dataset name matches the file stem or explicit name.At most two distinct y-axis units are supported: split traces into separatetime_plotinvocations.
MIT. See LICENSE.