(
chart: &mut ChartContext<
DB,
Cartesian2d<plotters::coord::types::RangedCoordf64, plotters::coord::types::RangedCoordf64>,
>,
ir: &plotlars_core::ir::trace::BoxPlotIR,
| 386 | /// Draw horizontal boxes: categories on y-axis, values on x-axis. |
| 387 | #[allow(clippy::too_many_arguments)] |
| 388 | fn draw_boxes_horizontal<DB: DrawingBackend>( |
| 389 | chart: &mut ChartContext< |
| 390 | DB, |
| 391 | Cartesian2d<plotters::coord::types::RangedCoordf64, plotters::coord::types::RangedCoordf64>, |
| 392 | >, |
| 393 | ir: &plotlars_core::ir::trace::BoxPlotIR, |
| 394 | trace_idx: usize, |
| 395 | categories: &[String], |
| 396 | n_cats: usize, |
| 397 | n_groups: usize, |
| 398 | slot_width: f64, |
| 399 | box_width: f64, |
| 400 | has_legend: &mut bool, |
| 401 | legend_entries: &mut Vec<LegendEntry>, |
| 402 | ) { |
| 403 | let color = resolve_trace_color(&ir.marker, trace_idx); |
| 404 | let opacity = ir.marker.as_ref().and_then(|m| m.opacity).unwrap_or(1.0); |
| 405 | let fill_style = color.mix(opacity).filled(); |
| 406 | let line_style = ShapeStyle { |
| 407 | color: color.mix(opacity), |
| 408 | filled: false, |
| 409 | stroke_width: 2, |
| 410 | }; |
| 411 | |
| 412 | let labels = extract_strings(&ir.labels); |
| 413 | let values = extract_f64(&ir.values); |
| 414 | |
| 415 | let mut cat_values: Vec<Vec<f64>> = vec![Vec::new(); n_cats]; |
| 416 | for (label, val) in labels.iter().zip(values.iter()) { |
| 417 | if let Some(cat_idx) = categories.iter().position(|c| c == label) { |
| 418 | cat_values[cat_idx].push(*val); |
| 419 | } |
| 420 | } |
| 421 | |
| 422 | let group_offset = if n_groups > 1 { |
| 423 | (trace_idx as f64 - (n_groups as f64 - 1.0) / 2.0) * slot_width |
| 424 | } else { |
| 425 | 0.0 |
| 426 | }; |
| 427 | |
| 428 | for (cat_idx, mut vals) in cat_values.into_iter().enumerate() { |
| 429 | if vals.len() < 2 { |
| 430 | continue; |
| 431 | } |
| 432 | let stats = compute_box_stats(&mut vals); |
| 433 | let c = cat_idx as f64 + group_offset; |
| 434 | let hw = box_width / 2.0 * 0.9; |
| 435 | |
| 436 | chart |
| 437 | .draw_series(std::iter::once(Rectangle::new( |
| 438 | [(stats.q1, c - hw), (stats.q3, c + hw)], |
| 439 | fill_style, |
| 440 | ))) |
| 441 | .unwrap(); |
| 442 | chart |
| 443 | .draw_series(std::iter::once(PathElement::new( |
| 444 | vec![ |
| 445 | (stats.q1, c - hw), |
no test coverage detected