plotters-rs / plotters

A rust drawing library for high quality data plotting for both WASM and native, statically and realtimely 🦀 📈🚀
https://plotters-rs.github.io/home/
MIT License
3.81k stars 276 forks source link

[BUG] Throunds of points will block draw_series #450

Open hemaolong opened 1 year ago

hemaolong commented 1 year ago

The code below will trigger the bug,it seems float overflow.

fn test_plot_bug() -> Result<()> { use plotters::prelude::*;

let mut datas: Vec<f64> = vec![0.0; 2000];
for i in 0..datas.len() {
    if i % 3 == 0 {
        datas[i] = 0.5
    }
}
let lb_d = LineSeries::new(
    datas.iter().enumerate().map(|(k, v)| (k as f32, *v)),
    MAGENTA.filled().stroke_width(3),
);

let root = BitMapBackend::new("./0.png", (640, 480)).into_drawing_area();
root.fill(&WHITE)?;
root.margin(10, 10, 10, 10);
let mut chart = ChartBuilder::on(&root)
    .margin(5)
    .build_cartesian_2d(0.0_f32..(datas.len() - 1) as f32, 0_f64..100_f64)?;

chart
    .draw_series(lb_d)?
    .legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &RED));

root.present()?;

Ok(())

}

DanielAristidou commented 1 year ago

I face a similar issue.

flamegraph points to:

https://github.com/plotters-rs/plotters/blob/master/plotters-backend/src/rasterizer/polygon.rs

image

I have identified that the loop ->

for sweep_line in low..=high { } uses -> Low: 4 High: 2147483647 when the number of points per above example is 2000 and -> Low: 4 High636 when the number of points is 200

High appears to be the i32::MAX

Which I believe is converted from f64 to i32 here: https://github.com/plotters-rs/plotters/blob/master/plotters-backend/src/rasterizer/line.rs#L31

DanielAristidou commented 1 year ago

@hemaolong If i change stroke width to 1 in your example it works as it avoids this logic.