什么是Plotters?
Plotters是一个用纯Rust开发的图形库,用于中渲染图形、图表和数据可视化。它支持静态图片渲染和实时渲染,并支持多种后端,包括:位图格式(png、bmp、gif等)、矢量图(svg)、窗口和HTML5 Canvas。
Plotters对不同后端使用统一的高级API,并允许开发者自定义坐标系。在Plotters中,任何类型的图表都被抽象为一系列绘图操作,通过这些绘图操作,开发者可以自由地操控和组合绘图内容。因此Plotters不会限制图表类型,开发者可以组合出任意内容的图表。
导入依赖库
[dependencies]
plotters = "0.3.3"
折线图
use plotters::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建svg图片对象
let root = SVGBackend::new("plot.svg", (640, 480)).into_drawing_area();
// 图片对象的背景颜色填充
root.fill(&WHITE)?;
// 创建绘图对象
let mut chart = ChartBuilder::on(&root)
// 图表名称 (字体样式, 字体大小)
.caption("折线图", ("sans-serif", 30))
// 图表左侧与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Left, 40)
// 图表底部与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Bottom, 40)
// 构建二维图像, x轴 0.0 - 10.0; y轴 0.0 - 10.0;
.build_cartesian_2d(0.0..10.0, 0.0..10.0)?;
// 配置网格线
chart.configure_mesh().draw()?;
// 绘制折线
chart.draw_series(LineSeries::new(
// vec![(0., 2.), (1., 1.), (2., 2.), (3., 3.), (4., 4.), (5., 5.), (6., 6.), (7., 7.), (8., 8.), (9., 9.)],
vec![0., 1., 2., 3., 4., 5., 6., 7., 8.].iter().map(|x| (*x, *x)),
// 线条颜色
&BLUE,
))?;
Ok(())
}
多折线图
use plotters::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建svg图片对象
let root = SVGBackend::new("plot.svg", (640, 480)).into_drawing_area();
// 图片对象的背景颜色填充
root.fill(&WHITE)?;
// 创建绘图对象
let mut chart = ChartBuilder::on(&root)
// 图表名称 (字体样式, 字体大小)
.caption("多折线图", ("sans-serif", 30))
// 图表左侧与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Left, 40)
// 图表底部与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Bottom, 40)
// 构建二维图像, x轴 0.0 - 10.0; y轴 0.0 - 10.0;
.build_cartesian_2d(0.0..10.0, 0.0..10.0)?;
// 配置网格线
chart.configure_mesh().draw()?;
// 绘制多折线图
// 折线1
chart.draw_series(LineSeries::new(
// x.powf(2) 求x的2次幂
(0..10).map(|x| (x as f64, (x as f64).powf(2.0))),
&RED.stroke_width(5).color,
// 标签
))?.label("y=x^2")
.legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &RED));
// 折线2
chart.draw_series(LineSeries::new(
(0..10).map(|x| (x as f64, (x as f64).powf(2.0) + 2.0)),
&BLUE.stroke_width(5).color,
// 标签
))?.label("y=x^2+2")
.legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &BLUE));
// 配置标签样式
chart.configure_series_labels()
.background_style(&WHITE.mix(0.8))
.border_style(&BLACK)
.draw()?;
Ok(())
}
散点图
use plotters::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建svg图片对象
let root = SVGBackend::new("plot.svg", (640, 480)).into_drawing_area();
// 图片对象的背景颜色填充
root.fill(&WHITE)?;
// 创建绘图对象
let mut chart = ChartBuilder::on(&root)
// 图表名称 (字体样式, 字体大小)
.caption("散点图", ("sans-serif", 30))
// 图表左侧与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Left, 40)
// 图表底部与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Bottom, 40)
// 构建二维图像, x轴 0.0 - 10.0; y轴 0.0 - 10.0;
.build_cartesian_2d(0.0..10.0, 0.0..10.0)?;
// 配置网格线
chart.configure_mesh().draw()?;
// 散点位置
let data = [
(1., 2.),
(2., 3.),
(3., 4.),
(4., 5.),
(5., 6.),
];
// 绘制散点
chart.draw_series(
data.iter()
.map(|(x, y)| {
Circle::new((*x, *y), 5, BLUE.filled())
})
.collect::<Vec<_>>(),
)?;
Ok(())
}
多标记散点图
use plotters::prelude::*;
const DATA1: [(i32, i32); 30] = [
(-3, 1), (-2, 3), (4, 2), (3, 0), (6, -5), (3, 11), (6, 0), (2, 14), (3, 9), (14, 7), (8, 11),
(10, 16), (7, 15), (13, 8), (17, 14), (13, 17), (19, 11), (18, 8), (15, 8), (23, 23), (15, 20),
(22, 23), (22, 21), (21, 30), (19, 28), (22, 23), (30, 23), (26, 35), (33, 19), (26, 19)
];
const DATA2: [(i32, i32); 30] = [
(1, 22), (0, 22), (1, 20), (2, 24), (4, 26), (6, 24), (5, 27), (6, 27), (7, 27), (8, 30), (10, 30),
(10, 33), (12, 34), (13, 31), (15, 35), (14, 33), (17, 36), (16, 35), (17, 39), (19, 38), (21, 38),
(22, 39), (23, 43), (24, 44), (24, 46), (26, 47), (27, 48), (26, 49), (28, 47), (28, 50)
];
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建svg图片对象
let root = SVGBackend::new("plot.svg", (640, 480)).into_drawing_area();
// 图片对象的背景颜色填充
root.fill(&WHITE)?;
// 创建绘图对象
let mut chart = ChartBuilder::on(&root)
// 图表名称 (字体样式, 字体大小)
.caption("散点图", ("sans-serif", 30))
// 图表左侧与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Left, 40)
// 图表底部与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Bottom, 40)
// 构建二维图像, x轴 0.0 - 10.0; y轴 0.0 - 10.0;
.build_cartesian_2d(-10..50, -10..50)?;
// 配置网格线
chart.configure_mesh().draw()?;
// 设置三角形标记散点
chart.draw_series(
DATA1.iter().map(
|point| TriangleMarker::new(*point, 5, &BLUE)
),
)?.label("三角")
.legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &BLUE));
// 设置圆圈标记散点
chart.draw_series(
DATA2.iter().map(
|point| Circle::new(*point, 5, &RED)
),
)?.label("圆圈")
.legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &RED));
// 配置标签样式
chart.configure_series_labels()
.background_style(&WHITE.mix(0.8))
.border_style(&BLACK)
.draw()?;
Ok(())
}
面积图
use plotters::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建svg图片对象
let root = SVGBackend::new("plot.svg", (640, 480)).into_drawing_area();
// 图片对象的背景颜色填充
root.fill(&WHITE)?;
// 创建绘图对象
let mut chart = ChartBuilder::on(&root)
// 图表名称 (字体样式, 字体大小)
.caption("面积图", ("sans-serif", 30))
// 图表左侧与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Left, 40)
// 图表底部与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Bottom, 40)
// 构建二维图像, x轴 0.0 - 10.0; y轴 0.0 - 10.0;
.build_cartesian_2d(0..10, 0..50)?;
// 配置网格线
chart.configure_mesh().draw()?;
let data = [25, 37, 15, 32, 45, 33, 32, 10, 29, 0, 21];
let temp = (0..).zip(data.iter().map(|x| *x));
println!("{:?}", temp);
chart.draw_series(
// 绘制面积图
AreaSeries::new(
// { a: 0.., b: Map { iter: Iter([25, 37, 15, 32, 45, 33, 32, 10, 29, 0, 21]) } }
// 0.. 顺序x轴
(0..).zip(data.iter().map(|x| *x)),
// 基线
0,
// 透明度
&RED.mix(0.2)
).border_style(&RED) // 最亮边线的样式
)?;
Ok(())
}
柱状图
use plotters::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建svg图片对象
let root = SVGBackend::new("plot.svg", (640, 480)).into_drawing_area();
// 图片对象的背景颜色填充
root.fill(&WHITE)?;
// 创建绘图对象
let mut chart = ChartBuilder::on(&root)
// 图表名称 (字体样式, 字体大小)
.caption("柱状图", ("sans-serif", 30))
// 图表左侧与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Left, 40)
// 图表底部与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Bottom, 40)
// 构建二维图像, x轴 0.0 - 10.0; y轴 0.0 - 10.0;
// 重点!!!! 这里的传值必须为SegmentedCoord类型
.build_cartesian_2d((0..10).into_segmented(), 0..50)?;
// 配置网格线
chart.configure_mesh().draw()?;
// 数值
let data = [25, 37, 15, 32, 45, 33, 32, 10, 0, 21, 5];
chart.draw_series(
(0..).zip(data.iter()).map(
|(x, y)| {
// 创建x轴底部分段对象
let x0 = SegmentValue::Exact(x);
// 创建x轴顶部分段对象
let x1 = SegmentValue::Exact(x + 1);
let mut bar = Rectangle::new([(x0, 0), (x1, *y)], RED.filled());
// 柱左右间距
bar.set_margin(0, 0, 5, 5);
bar
}
))?;
Ok(())
}
水平柱状图
use plotters::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建svg图片对象
let root = SVGBackend::new("plot.svg", (640, 480)).into_drawing_area();
// 图片对象的背景颜色填充
root.fill(&WHITE)?;
// 创建绘图对象
let mut chart = ChartBuilder::on(&root)
// 图表名称 (字体样式, 字体大小)
.caption("水平柱状图", ("sans-serif", 30))
// 图表左侧与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Left, 40)
// 图表底部与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Bottom, 40)
// 构建二维图像, x轴 0.0 - 10.0; y轴 0.0 - 10.0;
// 重点!!!! 这里的传值必须为SegmentedCoord类型
.build_cartesian_2d(0..50, (0..10).into_segmented())?;
// 配置网格线
chart.configure_mesh().draw()?;
// 数值
let data = [25, 37, 15, 32, 45, 33, 32, 10, 0, 21, 5];
// y轴
let index = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
chart.draw_series(
// 循环x轴数据
// 压缩y轴生成结构
data.iter().zip(index.iter()).map(
|(x, y)| {
// 创建y轴左部分段对象
let y0 = SegmentValue::Exact(*y);
// 创建y轴右部分段对象
let y1 = SegmentValue::Exact(*y + 1);
let mut bar = Rectangle::new([(0, y0), (*x, y1)], GREEN.filled());
// 设置上下柱间距
bar.set_margin(5, 5, 0, 0);
bar
}
))?;
Ok(())
}
真假柱状图
use plotters::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建svg图片对象
let root = SVGBackend::new("plot.svg", (640, 480)).into_drawing_area();
// 图片对象的背景颜色填充
root.fill(&WHITE)?;
// 创建绘图对象
let mut chart = ChartBuilder::on(&root)
// 图表名称 (字体样式, 字体大小)
.caption("真假柱状图", ("sans-serif", 30))
// 图表左侧与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Left, 40)
// 图表底部与图片边缘的间距
.set_label_area_size(LabelAreaPosition::Bottom, 40)
// 构建二维图像, x轴 0.0 - 10.0; y轴 0.0 - 10.0;
// 重点!!!! 这里的传值必须为SegmentedCoord类型
.build_cartesian_2d([true, false].into_segmented(), 0..50)?;
// 配置网格线
chart.configure_mesh().draw()?;
// 数值
let prim:Vec<_> = (2..50).map(is_prime).collect();
chart.draw_series(
Histogram::vertical(&chart)
.margin(100)
.data(prim.iter().map(|x| (x, 1)))
)?;
Ok(())
}
fn is_prime(n: i32) -> bool {
for i in 2..n {
if n % i == 0 {
return false;
}
}
true
}
其他可视化图-参考地址:https://plotters-rs.github.io/book/basic/draw_3d_plots.html
https://github.com/plotters-rs/plotters/tree/master?tab=readme-ov-file
部分内容来源:https://jarod.blog.csdn.net/article/details/128126174
标签:10.0,..,area,chart,Plotters,let,rust,root,Rust From: https://www.cnblogs.com/-CO-/p/18152675