| Crates.io | quill |
| lib.rs | quill |
| version | 0.2.0 |
| created_at | 2025-06-28 23:50:11.309004+00 |
| updated_at | 2025-08-04 02:45:23.071958+00 |
| description | A lightweight Rust plotting library for creating simple SVG 2D plots |
| homepage | https://github.com/Ryan-D-Gast/quill |
| repository | https://github.com/Ryan-D-Gast/quill |
| max_upload_size | |
| id | 1730205 |
| size | 736,586 |
A lightweight Rust plotting library for creating simple 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.
svg::Document for programmatic usepng featureAdd Quill to your Cargo.toml:
[dependencies]
quill = "0.1.7"
use quill::prelude::*;
fn main() {
let data = (0..=100).map(|x| {
let xf = x as f64 * 0.1;
(xf, xf.sin())
}).collect();
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)
.x_scale(Scale::Pi)
.data([Series::builder()
.name("Sine Curve")
.color(Color::Blue)
.data(data)
.marker(Marker::None)
.line(Line::Solid)
.build()])
.build();
line_plot.to_svg("./gallery/line.svg").unwrap();
}
plot.to_svg("output.svg").unwrap();
// Or get the SVG document for programmatic use
let svg_doc = plot.to_document();
// With feature "png", you can also save as PNG
plot.to_png("output.png").unwrap();
}
A simple sine wave visualization with connected points:
use quill::prelude::*;
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();
Data points without connecting lines:
use quill::prelude::*;
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();
Multiple datasets on the same plot:
use quill::prelude::*;
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(Color::Blue) // Both Color::(ColorName) and string colors are supported
.data(product_a_data)
.marker(Marker::Circle)
.line(Line::Solid)
.build(),
Series::builder()
.name("Product B")
.color("Red")
.data(product_b_data)
.marker(Marker::Square)
.line(Line::Dotted)
.build(),
// Add more series as needed
])
.build();
Points with different line styles:
use quill::prelude::*;
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();
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()
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()
// Save to SVG file
plot.to_svg("output.svg").unwrap();
// Get SVG document for programmatic use
let svg_doc: svg::Document = plot.to_document();
// Save to PNG file (requires "png" feature)
let scale = 1.0; // Scale factor for PNG
plot.to_png("output.png", scale).unwrap();
This project is licensed under the Apache-2.0 License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.