Skip to content

Conversation

abelaba
Copy link
Collaborator

@abelaba abelaba commented Aug 7, 2025

This PR refactors the plotting functions by improving code modularity for the pairplot and marginal_pairplot functions and provides typed configuration using dataclasses. The changes include:

  • Adds new dataclasses KdeDiagOptions, HistDiagOptions, ScatterDiagOptions passed to pairplot and marginal_pairplot functions, for customizing the diagonal plotting regions which are passed to the diag_kwargs argument.
  • Adds new dataclasses KdeOffDiagOptions, HistOffDiagOptions, ScatterOffDiagOptions, ContourOffDiagOptions, PlotOffDiagKwargs passed to the pairplot function, for customizing the upper and lower plotting regions, which are passed to the upper_kwargs and lower_kwargs arguments.
  • Adds a new dataclass FigOptions passed to pairplot and marginal_pairplot functions, for customizing the figure which is passed to the fig_kwargs argument.
  • Moves helper functions to a separate file sbi/utils/plotting_helpers.py
  • Modularizes repeated logic in pairplot and marginal_pairplot functions.
  • Maintains backward compatibility with the previous dictionary-based configuration.
  • Update the plotting tutorial to use the newly added dataclasses, docs/advanced_tutorials/17_plotting_functionality.ipynb.

This pull request builds upon the idea by @danielmk in PR #1529.

Copy link

codecov bot commented Aug 7, 2025

Codecov Report

❌ Patch coverage is 87.25869% with 33 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@ebb8c6f). Learn more about missing BASE report.
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
sbi/analysis/plotting_classes.py 90.44% 13 Missing ⚠️
sbi/analysis/plot.py 82.25% 11 Missing ⚠️
sbi/utils/plotting_helpers.py 85.24% 9 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1631   +/-   ##
=======================================
  Coverage        ?   82.70%           
=======================================
  Files           ?      136           
  Lines           ?    11256           
  Branches        ?        0           
=======================================
  Hits            ?     9309           
  Misses          ?     1947           
  Partials        ?        0           
Flag Coverage Δ
unittests 82.70% <87.25%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
sbi/utils/plotting_helpers.py 85.24% <85.24%> (ø)
sbi/analysis/plot.py 68.51% <82.25%> (ø)
sbi/analysis/plotting_classes.py 90.44% <90.44%> (ø)

elif isinstance(fig_kwargs, FigKwargs):
fig_kwargs = asdict(fig_kwargs)
else:
fig_kwargs = update(asdict(FigKwargs()), fig_kwargs)
Copy link
Collaborator

@janosg janosg Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has almost no guarantee that valid kwargs come out.

asdict(replace(FigKwargs(), **fig_kwargs))

Would mean that the options from the user passed kwargs correspond to a field in FigKwargs and I think it would also run the any init or post init method that might do additional validation

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even easier: asdict(FigKwargs(**fig_kwargs))

the number of samples when a legend is specified.

Returns:
A dictionary of fully resolved figure-level keyword arguments.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you choose to convert all possible ways of specifying kwargs to a dict; Why not convert everything to a Dataclass and then convert it to a dict in the last possible moment?



@dataclass(frozen=True)
class DiagKwargs:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer the name DiagOptions; Kwargs sounds like a dictionary.

Comment on lines 128 to 129
class TitleFormat:
fontsize: int = 16
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure all the options you have here need to be exposed in sbi? Matplotlib figures are mutable so many things can be changed after the figure is returned to the user. As long as data is plotted correctly and with the right color, most other things (e.g. titles) can be changed afterwards.

@abelaba abelaba changed the title Pairplot refactoring Refactor Plotting functions Sep 1, 2025
@danielmk danielmk mentioned this pull request Sep 8, 2025
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.

2 participants