Add scaled circular montage for fair density comparison across sample sizes - #408
Open
animmosmith wants to merge 4 commits into
Open
Add scaled circular montage for fair density comparison across sample sizes#408animmosmith wants to merge 4 commits into
animmosmith wants to merge 4 commits into
Conversation
4 tasks
animmosmith
added a commit
that referenced
this pull request
Jul 31, 2026
5 tasks
animmosmith
changed the base branch from
main
to
405-fix-junge-slope-uninitialized-memory
July 31, 2026 17:00
emlynjdavies
reviewed
Aug 5, 2026
| stats = stats.sort_values(by=["major_axis_length"], ascending=False) | ||
|
|
||
| roifiles = stats["export_name"][stats["export_name"] != "not_exported"].values | ||
| roifiles = roifiles[:max_particles] |
Collaborator
There was a problem hiding this comment.
should we be calling gen_roifiles() here?
… sizes Fixes #407. make_montage() always fills the same fixed rectangular canvas regardless of how much data went into it, making visual density comparisons across datasets with different sample sizes (e.g. depth bins with different numbers of raw images) misleading - every montage looks equally "full." make_montage_scaled() packs particles largest-first within a circular boundary whose area (not radius - area scales with sqrt(rel_scale) as the radius) is controlled by rel_scale. Setting rel_scale proportional to each dataset's relative sample size and placing the resulting montages side by side gives a fair visual comparison: half the raw images means half the circle area to fill. Also outputs grayscale rather than RGB, since particles from monochrome instruments don't need three channels, and it makes montage_plot()'s existing cmap='grey' argument actually take effect. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
animmosmith
force-pushed
the
407-scaled-circular-montage
branch
from
August 5, 2026 10:07
28c6790 to
43d6225
Compare
…d-memory' into 407-scaled-circular-montage
Prompted by Emlyn's review comment questioning the roifiles selection here. Truncating to the max_particles largest particles (or evenly subsampling, as gen_roifiles() does for the older make_montage) both misrepresent the true relative abundance of particle sizes - a scaled montage's whole purpose is a fair visual comparison, so it should reflect the real size distribution, not an artificially selected subset. Every exported particle is now attempted, largest first; particles that can't find a free spot are skipped as before, but now a warning is logged summarising how many were skipped once the montage is complete, since that means msize needs to be increased (not rel_scale, which exists specifically to preserve relative comparisons and would be distorted by nudging it to fit one particular montage).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #407.
`make_montage()` always fills the same fixed rectangular canvas regardless of how much data went into it, which makes visual density comparisons across datasets with different sample sizes (e.g. several depth bins with different numbers of raw images) misleading - every montage looks equally "full" no matter how much data it actually represents.
`make_montage_scaled()` packs particles largest-first within a circular boundary whose area (not radius) is controlled by `rel_scale` - the radius scales with `sqrt(rel_scale)` specifically so that area scales linearly with it. Set `rel_scale` proportional to each dataset's relative sample size (e.g. number of raw images, or total sample volume) against a shared reference, generate one montage per dataset, and place them side by side: a bin with half the raw images of another gets half the circle area to fill, so the packed density becomes a fair, directly comparable visual signal across montages.
A few other differences from `make_montage()`:
Test plan
rel_scale=0.25produces ~25% of the pixel area ofrel_scale=1.0, within ~0.3% of the expected ratio)flake8clean🤖 Generated with Claude Code