| Crates.io | runmat-plot |
| lib.rs | runmat-plot |
| version | 0.2.8 |
| created_at | 2025-10-15 04:20:28.187593+00 |
| updated_at | 2025-12-22 21:37:45.903287+00 |
| description | GPU-accelerated and static plotting for RunMat with WGPU and Plotters |
| homepage | https://runmat.org |
| repository | https://github.com/runmat-org/runmat |
| max_upload_size | |
| id | 1883748 |
| size | 546,701 |
RunMat Plot is the in-progress visualization layer for the RunMat pre-release. Simple 2D line and scatter plots run today on the GPU-backed renderer, while filled shapes, advanced 3D views, and polished exports are still being built. The focus is delivering fast, lightweight visuals for early adopters while the broader plotting surface takes shape.
As a core component of the RunMat project, it serves as the powerful handle-graphics engine for all visualization tasks.
wgpu for fast 2D line/scatter plots; more chart types are under active development.winit/egui window handles basic zoom and pan. Advanced camera controls and multiple plot management are still being polished.plot, scatter, future surf) keep syntax familiar even as capabilities expand.ModernDark preset is available now, with broader theming to follow as features land.The runmat-plot crate is designed with a layered architecture to separate concerns, providing both high-level simplicity and low-level control.
src/core - The Rendering Engine: This is the heart of the library.
WgpuRenderer abstracts over wgpu to manage render pipelines, shaders, and GPU buffers.Scene provides a scene graph to manage renderable objects, their transformations, and visibility.Camera implements both orthographic (2D) and perspective (3D) cameras with interactive navigation controls.PlotRenderer is a unified pipeline that handles rendering for both interactive windows and static exports, ensuring consistent output.src/plots - High-Level Plot Types: This module defines the user-facing API for creating plots.
Figure is the main container for a visualization, managing multiple overlaid plots.LinePlot, ScatterPlot, SurfacePlot, etc., encapsulate the data and styling for a specific plot type. They are responsible for generating RenderData (vertices, indices) to be consumed by the core renderer.src/gui - Interactive Windowing: This module provides the interactive GUI.
PlotWindow is the main entry point, creating a winit window and managing the event loop.PlotOverlay uses egui to draw UI elements (axes, grids, titles, controls) on top of the wgpu canvas.thread_manager and native_window contain robust, cross-platform logic to handle GUI operations, especially the main-thread requirements on macOS.src/styling - Theming & Appearance: This module controls the visual style.
PlotThemeConfig allows for complete customization of colors, fonts, and layout via RunMat's central configuration system (e.g., .runmat.yaml).ModernDarkTheme provides a professional, out-of-the-box dark theme.The crate is organized to clearly separate rendering, plot logic, and UI.
runmat-plot/
├── Cargo.toml # Dependencies and feature flags (gui, jupyter)
├── README.md # This file
├── examples/ # Runnable examples (interactive_demo.rs, etc.)
├── shaders/ # WGSL shaders for GPU rendering pipelines
└── src/
├── core/ # Low-level rendering engine (WGPU, scene, camera)
├── data/ # Data processing, LOD, buffer management (TODO)
├── export/ # Static export to PNG, SVG, HTML (TODO)
├── gui/ # Interactive GUI window, controls, and UI overlays
├── jupyter/ # Jupyter Notebook integration
├── lib.rs # Main library entry point and public API
├── plots/ # High-level plot types (LinePlot, SurfacePlot, etc.)
├── simple_plots.rs # Legacy static plotting with `plotters`
└── styling/ # Theming, colors, and layout configuration
Create a figure, add a line plot, and prepare it for rendering.
use runmat_plot::plots::{Figure, LinePlot, LineStyle};
use glam::Vec4;
let x: Vec<f64> = (0..=100).map(|i| i as f64 * 0.1).collect();
let y: Vec<f64> = x.iter().map(|&x| x.sin()).collect();
let mut figure = Figure::new()
.with_title("Sine Wave")
.with_labels("X-axis", "Y-axis")
.with_grid(true);
let line_plot = LinePlot::new(x, y)?
.with_style(Vec4::new(0.35, 0.78, 0.48, 1.0), 2.0, LineStyle::Solid)
.with_label("sin(x)");
figure.add_line_plot(line_plot);
Overlay multiple plot types in a single figure for comprehensive visualizations.
use runmat_plot::plots::{Figure, LinePlot, ScatterPlot, BarChart, MarkerStyle};
use glam::Vec4;
let mut figure = Figure::new().with_title("Sales Data Analysis");
// Add a bar chart for monthly sales
let sales_bars = BarChart::new(
vec!["Jan".to_string(), "Feb".to_string(), "Mar".to_string()],
vec![120.0, 135.0, 155.0]
)?.with_label("Monthly Sales");
// Add a line plot for the sales trend
let trend_line = LinePlot::new(vec![0.0, 1.0, 2.0], vec![120.0, 135.0, 155.0])?
.with_label("Sales Trend");
// Add a scatter plot for KPI targets
let kpi_points = ScatterPlot::new(vec![0.0, 1.0, 2.0], vec![125.0, 130.0, 160.0])?
.with_style(Vec4::new(1.0, 0.3, 0.3, 1.0), 8.0, MarkerStyle::Star)
.with_label("KPI Targets");
figure.add_bar_chart(sales_bars);
figure.add_line_plot(trend_line);
figure.add_scatter_plot(kpi_points);
Create a 3D surface plot from a mathematical function.
use runmat_plot::plots::{SurfacePlot, ColorMap, ShadingMode};
let surface = SurfacePlot::from_function(
(-3.0, 3.0),
(-3.0, 3.0),
(50, 50),
|x, y| (-(x*x + y*y)).exp() * 2.0 - 1.0 // Gaussian
).unwrap()
.with_colormap(ColorMap::Viridis)
.with_shading(ShadingMode::Smooth);
let mut figure = Figure::new().with_title("3D Gaussian Surface");
// Figure currently only supports 2D plots, but 3D integration is planned.
Launch a GPU-accelerated interactive window to display a figure.
// This requires the "gui" feature
// Add to Cargo.toml: runmat-plot = { version = "...", features = ["gui"] }
#[cfg(feature = "gui")]
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// ... create your figure as in the examples above ...
let mut figure = Figure::new().with_title("Interactive Demo");
// ... add plots to figure ...
// Launch the interactive window
runmat_plot::show_interactive_with_figure(&figure).await?;
Ok(())
}
runmat-plot is under active development. The core GPU-accelerated architecture is implemented and functional, but there are several important limitations to be aware of:
Triangle Rendering Issue (macOS Metal): Bar charts and filled 2D shapes currently render as thin lines instead of filled areas on macOS. This is a low-level WGPU/Metal triangle rasterization issue that affects the triangle rendering pipeline. Line plots work correctly.
Status: Under investigation. The issue has been isolated to triangle primitive assembly in the Metal backend. All high-level geometry generation, vertex data, shaders, and draw calls are correct.
Workaround: Line plots, scatter plots, and 3D point clouds work as expected. Bar charts will display but appear as outlines only.
Sequential Plotting: Opening multiple plot windows sequentially may cause EventLoop recreation errors on macOS due to winit limitations. The first plot window works correctly.
Workaround: Restart the application between different plotting sessions.
Legacy Export Backend: Static PNG exports currently use a fallback plotters-based renderer, which may not match the interactive GPU rendering exactly.
plot(), scatter(), scatter3() function interfaceActive areas of development, in priority order:
🔥 PRIORITY: Fix Triangle Rendering (macOS Metal): Resolve the triangle rasterization issue preventing filled shapes from rendering correctly. Investigation points to WGPU primitive topology or Metal driver interaction.
EventLoop Management: Implement robust sequential plotting support to eliminate EventLoop recreation errors.
Unified Static Export: Replace the legacy plotters-based backend in simple_plots.rs with a unified headless rendering mode using the wgpu engine. This will ensure that exported PNGs and SVGs are pixel-perfect matches of the interactive plots.
Complete Export Modules: Fully implement the src/export modules for high-quality vector (SVG, PDF) and web (HTML, interactive widgets) outputs.
Advanced Data Handling: Implement the src/data modules for optimized GPU buffer management, level-of-detail (LOD) for large datasets, and advanced geometry processing.
Volume Rendering: Implement the VolumePlot type for 3D volumetric data visualization.
Jupyter WebGL Widget: Complete the WebGL-based interactive widget for Jupyter to provide a fully interactive experience within notebooks, matching the native GUI.
Expanded Theming: Add more built-in themes and expand the customizability of the styling system.
3D in Figures: Fully integrate 3D plots like SurfacePlot into the Figure system for multi-plot 3D scenes.
For Developers: If you're contributing to the triangle rendering fix, see the detailed technical investigation in the Git history. Key files: crates/runmat-plot/src/plots/bar.rs, crates/runmat-plot/src/core/plot_renderer.rs, and crates/runmat-plot/shaders/vertex/triangle.wgsl. The issue has been isolated to direct vertex drawing with PrimitiveTopology::TriangleList on Metal backend.