Skip to content

[BUG] GIF backend sometimes produces incorrect color in the image #672

Open
@apirogov

Description

@apirogov

Describe the bug

I tried everything I could, at this point I guess its some low-level backend implementation error. Sometimes, in certain constellations of plotting setups (certain polygons, certain chart bounds, etc.), I get the wrong color for the vertex circles.

With animated GIFs, the bug appears per-frame (some different polygon on a following frame still can be rendered correctly).

I have more than two sequences where I have this issue popping up, I just picked out two.

I would appreciate any help, right now this is frustrating me so much that I consider looking for a different plotting library, even though except for that I think that plotters is amazing :(

Okay:

Image

Buggy:

Image

Also buggy:

Image

To Reproduce

use plotters::prelude::*;

fn main() {
    let okay: &[(f64, f64)] = &[(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0), (0.0, 0.0)];

    let bug1: &[(f64, f64)] = &[
        (0.0, 0.0),
        (-0.5, -0.8660254037844386),
        (0.3660254037844386, -0.3660254037844386),
        (-0.1339745962155614, 0.5),
        (-1.0, 0.0),
        (0.0, 0.0),
    ];
    let bug2: &[(f64, f64)] = &[
        (0.0, 0.0),
        (0.8660254037844386, -0.5),
        (0.3660254037844386, 0.3660254037844386),
        (-0.5, 0.8660254037844386),
        (-1.0, 0.0),
        (0.0, 0.0),
    ];

    let pts = bug1.to_vec(); // try the other sequences! with bug[1|2]: green vertices, with okay: red (o issue)

    // changing the bounds can make the problem disappear:
    let ((min_x, min_y), (max_x, max_y)) = ((-2.0, -1.86), (1.36, 1.5));
    // let ((min_x, min_y), (max_x, max_y)) = ((-2., -2.), (2., 2.)); // <- with these bounds, no issue

    // with PNG backend this never happened
    let root = BitMapBackend::gif("out.gif", (500, 500), 500)
        .unwrap()
        .into_drawing_area();

    let _ = root.fill(&WHITE);

    let mut cb = ChartBuilder::on(&root);
    let mut chart = cb.build_cartesian_2d(min_x..max_x, min_y..max_y).unwrap();

    // removing either the fill or the border rendering makes the bug disappear:

    // fill area
    let poly = Polygon::new(pts.clone(), &YELLOW.mix(1.0));
    let _ = chart.plotting_area().draw(&poly).unwrap();
    // draw border
    let path = PathElement::new(pts.clone(), &BLACK.mix(1.0));
    let _ = chart.plotting_area().draw(&path).unwrap();

    // vertex marker circles (sometimes rendered in ugly green instead of red)
    let node_func = |c: (f64, f64), s: i32, st: ShapeStyle| {
        EmptyElement::at(c) + Circle::<(i32, i32), i32>::new((0.into(), 0.into()), s.into(), st)
    };
    let nodes = PointSeries::of_element(pts.clone(), 10, RED.mix(1.0).filled(), &node_func);
    chart.draw_series(nodes).unwrap();

    root.present().unwrap();
}

Version Information
plotters 0.3.7

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions