Description
Describe the bug
I'm plotting a simple test plot of the equation y = x^2
.
// Simple chart setup for testing
let root = SVGBackend::new("test.svg", (640, 480)).into_drawing_area();
root.fill(&WHITE).unwrap();
let mut chart = ChartBuilder::on(&root)
.caption("Test Chart", ("sans-serif", 50).into_font())
.x_label_area_size(30)
.y_label_area_size(30)
.margin(5)
.build_cartesian_2d(0..10, 0..10)
.unwrap();
chart.configure_mesh().draw().unwrap();
chart
.draw_series(LineSeries::new(
(0..10).map(|x| (x, x * x)),
&RED,
))
.unwrap();
root.present().expect("Unable to write result to file");
This produces the following plot:
As you can see, the data goes out of range. What I would expect is that either:
- The line crosses outside the chart rectangle.
- The line is clipped off at the boundary
- The code produces an error/panic
However, with the current implementation, the slope of the line is instead adjusted between x=3 and x=4, and for x > 4, it just goes flat against the top boundary. I consider this a severe deformation of the input data.
Sure, in this example I artificially created some data that goes out-of-bounds, but with datasets in the wild, you might accidentally create artifacts in the plot that may lead to incorrect conclusions being drawn.
The root cause is this:
/// Used for 2d coordinate transformations.
pub struct BackendCoordOnly;
impl CoordMapper for BackendCoordOnly {
type Output = BackendCoord;
fn map<CT: CoordTranslate>(coord_trans: &CT, from: &CT::From, rect: &Rect) -> BackendCoord {
rect.truncate(coord_trans.translate(from))
}
}
Unfortunately, the truncation behavior here is a bit naïve, as this also applies to the endpoints of lines.
Version Information
plotters = { version = "0.3.7", default-features = false, features = ["svg_backend", "all_series","colormaps","full_palette","histogram"] }