A simple command-line plotting tool.
This project uses DuckDB for data loading and transformation, and tplot for terminal-based rendering. It supports multiple input formats (CSV, JSON, NDJSON, Parquet), SQL-style filtering, time-series bucketing with aggregation, and scatter plots with customizable markers.
This project should not be confused for an older, abandoned project already on the package index by the same name. Install directly from GitHub:
uv tool install git+https://github.com/glentner/plot-cliUsage:
plot [-h] [-v] [FILE] [-x NAME] [-y NAME] [--line | --scatter | --hist] ...
Simple command-line plotting tool.
By default, format is auto-detected from file extension. Use --format to override:
# CSV (default for stdin)
cat data.csv | plot -x timestamp -y value -T
# Parquet
plot data.parquet -x time -y metric
# JSON array
plot data.json --format json -x x -y y
# Newline-delimited JSON
plot logs.ndjson --format ndjson -x timestamp -y countFilter data using SQL WHERE clauses or datetime bounds:
# Custom WHERE clause
plot data.csv --where "value > 100 AND status = 'active'"
# Datetime filtering (requires -x to specify timestamp column)
plot timeseries.csv -x timestamp -y value --after "2024-01-01" --before "2024-02-01"Aggregate time-series data into buckets using -B/--bucket with an aggregation method:
# 15-minute buckets with mean aggregation
plot metrics.csv -x timestamp -y value -T -B 15min --mean
# Hourly buckets with sum
plot events.csv -x time -y count -T -B 1h --sum
# Supported aggregation methods: --mean, --sum, --count, --min, --max, --first, --lastBucket interval formats: 15min, 1h, 30m, 1d, 60s, or full syntax like 15 minutes.
Instead of plotting, output processed data as JSON or CSV:
# Output as JSON (useful for piping to jq)
plot data.csv --json --where "value > 50"
# Output as CSV
plot data.parquet --csv -x timestamp -y value -B 1h --meanConvert datetime axis to relative offset from start or end:
# Hours from start
plot timeseries.csv -x timestamp -y value -T -S +hours
# Minutes from end (negative offset)
plot timeseries.csv -x timestamp -y value -T -S -minutes| Option | Description |
|---|---|
-x, --xdata NAME |
Column for x-axis |
-y, --ydata NAME... |
Column(s) for y-axis |
--format NAME |
Input format: csv, json, ndjson, parquet |
--line |
Line plot (default) |
--scatter |
Scatter plot |
--marker CHAR |
Marker character for scatter plots (default: •) |
--hist |
Histogram |
--where EXPR |
SQL WHERE clause for filtering |
--after TIME |
Filter rows after timestamp |
--before TIME |
Filter rows before timestamp |
-T, --timeseries |
Treat x-axis as datetime |
-S, --scale SCALE |
Relative offset (e.g., +hours, -days) |
-B, --bucket INTERVAL |
Time bucket interval (e.g., 15min, 1h) |
-A, --agg-method NAME |
Aggregation: mean, sum, count, min, max, first, last |
--mean, --sum, etc. |
Aggregation method aliases |
-b, --bins NUM |
Histogram bins (default: 10) |
-d, --density |
Show histogram as percentage |
-t, --title NAME |
Plot title |
-s, --size W,H |
Plot size in characters |
-c, --color SEQ |
Comma-separated colors |
-l, --legend POS |
Legend position |
-X, --xlabel NAME |
X-axis label |
-Y, --ylabel NAME |
Y-axis label |
--json |
Output data as JSON |
--csv |
Output data as CSV |
-h, --help |
Show help |
-v, --version |
Show version |
Render data as a scatter plot with an optional custom marker:
# Basic scatter plot
plot data.csv -x x -y y --scatter
# Scatter plot with custom marker
plot data.csv -x x -y y --scatter --marker xUsing the basic line plot example from seaborn:
