RAS2FIM version explainer
Parent model
V1
What does the model look like?
A map…
What are the Rating Curves?


Zoom: 16

Longitudinal model profiles

V2
What does the model look like?
A map…
What are the Rating Curves?



Longitudinal model profiles

Compairing otherwise identical models
Hydraulic models have an incredible number of parameters. Comparing them directly requires harmonizing their outputs across a shared domain.




| Model Comparison Metrics | ||||
| Analysis of WSE Residuals (V2 - V1) across interpolated flow range | ||||
| River Stationing | MAE (ft) | RMSE (ft) | Mean Bias (ft) | Max Absolute Diff (ft) |
|---|---|---|---|---|
| 704 | 0.024 | 0.057 | 0.008 | 0.478 |
| 534 | 0.055 | 0.129 | 0.022 | 0.549 |
| 250 | 0.026 | 0.057 | −0.014 | 0.351 |
| 149 | 0.252 | 0.631 | 0.117 | 2.618 |
| Metrics calculated over the shared discharge domain. | ||||
global_max_width <- max(ras_xs$xid_d, na.rm = TRUE)
y_range <- range(common_q_seq)
ras_xs_mapped <- ras_xs |>
dplyr::left_join(crosswalk, by = "xid") |>
dplyr::filter(Xsection_name_mapped %in% stations_numeric) |>
# CRITICAL FIX: Arrange by station and then relative distance
# to ensure the path is drawn monotonically from one bank to the other.
dplyr::arrange(Xsection_name_mapped, xid_d) |>
dplyr::group_by(Xsection_name_mapped) |>
dplyr::mutate(
y_geom = y_range[1] + (xid_d / global_max_width) * (y_range[2] - y_range[1]),
z_ft = z * 3.28084,
z_stage = z_ft - min(z_ft),
# explicitly map the factor here so Plotly can use it for coloring
XS_Factor = factor(Xsection_name_mapped, levels = ordered_levels)
) |>
dplyr::ungroup()
merged_3d_plot <- plotly::plot_ly() |>
# V1 Surface (Base)
plotly::add_surface(
x = ~stations_numeric, y = ~common_q_seq, z = ~v1_interp_matrix,
name = "Base Model (V1)", opacity = 0.3,
colorscale = list(c(0, 1), c("#2c7bb6", "#2c7bb6")), showscale = FALSE,
legendgroup = "V1", showlegend = TRUE
) |>
# V2 Surface (Update) with Delta Color
plotly::add_surface(
x = ~stations_numeric, y = ~common_q_seq, z = ~v2_interp_matrix,
surfacecolor = ~diff_matrix, name = "Update (V2) Delta",
opacity = 0.8, colorscale = "RdBu", reversescale = TRUE,
colorbar = list(title = "Delta (ft)"),
legendgroup = "V2", showlegend = TRUE
) |>
# Physical Cross-Sections (The "Walls")
plotly::add_paths(
data = ras_xs_mapped,
x = ~Xsection_name_mapped, y = ~y_geom, z = ~z_stage,
split = ~XS_Factor,
color = ~XS_Factor, # Map color to the station factor
colors = global_xs_colors, # Apply the predefined named viridis palette
name = ~paste("XS", Xsection_name_mapped), # Creates clean legend names (e.g., "XS 114")
line = list(width = 4), # Keep width, remove hardcoded color
legendgroup = "XS", # Keeps them grouped for the toggle click
showlegend = TRUE
) |>
plotly::layout(
scene = list(
xaxis = list(title = "Stationing (ft)", autorange = "reversed"),
yaxis = list(title = "Relative Width (ft)"),
zaxis = list(title = "Stage (ft)"),
aspectmode = "manual",
aspectratio = list(x = 1, y = 1, z = 0.5)
),
# This allows you to toggle ALL cross-sections by clicking ANY single XS legend item
legend = list(groupclick = "toggleitem")
)
merged_3d_plot