Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .issueflows/03-solved-issues/issue186_original.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# #186 — y ranges not working for cycle summary grouped with spread

Labels: `yolo`
URL: https://github.com/cellpy/cellpy-simple-gui/issues/186

y range not working when we are using Group avg and Spread. Fix it.

(Screenshot in the issue: Cycle summary with Group avg + Spread on, per-panel
Y ranges filled in, panels still autoscaled.)
39 changes: 39 additions & 0 deletions .issueflows/03-solved-issues/issue186_plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Plan — #186 y ranges ignored with Group avg + Spread

## Goal

Per-panel **Y ranges** on the Cycle summary must apply when **Group avg** and
**Spread** are both on, exactly as they do for the plain and group-avg paths.

## Root cause (reproduced with two demo cells in one group)

`collect.figure_json` runs, in order: `collection.plot(spread=True)` →
`_add_spread_hover(fig)` → `_restyle` → `_apply_y_ranges(fig, y_ranges)`.

`_apply_y_ranges` finds the facet axis for a summary column id by reading
`variable=<id>` out of each trace's hovertemplate (`_variable_axis_map`).
cellpy's `spread_plot` does write `variable=charge_capacity_gravimetric` there,
but `_add_spread_hover` (#40) rewrites the mean trace's hovertemplate to
`variable=<pretty axis title>` *before* the ranges are applied — so the column
id no longer appears anywhere, the map misses, cellpy's pretty-title fallback
does not match the app's unit-bearing titles either, and every range is dropped
with a "did not match a summary facet axis" warning.

## Approach

- Resolve the `variable → (xaxis, yaxis)` map right after `collection.plot`,
before any hover rewrite, and hand it to `_apply_y_ranges` (new optional
`var_to_axes` argument; it still builds its own map when not given, so the
other callers are unchanged).
- Keep the human-readable hover from #40 as it is.

## Files to touch

- `src/cellpy_simple_gui/core/collect.py` — `figure_json`, `_apply_y_ranges`.
- `tests/test_core.py` — regression test: group-avg + spread + `y_ranges`
pins the matching axes (both ends, and one-sided).

## Test strategy

- New core test fails before the change (axes autoranged) and passes after.
- Full `uv run pytest` green; essential CI check green on the PR.
26 changes: 26 additions & 0 deletions .issueflows/03-solved-issues/issue186_status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Status — #186 y ranges ignored with Group avg + Spread

- [x] Done

Branch: `cursor/186-y-ranges-group-avg-spread-713a` (off `main` @ `8379324`).

## What's done

- Reproduced with two demo cells in one group: with `spread=True` every
`y_ranges` entry was dropped (`range=None`) while the same spec without
spread pinned the axes.
- Root cause: `_add_spread_hover` (#40) rewrites the mean traces'
`variable=<column id>` hover into the pretty axis title *before*
`_apply_y_ranges` looks the column id up, so no facet axis ever matched.
- Fix (`core/collect.py`): `figure_json` resolves the `variable → axes` map
straight after `collection.plot` and hands it to `_apply_y_ranges`
(new keyword `var_to_axes`; other callers unchanged).
- Tests (`tests/test_core.py`): `test_summary_figure_y_ranges_apply_with_group_avg_and_spread`
(two ranges pinned, third panel still autoranged, spread bands present) and
`test_summary_figure_y_ranges_one_sided_with_spread`. Both fail before the
fix and pass after; full `uv run pytest` green.
- `graphify update .` run (tracked graph artifacts refreshed).

## Remaining work

- None.
145 changes: 76 additions & 69 deletions graphify-out/.graphify_labels.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,65 @@
"3": "collect.py",
"4": "ss",
"5": "i",
"6": "I",
"6": ".get",
"7": "test_compare.py",
"8": "$",
"9": "SummaryPlotSpec",
"10": "select_ica_direction",
"10": "export_bytes",
"11": "vn",
"12": "test_api.py",
"13": "wo",
"14": "Uc",
"15": "e",
"16": "get_settings",
"17": "CellRecord",
"16": "test_remote_find.py",
"17": "apply_physical_meta",
"18": "ir",
"19": "issue-flow — issue comments triage",
"20": ".remove",
"20": ".add",
"21": "na",
"22": ".constructor",
"23": "test_projects.py",
"22": "wt",
"23": "get_settings",
"24": "oa",
"25": "eu",
"25": "tu",
"26": ".push",
"27": "issue-flow — issue plan (`/iflow-plan`)",
"28": "core/uploads.py",
"28": "core/__init__.py",
"29": "xi",
"30": "core/export.py",
"30": "routers/export.py",
"31": "issue-flow — issue close (`/iflow-close`)",
"32": "Cursor issue workflow (Agent Skills)",
"33": "he",
"34": ".populate",
"33": "load_raw",
"34": ".createVertexBuffer",
"35": "cellpy_config.py",
"36": "test_paths.py",
"37": ".resume",
"38": "hn",
"39": "app_main_module",
"38": ".getRenderableIds",
"39": "_apply_y_ranges",
"40": "Dt",
"41": "Plan — Issue #168: Create installer using CI",
"42": "Instructions",
"43": "issue-flow — history update",
"44": "Job",
"45": ".get",
"45": ".placeLayerBucketPart",
"46": "resize",
"47": "cellpy pain-points & wishlist (from building cellpy-simple-gui)",
"48": "pathlib",
"49": "hi",
"49": ".constructor",
"50": "Instructions",
"51": ".reset",
"52": "3. Plotting a collection",
"52": "plots.py",
"53": "issue-flow — create a normal issue (`/iflow-issue`)",
"54": "issue-flow — version bump",
"55": "fa",
"56": "pytest",
"57": "test_agent_docs.py",
"56": "test_journal.py",
"57": "I",
"58": ".renderLayer",
"59": "The tools",
"60": ".parse",
"61": "json",
"61": "loaded_library",
"62": "Original issue text",
"63": "yr",
"64": "or",
"63": "ti",
"64": ".max_files",
"65": "core/projects.py",
"66": ".evaluate",
"67": "system.py",
Expand All @@ -78,18 +78,18 @@
"76": "ah",
"77": "da",
"78": "Issue #136 — Plan: redesign the loading surface (files, projects, journals, raw import)",
"79": "layout",
"80": "finish",
"79": "instrument_meta_schema",
"80": "_render",
"81": "issue-flow — epic planning (`/iflow-epic`)",
"82": "gh",
"83": "expand_paths",
"84": "cellpy API surface",
"85": "ii",
"86": "issue-flow — issue yolo (`/iflow-yolo`)",
"87": "test_api_reference.py",
"87": "find_remote_files",
"88": "Plan — Issue #3: Manage cells in an expanded editor",
"89": "ju",
"90": "Issue #32: Plot appearance options: color scheme and figure theme",
"89": ".render",
"90": "test_uploads.py",
"91": "Original issue text",
"92": "Issue #60 status",
"93": "Be token greedy - as a caveman",
Expand All @@ -100,18 +100,18 @@
"98": "issue-flow — issue build (`/iflow-build`)",
"99": "Issue #67: Cell explorer dQ/dV: Charge/Discharge direction has no effect (and joins half-cycles)",
"100": "fo",
"101": "_ids",
"102": "dr",
"101": "test_gui_playwright.py",
"102": "Plan — Issue #38: cellpy label builders for axis titles",
"103": "test_core.py",
"104": "cellpy_adapter.py",
"105": "CyclesPlotSpec",
"106": "ln",
"107": "plotting.py",
"108": "o",
"106": "rh",
"107": "CellRecord",
"108": "ro",
"109": "Issue #36: Chart card stays white under dark figure theme; default figure theme to Match app",
"110": "_default_visible_hints",
"111": "Issue #39: Group-avg merge puts singleton CE traces on the wrong summary facet",
"112": ".getSouthEast",
"112": "qi",
"113": "Issue #3: Make the Cells list workable for many cells (modal or expanded editor)",
"114": "test_mcp_prototype.py",
"115": "gen_llms_txt.py",
Expand All @@ -132,7 +132,7 @@
"130": "wn",
"131": "Deploying cellpy simple GUI as a server",
"132": "Issue #48: create gui tests",
"133": "vr",
"133": ".draw",
"134": "Plan: Issue #13 — add workflows",
"135": "Ei",
"136": "Issue #55: need to add collector plot for cycles",
Expand All @@ -147,16 +147,16 @@
"145": "test_loader_availability.py",
"146": "Issue #56: add single cell dqdv plot",
"147": "issue-flow — graph rebuild (`/iflow-graphify`)",
"148": "sr",
"148": "di",
"149": "Issue #63: Iterative fixes: plot bottom clipping",
"150": "Issue #27: Iterative fixes: group average checkbox",
"151": "Issue #31: Iterative fixes: export download location",
"152": "Issue #63 status",
"153": "The prompts",
"153": "cellpy MCP server (prototype)",
"154": "`00-tools/` — shared helper tools",
"155": "playwright-gui-tests.md",
"156": "Cycle status",
"157": "bi",
"157": "mcp/server.py",
"158": "Issue #15: update readme",
"159": "mt",
"160": "oi",
Expand All @@ -168,7 +168,7 @@
"166": "entry.py",
"167": "Issue #50 — Status",
"168": "smoke_test.py",
"169": "issue-flow — review and label issues (`/iflow-review`)",
"169": "eu",
"170": "Issue #58 status",
"171": "Issue #5 status",
"172": "6. Process state and threading",
Expand All @@ -191,9 +191,9 @@
"189": "Issue #28: add ability to export cellpy cell",
"190": "_without_webview",
"191": "Status — Issue #36",
"192": "5. Configuration",
"192": "instruments",
"193": "Status — Issue #39",
"194": "We",
"194": ".outputDefined",
"195": "Issue #47: Iterative fixes: share-y-scale",
"196": "Issue #50: Iterative fixes: journal-load-logging",
"197": "Issue #54: add widgets for setting individual y-axis ranges.",
Expand All @@ -202,18 +202,18 @@
"200": "run",
"201": "cellpy-simple-gui",
"202": "m",
"203": "gr",
"204": "steps",
"203": "m",
"204": "drive",
"205": "README.md",
"206": "Kt",
"207": "get",
"207": "gr",
"208": "Exception",
"209": "gn",
"209": "getImageData",
"210": "ft",
"211": "k",
"212": "test_smoke_test_skips_only_a_missing_reader",
"211": ".load",
"212": "ps",
"213": "Hl",
"214": "prototype",
"214": ".restore_cell",
"215": "Instructions",
"216": "starter/app.py",
"217": "Continuous Windows installer from `main`",
Expand All @@ -223,62 +223,69 @@
"221": "_restyle",
"222": "cellpy-simple-gui",
"223": ".fire",
"224": "Plan: Issue #12 — add logging",
"224": "Plan — Issue #177: GUI color scheme and layout",
"225": "collect",
"226": "test_a_default_direction_plot_says_it_drew_less",
"226": "load_journal_cells",
"227": "qa",
"228": "issue-flow — harness init (`/iflow-init`)",
"229": "Releasing",
"230": "bt",
"231": "Guides: what belongs upstream in cellpy",
"232": "test_index_click_and_show_targets_exist",
"233": "test_describe_api_follows_the_reference_the_docstring_points_at",
"234": "_dva_spec",
"233": "Ki",
"234": "pl",
"235": "1. Getting cells into memory",
"236": "_warnings",
"237": "_load_entry",
"238": "cycle_numbers",
"239": "_wait_for_job",
"240": "fixture",
"236": ".cancel",
"237": "test_index_alpine_state_is_defined",
"238": "Issue #28 plan — Export cells from Manage cells",
"239": "Next phase — deployment routes and app-builder documentation",
"240": "uu",
"241": "Ic",
"242": "Issue #31 status — Iterative fixes: export download location",
"243": ".upload",
"243": ".emplaceBack",
"244": "En",
"245": "test_paths_outside_the_sandbox_are_refused",
"246": "Issue #175: missing or bad cycles not reported",
"246": "kn",
"247": "Issue #169: Compare selected cells",
"248": "skills/README.md",
"249": "test_startup_survives_an_unreadable_cellpy_config",
"250": "test_stderr_usable_rejects_a_broken_handle",
"249": "._forEachCell",
"250": "Zi",
"251": "issue-flow — PR queue sync (`/iflow-pr-sync`)",
"252": "4. Exporting data and figures",
"253": "test_dva_missing_cell_is_404_not_403",
"253": "Issue #41: Arbin SQL HDF5 import uses cellpy `.h5` loader instead of `arbin_sql_h5`",
"254": "Issue #81: Keep CE summary panel order consistent (prefer CE on top)",
"255": "Xe",
"256": "test_files_preview_honours_served_sandbox",
"256": "qr",
"257": "_t",
"258": "test_local_instance_keeps_its_freedom",
"259": "test_webview_file_type_filters_are_valid",
"260": "test_restrict_to_cycle_pairs_on_cycles_frame",
"261": "test_restrict_to_cycle_pairs_on_ica_frame",
"258": "gh-ci — wait on GitHub CI with `gh`",
"259": "Original issue text",
"260": ".possiblyEvaluate",
"261": ".clone",
"262": "Gu",
"263": "issue-flow — ops / no-PR (`/iflow-ops`)",
"264": "Ku",
"265": "2. Cells into a Collection",
"266": "7. What cellpy will and will not do for you",
"270": "Mn",
"267": "Status — Issue #169: Compare selected cells",
"268": "Issue #173 status",
"269": "P",
"270": "Issue #173: Create also a zip file with the installer during release.",
"271": "Issue #175: missing or bad cycles not reported",
"272": "N",
"273": "Issue #177: gui color scheme and layout",
"274": "issue186_original.md",
"275": "se",
"277": "test_ingest.py",
"278": "qn",
"280": "mcp/server.py",
"280": "Refused",
"282": "Xt",
"285": "Building on cellpy",
"286": "Issue #69: edit meta data",
"287": "ge",
"288": "Issue #86 — Status",
"293": "ht",
"295": "Issue #160: Add option to use OtherPath for loading files from remote directory",
"302": "Zi",
"302": "wi",
"304": "test_starter.py",
"306": "jh",
"310": "docker-entrypoint.sh",
Expand Down
Loading
Loading