使用绘图仪进行矢量可视化失败 "required by a bound in `plotters::chart::ChartContext::<'a, DB, CT>::draw_series`"

Vector visualization failed using plotters "required by a bound in `plotters::chart::ChartContext::<'a, DB, CT>::draw_series`"

我正在尝试使用板条箱“绘图仪”在 2D 中可视化矢量项。

fn main() -> Result<(), Box<dyn Error>> {
    let file_path = "out.csv";
    let file = File::open(file_path);
    let mut rdr = csv::ReaderBuilder::new().delimiter(b',').from_path(file_path)?;
    let mut ke: Vec<f64> = Vec::new();  // reading itself is ok
    let mut pe: Vec<f64> = Vec::new();  // reading itself is ok

    for res in rdr.records() {
        let record = res?;

        ke.push(record[0].parse().unwrap());
        pe.push(record[1].parse().unwrap());
        println!("{:?}, {:?}", &record[0], &record[1]);
    }

    let (ke_min, ke_max) = ke.iter().fold((0.0/0.0, 0.0/0.0),|(m,n), v| (v.min(m), v.max(n)));

    let mut backend = BitMapBackend::new("outputs/test.png", (600, 400));
    let root:DrawingArea<_,_> = backend.into();
    root.fill(&RGBColor(255,255,255)).unwrap();
    
    let font = ("san-serif", 20);

    let mut chart: ChartContext<BitMapBackend, Cartesian2d<RangedCoordusize, RangedCoordf64>> = ChartBuilder::on(&root)
        .caption("kinetic energy and potential", font.into_font())
        .build_cartesian_2d(0..ke.len(), ke_min..ke_max)?;
    chart.configure_mesh().draw()?;
    chart.draw_series(LineSeries::new(ke, &RGBColor(255,0,0)));

    Ok(())
}

错误是

error[E0277]: the trait bound `for<'b> &'b DynElement<'static, plotters::prelude::BitMapBackend<'_>, f64>: PointCollection<'b, (usize, f64)>` is not satisfied

我是几秒钟前从鸡蛋中孵化出来的锈菌,所以我不知道如何解决这个问题。

首先将chart.draw_series(LineSeries::new(ke, &RGBColor(255,0,0)));行拆分为两行:

let series = LineSeries::new(ke, &RGBColor(255, 0, 0));
chart.draw_series(series);

并查看 series 的类型:LineSeries<BitMapBackend<RGBPixel>, f64>.

如果您现在查看错误(简化了一些内容):

the trait bound DynElement<'static, BitMapBackend<'_>, f64>: PointCollection<'b, (usize, f64)> is not satisfied

您可以找到两个部分:<..., BitMapBackend..., f64>看起来非常类似于series的类型。事实上,这就是错误消息中 f64 的原因。

现在看看chart的类型:

ChartContext<BitMapBackend, Cartesian2d<RangedCoordusize, RangedCoordf64>>

简化了您想创建 x-values 类型 usize 和 y-values 类型 f64 的二维坐标系。您也可以在错误消息中找到这两种类型。

但现在看:您想要创建一个 2d 坐标系(x-values 类型 usize,y-values 类型 f64) 但只提供 LineSeries::new 中 y-values(f64 类型)的 Vec! 可能你忘了你的 x-values!

如果您查看 LineSeries::new,它需要一个可以迭代的类型来创建坐标。所以这就是你的 chart 类型的情况(你明确指定了 chart 的类型)IntoIterator<Item = (usize, f64)>.

我不知道 x-values 是从哪里来的,但如果你真的不在乎,你可以试试这个,它会从 0 向上创建一个 x-axis。

chart.draw_series(LineSeries::new(
   ke.into_iter().enumerate(),
   &RGBColor(255, 0, 0),
));

如果您想自定义 x-values,我建议将 ke 的类型更改为 Vec<(usize, f64)> 并在 for-loop.[=36 中创建适当的值=]

(如果您能包含您的 use 也会很有帮助,这样人们就可以轻松地编辑和测试您的代码。另外说明错误所在的行也会很有帮助)