{"id":50331937,"url":"https://github.com/rupurt/txtplot","last_synced_at":"2026-05-29T10:02:50.839Z","repository":{"id":343939420,"uuid":"1179791576","full_name":"rupurt/txtplot","owner":"rupurt","description":"High-performance terminal plotting for Rust.","archived":false,"fork":false,"pushed_at":"2026-03-12T17:04:27.000Z","size":117,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-12T17:53:15.606Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rupurt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-12T11:39:02.000Z","updated_at":"2026-03-12T17:04:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rupurt/txtplot","commit_stats":null,"previous_names":["rupurt/txtplot"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/rupurt/txtplot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rupurt%2Ftxtplot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rupurt%2Ftxtplot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rupurt%2Ftxtplot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rupurt%2Ftxtplot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rupurt","download_url":"https://codeload.github.com/rupurt/txtplot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rupurt%2Ftxtplot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33646429,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-29T10:02:50.143Z","updated_at":"2026-05-29T10:02:50.833Z","avatar_url":"https://github.com/rupurt.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# txtplot\n\nHigh-performance terminal plotting for Rust.\n\n`txtplot` renders mathematical plots, 3D visualizations, games, and complex terminal interfaces using Unicode Braille and block characters plus ANSI colors.\n\nUnlike many TUI plotting libraries, `txtplot` is designed for speed: it uses flat contiguous buffers, renderer-specific cell encodings, clipping, and a zero-allocation rendering path to support real-time terminal graphics.\n\nLicense: [MIT](LICENSE).\n\n## Project Navigation\n\nThis repository carries a small set of foundational documents for users, contributors, and agents:\n\n- [AGENTS.md](AGENTS.md) - implementation guidance for AI agents and contributors\n- [CONSTITUTION.md](CONSTITUTION.md) - project principles, decision hierarchy, and compatibility posture\n- [ARCHITECTURE.md](ARCHITECTURE.md) - module boundaries, data flow, and extension seams\n- [GUIDE.md](GUIDE.md) - user guide for plots, 3D visuals, games, and terminal interfaces\n- [CONFIGURATION.md](CONFIGURATION.md) - toolchain, shell, and API-level configuration surfaces\n- [RELEASE.md](RELEASE.md) - release checklist and versioning process\n\nIf you use Nix, `nix develop` provides the Rust toolchain plus `cargo-nextest`, `just`, `keel`, and `sift`.\n\n## Key Features\n\n- High resolution: 8 sub-pixels per character (Braille 2x4). A 100x50 terminal yields a 200x200 effective pixel canvas.\n- Pluggable cell renderers: Braille (`2x4`), HalfBlock (`1x2`), and Quadrant (`2x2`)\n- Performance-oriented design:\n  - flat buffers for cache-friendly access\n  - zero-allocation rendering via `render_to`\n  - Cohen-Sutherland line clipping to discard off-screen geometry before rasterization\n- Advanced pixel and color control:\n  - `unset_pixel` and `toggle_pixel`\n  - color blending modes with `Overwrite` and `KeepFirst`\n  - cell background colors for terminal panels and HUD-style layouts\n  - styled text with foreground, background, plus `Normal` / `Bold` / `Dim` intensity\n  - cell-space UI helpers with `text_screen()`, `text_screen_styled()`, `label_screen()`, and `panel_screen()`\n- High-level chart aesthetics:\n  - `legend()`: automatic, opaque legend boxes with color markers\n  - `anchored_text()`: effortless label placement at `TopLeft`, `Center`, etc.\n  - opaque UI panels that clear underlying raster data for professional overlays\n- Drawing primitives:\n  - lines, circles, polygons\n  - filled shapes via `rect_filled` and `circle_filled`\n  - text overlay support\n- Ready-to-use charts:\n  - `scatter()`, `line_chart()`, `bar_chart()`, `pie_chart()`, `plot_function()`\n  - linear and `log10` axes through `AxisScale`\n- Auto-range and axis helpers for chart setup\n- Exported 3D building blocks in `txtplot::three_d`:\n  - `Vec3`, `Projection`, and `ZBuffer`\n  - screen projection helpers plus z-buffered raster helpers\n  - sphere, torus, and triangle mesh generators\n\n## Installation\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\ntxtplot = \"0.1.0\"\ncolored = \"2.0\"\n```\n\n## Quick Start\n\n```rust\nuse colored::Color;\nuse txtplot::ChartContext;\n\nfn main() {\n    let mut chart = ChartContext::new(60, 15);\n    chart.draw_grid(10, 4, Some(Color::BrightBlack));\n    chart.draw_axes((0.0, 10.0), (-1.5, 1.5), Some(Color::White));\n    chart.plot_function(|x: f64| x.sin(), 0.0, 10.0, Some(Color::Cyan));\n    chart.plot_function(\n        |x: f64| (x * 0.5).cos() * 0.5,\n        0.0,\n        10.0,\n        Some(Color::Magenta),\n    );\n    chart.text(\"sin(x)\", 0.75, 0.85, Some(Color::Cyan));\n    chart.text(\"0.5*cos(0.5x)\", 0.56, 0.10, Some(Color::Magenta));\n\n    println!(\"{}\", chart.canvas.render());\n}\n```\n\n### Styled Text Labels\n\nUse `text_styled()` or the screen-space styled text helpers when you need label emphasis without changing the label content:\n\n```rust\nuse colored::Color;\nuse txtplot::{ChartContext, TextStyle};\n\nfn main() {\n    let mut chart = ChartContext::new(40, 10);\n    chart.text_styled(\n        \"core-node\",\n        0.45,\n        0.75,\n        TextStyle::new().with_foreground(Color::BrightWhite).bold(),\n    );\n    chart.text_styled(\n        \"outer-node\",\n        0.55,\n        0.30,\n        TextStyle::new().with_foreground(Color::BrightBlack).dim(),\n    );\n\n    println!(\"{}\", chart.canvas.render());\n}\n```\n\n### Anchored Text and Legends\n\nPlace labels and legends effortlessly using `ChartAnchor` without calculating pixel offsets:\n\n```rust\nuse colored::Color;\nuse txtplot::{ChartAnchor, ChartContext, TextStyle};\n\nfn main() {\n    let mut chart = ChartContext::new(60, 15);\n    chart.plot_function(|x| x.sin(), 0.0, 10.0, Some(Color::Cyan));\n\n    // Place a legend in the top right\n    let entries = [(\"Sine Wave\", TextStyle::new().with_foreground(Color::Cyan))];\n    chart.legend(ChartAnchor::TopRight, \u0026entries);\n\n    // Anchor a title or status label\n    chart.anchored_text_styled(\n        \"LIVE MONITOR\",\n        ChartAnchor::TopLeft,\n        TextStyle::new().with_foreground(Color::Yellow).bold(),\n    );\n\n    println!(\"{}\", chart.canvas.render());\n}\n```\n\n### Logarithmic Axes\n\n```rust\nuse colored::Color;\nuse txtplot::{AxisScale, ChartContext};\n\nfn main() {\n    let mut chart = ChartContext::new(60, 15);\n    chart.set_scales(AxisScale::Linear, AxisScale::Log10);\n\n    let points = vec![(1.0, 1.0), (2.0, 10.0), (3.0, 100.0), (4.0, 1000.0)];\n    let (range_x, range_y) = ChartContext::get_auto_range_scaled(\n        \u0026points,\n        0.05,\n        AxisScale::Linear,\n        AxisScale::Log10,\n    );\n\n    chart.draw_axes(range_x, range_y, Some(Color::White));\n    chart.line_chart(\u0026points, Some(Color::Cyan));\n    println!(\"{}\", chart.canvas.render());\n}\n```\n\n### Zero-Allocation Render Loop\n\nIf you are building a real-time app, avoid `render()` and use `render_to()`:\n\n```rust\nuse std::fmt;\nuse colored::Color;\nuse txtplot::ChartContext;\n\nfn main() -\u003e fmt::Result {\n    let mut chart = ChartContext::new(60, 15);\n    chart.draw_axes((0.0, 10.0), (-1.0, 1.0), Some(Color::White));\n    chart.plot_function(|x: f64| x.sin(), 0.0, 10.0, Some(Color::Cyan));\n\n    let mut buffer = String::with_capacity(8000);\n    chart.canvas.render_to(\u0026mut buffer, true, Some(\"60 FPS UI\"))?;\n    print!(\"{buffer}\");\n    Ok(())\n}\n```\n\n### Renderer Showcase\n\nBraille remains the default renderer, and `HalfBlockCanvas` / `HalfBlockChartContext` plus `QuadrantCanvas` / `QuadrantChartContext` provide alternate encodings. The showcase example renders the same chart and raster scene through all three renderers:\n\n```bash\ncargo run --release --example renderer_showcase\n```\n\n### Runtime Renderer Selection\n\nIf you want to choose a renderer from CLI or config input while still constructing a concrete generic chart or canvas, use `RendererKind` together with `with_renderer!`:\n\n```bash\ncargo run --release --example runtime_renderer -- halfblock\n```\n\n### 3D Surface Example\n\n`txtplot` does not ship a full scene graph, but it now exports reusable 3D math, projection, and z-buffer helpers under `txtplot::three_d`. The surface example projects a volatility mesh into terminal pixels, uses a z-buffer for occlusion, and overlays a gradient-ascent path:\n\n```bash\ncargo run --release --example vol_surface\n```\n\n### t-SNE and Nearest-Neighbor Graph\n\nThe examples also include a small self-contained manifold-learning demo: it builds clustered 6D data, runs a lightweight t-SNE embedding, and overlays the original-space 3-nearest-neighbor graph on top of the 2D layout.\n\n```bash\ncargo run --release --example tsne_neighbors\n```\n\n## Coordinate System and Pixel API\n\nTo avoid mathematical confusion, `txtplot` offers two coordinate modes and multiple pixel operators:\n\n| Coordinate Mode | Origin (0,0) | Y Direction | Best For |\n| --- | --- | --- | --- |\n| Cartesian | Bottom-left | Grows up | Math plots, functions, charts |\n| Screen | Top-left | Grows down | UI, games, sprites, 3D projections |\n\nPixel manipulation methods:\n\n- `set_pixel / set_pixel_screen`: turn a dot on\n- `unset_pixel / unset_pixel_screen`: turn a dot off\n- `toggle_pixel_screen`: flip the current state of a dot\n\nCell-space HUD methods:\n\n- `text_screen`: write text in top-left screen coordinates\n- `label_screen`: write text with per-cell background styling\n- `panel_screen`: draw boxed UI regions for dashboards and overlays\n\n## Demo Output\n\nThe following block is captured from `cargo run --example demo` using the built-in `render_no_color` path:\n\n```text\nA) Plain Render (render_no_color):\n⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀\n⠀⠀⠈⠉⠢⢄⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⡠⠔⠉⠁⠀⠀\n⠀⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⡠⠊⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⡠⠊⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠱⡀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠱⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⢀⠜⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⡗⠒⠈⢆⠒⠒⠒⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⠒⠒⠒⡠⠃⠒⠒⡗⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠣⡀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠘⢄⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢠⠊⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠈⠢⡀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⢀⠔⠁⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠘⢄⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⡠⠊⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠢⢄⡀⠀⠀⠀⠀⢀⡠⠔⠉⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠈⠉⠉⠉⠉⠁⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n```\n\n## Examples and Demos\n\nThe repository includes advanced examples and demos:\n\n1. Function and chart gallery\n\n```bash\ncargo run --example demo\n```\n\n2. Primitive shapes and blending\n\n```bash\ncargo run --release --example primitives_demo\n```\n\n3. 3D volatility surface with gradient ascent\n\n```bash\ncargo run --release --example vol_surface\n```\n\n4. Braille, half-block, and quadrant renderer showcase\n\n```bash\ncargo run --release --example renderer_showcase\n```\n\n5. Runtime renderer selection from CLI input\n\n```bash\ncargo run --release --example runtime_renderer -- quadrant\n```\n\n6. t-SNE embedding with nearest-neighbor graph\n\n```bash\ncargo run --release --example tsne_neighbors\n```\n\n7. 3D gallery with camera, z-buffer, and zoom\n\n```bash\ncargo run --release --example 3dengine\n```\n\n8. Solar system Kepler 3D\n\n```bash\ncargo run --release --example solarsystem_kepler\n```\n\n9. Sprite engine\n\n```bash\ncargo run --release --example sprite_demo\n```\n\n10. Interactive fractals\n\n```bash\ncargo run --release --example fractalmove\n```\n\n## Performance\n\n`txtplot` is optimized for real-time terminal rendering.\n\nIn a benchmark with a 236x104 sub-pixel canvas filled with trigonometric noise and particles on a modern machine:\n\n- Debug mode: about 60 FPS\n- Release mode: about 1600+ FPS\n\nUse `just bench` or `cargo bench --bench canvas_benchmark` to run the current Criterion suite. It now includes renderer comparison groups for chart-heavy and raster-heavy scenes across Braille, HalfBlock, and Quadrant output.\n\n## Roadmap\n\nDetailed implementation planning now lives in `ARCHITECTURE.md`. The list below is only the user-facing summary.\n\n- [x] Flat contiguous buffers for memory efficiency\n- [x] Explicit coordinate APIs for screen and cartesian modes\n- [x] Cohen-Sutherland line clipping\n- [x] Zero-allocation rendering via `render_to`\n- [x] Filled primitives and erasers\n- [x] Color blending policies\n- [x] Logarithmic scaling support\n- [ ] Automatic legend box\n- [x] Trait-based pluggable terminal renderers\n- [x] Runtime renderer selection helpers\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frupurt%2Ftxtplot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frupurt%2Ftxtplot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frupurt%2Ftxtplot/lists"}