plotters-rs/plotters
A rust drawing library for high quality data plotting for both WASM and native, statically and realtimely π¦ ππ
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained β safe to depend on.
Has a license, tests, and CI β clean foundation to fork and modify.
Documented and popular β useful reference codebase to read through.
No critical CVEs, sane security posture β runnable as-is.
- βLast commit 4w ago
- β28+ active contributors
- βDistributed ownership (top contributor 42% of recent commits)
Show all 6 evidence items βShow less
- βMIT licensed
- βCI configured
- βTests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README β live-updates from the latest cached analysis.
[](https://repopilot.app/r/plotters-rs/plotters)Paste at the top of your README.md β renders inline like a shields.io badge.
βΈPreview social card (1200Γ630)
This card auto-renders when someone shares https://repopilot.app/r/plotters-rs/plotters on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: plotters-rs/plotters
Generated by RepoPilot Β· 2026-05-09 Β· Source
π€Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale β STOP and ask the user to regenerate it before proceeding. - Treat the AI Β· unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/plotters-rs/plotters shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything β but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
π―Verdict
GO β Healthy across the board
- Last commit 4w ago
- 28+ active contributors
- Distributed ownership (top contributor 42% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
β Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live plotters-rs/plotters
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale β regenerate it at
repopilot.app/r/plotters-rs/plotters.
What it runs against: a local clone of plotters-rs/plotters β the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in plotters-rs/plotters | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit β€ 55 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of plotters-rs/plotters. If you don't
# have one yet, run these first:
#
# git clone https://github.com/plotters-rs/plotters.git
# cd plotters
#
# Then paste this script. Every check is read-only β no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of plotters-rs/plotters and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "plotters-rs/plotters(\\.git)?\\b" \\
&& ok "origin remote is plotters-rs/plotters" \\
|| miss "origin remote is not plotters-rs/plotters (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift β was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "plotters/Cargo.toml" \\
&& ok "plotters/Cargo.toml" \\
|| miss "missing critical file: plotters/Cargo.toml"
test -f "plotters-backend/src/lib.rs" \\
&& ok "plotters-backend/src/lib.rs" \\
|| miss "missing critical file: plotters-backend/src/lib.rs"
test -f "plotters-bitmap/src/lib.rs" \\
&& ok "plotters-bitmap/src/lib.rs" \\
|| miss "missing critical file: plotters-bitmap/src/lib.rs"
test -f "plotters-svg/src/lib.rs" \\
&& ok "plotters-svg/src/lib.rs" \\
|| miss "missing critical file: plotters-svg/src/lib.rs"
test -f "plotters-backend/src/rasterizer/mod.rs" \\
&& ok "plotters-backend/src/rasterizer/mod.rs" \\
|| miss "missing critical file: plotters-backend/src/rasterizer/mod.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 55 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~25d)"
else
miss "last commit was $days_since_last days ago β artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) β safe to trust"
else
echo "artifact has $fail stale claim(s) β regenerate at https://repopilot.app/r/plotters-rs/plotters"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
β‘TL;DR
Plotters is a pure-Rust drawing library for rendering data visualizations (charts, plots, figures) that compiles to both native binaries and WebAssembly. It provides a pluggable backend architecture supporting bitmap, SVG, Piston window, GTK/Cairo, and WASM targets, enabling the same charting code to run in browsers and on desktops without C dependencies. Monorepo with four workspace members: plotters/ (main facade), plotters-backend/ (core rendering traits and rasterization logic in src/rasterizer/ for circles, lines, paths, polygons), plotters-bitmap/ (pixel-based output), plotters-svg/ (vector output). Examples in doc-template/examples/ (quick_start.rs, chart.rs, mandelbrot.rs) demonstrate key patterns. Backend trait abstraction decouples drawing logic from output format.
π₯Who it's for
Rust developers building data dashboards, scientific applications, and financial charting tools who need cross-platform plotting without relying on JavaScript libraries (like D3.js) or C dependencies; particularly those targeting WebAssembly for browser-based visualization.
π±Maturity & risk
Production-ready with active maintenance. The project has comprehensive CI/CD workflows (rust-clippy, WASM, backend-specific tests in .github/workflows/), a monorepo structure with multiple stable sub-crates (plotters-backend, plotters-bitmap, plotters-svg), detailed CHANGELOG.md and RELEASE-NOTES.md, and a developer guide in progress. Code footprint of 812KB Rust indicates substantial implementation.
Low-to-moderate risk. The monorepo structure (4 crates in Cargo.toml workspace) reduces coupling, but plotters-backend is a core dependency for all rendering pathsβchanges there require coordinated updates. No single-maintainer risk evident from CI setup, but WASM and backend repos have been split out (per README), suggesting past maintenance load. Check .github/workflows/ for test coverage gaps across bitmap and SVG backends.
Active areas of work
Actively maintained with focus on documentation (Developer's Guide in progress at plotters-rs.github.io/book) and backend stabilization. Recent work evident in .github/workflows/plotters-*.yml suggesting per-backend testing and CI improvements. WASM support (.github/workflows/wasm.yml) and Jupyter integration (mentioned in README) are active targets. Dependabot configured (.github/dependabot.yml) for dependency updates.
πGet running
git clone https://github.com/plotters-rs/plotters.git
cd plotters
cargo build
cargo run --example quick_start # Run from plotters/ subdirectory
cargo test # Run full test suite across workspace
Daily commands:
# Build all crates in workspace
cargo build --release
# Run specific example (from plotters/ dir)
cd plotters && cargo run --example chart
# Build WASM demo
cd plotters/examples/wasm && wasm-pack build
# Run tests with all features
cargo test --all --all-features
πΊοΈMap of the codebase
plotters/Cargo.tomlβ Root workspace manifest defining all member crates (plotters, plotters-backend, plotters-bitmap, plotters-svg) and their interdependencies.plotters-backend/src/lib.rsβ Core trait definitions for DrawingBackend and coordinate transformation abstractions that all rendering backends must implement.plotters-bitmap/src/lib.rsβ Primary bitmap rendering backend implementation; handles rasterization and pixel buffer management for native rendering.plotters-svg/src/lib.rsβ SVG vector backend for scalable output; provides alternative rendering path to bitmap rasterization.plotters-backend/src/rasterizer/mod.rsβ Central rasterization pipeline for converting geometric primitives (lines, circles, polygons) into pixels.plotters-bitmap/src/bitmap.rsβ Bitmap target surface definition; orchestrates pixel formats, composition, and output serialization.plotters-backend/src/style.rsβ Style abstractions (colors, strokes, fills) that propagate through the entire rendering stack.
π οΈHow to make changes
Add a new drawing backend (e.g., for a GUI framework)
- Create a new crate (e.g., plotters-gtk) in the workspace with Cargo.toml depending on plotters-backend (
Cargo.toml (new crate root)) - Implement the DrawingBackend trait from plotters-backend/src/lib.rs in your new backend module (
plotters-backend/src/lib.rs (reference for trait)) - Implement coordinate transformation and style rendering methods (color, stroke, fill) (
plotters-backend/src/style.rs (reference for Style trait)) - Register the new backend in the workspace Cargo.toml and add a feature flag for conditional compilation (
Cargo.toml (workspace root)) - Add a GitHub Actions workflow similar to plotters-bitmap.yml to test the new backend (
.github/workflows/plotters-bitmap.yml (template))
Add a new chart type or plot element
- Study existing chart examples (e.g., plotters/examples/histogram.rs or area-chart.rs) to understand the Chart and ChartBuilder API (
plotters/examples/histogram.rs) - Implement element drawing logic using DrawingBackend primitives (draw_circle, draw_line, draw_polygon) from the backend trait (
plotters-backend/src/lib.rs (reference DrawingBackend methods)) - Add style configuration using the Style abstraction (colors, strokes) from plotters-backend/src/style.rs (
plotters-backend/src/style.rs) - Create a new example file in plotters/examples/ demonstrating your chart type (
plotters/examples/README.md (document the example))
Add a new pixel format or bitmap encoding
- Implement the PixelFormat trait in plotters-bitmap/src/bitmap_pixel/mod.rs for your format (RGB, BGRX, etc.) (
plotters-bitmap/src/bitmap_pixel/mod.rs) - Add format-specific pixel blending logic (fill, mix colors) in the PixelFormat implementation (
plotters-bitmap/src/bitmap_pixel/rgb.rs (reference existing implementation)) - Update BitMapBackend in plotters-bitmap/src/bitmap.rs to support the new format in pixel composition (
plotters-bitmap/src/bitmap.rs) - If adding image output format (e.g., WebP), implement encoding in plotters-bitmap/src/bitmap/target.rs (
plotters-bitmap/src/bitmap/target.rs)
Optimize rendering performance for a backend
- Run benchmarks in plotters-bitmap/benches/ or plotters/benches/ to identify bottlenecks (
plotters-bitmap/benches/benches/rasterizer.rs) - Analyze rasterization hotspots in plotters-backend/src/rasterizer/ (line, circle, polygon algorithms) (
plotters-backend/src/rasterizer/line.rs) - Profile pixel composition in plotters-bitmap/src/bitmap.rs and bitmap_pixel blending logic (
plotters-bitmap/src/bitmap.rs) - Consider parallelization: see plotters-bitmap/benches/benches/parallel.rs for rayon usage patterns (
plotters-bitmap/benches/benches/parallel.rs)
π§Why these technologies
- Rust β Memory safety without GC, zero-cost abstractions for geometric computation, cross-platform (native + WASM) without runtime overhead
- Trait-based backend abstraction (DrawingBackend) β Enables pluggable rendering targets (bitmap, SVG, GTK/Cairo, Piston, WASM canvas) without code duplication; supports both native and web seamlessly
- Software rasterization (line/circle/polygon algorithms) β Portable across platforms including WASM; no GPU dependency; sub-pixel accuracy for high-quality output
- Multiple crates (plotters-backend, plotters-bitmap, plotters-svg) β Modular architecture reduces dependency bloat; users can depend only on backends they need; enables parallel development and testing
βοΈTrade-offs already made
-
Software rasterization instead of GPU rendering
- Why: Portability and simplicity across native/WASM; no external graphics library dependency
- Consequence: Performance capped at CPU speed; not suitable for real-time 3D graphics or massive datasets (>100k points)
-
Bitmap backend requires in-memory pixel buffer allocation
- Why: Simplifies pixel composition logic (alpha blending, anti-aliasing); enables direct serialization to image formats
- Consequence: High memory usage for large resolutions (e.g., 4K requires ~32MB per frame); not suitable for streaming or extremely low-memory embedded systems
-
SVG backend outputs text serialization instead of binary
- Why: Human-readable, editable, scales infinitely, integrates with web ecosystems
- Consequence: Larger file sizes than optimized binary formats; no support for pixel-perfect raster effects or complex transparency
-
Coordinate abstraction layer decouples logical coords from pixel coords
- Why: Enables flexible axis scales (log, datetime, custom), nested coordinate systems, and 3D projections
- Consequence: Additional indirection in hot loops; increased complexity for backend implementers
πͺ€Traps & gotchas
No hidden service dependencies, but be aware: (1) WASM builds require wasm-pack installed separately; (2) GTK/Cairo and piston backends are optional feature gates (Cargo.toml features) and may have OS-specific header requirements; (3) The doc-template/render_readme.sh and update_readme.sh scripts regenerate README with version numbers from latest_version and msrv.txtβdon't manually edit generated sections; (4) Rasterizer tests are brittle to floating-point precision; see plotters-backend/src/rasterizer/ for tolerance constants.
ποΈArchitecture
π‘Concepts to learn
- Backend abstraction trait pattern β Plotters' entire multi-target design (bitmap/SVG/WASM/GTK) is built on a single DrawingBackend trait; understanding trait-based polymorphism is essential to extending Plotters.
- Rasterization algorithms (Bresenham line, circle midpoint) β The rasterizer/ module implements these for bitmap rendering; knowledge of these algorithms explains quality/performance trade-offs and bugs.
- Coordinate transformation pipelines β Charts transform data coordinates to pixel coordinates through multiple matrices; understanding this is critical for correct chart rendering and custom axis logic.
- WebAssembly (WASM) and browser canvas API β Plotters supports WASM compilation and browser canvas rendering; contributors targeting browser output must understand WASM calling conventions and canvas drawing.
- SVG path syntax and vector graphics primitives β The plotters-svg backend generates SVG path strings; understanding SVG paths (M, L, C, Z commands) is essential for vector backend debugging and feature additions.
- Monorepo workspace management with Cargo β This repo uses Cargo workspaces to share code across four crates (plotters, plotters-backend, plotters-bitmap, plotters-svg); understanding workspace publishing and version coordination is necessary for releases.
- Color space and anti-aliasing β The style.rs module handles RGB color and the rasterizer applies anti-aliasing for smooth lines; understanding color blending and filtering improves chart visual quality.
πRelated repos
BurntSushi/ripgrepβ Not directly related but exemplifies high-quality pure Rust CLI tooling; useful for understanding Rust ecosystem patterns this project follows.plotly/plotly.rsβ Direct alternative for Rust plotting; uses Plotly.js backend instead of pure Rust, trade-off between simplicity and browser dependency.nannou-org/nannouβ Companion creative-coding framework with Plotters integration; targets artists/generative work alongside scientific plotting.plotters-rs/plotters-wasm-demoβ Official WASM demo and template; shows how to package Plotters for browser deployment (mentioned in README as interactive example).gtk-rs/gtk4-rsβ GTK Rust bindings; enables Plotters' GTK/Cairo backend feature for native desktop GUIs.
πͺPR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for plotters-backend rasterizer modules
The plotters-backend/src/rasterizer/ directory contains critical geometric rendering code (circle.rs, line.rs, path.rs, polygon.rs, rect.rs) but there are no visible test files in the structure. These modules are foundational to all bitmap rendering. Adding unit tests would improve code reliability, catch regressions, and serve as usage examples for contributors.
- [ ] Create plotters-backend/src/rasterizer/tests/ directory
- [ ] Add unit tests in circle.rs for circle rasterization edge cases (radius 0, 1, large values, edge pixels)
- [ ] Add unit tests in line.rs for Bresenham/line algorithm correctness (horizontal, vertical, diagonal, thick lines)
- [ ] Add unit tests in polygon.rs for polygon filling and winding rules
- [ ] Add integration tests in plotters-backend/tests/ that verify rasterizer outputs match expected pixel patterns
- [ ] Update plotters-backend/README.md with testing instructions
Add GitHub Actions workflow for plotters-svg backend
The workflow directory shows dedicated CI pipelines for plotters-backend, plotters-bitmap, and plotters-core, but plotters-svg is missing its own workflow file (.github/workflows/plotters-svg.yml). This creates an incomplete CI picture where SVG backend changes may not be automatically tested before merge, risking regressions in this important output format.
- [ ] Create .github/workflows/plotters-svg.yml following the pattern of plotters-bitmap.yml and plotters-backend.yml
- [ ] Configure matrix testing for MSRV (check plotters-svg/Cargo.toml for rust-version)
- [ ] Add test steps: cargo test, cargo clippy, cargo doc (with --no-deps)
- [ ] Include any svg-specific feature flags (e.g., font support) in test matrix
- [ ] Ensure workflow triggers on changes to plotters-svg/** and Cargo.lock
- [ ] Test the workflow locally with act or verify via PR
Create missing GIF support tests in plotters-bitmap
The file plotters-bitmap/src/gif_support.rs exists but there are no visible tests (no test.rs module or #[cfg(test)] blocks referenced for GIF functionality). Given the complexity of GIF encoding with the rasterizer, this is a high-risk module. Adding tests would validate GIF output correctness, animation frame handling, and prevent regressions in a popular output format.
- [ ] Review plotters-bitmap/src/gif_support.rs to understand GIF encoding implementation
- [ ] Add unit tests within gif_support.rs using #[cfg(test)] for encoding logic, palette handling, and frame timing
- [ ] Create plotters-bitmap/tests/gif_integration_test.rs with end-to-end tests that generate sample GIFs and validate file structure
- [ ] Test edge cases: single frame (should create static GIF), very fast animation (frame delay validation), large image sizes
- [ ] Add test that compares generated GIF against reference output or validates against GIF spec headers
- [ ] Document GIF testing approach in plotters-bitmap/README.md
πΏGood first issues
- Add unit tests for plotters-svg backend with coverage of text rendering edge cases (currently text.rs in plotters-backend lacks exhaustive tests for rotation and alignment combinations): Text rendering is visible in examples but test coverage is incomplete; adds value without requiring architectural changes.
- Document the DrawingBackend trait with concrete examples in plotters-backend/src/lib.rs showing how to implement a minimal custom backend (e.g., PPM file output): The trait is currently terse; adding a worked example would help contributors understand the abstraction and reduce onboarding friction.
- Add a console-based backend implementation (mentioned in README as TODO) using plotters-backend traits, with example in plotters/examples/console.rs (skeleton exists): README explicitly calls this out as 'not ready'; completing it would add a low-complexity output format and demonstrate backend extensibility.
βTop contributors
Click to expand
Top contributors
- @AaronErhardt β 42 commits
- @dcampbell24 β 11 commits
- @zxq82lm β 5 commits
- @10ne1 β 4 commits
- @kristopherbullinger β 4 commits
πRecent commits
Click to expand
Recent commits
c63248eβ Merge pull request #703 from zxq82lm/fix/hslcolor-hue-wrap (AaronErhardt)3809561β Merge branch 'plotters-rs:master' into fix/hslcolor-hue-wrap (zxq82lm)48b01c4β Merge pull request #717 from chantakan/fix-inward-tick-labels (AaronErhardt)df86e2bβ Merge pull request #714 from dcampbell24/fix-lints (AaronErhardt)2d69fffβ Merge pull request #692 from JakkuSakura/fix-font (AaronErhardt)6717efbβ Merge pull request #713 from dcampbell24/update-dependencies- (AaronErhardt)ca681a6β fix: surface font handle errors (JakkuSakura)30e47b0β Fix: negative tick_mark_size now only affects tick direction (chantakan)854c18dβ cargo fmt --all (dcampbell24)3df137fβ Get rid of the rest of clippy lints. (dcampbell24)
πSecurity observations
The Plotters codebase demonstrates good foundational security practices as a Rust-based graphics library. No critical vulnerabilities were identified from the static analysis of the repository structure and provided file listings. Key strengths include use of Rust's memory safety guarantees, absence of obvious injection vulnerabilities (not a web framework), and lack of hardcoded secrets in visible configuration files. Main recommendations focus on: (1) establishing a unified dependency management strategy across workspace members, (2) extending security review practices to benchmark and test code, and (3) creating a formal security disclosure policy. The drawing library nature of this project means injection attacks (SQLi, XSS) are not primary concerns, though XSS could be relevant for WASM/web-based outputs. Regular dependency audits using 'cargo audit' are recommended to maintain security posture.
- Medium Β· Workspace Structure Without Central Dependency Management β
Cargo.toml (workspace root). The repository uses a Cargo workspace with multiple members (plotters, plotters-backend, plotters-bitmap, plotters-svg). While this is a normal Rust practice, each member can have independent dependency versions, potentially leading to version conflicts or security patches being missed in some workspace members. This requires careful coordination of security updates across all crates. Fix: Implement a unified dependency update policy. Use workspace-level dependency specifications where possible, and establish a process for coordinating security updates across all workspace members. Review each Cargo.toml file regularly for outdated or vulnerable dependencies. - Low Β· Benchmark Code May Not Be Security-Reviewed β
plotters/benches, plotters-bitmap/benches. Benchmark directories (plotters/benches and plotters-bitmap/benches) are present but typically less scrutinized than main source code. Benchmark code could potentially introduce security issues if it handles untrusted data or uses unsafe patterns without proper review. Fix: Apply the same security review standards to benchmark code as to production code. Ensure benchmarks don't introduce unsafe patterns or handle untrusted input insecurely. - Low Β· Test Module Potential Security Gaps β
plotters-bitmap/src/bitmap/test.rs and other test modules. Test files (e.g., plotters-bitmap/src/bitmap/test.rs) may contain code paths that aren't security-hardened. While test code typically doesn't execute in production, test-only unsafe code or patterns could inadvertently leak into production if not carefully managed. Fix: Use#[cfg(test)]attributes consistently. Apply security best practices to test code. Consider using testing frameworks that enforce security boundaries between test and production code. - Info Β· No Explicit Security Policy Visible β
Repository root. No visible SECURITY.md or security policy file in the repository root. This makes it difficult for security researchers to report vulnerabilities responsibly. Fix: Create a SECURITY.md file with instructions for responsible disclosure, including contact information for security reports. Consider implementing GitHub's built-in security advisory feature.
LLM-derived; treat as a starting point, not a security audit.
πWhere to read next
- Open issues β current backlog
- Recent PRs β what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals β see the live page for receipts. Re-run on a new commit to refresh.