首页 > 其他分享 >【rust】《Rust深度学习[3]-数据可视化(Plotters)》

【rust】《Rust深度学习[3]-数据可视化(Plotters)》

时间:2024-04-23 13:33:37浏览次数:25  
标签:10.0 .. area chart Plotters let rust root Rust

什么是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

相关文章

  • 【rust】《Rust深度学习[1]-科学计算库(Ndarray)》
    什么是Ndarray?ndarray是Rust生态中用于处理数组的库。它包含了所有常用的数组操作。简单地说ndarray相当于Rust版本的numpy。ndarray生态系统中crate的文档:ndarray基础库ndarray-rand随机数生成库ndarray-stats统计方法  顺序统计(最小、最大、中值、分位数等);  汇总......
  • three.js使用Instanced Draw+Frustum Cull+LOD来渲染大场景(开源)
    大家好,本文使用three.js实现了渲染大场景,在移动端也有较好的性能,并给出了代码,分析了关键点,感谢大家~关键词:three.js、InstancedDraw、大场景、LOD、FrustumCull、优化、Web3D、WebGL、开源代码:Github我正在承接Web3D数字孪生项目,具体介绍可看承接各种Web3D业务加QQ群交流:106......
  • vim配置rust开发环境
    vim配置需要环境首先需要安装rust,然后安装rust-analysis,还需要nodejs,npm。插件使用vim-plug管理,也是需要提前安装的安装coc之后还需要安装CocInstallcoc-rust-analysis下边是踩坑出来的配置文件"插件安装在callplug#begin('~/.vim/plugged')和callplug#end()之间。cal......
  • Windows快速安装Rust
    本文是最简最快最小化安装重点提示:如果不想安装VS消耗时间和6-8G的空间,可以按本文安装。如果系统中已经安装了VS,那么直接运行rustup-init安装Rust,并一路回车即可。前置条件:安装C++环境rust底层是依赖C环境的连接器,所以需要先安装C/C++编译环境,点击下载64位mingw-builds......
  • The Stack and the Heap栈与堆__Rust
    Manyprogramminglanguagesdon’trequireyoutothinkaboutthestackandtheheapveryoften.许多编程语言并不会要求你经常思考堆栈。ButinasystemprogramminglanguagelikeRust,whetheravalueisonthestackortheheapaffectshowthelanguagebehaves......
  • rust程序中设置和访问环境变量
    在项目中,我们通常需要设置一些环境变量,用来保存一些凭证或其它数据,这时我们可以使用dotenv这个crate。1、添加crate依赖首先在项目中添加dotenv这个依赖:  2、添加.env文件在开发环境下,我们可以在项目根目录下创建和编辑.env这个文件: 在运行环境下,这个.env文件要......
  • 50个Rust新手常犯的错误:看看你中过几条?
    错误地使用可变和不可变借用letmutdata=vec![1,2,3];letx=&data[0];data.push(4);println!("{}",x);不能在有不可变引用时修改数据。忘记处理Optionfnmain(){letsome_number=Some(5);letsum=some_number+5;//错误:Option类型不能这......
  • Rust简易入门(六)
    Trait特质Trait是一种定义方法签名的机制,特质允许你定义一组方法的签名,但可以不提供具体的方法实现任何类型都可以实现特质,只要他们提供了特质中定义的所有方法。这是的你可以为不同类型提供相同的行为内置常量:const,整个生命周期都是有效的默认实现多重实现:类型可以实......
  • [Rust] Intro Lifetimes
    Thefollowingcodehascompilererror:fnjazz(years:&[i64])->Releases{leteighties:[i64]=&years[0..2];letnineties:[i64]=&years[2..4];Releases{years,eighties,nineties,}}let......
  • rust和内部可变性模式RefCell<T>
    内部可变性(Interiormutability)是Rust中的一个设计模式,它允许你即使在有不可变引用时也可以改变数据,这通常是借用规则所不允许的。为了改变数据,该模式在数据结构中使用 unsafe 代码来模糊Rust通常的可变性和借用规则。不安全代码表明我们在手动检查这些规则而不是让编译器替......