|
|
@@ -1,4 +1,9 @@
|
|
|
use anyhow::Context;
|
|
|
+use charming::{
|
|
|
+ component::{Axis, Legend, Title},
|
|
|
+ element::{AxisType, ItemStyle, Label, LabelPosition, Tooltip, Trigger},
|
|
|
+ Chart,
|
|
|
+};
|
|
|
use indexmap::IndexMap;
|
|
|
use log::{info, warn};
|
|
|
use pandora_lib_graph::cytoband::{svg_chromosome, AdditionalRect, RectPosition};
|
|
|
@@ -385,43 +390,56 @@ impl Counts {
|
|
|
.collect();
|
|
|
masked.push(("Un masked".to_string(), n_final as f64 / len as f64));
|
|
|
|
|
|
- let under_6_rects: Vec<AdditionalRect> = ranges_under(&d, 5, tol)
|
|
|
+ let colors = pandora_lib_graph::theme::Colors::default();
|
|
|
+
|
|
|
+ let masked_rec: Vec<AdditionalRect> = ranges_over(&d, 10000, tol)
|
|
|
+ .iter()
|
|
|
+ .filter(|(s, e)| e > s)
|
|
|
+ .map(|(start, end)| AdditionalRect {
|
|
|
+ start: *start as u32 * 1000,
|
|
|
+ end: *end as u32 * 1000,
|
|
|
+ color: String::from("grey"),
|
|
|
+ position: RectPosition::Below(0),
|
|
|
+ })
|
|
|
+ .collect();
|
|
|
+
|
|
|
+ let under_6_rects: Vec<AdditionalRect> = ranges_under(&d, 6, tol)
|
|
|
.iter()
|
|
|
.filter(|(s, e)| e > s)
|
|
|
.map(|(start, end)| AdditionalRect {
|
|
|
start: *start as u32 * 1000,
|
|
|
end: *end as u32 * 1000,
|
|
|
- color: String::from("red"),
|
|
|
+ color: colors.get("red"),
|
|
|
position: RectPosition::Below(1),
|
|
|
})
|
|
|
.collect();
|
|
|
|
|
|
- let over_6_rects: Vec<AdditionalRect> = ranges_between(&d, 6, 9999, tol)
|
|
|
+ let between_6_15_rects: Vec<AdditionalRect> = ranges_between(&d, 6, 15, tol)
|
|
|
.iter()
|
|
|
.filter(|(s, e)| e > s)
|
|
|
.map(|(start, end)| AdditionalRect {
|
|
|
start: *start as u32 * 1000,
|
|
|
end: *end as u32 * 1000,
|
|
|
- color: String::from("green"),
|
|
|
+ color: colors.get("yellow"),
|
|
|
position: RectPosition::Below(2),
|
|
|
})
|
|
|
.collect();
|
|
|
|
|
|
- let masked_rec: Vec<AdditionalRect> = ranges_over(&d, 10000, tol)
|
|
|
+ let over_15_rects: Vec<AdditionalRect> = ranges_between(&d, 15, 9999, tol)
|
|
|
.iter()
|
|
|
.filter(|(s, e)| e > s)
|
|
|
.map(|(start, end)| AdditionalRect {
|
|
|
start: *start as u32 * 1000,
|
|
|
end: *end as u32 * 1000,
|
|
|
- color: String::from("grey"),
|
|
|
- position: RectPosition::Below(0),
|
|
|
+ color: colors.get("green"),
|
|
|
+ position: RectPosition::Below(3),
|
|
|
})
|
|
|
.collect();
|
|
|
|
|
|
let mut all = Vec::new();
|
|
|
all.extend(under_6_rects);
|
|
|
- all.extend(over_6_rects);
|
|
|
- // all.extend(over15);
|
|
|
+ all.extend(between_6_15_rects);
|
|
|
+ all.extend(over_15_rects);
|
|
|
all.extend(masked_rec);
|
|
|
|
|
|
svg_chromosome(
|
|
|
@@ -482,8 +500,6 @@ impl Counts {
|
|
|
stats.push(stat);
|
|
|
}
|
|
|
|
|
|
- let mut plot = Plot::new();
|
|
|
- let layout = Layout::new().bar_mode(BarMode::Stack);
|
|
|
let colors = pandora_lib_graph::theme::Colors::default();
|
|
|
|
|
|
let colors = [
|
|
|
@@ -496,20 +512,66 @@ impl Counts {
|
|
|
|
|
|
let mut contigs_rev = contigs.clone();
|
|
|
contigs_rev.reverse();
|
|
|
+ // Create series for each proportion
|
|
|
+ let mut chart = Chart::new()
|
|
|
+ // .title(Title::new().text("Stacked Bar Chart"))
|
|
|
+ .tooltip(Tooltip::new().trigger(Trigger::Axis))
|
|
|
+ .legend(Legend::new())
|
|
|
+ .x_axis(Axis::new().type_(AxisType::Value).max(
|
|
|
+ charming::datatype::CompositeValue::Number(
|
|
|
+ charming::datatype::NumericValue::Float(1.0),
|
|
|
+ ),
|
|
|
+ ))
|
|
|
+ .y_axis(
|
|
|
+ Axis::new()
|
|
|
+ .type_(AxisType::Category)
|
|
|
+ .data(contigs_rev)
|
|
|
+ .inverse(false),
|
|
|
+ );
|
|
|
+
|
|
|
for (i, (k, v)) in proportions.iter().enumerate() {
|
|
|
let mut v = v.to_vec();
|
|
|
v.reverse();
|
|
|
- plot.add_trace(
|
|
|
- Bar::new(v, contigs_rev.clone())
|
|
|
- // Bar::new(contigs.clone(), v.to_vec())
|
|
|
- .orientation(plotly::common::Orientation::Horizontal)
|
|
|
- .name(k)
|
|
|
- .marker(Marker::new().color(colors[i].to_string())),
|
|
|
- );
|
|
|
+
|
|
|
+ let bar = charming::series::Bar::new()
|
|
|
+ .name(k)
|
|
|
+ .data(v)
|
|
|
+ .stack("total")
|
|
|
+ .label(
|
|
|
+ Label::new()
|
|
|
+ .show(true)
|
|
|
+ .position(LabelPosition::Inside)
|
|
|
+ .font_size(8)
|
|
|
+ .formatter(charming::element::formatter::Formatter::Function(
|
|
|
+ r#"function(params) {
|
|
|
+ if ( params.value >= 0.01 ) { return params.value.toFixed(2);
|
|
|
+ } else { return "" }}"#.into(),
|
|
|
+ )),
|
|
|
+ )
|
|
|
+ .item_style(ItemStyle::new().color(colors[i].clone()));
|
|
|
+
|
|
|
+ chart = chart.series(charming::series::Series::Bar(bar));
|
|
|
}
|
|
|
- plot.set_layout(layout);
|
|
|
+
|
|
|
+ // Save the chart as SVG
|
|
|
+ let mut renderer = charming::ImageRenderer::new(1000, 600);
|
|
|
let global_path = format!("{prefix}_global.svg");
|
|
|
- plot.write_image(global_path, plotly::ImageFormat::SVG, 1000, 600, 1.0);
|
|
|
+ renderer.save(&chart, global_path).unwrap();
|
|
|
+
|
|
|
+ // for (i, (k, v)) in proportions.iter().enumerate() {
|
|
|
+ // let mut v = v.to_vec();
|
|
|
+ // v.reverse();
|
|
|
+ // plot.add_trace(
|
|
|
+ // Bar::new(v, contigs_rev.clone())
|
|
|
+ // // Bar::new(contigs.clone(), v.to_vec())
|
|
|
+ // .orientation(plotly::common::Orientation::Horizontal)
|
|
|
+ // .name(k)
|
|
|
+ // .marker(Marker::new().color(colors[i].to_string())),
|
|
|
+ // );
|
|
|
+ // }
|
|
|
+ // plot.set_layout(layout);
|
|
|
+ //
|
|
|
+ // plot.write_image(global_path, plotly::ImageFormat::SVG, 1000, 600, 1.0);
|
|
|
|
|
|
Ok(())
|
|
|
}
|
|
|
@@ -579,7 +641,7 @@ pub fn generate_range(start: f64, end: f64, steps: usize) -> Vec<f64> {
|
|
|
use rayon::prelude::*;
|
|
|
|
|
|
pub fn ranges_under(vec: &[u32], x: u32, tolerance: usize) -> Vec<(usize, usize)> {
|
|
|
- get_ranges_parallel(vec, x, tolerance, |val, threshold| val <= threshold)
|
|
|
+ get_ranges_parallel(vec, x, tolerance, |val, threshold| val < threshold)
|
|
|
}
|
|
|
|
|
|
pub fn ranges_over(vec: &[u32], x: u32, tolerance: usize) -> Vec<(usize, usize)> {
|
|
|
@@ -593,7 +655,7 @@ pub fn ranges_between(
|
|
|
tolerance: usize,
|
|
|
) -> Vec<(usize, usize)> {
|
|
|
get_ranges_parallel(vec, (lower, upper), tolerance, |val, (l, u)| {
|
|
|
- val >= l && val <= u
|
|
|
+ val >= l && val < u
|
|
|
})
|
|
|
}
|
|
|
|