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.89k stars 281 forks source link

[BUG] Boxplot type error when drawing chart #496

Open Pierstoval opened 1 year ago

Pierstoval commented 1 year ago

Hello, rookie Rustacean here.

Using latest Plotters version as of today (0.3.5), I got this kind of code where I want to draw a single boxplot on an existing chart:

let index: i32 = 1; // Fetched from an external source, but it's an i32
let means_vec: Vec<i32> = means.to_vec(); // Fetched from an external source, it's just a Vec<i32> anyway
let quartiles: Quartiles = Quartiles::new(&means_vec);
let boxplot: Boxplot<i32, BoxplotOrientV<i32, f32>> = Boxplot::new_vertical(index, &quartiles);
chart.draw_series(vec![boxplot]).unwrap();

However I encounter this error:

error[E0271]: type mismatch resolving `<BoxplotOrientV<i32, f32> as BoxplotOrient<i32, f32>>::YType == i32`
   --> src/main.rs:381:19
    |
381 |             chart.draw_series(vec![boxplot])
    |                   ^^^^^^^^^^^ expected `i32`, found `f32`
    |
note: required by a bound in `ChartContext::<'a, DB, CT>::draw_series`
   --> /home/pierstoval/.cargo/registry/src/index.crates.io-6f17d22bba15001f/plotters-0.3.5/src/chart/context.rs:126:24
    |
120 |     pub fn draw_series<B, E, R, S>(
    |            ----------- required by a bound in this associated function
...
126 |         for<'b> &'b E: PointCollection<'b, CT::From, B>,
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ChartContext::<'a, DB, CT>::draw_series`

For more information about this error, try `rustc --explain E0271`.
error: could not compile `graphs` (bin "graphs") due to previous error

Turns out Boxplot's default Y-axis implementation requires f32, but my entire graph only uses integers, especially i32 ones.

How can I mitigate this? Is it a type error on the Boxplot side that requires change?

If you want to reproduce:

The actual code is here. Clone the repo, run git checkout 38efc8791068c (it's the actual HEAD but it's to be sure to checkout the proper commit in case I have to work on something else in the meantime).

Then run cargo run --manifest-path=graphs/Cargo.toml -- vps from the root of the repo.

List of commands:

git clone https://github.com/Pierstoval/benchmarks-react-svelte-vue
git checkout 38efc8791068c
cd benchmarks-react-svelte-vue
cargo run --manifest-path=graphs/Cargo.toml -- vps

Should do the trick to reproduce the issue

Pierstoval commented 1 year ago

I managed to fix this by converting the entirety of all my graphs' Y coordinates to f32 instead of i32, but it's really bothersome and I definitely wish there were a solution to allow i32 to be used.

wangjiawen2013 commented 8 months ago

Boxplot support only f32 coordinates. You can see the values of quartiles are converted to f32 by the Quartiles.values() method. Perhaps it's a typo from boxplot developer. https://docs.rs/plotters/latest/src/plotters/data/quartiles.rs.html#3-9 image

f64 is preferred because the quartiles struct is defined on f64:

image