Rust中使用Plotters添加PointSeries绘图报错求助
尝试用Plotters库生成同时包含折线和点系列的图表,折线系列正常,但点系列抛出类型推断错误,简化代码及错误信息如下:
问题代码
fn main() { let points: Vec<(f64, f64)> = vec![(2.0, 2.0), (3.0, 3.0 ), (4.0, 4.0), (8.0, 8.0)]; generate_plot(&points); } fn generate_plot(points: &Vec<(f64, f64)>) -> Result<(), Box<dyn std::error::Error>> { let root = BitMapBackend::new("C:\\Users\\ppp\\Documents\\Rust\\tpy\\Data\\test.png", (800, 800)).into_drawing_area(); root.fill(&WHITE)?; let mut chart = ChartBuilder::on(&root) .build_cartesian_2d(0f64..10f64, 0f64..10f64)?; chart.configure_mesh().draw()?; chart.draw_series(PointSeries::new(points.clone(), 5, &BLUE))?; //此处报错 root.present()?; Ok(()) }
错误信息
error[E0282]: type annotations needed
--> src\main.rs:29:11
| 29 | chart.draw_series(PointSeries::new(points.clone(), 5, &BLUE))?;
| ^^^^^^^^^^^ cannot infer type of the type parameterBdeclared on the associated functiondraw_series
error[E0283]: type annotations needed
--> src\main.rs:29:23
| 29 | chart.draw_series(PointSeries::new(points.clone(), 5, &BLUE))?;
| ^^^^^^^^^^^^^^^^ cannot infer type of the type parameterEdeclared on the structPointSeries
| = note: multipleimpls satisfying_: PointElement<(f64, f64), i32>found in theplotterscrate:
- impl<Coord, Size> PointElement<Coord, Size> for Circle<Coord, Size> where Size: SizeDesc;
- impl<Coord, Size> PointElement<Coord, Size> for Pixel where Size: SizeDesc;
- impl<Coord, Size> PointElement<Coord, Size> for TriangleMarker<Coord, Size> where Size: SizeDesc;
- impl<Coord, Size> PointElement<Coord, Size> for plotters::element::Cross<Coord, Size> where Size: SizeDesc;
解决方案
报错原因是编译器无法自动推断PointSeries使用的点元素类型(Plotters提供了Circle、Pixel、TriangleMarker等多种点元素实现),与点大小参数无关。只需显式指定点元素类型即可解决,以下是两种可行修改方式:
方式1:使用element方法指定点元素
修改draw_series调用行,通过element::<Circle<_>>()明确使用圆形点:
chart.draw_series(PointSeries::new(points.clone(), 5, &BLUE).element::<Circle<_>>())?;
方式2:显式标注PointSeries的类型参数
直接在PointSeries::new处指定类型参数,以Circle为例:
chart.draw_series(PointSeries::<_, _, _, Circle<_>, _>::new(points.clone(), 5, &BLUE))?;
完整修正代码
use plotters::prelude::*; fn main() { let points: Vec<(f64, f64)> = vec![(2.0, 2.0), (3.0, 3.0 ), (4.0, 4.0), (8.0, 8.0)]; if let Err(e) = generate_plot(&points) { eprintln!("Error: {}", e); } } fn generate_plot(points: &Vec<(f64, f64)>) -> Result<(), Box<dyn std::error::Error>> { let root = BitMapBackend::new("C:\\Users\\ppp\\Documents\\Rust\\tpy\\Data\\test.png", (800, 800)).into_drawing_area(); root.fill(&WHITE)?; let mut chart = ChartBuilder::on(&root) .build_cartesian_2d(0f64..10f64, 0f64..10f64)?; chart.configure_mesh().draw()?; // 使用方式1的修正代码 chart.draw_series(PointSeries::new(points.clone(), 5, &BLUE).element::<Circle<_>>())?; root.present()?; Ok(()) }
内容的提问来源于stack exchange,提问作者PMG

