Skip to content

Plot refactor#438

Open
billbrod wants to merge 59 commits into
mainfrom
plot_refactor
Open

Plot refactor#438
billbrod wants to merge 59 commits into
mainfrom
plot_refactor

Conversation

@billbrod
Copy link
Copy Markdown
Member

@billbrod billbrod commented May 20, 2026

Describe the change in this PR at a high-level

Following up from #418, this restructures a lot of the synthesis-specific plotting code. In that PR, I realized that there was a lot of redundancy (e.g., po.plot.mad_pixel_values and po.plot.metamer_pixel_values) were essentially the same function, and that I could make the plotting code either to use by consolidating it. To that end, I have combined many of the synthesis-specific plotting function into single synthesis_{plot} functions (e.g., synthesis_loss) which accept multiple synthesis objects. If the plot cannot accept a given synthesis object (e.g., synthesis_loss cannot accept an Eigendistortion object, because eigendistortions don't have optimization loss), then they raise an informative error message to that effect (and the docstrings/annotations hopefully clarify this). For plotting functions that only operate on a single synthesis object (e.g., metamer_representation_error), they have been kept separate and retain the naming scheme from #418.

Consolidated functions:

  • synthesis_loss: metamer_loss, mad_loss
  • synthesis_histogram: metamer_pixel_values, mad_pixel_values. Adds capability for Eigendistortion and renamed because a histogram is potentially valuable even if the values aren't pixels.
  • synthesis_imshow: metamer_imshow, mad_imshow, eigendistortion_imshow.
  • synthesis_status: metamer_synthesis_status, mad_synthesis_status. Adds capability for Eigendistortion.
  • synthesis_animshow: metamer_animshow, mad_animshow.

Adds:

  • histogram: tensor-level histogram plot used by synthesis_histogram (analogous to how we have an imshow that operates directly on image tensors used by synthesis_imshow)

Remaining functions:

  • metamer_representation_error
  • eigendistortion_imshow_all
  • mad_imshow_all
  • mad_loss_all

For giving feedback on how users will interact with these functions, I think the most informative way to review will be to look at the plotting section of the API guide, and look through the docstrings of each of the functions there.

Link any related issues, discussions, PRs

Follow up from #418, closes #417.

Outstanding questions / particular feedback

  • We generally use batch_idx to refer to the first index in the tensors, as image tensors in pytorch typically are 4d: batch, channel, height, width. For eigendistortions, this has a special meaning: the eigenindex (e.g., eigenindex=0 means the distortion corresponds to the first eigenvector). In the shared functions, I've used batch_idx as the argument name, describing the relationship in the docstring, whereas I've kept it as eigenindex for eigendistortion_imshow_all (also explaining in the docstring). Is this better than being consistent?
  • synthesis_status and synthesis_animshow create single figures by combining the outputs of the axis-level functions (synthesis_loss, synthesis_imshow, etc). I have made it so that users can pass arguments to these functions directly using kwargs (hopefully docstrings are clear on this), so they don't clutter up the function signature. Is that clear right now?
    • The one weird thing here is synthesis_animshow's ylim arg, which controls how we rescale the y-limits of the metamer_representation_error plot. It is only related to that function, but it only makes sense when animating its output. Therefore, I've kept it as an argument for the animshow function. Is this okay? is there a better way to handle it?
  • What is now synthesis_animshow was animate before [BREAKING CHANGE] API restructure, adds lazy loading #418, to try and make it more consistent with the tensor-level functions. However, now I'm not sure of that name -- synthesis_animshow is the animated analogue of synthesis_status, animating that figure over synthesis iteration. But this naming makes it sound like it's the animated analogue of synthesis_imshow (as po.plot.animshow is the animated analogue of po.plot.imshow). So that makes me inclined to change the name -- synthesis_status_animate or somethign seems too long to me. I could go back to synthesis_animate. Any other ideas?
  • I have put versionadded tags in the docstring of each of the consolidated functions above, but the way they are interacted with has changed somewhat. Should I try to explain that more explicitly? Or just rely on people reading the docstrings? (The section in the "Migration Guide" also basically just says "check their docstrings")

Describe changes

  • Consolidated synthesis plotting functions into a small number which work on multiple synthesis objects.
  • Added new tensor-level po.plot.histogram function, used by the po.plot.synthesis_histogram function.
  • Added "New function" table to migration guide, which just consists of po.plot.histogram. Updates section on plotting functions.
  • Added new example synthesis objects to test_uploaded_files / fetch capability: example_mad.pt, example_mad-cuda.pt, example_eigendistortion_color.pt
  • po.plot.imshow and po.plot.animshow raise some more informative error messages around dimensionality/shape.
  • Moved eigendistortion plotting tests from test_eigendistortion into test_display.
  • Added variety of tests for new functionality.
  • Renamed Synthesis, OptimizedSynthesis to _Synthesis, _OptimizedSynthesis since they're private.
  • Updated references to consolidated functions throughout.
  • Restructured the plotting section of the API docs (formally, "Display", now "Plotting functions").
  • in CI, set doctests to continue on failure for more informative errors.

Checklist

Affirm that you have done the following:

  • I have described the changes in this PR, following the template above.
  • I have added any necessary tests.
  • I have added any necessary documentation. This includes docstrings, updates to existing files found in docs/, or (for large changes) adding new files to the docs/ folder.
  • If a public new class or function was added: I have double-checked that it is present in the API docs, adding it to one of the rst files in docs/api/ or adding a new file as necessary.

billbrod added 20 commits May 18, 2026 15:43
for more informative errors
This reverts commit 1f24944.

we're moving this to a separate PR
This reverts commit f576ced.

only reverts the parts about the close figure teardown, not the new
tests. because the teardown is moved to a separate PR
for displaying eigendistortions, since alpha is also used as kwarg for
meaning transparency in other plots, as is more typical for plotting
…lot functions

in particular

 - remove as_rgb arg, since we can infer that (behavior as described in
   docstring didn't work)

 - adds process_distortion arg to be more explicit for that

 - use more internals from synthesis_imshow
more examples there, showing example with RGB(A) and ImageNet models.
also adds new example_eigendistortion_color.pt to registry for use in
this example
to avoid the issue of checking for output in doctest
@billbrod
Copy link
Copy Markdown
Member Author

Documentation built by Jenkins: https://docs.plenoptic.org/docs/pulls/438/index.html

@codecov
Copy link
Copy Markdown

codecov Bot commented May 23, 2026

Codecov Report

❌ Patch coverage is 91.85751% with 32 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/plenoptic/plot/synthesis.py 92.88% 21 Missing ⚠️
src/plenoptic/conftest.py 0.00% 4 Missing ⚠️
src/plenoptic/plot/display.py 92.30% 4 Missing ⚠️
src/plenoptic/plot/eigendistortion.py 88.46% 3 Missing ⚠️
Files with missing lines Coverage Δ
src/plenoptic/_api_change.py 100.00% <100.00%> (ø)
src/plenoptic/_synthesize/eigendistortion.py 98.79% <100.00%> (ø)
src/plenoptic/_synthesize/mad_competition.py 94.84% <100.00%> (ø)
src/plenoptic/_synthesize/metamer.py 97.48% <100.00%> (ø)
src/plenoptic/_synthesize/synthesis.py 92.35% <100.00%> (ø)
src/plenoptic/data/_fetch.py 96.00% <ø> (ø)
src/plenoptic/models/portilla_simoncelli.py 98.17% <ø> (ø)
src/plenoptic/plot/mad_competition.py 84.90% <100.00%> (-3.51%) ⬇️
src/plenoptic/plot/metamer.py 90.47% <ø> (+2.11%) ⬆️
src/plenoptic/plot/eigendistortion.py 92.85% <88.46%> (-5.51%) ⬇️
... and 3 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

Refactor plotting funtions

1 participant