Audit pass 10: complete the .plot() convention and tidy the plotting layer (#120)
* feat: complete the .plot() convention and tidy the plotting layer
Audit batch 10:
Every result dataclass with a plottable series now exposes .plot()
(eleven new): open-plan spatial decay with the Clause 6.2 regression
and rD/rP markers; outdoor attenuation with signed pos/neg stacking (a
net ground gain stacks below zero); impedance-tube alpha(f) with the
muted |r| companion; Monte Carlo histogram with the coverage interval -
via a new opt-in monte_carlo(keep_samples=True) that stores the sample
on the result (the 8 MB/1M-trial cost stays off the default path, and
.plot() without samples raises with the hint); occupational-exposure
per-task contributions with the LEX and LEX+U lines; plus simple
renderers for static airflow, airborne/impact prediction,
airborne/impact insulation bands and band uncertainty. TransferMatrix
and ScatteringUncertainty are documented skips (value objects with no
stored frequency axis). The five priority plots are mentioned in their
guides on all three surfaces.
Plotting hygiene: _freq_axis in the enclosed-space renderer (minor-tick
suppression restored); shared _band_axis/_fractile_band/_hatch_invalid
helpers and plot_weighted_absorption folded into _plot_rating; named
color constants with the three neutral greys collapsed into one _C_MUTED
(the per-metric tonality red and roughness brown stay, commented);
every title now leads with its standard designation (17 aligned, with
per-type designations where one renderer serves several standards);
band x-labels unified to the dominant wording; the 11 result: Any
renderers typed; kwargs documented; the missing small legend fixed;
user color propagates into the companion fill_between in the five
loudness/tonality/roughness renderers.
Tests: 11 new kwargs-forwarding cases, 13 content/raise tests, and the
external-ax contract extended to all single-axes results (64/64).
* fix: address the review findings on the plotting batch
- plot_monte_carlo lets callers override density (setdefault instead of
a hardcoded kwarg that collided) (Copilot)
- plot_open_plan imports matplotlib.ticker after the lazy axes creation
so a missing matplotlib still raises the actionable hint (Copilot)
- the exposure plot computes its y-limits from the data instead of
clamping at 0 dB (negative levels no longer clip) (Copilot)
- the sound-power legend also renders when the caller passes label=
(Gemini)
- the insulation plot annotations are quoted for consistency (the file
already had future annotations, so this is style, not a crash fix)
(Gemini)
- the GUM example comment now says honestly that the committed figure
overlays the Gaussian, and the open-plan one-liner snippet gains
plt.show(), on all surfaces (CodeRabbit)