如何用plotters-rs绘制0.0-1.0区间、50段的浮点值直方图
使用plotters-rs创建0.0~1.0范围、含50个分段的直方图
我正在试用plotters-rs,想要创建一个数值范围为0.0f64到1.0f64、包含50个分段的直方图。以下是调整后的可行代码及关键说明:
修改后的完整代码
use plotters::prelude::*; use tch::{kind, Tensor}; use ndarray::ArrayD; fn main() -> Result<(), Box<dyn std::error::Error>> { let path = "plots/0.png"; let root = BitMapBackend::new(path, (1280, 720)).into_drawing_area(); root.fill(&WHITE)?; // 生成x轴的50个均匀分段,覆盖0.0到1.0范围 let x_segments = SegmentedCoord::new((0..50).map(|i| { let start = i as f64 / 50.0; let end = (i + 1) as f64 / 50.0; (start, end) })); let mut chart = ChartBuilder::on(&root) .set_label_area_size(LabelAreaPosition::Left, 40) .set_label_area_size(LabelAreaPosition::Bottom, 40) .caption("直方图", ("sans-serif", 40)) .build_cartesian_2d(x_segments, 0i64..20) .unwrap(); chart.configure_mesh() .x_labels(10) // 仅显示10个x轴标签,避免过度拥挤 .draw()?; // 生成0.0~1.0之间的随机测试数据 let t = Tensor::rand(&[1000], kind::FLOAT_CPU); let data: ArrayD<f64> = (&t).try_into()?; // 统计每个分段内的数据数量 let mut counts = vec![0; 50]; for &val in data.iter() { let idx = (val * 50.0).floor() as usize; // 处理值为1.0的边界情况,归入最后一个分段 let idx = if idx >= 50 { 49 } else { idx }; counts[idx] += 1; } // 绘制直方图 root.draw_series( Histogram::vertical(&chart) .style(BLUE.filled()) .margin(2) // 缩小柱子间距适配50个分段 .data(counts.into_iter().enumerate().map(|(i, cnt)| (i, cnt))) )?; root.present()?; Ok(()) }
Cargo.toml配置
[package] name = "test-rs" version = "0.1.0" edition = "2021" [dependencies] ndarray = "0.15.6" plotters = "0.3.4" tch = "0.10.1"
关键调整说明
- x轴分段定义:用
SegmentedCoord::new生成50个均匀分布的区间,每个区间宽度为0.02(1.0/50),精准覆盖0.0到1.0的数值范围。 - 数据统计优化:先遍历数据统计每个分段的数量,再将统计结果传给直方图,避免逐个传递单条数据,提升绘制效率。
- 布局适配:将柱子
margin从10改为2,避免50个分段出现重叠或超出画布的情况;x轴仅显示10个标签,防止文字拥挤。 - 边界处理:对值为1.0的数据做特殊处理,确保其归入最后一个分段,避免索引越界。
内容的提问来源于stack exchange,提问作者Tomkimsour
相关产品推荐
相关产品推荐

