Paulnewling/visualizations tabs - #6
Conversation
Two graph-maker panels read the existing propertiesPf p-frame and pick modality-aware defaults: peptide charge / hydrophobicity in peptide mode, chain "A" CDR3 charge / hydrophobicity in antibody/TCR mode. Axis pickers list every numeric scalar PColumn emitted by the run; the 2-axis AA fraction column (R7) is excluded. Model: - propertiesPfHandle output uses getRelatedColumns + a self-trace predicate to drop the blockId-stamped exports.properties duplicates. - propertiesPfCols output exposes PColumnIdAndSpec[] for default-axis lookup. - Three sections: Properties / Scatterplot / Histogram. - BlockData migration Ver_2026_05_05 adds graphStateScatter + graphStateHistogram (default light-green bin fill). R21 / R21a reference line at GRAVY = 0 deferred — graph-maker has no path to inject significantLines on a data-column axis today. Documented in docs/spec-deviations.md as SD-009.
Match the standard block convention — main page is labeled 'Main', not the page-content noun.
The previous self-trace predicate filtered every column the workflow emits — trace.inject stamps every output with this block's trace, so the predicate excluded our own pCols too, leaving an empty pframe and breaking the histogram. Skip the result-pool walk entirely. The pickers no longer pull in linker / meta columns from the pool; sample-level grouping is tracked as a follow-up.
Replace createPFrameForGraphs with ctx.createPFrame([...pCols, ...meta]). The pool walk pulled in this block's own exports.properties — a trace-stamped re-emission of every column already in propertiesPf — so the data-mapping picker showed every property twice. Pull single-axis metadata anchored to the input dataset's two axes (sample idx 0, entity idx 1) so sample groups / abundance / patient IDs remain available for grouping, then drop self-trace to keep our own exports out. Same pattern used by cdr3-spectratype, batch-correction, cell-type-annotation, dimensionality-reduction, and lead-selection. Also default the scatterplot to the 'bright' categorical palette.
Two changes that together let the scatterplot stay under graph-maker's 1M-cell guard on real datasets: - model: drop pl7.app/aaFraction from propertiesPfHandle. Two-axis (variantKey × aminoAcid) — ~1M cells alone at 50k peptides. The picker already excludes it via isNumericScalar (axesSpec.length === 1), so the data was pure overhead. - ui: drop the entity-key grouping default on the scatter page. Pre-selecting axesSpec[0] gave every peptide / clonotype its own colour, exploding the palette, legend, and render path on any realistically-sized dataset. Sample-axis and entity-axis meta cols remain available via the picker.
There was a problem hiding this comment.
Code Review
This pull request introduces Scatterplot and Histogram visualizations to the Sequence Properties block, featuring modality-aware defaults for peptide and antibody/TCR data. Key changes include a data model migration to version Ver_2026_05_05 to store graph states, new PFrame and column metadata outputs in the model, and the addition of dedicated UI pages for the charts. Feedback was provided regarding the use of shallow copies for default graph states, which could lead to shared references to nested objects across block instances; using factory functions was suggested as a safer alternative.
| graphStateScatter: { ...DEFAULT_SCATTER_STATE }, | ||
| graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE }, |
There was a problem hiding this comment.
Use the factory functions to initialize the graph states to avoid shared references to nested objects.
| graphStateScatter: { ...DEFAULT_SCATTER_STATE }, | |
| graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE }, | |
| graphStateScatter: createDefaultScatterState(), | |
| graphStateHistogram: createDefaultHistogramState(), |
Summary
Adds Scatterplot and Histogram tabs to Sequence Properties. Two graph-maker panels read the existing
propertiesPfp-frame and pick modality-aware defaults — peptide charge / hydrophobicity in peptide mode; chain "A" CDR3 charge / hydrophobicity in antibody/TCR mode. Sample-axis and entity-axis metadata anchored to the input dataset is pulled in for grouping and filtering, with a self-trace filter that drops this block's ownexports.propertiesre-emission to keep the picker free of duplicates.Notes
Ver_2026_05_05addsgraphStateScatterandgraphStateHistogramtoBlockData. Default state built via factories so nestedlayersSettingsreferences stay per-instance.isNumericScalar.significantLineson a data-column axis today; documented indocs/spec-deviations.mdas SD-009.Spec: milaboratory/text#118