Handle mixed CDR3 lengths in logoplots#692
Conversation
Automatically split CDR3 sequences by length in pl.logoplot_cdr3_motif and generate one logo subplot per length. Preserve single-logo behavior for equal-length inputs, and raise a clear error when mixed lengths are provided with a single pre-defined axis. Add regression tests covering mixed-length return behavior and single-axis error handling. Validated with full test suite: 983 passed, 2 deselected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes scirpy issue #691 by enabling pl.logoplot_cdr3_motif to handle mixed CDR3 sequence lengths: it now splits sequences by length and renders one logo plot per detected length instead of failing.
Changes:
- Group CDR3 sequences by length and generate one logo plot per length when mixed lengths are present.
- Preserve existing single-length behavior (returning a single
logomaker.Logo) and returnlist[logomaker.Logo]only for mixed lengths. - Add tests for mixed-length behavior and for the error raised when a single user-supplied
axis provided with mixed lengths.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/scirpy/pl/_logoplots.py |
Implements length-splitting logic, multi-subplot rendering, updated return type, and a clearer error for ax misuse. |
src/scirpy/tests/test_plotting.py |
Adds regression tests covering mixed-length return type and the single-ax error path. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| sequences_by_length: dict[int, list[str]] = {} | ||
| for sequence in sequence_list: | ||
| sequences_by_length.setdefault(len(sequence), []).append(sequence) | ||
| n_lengths = len(sequences_by_length) |
There was a problem hiding this comment.
sequence_list can be empty (e.g., when the selected chains/cdr3_col are all missing after subsetting). In that case n_lengths becomes 0 and the function falls through to plt.subplots(n_lengths, ...), which will raise a low-level Matplotlib error (nrows must be > 0). Add an explicit check for no sequences and raise a clear ValueError (e.g., "No CDR3 sequences found for the selected chains/column").
| n_lengths = len(sequences_by_length) | |
| n_lengths = len(sequences_by_length) | |
| if n_lengths == 0: | |
| raise ValueError("No CDR3 sequences found for the selected chains/column") |
| Parameters passed to the :func:`matplotlib.pyplot.figure` call | ||
| if no `ax` is specified. |
There was a problem hiding this comment.
The docstring says fig_kws is passed to matplotlib.pyplot.figure, but this function uses _init_ax(fig_kws) / plt.subplots(..., **fig_kws) (and _init_ax itself wraps plt.subplots). Please update the parameter description to match the actual call site (i.e. plt.subplots/figure creation kwargs) so users know which keys are supported.
| Parameters passed to the :func:`matplotlib.pyplot.figure` call | |
| if no `ax` is specified. | |
| Parameters passed to the axes/figure creation call via | |
| :func:`matplotlib.pyplot.subplots` if no `ax` is specified. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #692 +/- ##
==========================================
- Coverage 19.30% 19.18% -0.13%
==========================================
Files 51 51
Lines 4636 4655 +19
==========================================
- Hits 895 893 -2
- Misses 3741 3762 +21
🚀 New features to boost your workflow:
|
Summary
Fixes #691.
pl.logoplot_cdr3_motifnow handles mixed CDR3 sequence lengths by automatically creating one logo subplot per detected length.Changes
alignment_to_matrix.logomaker.Logo).list[logomaker.Logo].ValueErrorwhen mixed lengths are provided with a single user-suppliedax.Validation
pytest -q src/scirpy/tests/test_plotting.py -k logoplotpytest -q(983 passed, 2 deselected)