Skip to content

Config labels in every output, independent facet scales, green CI - #3

Merged
degoldschmidt merged 3 commits into
mainfrom
fix/issue-2-config-labels
Aug 20, 2026
Merged

Config labels in every output, independent facet scales, green CI#3
degoldschmidt merged 3 commits into
mainfrom
fix/issue-2-config-labels

Conversation

@degoldschmidt

Copy link
Copy Markdown
Collaborator

Closes #2.

Config labels set in experiment.yaml reached config.used.yaml but not the exported
tables or the figures. The bulk of that was already fixed in a39a78d (on main since
2026-07-29, after the issue was filed against 2778288); this branch finishes the job,
takes care of a readability problem the fix exposed, and gets CI green again.

Name the substrates in the two-choice figure (9fc8fd6)

substrate_comparison() was the last output ignoring the configured labels: its legend
hardcoded left / right, so metadata.substrates never reached it. Each side is now
named after the substrate it holds, falling back to left / right when the experiment
records no labels — or the same label on both sides, where the side is the only thing
telling the two boxes apart.

The same figure ordered conditions alphabetically while every other figure uses the
experiment sequence; it now shares ordered_condition_labels(), which additionally
learns to group by the order column itself so an unlabelled experiment (grouping on the
numeric code) no longer trips over a duplicate column.

Stack facets and scale each to its own data (894dd6c)

Faceted figures shared one y-axis, so a substrate the flies barely touched collapsed onto
the baseline beside one they fed on heavily. Facets now scale independently and stack
top-to-bottom, with the shared condition axis drawn once under the bottom facet.

Two new options restore the old behaviour: plotting.facet_share_y: true for a single
shared scale (magnitudes comparable across facets, at the cost of the smaller one), and
plotting.facet_layout: columns for the side-by-side arrangement.

This exposed a latent bug in the significance brackets, fixed here: the stack was laid
out in axes fractions computed before the y-limit was grown to fit it, so with 5
conditions (10 brackets) it overshot 1.0 — drawing over the facet title — while squashing
the data into the lower third. The layout is now solved in final fractions and the step
compresses into a bounded band, so brackets stay inside the axes and the data always
keeps at least half the height. On independent axes brackets anchor to their own facet's
data rather than the tallest, which would otherwise re-inflate the axis the independent
scaling was meant to keep tight.

Type-check the GUI layer without the gui extra (12135c7)

CI has been red since 2026-07-30, unrelated to the above. It syncs with
uv sync --frozen, which installs the dev group but not the optional gui one, so
every Qt accessor degrades to Any and reading a value back out of a widget trips
warn_return_any. Locally PySide6 is installed, the accessors are typed, and mypy is
silent — which is why this only ever showed up on the runner. The flypad.gui.* override
already exists to make the layer check identically with or without the extra;
warn_return_any was the one setting missing from it.

Verification

End-to-end on the shipped data/sample/20240215 fixture:

uv run flypad run data/sample/20240215 -c configs/example_experiment.yaml -o /tmp/retest \
  --set 'metadata.substrates=["10% yeast", "20mM sucrose"]' \
  --set 'metadata.conditions=["1st condition", "2nd condition"]'

The configured names appear in per_fly / events / per_condition / comparisons
(CSV and Parquet), the box-plot tick labels, the facet titles, the substrate-figure
legend, and the raster and time-course legends.

  • 240 tests pass locally (with the gui extra installed).
  • Reproducing the runner's environment (UV_PROJECT_ENVIRONMENT + uv sync --frozen):
    ruff, ruff format, mypy and pytest all pass — 227 passed, test_gui skipped for the
    absent qtpy.
  • 12 new tests cover the substrate legend and its fallbacks, condition ordering, facet
    layout / independent scaling, the x-axis being captioned once, and the bracket stack
    staying inside the axes.

Docs

docs/configuration.md gains a section on how metadata.conditions / .substrates apply
positionally and which outputs they reach, versus the figure-only
plotting.condition_labels rename, plus a table for the two new faceting options.
CHANGELOG.md gains an [Unreleased] section.

The two-choice substrate plot was the last output still ignoring the
configured labels: its legend hardcoded "left" / "right", so
`metadata.substrates` never reached it. It now names each side after the
substrate that side holds, falling back to left/right when the experiment
records no labels, or the same label on both sides — where the side is the
only thing telling the two boxes apart.

Same figure was also ordering conditions alphabetically while every other
figure uses the experiment sequence; it now shares ordered_condition_labels(),
which additionally learns to group by the order column itself so an unlabelled
experiment (grouping on the numeric code) no longer trips over a duplicate
column.

Documents how metadata.conditions / metadata.substrates apply positionally to
the channel map and flow into every table and figure, versus the plot-only
plotting.condition_labels rename, and records the unreleased changes since
v0.1.0.
Faceted figures shared one y-axis, so a substrate the flies barely touched
collapsed onto the baseline next to one they fed on heavily — the sucrose panel
was unreadable. Facets now scale independently and stack top-to-bottom, with the
shared condition axis drawn once under the bottom facet. plotting.facet_share_y
restores the single shared scale (magnitudes comparable across facets, at the
cost of the smaller one) and plotting.facet_layout: columns the side-by-side
arrangement.

Fixes the significance brackets, which the independent scaling exposed: the
stack was laid out in axes fractions computed *before* the y-limit was grown to
fit it, so with 5 conditions (10 brackets) it overshot 1.0 — drawing over the
facet title — while squashing the data into the lower third. The layout is now
solved in final fractions and the step compresses to a bounded band, so the
brackets stay inside the axes and the data always keeps at least half the
height.

Brackets on independent axes anchor to their own facet's data rather than the
tallest, which would otherwise re-inflate the axis the independent scaling was
meant to keep tight.
CI has been red since 2026-07-30: it syncs with `uv sync --frozen`, which
installs the `dev` group but not the optional `gui` one, so every Qt accessor
degrades to Any and reading a value back out of a widget trips warn_return_any.
Locally PySide6 is installed, the accessors are typed, and mypy is silent —
which is why this only ever showed up on the runner.

The flypad.gui.* override already exists to make the layer check identically
with or without the extra; warn_return_any was the one setting missing from it.

Verified by reproducing the runner's environment (UV_PROJECT_ENVIRONMENT with
`uv sync --frozen`): ruff, ruff format, mypy and pytest all pass there now
(227 passed, test_gui skipped for the absent qtpy).
@degoldschmidt degoldschmidt self-assigned this Aug 20, 2026
@degoldschmidt degoldschmidt added the bug Something isn't working label Aug 20, 2026
@degoldschmidt
degoldschmidt merged commit af3eeb4 into main Aug 20, 2026
4 checks passed
@degoldschmidt
degoldschmidt deleted the fix/issue-2-config-labels branch August 20, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

substrate and condition labels in .yaml are being ignored

1 participant