From e8779852021035fc5758808180e88817b9b410a6 Mon Sep 17 00:00:00 2001 From: Aaron Fenyes Date: Wed, 25 Jun 2025 15:44:42 -0700 Subject: [PATCH] Map diagnostics chart series to log scale by hand This works around problems with the way ECharts does scaling and data zoom for logarithmic axes. --- app-proto/src/diagnostics.rs | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/app-proto/src/diagnostics.rs b/app-proto/src/diagnostics.rs index 0aa46c3..47a9086 100644 --- a/app-proto/src/diagnostics.rs +++ b/app-proto/src/diagnostics.rs @@ -50,8 +50,11 @@ fn RealizationStatus() -> View { } } -fn into_time_point((step, value): (usize, f64)) -> Vec> { - vec![Some(step as f64), Some(value)] +fn into_log10_time_point((step, value): (usize, f64)) -> Vec> { + vec![ + Some(step as f64), + if value == 0.0 { None } else { Some(value.abs().log10()) } + ] } // the loss history from the last realization @@ -69,15 +72,15 @@ fn LossHistory() -> View { .iter() .enumerate() .map(|(step, &loss)| (step, loss)) - .map(into_time_point) + .map(into_log10_time_point) .collect() ); - // initialize the chart axes and series + // initialize the chart axes let step_axis = Axis::new() .type_(AxisType::Category) .boundary_gap(false); - let scaled_loss_axis = Axis::new().type_(AxisType::Log); + let scaled_loss_axis = Axis::new(); // load the chart data. when there's no history, we load the data // point (0, None) to clear the chart. it would feel more natural to @@ -116,9 +119,8 @@ fn SpectrumHistory() -> View { on_mount(move || { create_effect(move || { // get the spectrum of the Hessian at each step, split into its - // positive and negative parts. throw away eigenvalues that are - // close to zero - const ZERO_THRESHOLD: f64 = 1e-6; + // positive and negative parts. exact zero eigenvalues will be + // filtered out by `into_log10_time_point` later let ( hess_eigvals_pos, hess_eigvals_neg @@ -127,22 +129,19 @@ fn SpectrumHistory() -> View { .iter() .enumerate() .map( - |(step, eigvals)| eigvals - .iter() - .filter(|&&val| val.abs() > ZERO_THRESHOLD) - .map( - move |&val| (step, val) - ) + |(step, eigvals)| eigvals.iter().map( + move |&val| (step, val) + ) ) .flatten() .partition(|&(_, val)| val > 0.0) ); - // initialize the chart axes and series + // initialize the chart axes let step_axis = Axis::new() .type_(AxisType::Category) .boundary_gap(false); - let eigval_axis = Axis::new().type_(AxisType::Log); + let eigval_axis = Axis::new(); // load the chart data. when there's no history, we load the data // point (0, None) to clear the chart. it would feel more natural to @@ -154,7 +153,7 @@ fn SpectrumHistory() -> View { if hess_eigvals_pos.len() > 0 { hess_eigvals_pos .into_iter() - .map(into_time_point) + .map(into_log10_time_point) .collect() } else { vec![vec![Some(0.0), None::]] @@ -167,8 +166,7 @@ fn SpectrumHistory() -> View { if hess_eigvals_neg.len() > 0 { hess_eigvals_neg .into_iter() - .map(|(step, val)| (step, -val)) - .map(into_time_point) + .map(into_log10_time_point) .collect() } else { vec![vec![Some(0.0), None::]]