|
|
@@ -1,20 +1,23 @@
|
|
|
use anyhow::Context;
|
|
|
use charming::{
|
|
|
component::{Axis, Legend, Title},
|
|
|
- element::{AxisType, ItemStyle, Label, LabelPosition, Tooltip, Trigger},
|
|
|
+ datatype::DataPointItem,
|
|
|
+ df,
|
|
|
+ element::{AxisType, ItemStyle, Label, LabelPosition, TextStyle, Tooltip, Trigger},
|
|
|
+ series::{Bar, Line},
|
|
|
Chart,
|
|
|
};
|
|
|
use indexmap::IndexMap;
|
|
|
use log::{info, warn};
|
|
|
use pandora_lib_graph::cytoband::{svg_chromosome, AdditionalRect, RectPosition};
|
|
|
-use plotly::{color::Rgb, common::Marker, layout::BarMode, Bar, Layout, Plot, Scatter};
|
|
|
+// use plotly::{color::Rgb, common::Marker, layout::BarMode, Bar, Layout, Plot, Scatter};
|
|
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
|
|
use serde::{
|
|
|
de::{self, Visitor},
|
|
|
Deserialize, Deserializer, Serialize,
|
|
|
};
|
|
|
use statrs::{
|
|
|
- distribution::{Continuous, Discrete},
|
|
|
+ distribution::{Continuous, Discrete, Normal, Poisson},
|
|
|
statistics::Statistics,
|
|
|
};
|
|
|
use std::{
|
|
|
@@ -263,65 +266,80 @@ impl Counts {
|
|
|
let n_final = data.len();
|
|
|
|
|
|
let frequencies = self.frequencies(contig)?;
|
|
|
- let percentile_99 = self.percentile(contig, 99.0)?;
|
|
|
+ let percentile_99 = self.percentile(contig, 99.0)? + 1;
|
|
|
|
|
|
let mut data_x = Vec::new();
|
|
|
let mut data_y = Vec::new();
|
|
|
+ let mut data_x_chart = Vec::new();
|
|
|
+ let mut data_y_chart = Vec::new();
|
|
|
+ let colors = pandora_lib_graph::theme::Colors::default();
|
|
|
frequencies.iter().for_each(|(x, y)| {
|
|
|
if *x <= percentile_99 as f64 {
|
|
|
data_x.push(*x);
|
|
|
- data_y.push(*y / n_final as f64);
|
|
|
+ data_x_chart.push((*x as u32).to_string());
|
|
|
+ let color = match *x {
|
|
|
+ x if x < 2.0 => colors.get("dark_red"),
|
|
|
+ x if x < 6.0 => colors.get("red"),
|
|
|
+ x if x < 15.0 => colors.get("yellow"),
|
|
|
+ _ => colors.get("green"),
|
|
|
+ }
|
|
|
+ .to_string();
|
|
|
+ let y = *y / n_final as f64;
|
|
|
+ data_y.push(y);
|
|
|
+ data_y_chart.push(DataPointItem::new(y).item_style(ItemStyle::new().color(color)));
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// Distribution plot
|
|
|
let distribution_path = format!("{prefix}_{contig}_distrib.svg");
|
|
|
info!("Saving graph: {distribution_path}");
|
|
|
- let mut plot = Plot::new();
|
|
|
- let colors: Vec<Rgb> = data_x
|
|
|
- .iter()
|
|
|
- .map(|&x| match x {
|
|
|
- x if x < 2.0 => Rgb::new(193, 18, 31),
|
|
|
- x if x < 6.0 => Rgb::new(243, 114, 44),
|
|
|
- x if x < 15.0 => Rgb::new(255, 202, 58),
|
|
|
- _ => Rgb::new(138, 201, 38),
|
|
|
- })
|
|
|
- .collect();
|
|
|
-
|
|
|
- let bars = Bar::new(data_x.clone(), data_y.clone())
|
|
|
- .show_legend(false)
|
|
|
- .marker(Marker::new().color_array(colors));
|
|
|
-
|
|
|
- plot.add_trace(bars);
|
|
|
|
|
|
let sum: f64 = data.iter().sum();
|
|
|
let mean = (&data).mean();
|
|
|
let count = data.len() as f64;
|
|
|
let std_dev = (&data).std_dev();
|
|
|
|
|
|
- // Normal
|
|
|
- let normal = statrs::distribution::Normal::new(mean, std_dev)?;
|
|
|
- let data_y: Vec<f64> = data_x.iter().map(|x| normal.pdf(*x)).collect();
|
|
|
- let trace = Scatter::new(data_x.clone(), data_y).name("Normal");
|
|
|
- plot.add_trace(trace);
|
|
|
-
|
|
|
- // // Gamma
|
|
|
- // let shape = mean * mean / variance;
|
|
|
- // let rate = mean / variance;
|
|
|
+ // Create bar chart
|
|
|
+ let chart = Chart::new()
|
|
|
+ .x_axis(
|
|
|
+ Axis::new()
|
|
|
+ .type_(AxisType::Category)
|
|
|
+ .data(data_x_chart)
|
|
|
+ .name_text_style(TextStyle::new().color(colors.get("dark_blue"))),
|
|
|
+ )
|
|
|
+ .y_axis(
|
|
|
+ Axis::new()
|
|
|
+ .type_(AxisType::Value)
|
|
|
+ .name_text_style(TextStyle::new().color(colors.get("dark_blue"))),
|
|
|
+ )
|
|
|
+ .series(Bar::new().data(data_y_chart));
|
|
|
+
|
|
|
+ // Normal distribution
|
|
|
+ // let normal = Normal::new(mean, std_dev).unwrap();
|
|
|
+ // let normal_y: Vec<f64> = data_x.iter().map(|&x| normal.pdf(x)).collect();
|
|
|
//
|
|
|
- // let gamma = statrs::distribution::Gamma::new(shape, rate).unwrap();
|
|
|
- // let data_y: Vec<f64> = data_x.iter().map(|x| gamma.pdf(*x)).collect();
|
|
|
- // let trace = Scatter::new(data_x.clone(), data_y).name("Gamma");
|
|
|
- // plot.add_trace(trace);
|
|
|
-
|
|
|
- // Poisson
|
|
|
+ // let normal_line = Line::new()
|
|
|
+ // .name("Normal")
|
|
|
+ // .data(normal_y)
|
|
|
+ // .item_style(ItemStyle::new().color("#1E88E5".to_string()));
|
|
|
+ //
|
|
|
+ // let chart = chart.series(normal_line);
|
|
|
+ //
|
|
|
+ // Poisson distribution
|
|
|
let lambda = sum / count;
|
|
|
- let poisson = statrs::distribution::Poisson::new(lambda)?;
|
|
|
- let data_y = data_x.iter().map(|x| poisson.pmf(*x as u64)).collect();
|
|
|
- let trace = Scatter::new(data_x.clone(), data_y).name("Poisson");
|
|
|
- plot.add_trace(trace);
|
|
|
+ let poisson = Poisson::new(lambda).unwrap();
|
|
|
+ let poisson_y: Vec<f64> = data_x.iter().map(|&x| poisson.pmf(x as u64)).collect();
|
|
|
+
|
|
|
+ let poisson_line = Line::new()
|
|
|
+ .name("Poisson")
|
|
|
+ .data(poisson_y)
|
|
|
+ .item_style(ItemStyle::new().color(colors.get("dark_blue")));
|
|
|
|
|
|
- plot.write_image(distribution_path, plotly::ImageFormat::SVG, 800, 600, 1.0);
|
|
|
+ let chart = chart.series(poisson_line);
|
|
|
+
|
|
|
+ // Save chart
|
|
|
+ let mut renderer = charming::ImageRenderer::new(1000, 600);
|
|
|
+ renderer.save(&chart, distribution_path).unwrap();
|
|
|
|
|
|
// Fractions
|
|
|
let mut breaks_values = Vec::new();
|
|
|
@@ -390,8 +408,6 @@ impl Counts {
|
|
|
.collect();
|
|
|
masked.push(("Un masked".to_string(), n_final as f64 / len as f64));
|
|
|
|
|
|
- let colors = pandora_lib_graph::theme::Colors::default();
|
|
|
-
|
|
|
let masked_rec: Vec<AdditionalRect> = ranges_over(&d, 10000, tol)
|
|
|
.iter()
|
|
|
.filter(|(s, e)| e > s)
|
|
|
@@ -514,7 +530,6 @@ impl Counts {
|
|
|
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(
|
|
|
@@ -544,8 +559,13 @@ impl Counts {
|
|
|
.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(),
|
|
|
+ if ( params.value >= 0.01 ) {
|
|
|
+ return params.value.toFixed(2);
|
|
|
+ } else {
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ }"#
|
|
|
+ .into(),
|
|
|
)),
|
|
|
)
|
|
|
.item_style(ItemStyle::new().color(colors[i].clone()));
|
|
|
@@ -558,21 +578,6 @@ impl Counts {
|
|
|
let global_path = format!("{prefix}_global.svg");
|
|
|
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(())
|
|
|
}
|
|
|
|