The Problem

Analyzing data in a terminal usually means switching between tools—awk for transformation, a language runtime for statistics, and a browser or GUI for visualization. YouPlot removes the visualization hop by drawing plots directly in the terminal from piped data, which makes it useful for quick exploratory analysis in SSH sessions, CI logs, or anywhere a GUI isn't available.

What This Does

YouPlot is a Ruby CLI that reads tabular data from stdin or files and renders barplots, histograms, lineplots, scatter plots, density plots, and boxplots as Unicode characters. The plotting engine lives in lib/youplot/backends/unicode_plot.rb, while lib/youplot/command.rb and lib/youplot/parser.rb handle argument parsing and data ingestion.

The repo is a fork of red-data-tools/YouPlot (4,837 stars), stripped down to 72 files. The core logic is compact: 19 Ruby files, with the CLI entry points at exe/uplot and exe/youplot.

How It Is Wired

Execution starts at exe/uplot, which requires lib/youplot.rb and delegates to YouPlot::Command.run. The command flow is:

  1. lib/youplot/command.rb parses subcommands (bar, hist, line, scatter, density, boxplot) and options via lib/youplot/options.rb and lib/youplot/parameters.rb.
  2. lib/youplot/dsv.rb reads delimited data from stdin or files, handling TSV/CSV and headers.
  3. lib/youplot/aggregation.rb transforms the raw data (e.g., binning for histograms, grouping for boxplots).
  4. lib/youplot/parser.rb validates and normalizes inputs before unicode_plot.rb renders the final output to stdout.

The pipeline is short—4 hops from entry point to output. The widest blast radius sits in lib/youplot/dsv.rb and lib/youplot/aggregation.rb: both carry heavy branching (46 branch points over 86 lines combined), meaning a change to input parsing can ripple across every plot type. lib/youplot/parser.rb has deep nesting (max indentation depth 9), which makes its control flow the hardest to follow when debugging edge cases.

The repo has no internal module graph (0 internal modules, 0 import edges), so all coupling is through direct file requires. The test/ directory (49 files) mirrors the lib/ structure with fixtures for each plot type, which is good coverage for a tool this size.

How To Use It

Setup (from README, verbatim):

gem install youplot
# or
brew install youplot

Running it—the CLI reads from stdin, so the pattern is pipe data in:

curl -sL https://git.io/ISLANDScsv | sort -nk2 -t, | tail -n15 | uplot bar -d, -t "Areas of the World's Major Landmasses"

For offline use, the repo includes fixtures:

cat test/fixtures/iris.csv | cut -f1-4 -d, | uplot scatter -H -d, -t IRIS

No environment variables or config files are required. The Gemfile declares dependencies, but there's no lockfile, so installs are non-reproducible.

Real-World Use

A practical pattern: monitoring disk usage in a headless server. You can pipe ls output directly into a barplot without installing any GUI tooling:

ls -l | awk '{print $9, $5}' | sort -nk 2 | uplot bar -d ' '

The same approach works for log analysis—pipe a timestamped CSV into uplot line to spot traffic spikes without pulling data into a spreadsheet.

Code Health & Issues

Static analysis found 5 issues (2 high, 2 medium, 1 low):

  • High - Pin third-party GitHub Actions to commit SHAs - .github/workflows. The workflows use ruby/setup-ruby@v1 and peaceiris/actions-gh-pages@v4. A moved tag can execute arbitrary code with your repo's token.
  • High - Commit a lockfile - Gemfile. Unlocked dependency ranges mean the tested artifact can differ from production.
  • Medium - Declare least-privilege GITHUB_TOKEN permissions - .github/workflows/ci.yml. Two workflows declare no permissions, one references secrets.
  • Medium - Gate PRs on a dependency vulnerability scan - .github/workflows. No dependency-review-action or osv-scanner in CI.
  • Low - Set timeout-minutes on workflow jobs - .github/workflows/ci.yml. A wedged step runs to the six-hour platform default.

Additional code-quality findings from static analysis: lib/youplot/parser.rb and test/youplot/dsv_test.rb have deep nesting (max depth 9), and three test files (integer_test.rb, iris_test.rb, simple_test.rb) duplicate 9 repeated 6-line blocks. Tests and CI are present; no Dockerfile, no lockfile, no committed secrets.

The Bottom Line

YouPlot is a well-scoped, dependency-light CLI that solves a real friction point—terminal-native plotting with zero setup beyond a gem install. The codebase is small enough to audit in an afternoon, and the test suite covers the major plot types. The main risks are supply-chain: unpinned CI actions and no lockfile. If you need quick terminal plots in scripts or SSH sessions, this is worth adopting; if you need reproducibility guarantees, pin the dependencies first.