7 releases
Uses new Rust 2024
new 0.1.6 | Jul 8, 2025 |
---|---|
0.1.5 | Jul 6, 2025 |
0.1.1 | Jun 30, 2025 |
#79 in Visualization
743 downloads per month
Used in differential-equations
165KB
2K
SLoC
Quill ðŠķ
A lightweight Rust plotting library for creating simple SVG 2D plots. Quill is designed for simplicity and ease of use, making it perfect for generating basic plots for reports, examples, or any application that needs clean, vector-based visualizations.
Features
- ðĻ Basic Styling: Choose colors, marker types, and line styles
- ð Simple Layouts: Configurable dimensions, titles, axis labels, legends, and grids
- ð§ Builder Pattern: Clean API with method chaining
- ð Multiple Data Series: Support for multiple datasets on a single plot
- ðžïļ SVG Output: Export to SVG files or return as
svg::Document
for programmatic use - ðžïļ PNG Support: Optional PNG output via
png
feature - ⥠Lightweight: Minimal dependencies for fast compilation
Quick Start
Add Quill to your Cargo.toml
:
[dependencies]
quill = "0.1.0"
Basic Line Plot
use quill::*;
fn main() {
let data = (0..=100).map(|x| {
let xf = x as f64 * 0.1;
(xf, xf.sin())
}).collect();
let plot = Plot::builder()
.dimensions((600, 400))
.title("Sine Wave")
.x_label("X Axis")
.y_label("Y Axis")
.data([
Series::builder()
.name("sin(x)")
.color("Blue")
.data(data)
.line(Line::Solid)
.build(),
])
.build();
plot.to_svg("output.svg").unwrap();
// Or get the SVG document for programmatic use
let svg_doc = plot.to_document();
}
Examples
Line Plot
A simple sine wave visualization with connected points:
use quill::*;
let line_plot = Plot::builder()
.dimensions((600, 400))
.title("Line Graph Example")
.x_label("X Axis")
.y_label("Y Axis")
.legend(Legend::TopRightOutside)
.grid(Grid::Solid)
.data([
Series::builder()
.name("Sine Curve")
.color("Blue")
.data(line_data())
.marker(Marker::None)
.line(Line::Solid)
.build(),
])
.build();
Scatter Plot
Data points without connecting lines:
use quill::*;
let scatter_plot = Plot::builder()
.dimensions((600, 400))
.title("Scatter Graph Example")
.legend(Legend::TopRightOutside)
.grid(Grid::Dashed)
.data([
Series::builder()
.name("Lissajous Curve")
.color("Red")
.data(scatter_data())
.marker(Marker::Circle)
.marker_size(5.0)
.line(Line::None) // No connecting lines
.build(),
])
.build();
Multi-Series Plot
Multiple datasets on the same plot:
use quill::*;
let plot = Plot::builder()
.dimensions((900, 500))
.title("Sales Data")
.x_label("Month")
.y_label("Units Sold")
.legend(Legend::TopLeftInside)
.grid(Grid::Solid)
.data([
Series::builder()
.name("Product A")
.color("Blue")
.data(product_a_data)
.marker(Marker::Circle)
.line(Line::Solid)
.build(),
Series::builder()
.name("Product B")
.color("Firebrick")
.data(product_b_data)
.marker(Marker::Square)
.line(Line::Dotted)
.build(),
// Add more series as needed
])
.build();
Investment Growth Data
Points with different line styles:
use quill::*;
let plot = Plot::builder()
.dimensions((800, 600))
.title("Hypothetical Investment Growth")
.x_label("Years")
.y_label("Value ($)")
.x_range(Range::Manual { min: 0.0, max: 10.0 })
.legend(Legend::TopLeftInside)
.grid(Grid::Dotted)
.font("Times New Roman")
.data([
Series::builder()
.name("Low-Risk Investment")
.color("Green")
.data(low_risk_data)
.marker(Marker::Circle)
.line(Line::Solid)
.build(),
// Add more investment types
])
.build();
API Overview
Plot Builder
Configure your plot with the builder pattern:
Plot::builder()
.dimensions((width, height)) // Plot size
.title("Plot Title") // Chart title
.x_label("X Axis") // X-axis label
.y_label("Y Axis") // Y-axis label
.x_range(Range::Auto) // X-axis range (Auto or Manual)
.y_range(Range::Auto) // Y-axis range (Auto or Manual)
.legend(Legend::TopRightOutside) // Legend position
.grid(Grid::Solid) // Grid style
.font("Arial") // Font family
.margin(Margin::default()) // Plot margins
.data([Series]) // Data series
.build()
Series Builder
Define data series with markers and line styling:
Series::builder()
.name("Series Name") // Legend name
.color("Blue") // Line/marker color
.data(vec![(x, y)]) // Data points (f32, f64, i32, or i64 tuples)
.marker(Marker::Circle) // Point markers
.marker_size(5.0) // Marker size
.line(Line::Solid) // Line style (or Line::None for scatter)
.build()
Note the Colors are derived from the pigment
crate. More information at pigment.
Output Options
// Save to SVG file
plot.to_svg("output.svg").unwrap();
// Get SVG document for programmatic use
let svg_doc: svg::Document = plot.to_document();
Available Options
Markers
Marker::None
- No markersMarker::Circle
- Circular pointsMarker::Square
- Square pointsMarker::Cross
- Cross markers
Line Styles
Line::Solid
- Solid linesLine::Dashed
- Dashed linesLine::Dotted
- Dotted linesLine::None
- No connecting lines
Grid Styles
Grid::Solid
- Solid grid linesGrid::Dashed
- Dashed grid linesGrid::Dotted
- Dotted grid linesGrid::None
- No grid
Legend Positions
Legend::TopLeftInside
Legend::TopRightInside
Legend::TopRightOutside
Legend::BottomLeftInside
Legend::BottomRightInside
Legend::BottomRightOutside
Legend::LeftCenterInside
Legend::RightCenterInside
Legend::RightCenterOutside
Legend::TopCenter
Legend::BottomCenter
Legend::None
Dependencies
Quill has minimal dependencies to keep your build fast:
bon
- For builder patternspigment
- For color handlingsvg
- For SVG generation
License
This project is licensed under the Apache-2.0 License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.
Dependencies
~1â2MB
~45K SLoC