Skip to content

More fims plots joint residuals (depends on #473 being merged first) - #481

Open
ericward-noaa wants to merge 9 commits into
nmfs-ost:mainfrom
ericward-noaa:more-fims-plots-joint-residuals
Open

ericward-noaa wants to merge 9 commits into
nmfs-ost:mainfrom
ericward-noaa:more-fims-plots-joint-residuals

Conversation

@ericward-noaa

@ericward-noaa ericward-noaa commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

What is the feature?

plot_runs_test() does residual plots for each index. The joint residual plot from JABBA (jbplot_residuals(), jbplot_stdresiduals()) and ss3diags (SSplotJABBAres()) does both:

  • It shows all indices’ residuals together, with a smoother through the yearly mean.
  • It summarizes the fit with RMSE, or with SDNR for standardized residuals.
    This PR adds plot_joint_residuals(), which works on any convert_output() output (SS3, BAM, FIMS) and on the package’s example data.

How have you implemented the solution?

  • New exported function plot_joint_residuals()
  • Options: scaled: FALSE plots log residuals with the RMSE. TRUE plots standardized residuals (log residual ÷ SE) with the SDNR
  • Options: overlay: TRUE puts all indices on one panel
  • Options: show_stat: shows or hides the RMSE/SDNR label in the top-right corner
  • Residuals come from index_residuals()
  • Tests:
  • All four example datasets plus converted FIMS output, plain and scaled.
  • The RMSE, SDNR and critical-value formulas.
  • Each display option, the scaling and the missing-SE message.
  • The caption and alt text.

Does the PR impact any other area of the project, maybe another repo?

PR contribution checklist

Thank you for contributing to stockplotr! Please check the boxes below to confirm this pull request (PR) is ready for review. Edit this PR description to add the release indicator and any explanations.

  • I have read and adhered to the contributor guide.
  • I have kept this PR focused on one plot where applicable. For multiple features, I have used separate PRs (stacked PRs are welcome if needed).
  • I have aimed to keep this PR to no more than 750 lines, excluding tests and example data (for example, up to 750 lines for a new function).
  • If I have provided an example dataset, I have explained why the existing sample datasets are not sufficient.
  • I have tested that my changes are compatible with all example outputs in the "data" folder (example_data.rda; pollock.rda; ss3_simple.rda; vermilion_snapper.rda).
  • If I didn't follow the development workflow, I have explained why in this PR.
  • If applicable, I've added the plot to save_all_plots() and updated the associated tests in test-save_all_plots.R.
  • After opening this PR, I have checked that my own tests and spellcheck pass (spelling::spell_check_package()). If other checks fail, I have flagged them for the package maintainers to help diagnose and remedy.
  • I have requested review from one package maintainer (Sam or Sophie).

ericward-noaa and others added 8 commits November 6, 2026 07:12
convert_output() passed FIMS output through unchanged, so `estimate` and
`year` were empty and no stockplotr plot could use it. The new
conout_fims() reshapes `FIMS::get_estimates()` output (or a FIMSFit object,
or an .rds file with either):

- Each data point (index, landings, age and length compositions) is split
  into "*_observed" and "*_predicted" rows, with the observation error and
  negative log-likelihood on the observed row, as for SS
- `estimated` becomes `estimate`, and the new `start_year` argument converts
  FIMS year indices to years; `era` is "time", or "fore" after the last year
  of data.
- fims_var_names.csv maps current FIMS labels (e.g., expected_recruitment,
  numbers_at_age, log_devs) to the standard labels.

Also fixes:
- convert_output() ignored a user-supplied `model` when `file` is an object.
- plot_index() matched every label containing "index" (e.g., index_log_q in
  Rceattle output or index numbers at age in FIMS output); it now plots only
  index_observed and index_predicted.
- plot_index() failed for a single index fleet, because the fleet facet was
  added back after process_data() dropped the column.
these tests were failing, should pass now
Residuals of the fit to each index over time, with three-sigma control
limits and a runs test for non-random residuals (as in ss3diags/JABBA).
Works on convert_output() output for SS3, BAM, and FIMS.
Residuals of all index fits over time, with a loess smoother and a fit
statistic, as in JABBA (jbplot_residuals(), jbplot_stdresiduals()) and
ss3diags (SSplotJABBAres()).

- scaled: log residuals with RMSE, or standardized residuals with SDNR
  and its critical value (Francis 2011)
- overlay: all indices on one panel with yearly boxplots, or one panel
  per index
- show_stat: show or hide the RMSE/SDNR label
- Reuses index_residuals() and the caption helpers from plot_runs_test()
- Tests on all four example datasets and FIMS
@ericward-noaa

Copy link
Copy Markdown
Contributor Author

Ready for review @sbreitbart-NOAA @Schiano-NOAA

@Schiano-NOAA

Copy link
Copy Markdown
Collaborator

Will review this tomorrow!

@ericward-noaa

Copy link
Copy Markdown
Contributor Author

The default call for this produces the plot below

plot_joint_residuals(
     stockplotr::example_data,
     scaled = FALSE,
     overlay = FALSE,
     interactive = FALSE
)
residuals_1

Changing scaled = TRUE rescales them JABBA-style

residuals_2

And changing the overlay puts them on the same facet

residuals_3

@iantaylor-NOAA

Copy link
Copy Markdown
Contributor

@ericward-noaa, thanks for adding these diagnostics. All of these plots are improvements over anything r4ss has ever provided, especially the overlaid residuals which I think will be really useful.

One suggestion: I don't know if this is specific to the code in this PR or throughout stockplotr, but I wonder if we would be better specifying a white background by default rather than transparent. For purposes of the dark mode in github the transparency doesn't work well as shown in the screenshot below, but I don't know if there are use cases where transparency would be beneficial.

image

@Schiano-NOAA

Copy link
Copy Markdown
Collaborator

@iantaylor-NOAA I don't think this is a thing set by stockplotr but either way a user can make this change themself if they want since this is a ggplot. If this issue is persistent and that ends up being a common fix, I think we could make the change in theme_noaa to be permanent.

…more-fims-plots-joint-residuals

This is bringing the runs-test changes into the joint-residuals, and updating the key quantities for the joint-residuals plots

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants