plotters icon indicating copy to clipboard operation
plotters copied to clipboard

[BUG] Drawing series can hang under certain conditions

Open JuliDi opened this issue 11 months ago • 7 comments

Describe the bug Using the code in the following repo, plotters will hang when drawing the series. It only happens under very specific conditions, i.e., the specifically set stroke width and backend dimensions with a certain dataset. It looks like there is something going on with an over-/underflow because when the bug occurs, the vertices vector has at least once the values (2147483647, 2147483647), which cause the x_span here https://github.com/plotters-rs/plotters/blob/af0b63ca2c0ca18780ec9e92730fa97a444dbfca/plotters-backend/src/rasterizer/polygon.rs#L124 to be huge and the subsequent loop takes forever.

I am not sure where these might come from and wasn't able to pinpoint the exact issue with the debugger.

To Reproduce The code to reproduce the issue can be found here for convenience: https://github.com/JuliDi/plotters-bug-demo including a set of data that triggers the bug.

Details
use plotters::prelude::*;

const PLOT_LINE_COLOR: RGBColor = RGBColor(0, 175, 255);

pub fn main() {

let data = vec![16.813898, 21.467485, 16.699194, 18.656145, 1.8458271, 6.958304, 4.668895, 3.4034894, 11.170396, 22.686535, 20.591629, 8.35795, 18.369057, 13.557362, 24.329618, 17.74448, 39.69061, 28.81381, 39.383015, 25.405262, 20.539597, 14.12167, 32.729282, 17.82943, 25.446245, 21.351706, 12.016595, 17.353453, 12.965088, 9.063063, 14.804887, 3.3717983, 18.540174, 16.883198, 23.810902, 11.066169, 7.347625, 11.817309, 6.2633786, 17.756893, 4.029601, 2.5398593, 10.924131, 24.878021, 28.928385, 12.491558, 11.346132, 9.482814, 16.11943, 16.64973, 10.3768425, 18.920292, 11.828327, 9.192125, 33.367313, 16.697374, 13.507518, 14.694922, 16.67566, 27.475872, 21.03208, 14.162327, 10.873885, 16.531784, 8.103211, 8.684803, 18.726849, 17.095837, 23.579023, 5.048337, 10.975269, 14.428657, 12.765751, 21.9303, 7.9336004, 20.152481, 12.144512, 1.0923405, 15.923292, 15.101516, 28.304052, 18.786118, 11.663957, 11.990492, 12.881969, 7.450888, 18.492188, 24.230925, 23.171167, 11.404102, 19.609896, 4.8243628, 13.179412, 17.68572, 9.867716, 5.25622, 18.082666, 30.46109, 20.762335, 19.089638, 24.995098, 13.9115095, 33.071114, 12.434493, 20.163658, 28.058327, 39.1902, 19.891376, 8.897499, 4.2061777, 21.742756, 7.37039, 17.926682, 11.314838, 19.42905, 15.376271, 20.434095, 11.794729, 16.583397, 21.013033, 31.112232, 15.628697, 28.886744, 27.737251, 21.806887, 5.764174, 7.6569896, 34.653584, 34.28854, 67.45283, 135.27437, 189.08481, 42.77188, 25.337303, 2.5914989, 34.182064, 18.974936, 19.168165, 23.921913, 20.48953, 26.52906, 3.7035255, 22.675589, 7.4574223, 22.76912, 9.460767, 27.8287, 12.066594, 15.412456, 26.818674, 32.694702, 21.808376, 23.520004, 6.5400176, 35.558197, 11.853939, 30.302734, 24.195833, 24.629995, 35.11812, 19.725723, 9.664452, 11.475963, 17.11769, 16.859127, 6.533736, 17.694416, 11.510996, 23.27193, 27.069403, 15.088213, 9.736533, 11.172734, 15.25471, 9.9892235, 15.910875, 25.13705, 17.351255, 13.522468, 2.7220654, 12.812791, 17.815294, 8.057408, 23.95524, 9.931442, 13.47129, 9.590451, 4.1158338, 25.822966, 17.54566, 16.215902, 10.901377, 10.184222, 19.054682, 11.37252, 14.23101, 18.637873, 29.038452, 18.053534, 12.394553, 12.092359, 15.310099, 31.077723, 11.126249, 9.835912, 21.09747, 12.272691, 17.513615, 18.027584, 10.414021, 10.325374, 12.878272, 29.663559, 23.240133, 10.942607, 3.6961594, 5.338874, 19.394537, 7.8832135, 13.525047, 8.452841, 9.082503, 21.842276, 17.172523, 18.812967, 3.000104, 13.053461, 10.148841, 14.264377, 19.06721, 10.129463, 19.937485, 23.757084, 17.275042, 32.77665, 15.181078, 21.922976, 25.597387, 37.654034, 26.974955, 38.232346, 18.491838, 23.584059, 11.730393, 18.376102, 8.435054, 22.3173, 23.999996, 12.698569, 3.2221498, 5.5601172, 8.75537, 1.2027137, 16.975645, 17.858566, 19.673578];

let width = 677u32;
let height = 799u32;

let backend = BitMapBackend::new("test.bmp", (width, height));

let root = backend.into_drawing_area();
root.fill(&WHITE).expect("error filling drawing area");

let data_y_min = data.iter().cloned().reduce(f32::min).unwrap().ceil();
let data_y_max = data.iter().cloned().reduce(f32::max).unwrap().floor();

let (y_min, y_max) = (data_y_min, data_y_max);

let x_min = 0;
let x_max = data.len();

let mut chart = ChartBuilder::on(&root)
    .x_label_area_size(28)
    .y_label_area_size(28)
    .margin(20)
    .build_cartesian_2d(
        (x_min as f64)..(x_max as f64),
        (y_min as f64)..(y_max as f64),
    )
    .expect("failed to build chart");

chart
    .configure_mesh()
    .draw()
    .expect("failed to draw chart mesh");


let area_series = AreaSeries::new(
    data.iter().enumerate().map(|(x, y)| (x as f64, *y as f64)),
    -1.0,
    PLOT_LINE_COLOR.mix(0.175),
)
    .border_style(ShapeStyle::from(PLOT_LINE_COLOR).stroke_width(2));


chart
    .draw_series(area_series)
    .expect("failed to draw chart data");

root.present().expect("error presenting");

println!("done");

}

Version Information Latest master branch, commit af0b63ca2c0ca18780ec9e92730fa97a444dbfca

JuliDi avatar Mar 24 '24 16:03 JuliDi