Skip to content

Polish polar+ring figure: arrows/asterisks swap, un-mirror ring, AR overflow handling#10

Open
mbreiser wants to merge 4 commits into
leburnett:mainfrom
mbreiser:claude/figure-polish-cosmetic
Open

Polish polar+ring figure: arrows/asterisks swap, un-mirror ring, AR overflow handling#10
mbreiser wants to merge 4 commits into
leburnett:mainfrom
mbreiser:claude/figure-polish-cosmetic

Conversation

@mbreiser
Copy link
Copy Markdown
Contributor

Summary

Cosmetic polish + small infrastructure fixes to generate_manuscript_fig_ds.m. Affects both 56 dps (main figure) and 28 dps (supp), specifically the polar+ring-of-traces panels and the right-side boxplot/AR panels.

Changes

Layout / cosmetics

  • Direction arrows moved from outer ring corners → onto the polar plot, aligned with the 16 grid spokes (filled triangular arrowheads, thin shaft, small gap from the 30 mV ring)
  • Per-direction significance asterisks moved from the polar plot → onto the ring traces, anchored at the right edge / −63 mV of each subplot so each asterisk clearly belongs to its trace
  • Ring layout un-mirrored: dropped the 180 − angle_deg transform so a direction's polar position and its ring-trace position agree. PD stays at 12, ND at 6; the ODs swap east/west to match the polar. This addresses a long-standing visual inconsistency that became obvious once asterisks lived on the ring.
  • Ring subplots ~10% narrower (subW 0.048 → 0.0433) for more inter-trace whitespace
  • polar_scale 0.65 → 0.70 so the polar fills more of the inner space
  • Boxplot scatter dots size 20 → 12

AR plot overflow handling

  • Values exceeding the (existing) y_limits = [0 4.4] cap are drawn at y_top = 4 with a small upward filled triangle above to signal "off-axis high"
  • One real point in 28 dps T4 ctrl has AR = 4.573 and is now rendered this way instead of as a floating dot above the axis
  • Significance brackets shifted up slightly so they don't collide with the overflow triangle

Infrastructure

  • opts.preview_ring_only flag added — renders only Panels A & B (polar + ring), writes to a _preview_ring filename. Used as a fast iteration loop on the polar+ring panel.
  • Function now self-bootstraps src/ onto the MATLAB path relative to its own file location, so load_protocol2_data / parse_bar_data / parse_bar_data_pre_bf resolve in a fresh session. Previously the function would silently fail voltage extraction and emit an empty Panel D / H when src/ wasn't already on the path.

Test plan

  • generate_manuscript_fig_ds(56) renders all panels including populated V_m boxplots
  • generate_manuscript_fig_ds(28) renders all panels with AR=4.573 outlier shown as capped marker + up-arrow
  • generate_manuscript_fig_ds(56, struct('preview_ring_only', true)) renders just the polar+ring as *_preview_ring_*.pdf/.png
  • Asterisk placement on the ring matches the polar's ctrl-vs-tutl- gaps on the same side (verified for both T4 and T5 at both speeds)
  • Verified from a clean MATLAB path (only scripts/ on path) — function bootstraps src/ itself

🤖 Generated with Claude Code

mbreiser and others added 4 commits May 19, 2026 20:59
…verflow handling

- Add opts.preview_ring_only flag for fast iteration on just the polar+ring panel
- Self-bootstrap src/ onto MATLAB path so load_protocol2_data and friends resolve
  in a clean session (previously: silent voltage-extraction failure → empty Panel H)
- Move direction arrows from outer ring corners onto the polar plot itself,
  aligned with the 16 grid spokes; filled triangular arrowheads with a small
  whitespace gap from the 30 mV ring
- Move per-direction significance asterisks from the polar plot onto the ring
  traces, anchored at right-edge / -63 mV inside each subplot — each asterisk
  now clearly belongs to its trace
- Un-mirror the ring layout (drop 180-angle_deg transform) so a direction's
  polar position and its ring-trace position agree; PD stays at 12 o'clock,
  ND at 6 o'clock, ODs swap east/west to match the polar
- Tighten subplots: subW 0.048 → 0.0433 (~10% narrower) for more inter-trace
  whitespace; polar_scale 0.65 → 0.70 so the polar fills a bit more of the
  inner space
- Boxplot scatter dots: size 20 → 12 (less visual weight)
- AR plot: clamp any value above the y-cap to y_top and draw a small upward
  triangle above to indicate off-axis (preserves the data point at AR=4.573
  in the 28 dps T4 ctrl group without breaking the new y-axis cap at 4); shift
  significance brackets up to clear the triangle

Verification: both 56 dps and 28 dps render end-to-end; voltage extraction
succeeds (48/48 cells); asterisk placement on the ring now matches the polar
plot's ctrl-vs-tutl- gaps on the same side.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… speeds

The polar direction arrows were anchored to rL(2)=30 mV (data coords), which
meant their visual position relative to the polar box edge varied with
opts.rpad_factor. On 56 dps (rpad_factor=1.10) the arrows landed cleanly
outside the box; on 28 dps (rpad_factor=1.15) the same data positions ended
up inside the box, overlapping the polar grid.

Switch r_tail / r_head to be multiples of rpad (the actual axFill box edge).
The 56 dps appearance is essentially unchanged (33.6→33.66 mV tail). The
28 dps arrows move outward by ~5% and now sit clearly outside the polar
grid like on the main figure.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e caps)

MATLAB Line objects don't expose a LineCap property, so the LineWidth=2.5
horizontal FWHM bars were rendered in PDF with the default projecting
('square') cap — extending ~1.25 pt beyond each geometric endpoint and
making the visible bar appear ~2.5 pt longer than the actual FWHM extent.

Replace the two plot() calls in add_fwhm_bars with patch() rectangles
whose width is exactly rx-lx in data coords. Bar thickness is computed
from the axes' Position in points so it matches the prior visual ~2.5 pt
height. The endpoint tick marks remain as thin plot() lines (their cap
projection is negligible at LineWidth=1.0).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… figure)

When opts.rotate_pd_left = true, the polar+ring panel is rotated CCW by
90° so PD points LEFT (and ND points RIGHT), matching the orientation of
the M6-aligned PD-axis flash figure (generate_manuscript_fig_ef.m with
axis_mode='pd' produces PD on the left side).

Implementation: a single rot_offset (0 or pi/2) is threaded through
draw_ring_panel and plot_polar_with_patch. It is added to:
  - the ring subplot angle (positions all 16 time-series around the ring)
  - the theta argument to draw_polar_patch (rotates ctrl/tutl- curves)
  - the theta inputs to pol2cart for the polar arrows
  - the 30 mV label position
  - the PD/OD/ND reference lines (via a rot2d helper) and labels
    (with HorizontalAlignment/VerticalAlignment swapped so labels stay
    on the outer side of the tip)

Ring asterisks, scale bar, and per-axes drawing are unaffected — they
follow whichever subplot they belong to.

Outputs are saved with a _rot90 suffix so they coexist with the standard
(PD-up) outputs. Other panels (boxplots, AR, V_m) are unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant