From ba93136fdfc2903e2a7a84971aa97476184f36a4 Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 19:19:58 -0700 Subject: [PATCH 01/15] Consolidate Matplotlib gallery compatibility --- benchmarks/test_codspeed_pyplot.py | 9 +- js/src/10_colormaps.ts | 5 + js/src/20_theme.ts | 17 +- js/src/40_gl.ts | 16 +- js/src/50_chartview.ts | 253 +- js/src/51_annotations.ts | 22 +- .../annotation-basic.png | Bin 0 -> 199040 bytes .../bar-label-demo.png | Bin 0 -> 114064 bytes .../provenance.json | 24 + python/xy/_figure.py | 33 +- python/xy/_fontmetrics.py | 64 + python/xy/_native.py | 4 + python/xy/_paint.py | 64 + python/xy/_raster.py | 452 ++- python/xy/_svg.py | 916 +++++- python/xy/channels.py | 5 + python/xy/components.py | 50 +- python/xy/marks.py | 279 +- python/xy/pyplot/__init__.py | 28 +- python/xy/pyplot/_artists.py | 317 ++- python/xy/pyplot/_axes.py | 2533 +++++++++++++++-- python/xy/pyplot/_colors.py | 5 + python/xy/pyplot/_grid.py | 166 +- python/xy/pyplot/_mathtext.py | 86 +- python/xy/pyplot/_mplfig.py | 264 +- python/xy/pyplot/_plot_types.py | 1550 ++++++++-- python/xy/pyplot/_rc.py | 29 + python/xy/pyplot/_ticker.py | 25 +- python/xy/pyplot/_translate.py | 5 +- python/xy/styles.py | 41 +- scripts/gen_font.py | 77 +- spec/api/styling.md | 468 ++- spec/design/pan-and-zoom-configuration.md | 22 + spec/design/rust-engine.md | 19 +- spec/matplotlib/compat-changelog.md | 63 + spec/matplotlib/compat.md | 38 +- spec/matplotlib/shim-todo.md | 34 +- src/font.rs | 224 +- src/kernels.rs | 97 +- src/lib.rs | 14 +- src/raster.rs | 238 +- tests/pyplot/test_advanced_compatibility.py | 4 +- .../test_annotation_box_text_fidelity.py | 355 +++ .../test_autoscale_margin_bar_regressions.py | 187 ++ tests/pyplot/test_axes_charts.py | 12 +- tests/pyplot/test_axes_layout.py | 75 +- tests/pyplot/test_axis_tick_gallery_compat.py | 88 + tests/pyplot/test_best_legend_placement.py | 438 +++ .../test_categorical_gallery_regressions.py | 89 + tests/pyplot/test_color_pipeline_fixes.py | 12 +- tests/pyplot/test_contour_gallery_colors.py | 107 + tests/pyplot/test_frame_geometry.py | 275 ++ .../pyplot/test_gallery_auto_ticks_compat.py | 92 + tests/pyplot/test_gallery_canvas_gutters.py | 155 + tests/pyplot/test_gallery_colorbar_options.py | 104 + .../test_gallery_hist_errorbar_compat.py | 181 ++ .../test_gallery_layout_api_regressions.py | 116 + .../test_gallery_statistics_semantics.py | 101 + tests/pyplot/test_gallery_stem_regressions.py | 74 + tests/pyplot/test_gallery_text_pie_compat.py | 293 ++ tests/pyplot/test_grid_legend_contracts.py | 32 +- tests/pyplot/test_launch_compat.py | 6 +- tests/pyplot/test_layout_text_parity_fixes.py | 20 +- tests/pyplot/test_line_gallery_semantics.py | 71 + .../pyplot/test_line_legend_gallery_compat.py | 397 +++ tests/pyplot/test_marker_fidelity.py | 23 + .../test_matplotlib_mismatch_regressions.py | 110 + .../pyplot/test_mesh_autoscale_regressions.py | 267 ++ tests/pyplot/test_p3_option_contracts.py | 264 +- tests/pyplot/test_pdsh_gap_features.py | 53 + tests/pyplot/test_rc_chrome_contracts.py | 69 + .../pyplot/test_rc_color_export_contracts.py | 3 + tests/pyplot/test_reference_semantics.py | 12 +- tests/pyplot/test_silent_drop_regressions.py | 4 +- tests/pyplot/test_state_and_figs.py | 9 +- tests/pyplot/test_visible_style_contracts.py | 36 +- tests/test_axis_title_gutter.py | 248 ++ tests/test_components.py | 26 + tests/test_css_mark_styles.py | 7 +- tests/test_kernels.py | 14 + tests/test_png_export.py | 245 ++ tests/test_static_client_security.py | 4 + tests/test_svg_export.py | 319 ++- tests/test_text_weight_defaults.py | 201 ++ tests/test_ui_issue_regressions.py | 99 + 85 files changed, 12647 insertions(+), 1206 deletions(-) create mode 100644 pr-assets/matplotlib-gallery-consolidation/annotation-basic.png create mode 100644 pr-assets/matplotlib-gallery-consolidation/bar-label-demo.png create mode 100644 pr-assets/matplotlib-gallery-consolidation/provenance.json create mode 100644 python/xy/_fontmetrics.py create mode 100644 tests/pyplot/test_annotation_box_text_fidelity.py create mode 100644 tests/pyplot/test_autoscale_margin_bar_regressions.py create mode 100644 tests/pyplot/test_axis_tick_gallery_compat.py create mode 100644 tests/pyplot/test_best_legend_placement.py create mode 100644 tests/pyplot/test_categorical_gallery_regressions.py create mode 100644 tests/pyplot/test_contour_gallery_colors.py create mode 100644 tests/pyplot/test_frame_geometry.py create mode 100644 tests/pyplot/test_gallery_auto_ticks_compat.py create mode 100644 tests/pyplot/test_gallery_canvas_gutters.py create mode 100644 tests/pyplot/test_gallery_colorbar_options.py create mode 100644 tests/pyplot/test_gallery_hist_errorbar_compat.py create mode 100644 tests/pyplot/test_gallery_layout_api_regressions.py create mode 100644 tests/pyplot/test_gallery_statistics_semantics.py create mode 100644 tests/pyplot/test_gallery_stem_regressions.py create mode 100644 tests/pyplot/test_gallery_text_pie_compat.py create mode 100644 tests/pyplot/test_line_gallery_semantics.py create mode 100644 tests/pyplot/test_line_legend_gallery_compat.py create mode 100644 tests/pyplot/test_matplotlib_mismatch_regressions.py create mode 100644 tests/pyplot/test_mesh_autoscale_regressions.py create mode 100644 tests/test_axis_title_gutter.py create mode 100644 tests/test_text_weight_defaults.py diff --git a/benchmarks/test_codspeed_pyplot.py b/benchmarks/test_codspeed_pyplot.py index 9e5c359f..7f95c362 100644 --- a/benchmarks/test_codspeed_pyplot.py +++ b/benchmarks/test_codspeed_pyplot.py @@ -150,8 +150,9 @@ def export_data() -> tuple[np.ndarray, np.ndarray]: # -- paired build arms -------------------------------------------------------- # -# The raw arm mirrors the shim's implicit defaults (explicit x/y axes, the -# 640x480 canvas) so the pair differs only in which API expressed the chart. +# The raw arm mirrors the shim's implicit defaults (explicit x/y axes, +# Matplotlib's 5% line margins, and the 640x480 canvas) so the pair differs +# only in which API expressed the chart. # The pyplot arm includes plt.close("all") because figure-registry bookkeeping # is part of the shim's per-figure cost — the exact cost the guardrail bounds. @@ -159,8 +160,8 @@ def export_data() -> tuple[np.ndarray, np.ndarray]: def _raw_line_payload(x: np.ndarray, y: np.ndarray) -> int: c = xy.chart( xy.line(x=x, y=y, color="#1f77b4"), - xy.x_axis(), - xy.y_axis(), + xy.x_axis(margin=0.05), + xy.y_axis(margin=0.05), width=WIDTH, height=HEIGHT, ) diff --git a/js/src/10_colormaps.ts b/js/src/10_colormaps.ts index 7a93f964..d1353121 100644 --- a/js/src/10_colormaps.ts +++ b/js/src/10_colormaps.ts @@ -5,6 +5,11 @@ const COLORMAP_STOPS = { binary: [[255, 255, 255], [0, 0, 0]], + reds: [[255, 245, 240], [254, 229, 216], [253, 202, 181], [252, 171, 143], [252, 138, 106], [251, 105, 74], [241, 68, 50], [217, 37, 35], [188, 20, 26], [152, 12, 19], [103, 0, 13]], + bone: [[0, 0, 0], [22, 22, 30], [45, 45, 62], [66, 66, 93], [89, 92, 121], [112, 123, 144], [134, 154, 166], [157, 185, 188], [185, 210, 210], [221, 233, 233], [255, 255, 255]], + autumn: [[255, 0, 0], [255, 25, 0], [255, 51, 0], [255, 76, 0], [255, 102, 0], [255, 128, 0], [255, 153, 0], [255, 179, 0], [255, 204, 0], [255, 230, 0], [255, 255, 0]], + winter: [[0, 0, 255], [0, 25, 242], [0, 51, 230], [0, 76, 217], [0, 102, 204], [0, 128, 191], [0, 153, 178], [0, 179, 166], [0, 204, 153], [0, 230, 140], [0, 255, 128]], + bupu: [[247, 252, 253], [229, 239, 246], [204, 221, 236], [178, 202, 225], [154, 180, 214], [140, 149, 198], [140, 116, 181], [138, 81, 165], [133, 45, 144], [118, 12, 113], [77, 0, 75]], gray: [[0, 0, 0], [25, 25, 25], [51, 51, 51], [76, 76, 76], [102, 102, 102], [128, 128, 128], [153, 153, 153], [179, 179, 179], [204, 204, 204], [230, 230, 230], [255, 255, 255]], viridis: [[68, 1, 84], [72, 36, 117], [65, 68, 135], [53, 95, 141], [42, 120, 142], [33, 145, 140], [34, 168, 132], [68, 191, 112], [122, 209, 81], [189, 223, 38], [253, 231, 37]], plasma: [[13, 8, 135], [65, 4, 157], [106, 0, 168], [143, 13, 164], [177, 42, 144], [204, 71, 120], [225, 100, 98], [242, 132, 75], [252, 166, 54], [252, 206, 37], [240, 249, 33]], diff --git a/js/src/20_theme.ts b/js/src/20_theme.ts index c4c37825..ca6fbf37 100644 --- a/js/src/20_theme.ts +++ b/js/src/20_theme.ts @@ -108,15 +108,26 @@ export function cssColor([r, g, b, a]: any) { // convention every host we target uses (Reflex/next-themes, Radix Themes, // Tailwind). These remain zero-specificity :where() rules, so public // --chart-badge-* / --chart-modebar-* tokens or utility classes override them. +// +// Every chrome text slot below either declares `font-weight:400` or declares +// no weight at all and inherits 400. Matplotlib's `axes.titleweight`, +// `axes.labelweight` and `font.weight` all default to "normal", and its legend +// title and colorbar label are normal too, so 400 is the parity default for +// title, axis titles, annotations, legend titles and colorbar titles alike. +// The SVG (`python/xy/_svg.py`) and native raster (`python/xy/_raster.py`) +// exporters carry the same 400 default — the three renderers must not +// disagree; tests/test_text_weight_defaults.py guards all three. A heavier +// weight is opt-in, via `styles[slot]`, a mark/axis text style, or the pyplot +// `axes.titleweight`/`axes.labelweight` rcParams. export const XY_CHROME_CSS = ` @layer base{ -:where(.xy [data-xy-slot="title"]){text-align:center;font-size:14px;font-weight:600;color:var(--chart-text,inherit)} +:where(.xy [data-xy-slot="title"]){text-align:center;font-size:14px;font-weight:400;color:var(--chart-text,inherit)} :where(.xy [data-xy-slot="tooltip"]){max-width:calc(100% - 8px);max-height:calc(100% - 8px);box-sizing:border-box;white-space:normal;overflow-wrap:anywhere;overflow:auto;background:var(--chart-tooltip-bg,rgba(20,24,33,.92));color:var(--chart-tooltip-text,#fff);padding:5px 8px;border-radius:4px;font-size:11px;line-height:1.35;box-shadow:0 2px 8px rgba(0,0,0,.3)} :where(.xy [data-xy-slot="legend"]){left:var(--xy-legend-left,auto);right:var(--xy-legend-right,auto);top:var(--xy-legend-top,auto);bottom:var(--xy-legend-bottom,auto);transform:var(--xy-legend-transform,none);max-width:var(--xy-legend-max-width);max-height:var(--xy-legend-max-height);gap:2px;font-size:11px;background:var(--chart-legend-bg,rgba(128,128,128,.08));border-radius:4px;padding:4px 8px;color:var(--chart-text,inherit)} :where(.xy [data-xy-slot="legend_swatch"]){width:12px;height:10px;border-radius:2px;margin-right:5px} :where(.xy [data-xy-slot="colorbar"]){color:var(--chart-text,inherit);font-size:10px} :where(.xy [data-xy-slot="colorbar_bar"]){background:var(--xy-colorbar-gradient);border:1px solid currentColor;box-sizing:border-box} -:where(.xy [data-xy-slot="colorbar_title"]){font-weight:500} +:where(.xy [data-xy-slot="colorbar_title"]){font-weight:400} :where(.xy [data-xy-slot="badge"]){gap:3px;font-size:11px;line-height:1.2} :where(.xy [data-xy-slot="badge_item"]){padding:3px 6px;border-radius:4px;color:var(--chart-badge-text,var(--xy-badge-text));background:var(--chart-badge-bg,var(--xy-badge-bg));box-shadow:var(--xy-badge-shadow)} :where(.xy){--xy-badge-text:#0f172a;--xy-badge-bg:rgba(255,255,255,.82);--xy-badge-shadow:0 1px 4px rgba(15,23,42,.14);--xy-modebar-bg:#fff;--xy-modebar-menu-bg:#fff;--xy-modebar-hover:#edf1f6;--xy-modebar-focus:#1b212a;--xy-modebar-text:#5c6573;--xy-modebar-text-strong:#1b212a;--xy-modebar-text-soft:#798495;--xy-modebar-text-subtle:#9aa4b2;--xy-modebar-border:rgba(27,33,42,.12);--xy-modebar-separator:rgba(27,33,42,.08);--xy-modebar-active:#edf1f6;--xy-modebar-shadow:0 8px 24px rgba(28,32,36,.1),0 2px 6px rgba(28,32,36,.06);--xy-modebar-menu-shadow:0 8px 24px rgba(28,32,36,.12);--xy-modebar-button-shadow:0 1px 2px rgba(28,32,36,.06);--xy-selection:rgba(92,101,115,.6);--xy-selection-fill:rgba(92,101,115,.12)} @@ -169,7 +180,7 @@ export const XY_CHROME_CSS = ` :where(.xy [data-xy-slot="crosshair_x"],.xy [data-xy-slot="crosshair_y"]){background:var(--chart-crosshair,rgba(15,23,42,.42))} :where(.xy [data-xy-slot="tick_label"]){color:var(--chart-text,inherit)} :where(.xy [data-xy-slot="axis_title"]){color:var(--chart-text,inherit);font-size:12px} -:where(.xy [data-xy-slot="annotation_label"]){font-size:11px;line-height:1.2;font-weight:500;color:var(--chart-annotation-text,var(--chart-text,inherit))} +:where(.xy [data-xy-slot="annotation_label"]){font-size:11px;line-height:1.2;font-weight:400;color:var(--chart-annotation-text,var(--chart-text,inherit))} :where(.xy [data-xy-slot="canvas"]){cursor:var(--chart-cursor,crosshair)} :where(.xy [data-xy-slot="canvas"][data-xy-dragmode="pan"]){cursor:var(--chart-cursor-pan,grab)} :where(.xy [data-xy-slot="canvas"][data-xy-dragmode="none"]){cursor:default} diff --git a/js/src/40_gl.ts b/js/src/40_gl.ts index 782e7f16..df5de777 100644 --- a/js/src/40_gl.ts +++ b/js/src/40_gl.ts @@ -109,7 +109,7 @@ in vec4 a_rgba; in vec4 a_style; in vec4 a_stroke; uniform vec2 u_xmap; uniform vec2 u_ymap; uniform vec2 u_xmeta; uniform vec2 u_ymeta; uniform int u_xmode; uniform float u_xconstant; uniform int u_ymode; uniform float u_yconstant; uniform float u_size; uniform int u_sizeMode; uniform vec2 u_sizeRange; -uniform int u_colorMode; uniform float u_dpr; uniform int u_selActive; +uniform int u_colorMode; uniform int u_symbol; uniform float u_dpr; uniform int u_selActive; uniform float u_selectedOpacity; uniform float u_unselectedOpacity; uniform float u_transitionProgress; uniform int u_transitionActive; out float v_lutCoord; out float v_dim; out float v_dval; out float v_ptSize; out float v_sel; @@ -120,8 +120,10 @@ void main() { float y = u_transitionActive == 1 ? mix(a_prevy, ay, u_transitionProgress) : ay; gl_Position = vec4(xyMap(x, u_xmap, u_xmeta, u_xmode, u_xconstant), xyMap(y, u_ymap, u_ymeta, u_ymode, u_yconstant), 0.0, 1.0); float sz = u_sizeMode == 1 ? mix(u_sizeRange.x, u_sizeRange.y, a_sval) : u_size; - gl_PointSize = sz * u_dpr; - v_ptSize = sz * u_dpr; + int symbol = a_style.w >= 0.0 ? int(a_style.w + 0.5) : u_symbol; + float symbolScale = symbol == 2 || symbol == 14 ? 1.414213562 : 1.0; + gl_PointSize = sz * u_dpr * symbolScale; + v_ptSize = sz * u_dpr * symbolScale; v_sel = a_sel; v_rgba = a_rgba; v_style = a_style; @@ -202,8 +204,8 @@ float xyMarkerSdf(vec2 d, int shape) { if (shape == 3 || shape == 8 || shape == 9 || shape == 10) { // Matplotlib triangle path vec2 q = d; if (shape == 8) q = -d; - if (shape == 9) q = vec2(d.y, -d.x); - if (shape == 10) q = vec2(-d.y, d.x); + if (shape == 9) q = vec2(-d.y, d.x); + if (shape == 10) q = vec2(d.y, -d.x); return xyTriangleDistance(q, vec2(0.0, -0.5), vec2(-0.5, 0.5), vec2(0.5, 0.5)); } if (shape == 11) { // diagonal x @@ -649,7 +651,7 @@ void main() { float coverage = smoothstep(0.0, max(fwidth(edge) * strokeWidth, 1e-5), edge); // Both stroke sources ship straight alpha; the per-item alpha stack // applies to scalar strokes as well (parity with static exporters). - vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : u_stroke; + vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : (u_strokeMode == 2 ? paint : u_stroke); float strokeAlpha = (v_style.y >= 0.0 ? v_style.y : strokeSrc.a) * v_style.x * u_strokeOpacity; vec4 stroke = vec4(strokeSrc.rgb * strokeAlpha, strokeAlpha); outColor = mix(stroke, fill, coverage); @@ -886,7 +888,7 @@ void main() { if (strokeWidth > 0.0) { // Both stroke sources ship straight alpha; the per-item alpha stack // applies to scalar strokes as well (parity with static exporters). - vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : u_stroke; + vec4 strokeSrc = u_strokeMode == 1 ? v_stroke : (u_strokeMode == 2 ? paint : u_stroke); float strokeAlpha = (v_style.y >= 0.0 ? v_style.y : strokeSrc.a) * v_style.x * u_strokeOpacity; vec4 stroke = vec4(strokeSrc.rgb * strokeAlpha, strokeAlpha); float inner = 1.0 - smoothstep(-aa, aa, d + strokeWidth); diff --git a/js/src/50_chartview.ts b/js/src/50_chartview.ts index 7a3c9c7d..106727f9 100644 --- a/js/src/50_chartview.ts +++ b/js/src/50_chartview.ts @@ -1518,7 +1518,8 @@ export class ChartView { this.overlay.width = this.size.w * this.dpr; this.overlay.height = this.size.h * this.dpr; for (const lg of this._legends || []) { - this._positionLegend(lg, lg.dataset.xyLegendLoc || "upper right"); + const anchor = lg.dataset.xyLegendAnchor ? JSON.parse(lg.dataset.xyLegendAnchor) : null; + this._positionLegend(lg, lg.dataset.xyLegendLoc || "upper right", anchor); } this._positionReductionBadges(); this._positionColorbar(); @@ -1749,11 +1750,23 @@ export class ChartView { this._legendOffCats = this._legendOffCats || new Map(); const items = []; if (s.show_legend !== false) { - // Two identically-encoded unnamed continuous traces must not stack two - // identical gradient rows; the row is about the encoding, so later - // traces join the first row's hover-target list instead. - const continuousRows = new Map(); - s.traces.forEach((t, ti) => { + const explicit = (s.legend && s.legend.items) || []; + if (explicit.length) { + for (const it of explicit) { + items.push({ + swatch: it.style && it.style.color, + name: it.name, + symbol: it.kind === "scatter" ? (it.style?.symbol || "circle") : null, + line: ["line", "segments", "step", "stairs", "errorbar"].includes(it.kind), + style: it.style || {}, + }); + } + } else { + // Two identically-encoded unnamed continuous traces must not stack two + // identical gradient rows; the row is about the encoding, so later + // traces join the first row's hover-target list instead. + const continuousRows = new Map(); + s.traces.forEach((t, ti) => { // A density-tier surface encodes count as alpha and wears the mean // point color (LOD doc §2), so it gets no colormap gradient swatch — // a gradient would claim color == density. A named density trace @@ -1786,7 +1799,8 @@ export class ChartView { // same handle the raster/SVG exporters draw — not a filled swatch. items.push({ swatch: c, name: t.name, symbol: t.kind === "scatter" ? (t.style?.symbol || "circle") : null, line, style: t.style || {}, traces: [ti] }); } - }); + }); + } for (const it of items) { if (!it.traces) continue; it.off = it.cat != null @@ -1814,16 +1828,27 @@ export class ChartView { const loc = options.loc || "upper right"; const ncols = Math.max(1, Number(options.ncols) || 1); const horizontal = ncols > 1; + const handleHeight = options.handleheight == null + ? null + : Math.max(8, 11 * Number(options.handleheight)); lg.style.cssText = "position:absolute;" + `display:grid;grid-template-columns:repeat(${horizontal ? ncols : 1},max-content);` + - "overflow:auto;"; + "column-gap:2em;row-gap:.5em;overflow:auto;"; lg.dataset.xyLegendLoc = loc; - this._positionLegend(lg, loc); + if (Array.isArray(options.anchor)) { + lg.dataset.xyLegendAnchor = JSON.stringify(options.anchor); + } + if (Number.isFinite(Number(options.border_pad))) { + lg.dataset.xyLegendBorderPad = String(Math.max(0, Number(options.border_pad))); + } + this._positionLegend(lg, loc, options.anchor); this._applySlot(lg, "legend"); + this._applyStyle(lg, options.style); if (options.title) { const title = document.createElement("div"); title.textContent = String(options.title); - title.style.fontWeight = "600"; + title.style.fontWeight = "400"; + title.style.textAlign = "center"; title.style.gridColumn = `1 / span ${horizontal ? ncols : 1}`; lg.appendChild(title); } @@ -1831,6 +1856,7 @@ export class ChartView { for (const it of items) { const row = document.createElement("div"); this._applySlot(row, "legend_item"); + if (handleHeight != null) row.style.minHeight = `${handleHeight + 2}px`; const sw = document.createElement("span"); // Swatch geometry is a stylesheet default; only the paint (dynamic per // series) stays inline, and it now has its own slot so it's classable. @@ -1901,7 +1927,25 @@ export class ChartView { sw.style.width = "22px"; sw.style.height = "12px"; } else if (it.swatch !== "gradient") { + // Keep the dynamic paint on the security-audited safe sink. Hatch + // layers below only add generated gradients over that sanitized base. sw.style.background = safeCssPaint(this.root, bg); + if (it.style?.hatch) { + const hatchColor = safeCssPaint(this.root, it.style.hatch_color || "#222222"); + const patterns = []; + const hatch = String(it.style.hatch); + if (hatch.includes("/") || hatch.includes("*")) + patterns.push(`repeating-linear-gradient(135deg,transparent 0 4px,${hatchColor} 4px 5px)`); + if (hatch.includes("\\") || hatch.includes("*")) + patterns.push(`repeating-linear-gradient(45deg,transparent 0 4px,${hatchColor} 4px 5px)`); + if (hatch.includes("-")) + patterns.push(`repeating-linear-gradient(0deg,transparent 0 4px,${hatchColor} 4px 5px)`); + if (hatch.includes(".")) + patterns.push(`radial-gradient(circle,${hatchColor} 1px,transparent 1px)`); + sw.style.backgroundImage = patterns.join(","); + if (hatch.includes(".")) sw.style.backgroundSize = "5px 5px"; + } + if (handleHeight != null) sw.style.height = `${handleHeight}px`; } this._applySlot(sw, "legend_swatch"); row.appendChild(sw); @@ -2282,7 +2326,7 @@ export class ChartView { } } - _positionLegend(lg, loc) { + _positionLegend(lg, loc, anchor = null) { if (!lg) return; // Responsive anchors flow through private custom properties consumed by a // zero-specificity rule. Author classes or component styles can still set @@ -2290,16 +2334,29 @@ export class ChartView { const rightInset = this.size.w - (this.plot.x + this.plot.w); const h = loc.includes("left") ? "left" : loc.includes("right") ? "right" : "center"; const v = loc.includes("upper") ? "upper" : loc.includes("lower") ? "lower" : "center"; - const left = h === "left" ? this.plot.x + 6 : h === "center" ? this.plot.x + this.plot.w / 2 : null; - const right = h === "right" ? rightInset + 6 : null; - const top = v === "upper" ? this.plot.y + 6 : v === "center" ? this.plot.y + this.plot.h / 2 : null; - const bottom = v === "lower" ? this.size.h - (this.plot.y + this.plot.h) + 6 : null; + let left = h === "left" ? this.plot.x + 6 : h === "center" ? this.plot.x + this.plot.w / 2 : null; + let right = h === "right" ? rightInset + 6 : null; + let top = v === "upper" ? this.plot.y + 6 : v === "center" ? this.plot.y + this.plot.h / 2 : null; + let bottom = v === "lower" ? this.size.h - (this.plot.y + this.plot.h) + 6 : null; + if (Array.isArray(anchor) && (anchor.length === 2 || anchor.length === 4)) { + const hx = h === "left" ? 0 : h === "right" ? 1 : 0.5; + const vy = v === "lower" ? 0 : v === "upper" ? 1 : 0.5; + const aw = anchor.length === 4 ? Number(anchor[2]) : 0; + const ah = anchor.length === 4 ? Number(anchor[3]) : 0; + const borderPad = Math.max(0, Number(lg.dataset.xyLegendBorderPad) || 0); + left = this.plot.x + (Number(anchor[0]) + hx * aw) * this.plot.w + + (hx === 0 ? borderPad : hx === 1 ? -borderPad : 0); + top = this.plot.y + (1 - Number(anchor[1]) - vy * ah) * this.plot.h + + (vy === 1 ? borderPad : vy === 0 ? -borderPad : 0); + right = null; + bottom = null; + } lg.style.setProperty("--xy-legend-left", left == null ? "auto" : left + "px"); lg.style.setProperty("--xy-legend-right", right == null ? "auto" : right + "px"); lg.style.setProperty("--xy-legend-top", top == null ? "auto" : top + "px"); lg.style.setProperty("--xy-legend-bottom", bottom == null ? "auto" : bottom + "px"); - const tx = h === "center" ? "-50%" : "0"; - const ty = v === "center" ? "-50%" : "0"; + const tx = h === "center" ? "-50%" : h === "right" && anchor ? "-100%" : "0"; + const ty = v === "center" ? "-50%" : v === "lower" && anchor ? "-100%" : "0"; lg.style.setProperty("--xy-legend-transform", `translate(${tx},${ty})`); } @@ -2338,7 +2395,10 @@ export class ChartView { const domain = cb.domain || [0, 1]; const lo = Number(domain[0]), hi = Number(domain[1]); const span = hi - lo || 1; - const tickResult = linearTicks(lo, hi, 8); + const shrink = Math.max(0.01, Math.min(1, Number(cb.shrink) || 1)); + const barLength = (horizontal ? this.plot.w : this.plot.h) * shrink; + const tickTarget = Math.max(2, Math.min(8, Math.floor(Math.max(0, barLength) / 48) + 1)); + const tickResult = linearTicks(lo, hi, tickTarget); const hasExplicitTicks = Array.isArray(cb.ticks); const tickValues = hasExplicitTicks ? cb.ticks : tickResult.ticks; const tickStep = tickResult.step; @@ -2354,6 +2414,25 @@ export class ChartView { this._applySlot(tick, "colorbar_tick"); box.appendChild(tick); } + if (cb.minor_ticks) { + const orderedTicks = [...tickValues] + .map(Number) + .filter(Number.isFinite) + .sort((a, b) => a - b); + for (let index = 0; index + 1 < orderedTicks.length; index++) { + const left = orderedTicks[index], right = orderedTicks[index + 1]; + for (let step = 1; step < 5; step++) { + const value = left + (right - left) * step / 5; + const fraction = (value - lo) / span; + const tick = document.createElement("i"); + tick.dataset.xyColorbarMinor = "true"; + tick.style.cssText = horizontal + ? `position:absolute;left:${100 * fraction}%;top:${COLORBAR_THICKNESS}px;height:3px;border-left:1px solid currentColor;` + : `position:absolute;left:${COLORBAR_THICKNESS}px;top:${100 * (1 - fraction)}%;width:3px;border-top:1px solid currentColor;`; + box.appendChild(tick); + } + } + } if (cb.label) { const label = document.createElement("span"); label.textContent = String(cb.label); @@ -2372,19 +2451,24 @@ export class ChartView { _positionColorbar() { if (!this._colorbar) return; + const cb = this.spec.colorbar || {}; const horizontal = this._colorbarHorizontal; const compactVertical = !horizontal && this._compactVerticalColorbar; const gap = compactVertical ? COMPACT_COLORBAR_GAP : COLORBAR_GAP; + const shrink = Math.max(0.01, Math.min(1, Number(cb.shrink) || 1)); + const anchor = Array.isArray(cb.anchor) ? cb.anchor : [0.5, 0.5]; + const barWidth = this.plot.w * shrink; + const barHeight = this.plot.h * shrink; this._colorbar.style.left = (horizontal - ? this.plot.x + ? this.plot.x + (this.plot.w - barWidth) * Number(anchor[0] ?? 0.5) : this.plot.x + this.plot.w + this._rightAxisRoom + gap) + "px"; this._colorbar.style.top = (horizontal ? this.plot.y + this.plot.h + (this._bottomAxisRoom || 8) - : this.plot.y) + "px"; + : this.plot.y + (this.plot.h - barHeight) * (1 - Number(anchor[1] ?? 0.5))) + "px"; this._colorbar.style.width = (horizontal - ? this.plot.w + ? barWidth : compactVertical ? COLORBAR_THICKNESS : 66) + "px"; - this._colorbar.style.height = (horizontal ? 50 : Math.max(24, this.plot.h)) + "px"; + this._colorbar.style.height = (horizontal ? 50 : Math.max(24, barHeight)) + "px"; this._colorbar.dataset.xyCompact = compactVertical ? "true" : "false"; for (const node of this._colorbar.querySelectorAll( '[data-xy-slot="colorbar_tick"], [data-xy-slot="colorbar_title"]' @@ -2995,7 +3079,7 @@ export class ChartView { // stack in and premultiplies there (uniform and buffer strokes alike). const sc = g.strokeColor || [0, 0, 0, 0]; gl.uniform4f(u("u_stroke"), sc[0], sc[1], sc[2], sc[3]); - gl.uniform1i(u("u_strokeMode"), g.strokeBuf ? 1 : 0); + gl.uniform1i(u("u_strokeMode"), g.strokeBuf ? 1 : (g.strokeMatchFill ? 2 : 0)); gl.uniform1f(u("u_strokeOpacity"), this._strokeOpacity(g.trace.style || {})); this._setGradientUniforms(prog, g.grad); } @@ -3011,6 +3095,7 @@ export class ChartView { ? [Number(cr[0]) || 0, Number(cr[1]) || 0] : [Number(cr) || 0, Number(cr) || 0]; g.strokeWidth = Number(s.stroke_width) || 0; + g.strokeMatchFill = !!(t.stroke && t.stroke.mode === "match_fill"); const opaque = [g.color[0], g.color[1], g.color[2], 1]; g.strokeColor = s.stroke ? parseColor(this.root, s.stroke, opaque) : opaque; g.grad = this._resolveMarkFill(s, g.color); @@ -3134,6 +3219,7 @@ export class ChartView { const style = t.style || {}; g.meshStrokeWidth = Number(style.stroke_width) || 0; g.meshStroke = parseColor(this.root, style.stroke || "transparent", [0, 0, 0, 0]); + g.strokeMatchFill = !!(t.stroke && t.stroke.mode === "match_fill"); } // Hexbin ships cell centers plus one color value per cell; every hexagon @@ -4190,7 +4276,7 @@ export class ChartView { const stroke = g.meshStroke || [0, 0, 0, 0]; gl.uniform4f(u("u_stroke"), stroke[0], stroke[1], stroke[2], stroke[3]); gl.uniform1f(u("u_strokeWidth"), g.meshStrokeWidth || 0); - gl.uniform1i(u("u_strokeMode"), g.strokeBuf ? 1 : 0); + gl.uniform1i(u("u_strokeMode"), g.strokeBuf ? 1 : (g.strokeMatchFill ? 2 : 0)); gl.uniform1f(u("u_strokeOpacity"), this._strokeOpacity(g.trace.style) * (g._legendDim ?? 1)); if (g.colorMode && g.lut) { gl.activeTexture(gl.TEXTURE0); @@ -4649,7 +4735,7 @@ export class ChartView { const hasAngle = axis && Number.isFinite(Number(axis.label_angle)); if (!hasPosition && !hasOffset && !hasAngle) return { css: fallbackCss, style: null }; if (rawPosition && typeof rawPosition === "object" && !Array.isArray(rawPosition)) { - return { css: "font-weight:500;white-space:nowrap;", style: rawPosition }; + return { css: "font-weight:400;white-space:nowrap;", style: rawPosition }; } const p = this.plot; @@ -4672,7 +4758,7 @@ export class ChartView { css: `left:${x}px;top:${y}px;` + `transform:translateX(${translateX}%) rotate(${angle}deg);` + - "transform-origin:center;font-weight:500;white-space:nowrap;", + "transform-origin:center;font-weight:400;white-space:nowrap;", style: null, }; } @@ -4687,7 +4773,7 @@ export class ChartView { css: `left:${x}px;top:${y}px;` + `transform:translate(-50%,-50%) rotate(${angle}deg);` + - "transform-origin:center;font-weight:500;white-space:nowrap;", + "transform-origin:center;font-weight:400;white-space:nowrap;", style: null, }; } @@ -4780,6 +4866,14 @@ export class ChartView { // instead of covering the chrome line drawn behind it (grid lines stay on // the chrome canvas, behind the data). Rebuilt with the labels; static // between throttled zoom frames since the plot rect doesn't move on zoom. + const tickParts = (axis) => { + const length = Math.max(0, this._axisStyleNumber(axis, "tick_length", 0)); + const width = Math.max(0.5, this._axisStyleNumber(axis, "tick_width", 1)); + const direction = String(this._axisStyleValue(axis, "tick_direction") || "out"); + if (direction === "in") return { inward: length, outward: 0, width }; + if (direction === "inout") return { inward: length / 2, outward: length / 2, width }; + return { inward: 0, outward: length, width }; + }; if (updateLabels) { const rule = (styleAxis, left, top, w, h, colorKey = "axis_color") => { const d = document.createElement("div"); @@ -4792,12 +4886,13 @@ export class ChartView { const frameSides = Array.isArray(s.frame_sides) ? s.frame_sides : [xAxis.side || "bottom", yAxis.side || "left"]; - if (!hideY) { + const explicitFrameSides = Array.isArray(s.frame_sides); + if (!hideY || explicitFrameSides) { const yWidth = Math.max(1, this._axisStyleNumber(yAxis, "axis_width", 1)); if (frameSides.includes("left")) rule(yAxis, p.x, p.y, yWidth, p.h); if (frameSides.includes("right")) rule(yAxis, p.x + p.w - yWidth, p.y, yWidth, p.h); } - if (!hideX) { + if (!hideX || explicitFrameSides) { const xHeight = Math.max(1, this._axisStyleNumber(xAxis, "axis_width", 1)); if (frameSides.includes("top")) rule(xAxis, p.x, p.y, p.w, xHeight); if (frameSides.includes("bottom")) rule(xAxis, p.x, p.y + p.h - xHeight, p.w, xHeight); @@ -4815,14 +4910,6 @@ export class ChartView { rule(axis, x, p.y, w, p.h); } - const tickParts = (axis) => { - const length = Math.max(0, this._axisStyleNumber(axis, "tick_length", 0)); - const width = Math.max(0.5, this._axisStyleNumber(axis, "tick_width", 1)); - const direction = String(this._axisStyleValue(axis, "tick_direction") || "out"); - if (direction === "in") return { inward: length, outward: 0, width }; - if (direction === "inout") return { inward: length / 2, outward: length / 2, width }; - return { inward: 0, outward: length, width }; - }; if (!hideX) { const tick = tickParts(xAxis); const side = xAxis.side || "bottom"; @@ -4880,7 +4967,7 @@ export class ChartView { } const label = (text, css, axis, kind = "tick", extraStyle = null, yPlacement = null) => { - if (!updateLabels) return; + if (!updateLabels) return null; const d = document.createElement("div"); d.textContent = text; d.dataset.xyLabelKind = kind; @@ -4917,7 +5004,22 @@ export class ChartView { d.style.boxSizing = "border-box"; } this._applySlot(d, kind === "label" ? "axis_title" : "tick_label"); - this._applyStyle(d, extraStyle); + const axisLabelStyle = kind === "label" ? { + "font-family": this._axisStyleValue(axis, "label_font_family"), + "font-style": this._axisStyleValue(axis, "label_font_style"), + "font-weight": this._axisStyleValue(axis, "label_font_weight"), + } : null; + if (axisLabelStyle) { + for (const key of Object.keys(axisLabelStyle)) { + if (axisLabelStyle[key] === undefined) delete axisLabelStyle[key]; + } + } + this._applyStyle( + d, + axisLabelStyle || extraStyle + ? { ...(axisLabelStyle || {}), ...(extraStyle || {}) } + : null, + ); this.labels.appendChild(d); if (kind === "tick" && axis && axis.kind === "category" && yPlacement) { // Rotation contributes half the untransformed label height to each @@ -4943,6 +5045,7 @@ export class ChartView { d.style.maxWidth = `min(var(--chart-tick-label-max-width, ${available}px), ${available}px)`; } + return d; }; const xLabelCandidates = []; for (const v of (xt.labels || xt.ticks)) { @@ -4956,9 +5059,30 @@ export class ChartView { "tick_label_size", this._axisStyleNumber(xAxis, "tick_size", 11), ); + // Spine→label distance. mpl measures tick padding from the outward end of + // the tick mark, and a `top` label then needs `fontRoom` more to clear its + // own line box. That derived geometry only applies once the axis authors + // tick geometry: core's default tick_length is 0 and it has no default + // tick_label_pad, so deriving it unconditionally would move the labels of + // every chart that styles no ticks. Unstyled axes keep `unstyled`, the + // per-side gap this client has always used (pyplot supplies mpl's + // {x,y}tick.major.pad, so it takes the derived branch). Mirrors + // `_axis_tick_label_offset` in `_svg.py`/`_raster.py`. + const tickLabelOffset = (axis, unstyled, fontRoom = 0) => { + const authored = this._axisStyleValue(axis, "tick_padding") !== undefined + || this._axisStyleValue(axis, "tick_length") !== undefined; + if (!authored) return unstyled; + const length = Math.max(0, this._axisStyleNumber(axis, "tick_length", 0)); + const direction = String(this._axisStyleValue(axis, "tick_direction") || "out"); + const outward = direction === "in" ? 0 : direction === "inout" ? length / 2 : length; + const pad = outward + this._axisStyleNumber(axis, "tick_padding", 4); + return pad + fontRoom; + }; for (const item of this._layoutTickLabels(xAxis, "x", xLabelCandidates)) { const rowOffset = Number(item.row || 0) * (Math.max(8, tickLabelSize) + 4); - const top = xAxis.side === "top" ? p.y - 18 - rowOffset : p.y + p.h + 6 + rowOffset; + const top = xAxis.side === "top" + ? p.y - tickLabelOffset(xAxis, 18, Math.max(8, tickLabelSize) * 1.2) - rowOffset + : p.y + p.h + tickLabelOffset(xAxis, 6) + rowOffset; const placement = this._xTickLabelTransform(xAxis, item.angle); label( item.text, @@ -4985,7 +5109,9 @@ export class ChartView { this._axisStyleNumber(axis, "tick_size", 11), ); const rowOffset = Number(item.row || 0) * (Math.max(8, tickLabelSize) + 4); - const top = axis.side === "top" ? p.y - 18 - rowOffset : p.y + p.h + 6 + rowOffset; + const top = axis.side === "top" + ? p.y - tickLabelOffset(axis, 18, Math.max(8, tickLabelSize) * 1.2) - rowOffset + : p.y + p.h + tickLabelOffset(axis, 6) + rowOffset; const placement = this._xTickLabelTransform(axis, item.angle); label( item.text, @@ -4997,7 +5123,7 @@ export class ChartView { if (axis.label && this._axisTickLabelStrategy(axis) !== "none") { const top = axis.side === "top" ? p.y - 34 : p.y + p.h + 24; const fallbackCss = - `left:${p.x + p.w / 2}px;top:${top}px;transform:translateX(-50%);font-weight:500;`; + `left:${p.x + p.w / 2}px;top:${top}px;transform:translateX(-50%);font-weight:400;`; const placement = this._axisLabelCss(axis, "x", fallbackCss); label(axis.label, placement.css, axis, "label", placement.style); } @@ -5014,7 +5140,8 @@ export class ChartView { // tick. Unset defaults to the tick-side edge — mpl `ha`: "end" left of // the plot, "start" right of it — reproducing the classic layout. const yLabelPlacement = (axis, onRight, item) => { - const pin = onRight ? p.x + p.w + 8 : p.x - 8; + const offset = tickLabelOffset(axis, 8); + const pin = onRight ? p.x + p.w + offset : p.x - offset; const anchor = this._axisTickLabelAnchor(axis) ?? (onRight ? "start" : "end"); const angle = Number(item.angle || 0); const shift = anchor === "end" ? "-100%" : anchor === "start" ? "0%" : "-50%"; @@ -5047,24 +5174,52 @@ export class ChartView { } if (axis.label && this._axisTickLabelStrategy(axis) !== "none") { const fallbackCss = axis.side === "left" - ? `left:10px;top:${p.y + p.h / 2}px;transform:rotate(-90deg) translateX(50%);transform-origin:left;font-weight:500;` - : `left:${p.x + p.w + 40}px;top:${p.y + p.h / 2}px;transform:rotate(90deg) translateX(-50%);transform-origin:left;font-weight:500;`; + ? `left:10px;top:${p.y + p.h / 2}px;transform:rotate(-90deg) translateX(50%);transform-origin:left;font-weight:400;` + : `left:${p.x + p.w + 40}px;top:${p.y + p.h / 2}px;transform:rotate(90deg) translateX(-50%);transform-origin:left;font-weight:400;`; const placement = this._axisLabelCss(axis, "y", fallbackCss); label(axis.label, placement.css, axis, "label", placement.style); } } + const attachYTitleToTicks = (title, axis, onRight) => { + if (!title || !axis) return; + const position = String(axis.label_position || "center").replace(/-/g, "_"); + if (position.startsWith("inside_")) return; + const tickLabels = [...this.labels.children].filter((element) => + element.dataset.xyLabelKind === "tick" + && element.dataset.xyAxis === String(axis.id ?? "") + ); + if (!tickLabels.length) return; + const root = this.root.getBoundingClientRect(); + const tickRects = tickLabels.map((element) => element.getBoundingClientRect()); + const titleRect = title.getBoundingClientRect(); + const fontSize = parseFloat(getComputedStyle(title).fontSize) || 12; + const labelOffset = Number(axis.label_offset || 0); + const targetEdge = onRight + ? Math.max(...tickRects.map((rect) => rect.right)) + 0.4 * fontSize + labelOffset + : Math.min(...tickRects.map((rect) => rect.left)) - 0.4 * fontSize - labelOffset; + const currentEdge = onRight ? titleRect.left : titleRect.right; + const currentLeft = parseFloat(title.style.left) || 0; + title.style.left = `${currentLeft + targetEdge - currentEdge}px`; + // Keep an unusually large title inside the chart canvas. + const adjusted = title.getBoundingClientRect(); + const correction = adjusted.left < root.left + ? root.left - adjusted.left + 1 + : adjusted.right > root.right ? root.right - adjusted.right - 1 : 0; + if (correction) title.style.left = `${parseFloat(title.style.left) + correction}px`; + }; if (s.x_axis.label && !hideX) { const top = xAxis.side === "top" ? p.y - 34 : p.y + p.h + 24; - const fallbackCss = `left:${p.x + p.w / 2}px;top:${top}px;transform:translateX(-50%);font-weight:500;`; + const fallbackCss = `left:${p.x + p.w / 2}px;top:${top}px;transform:translateX(-50%);font-weight:400;`; const placement = this._axisLabelCss(xAxis, "x", fallbackCss); label(s.x_axis.label, placement.css, xAxis, "label", placement.style); } if (s.y_axis.label && !hideY) { const fallbackCss = yAxis.side === "right" - ? `left:${p.x + p.w + 40}px;top:${p.y + p.h / 2}px;transform:rotate(90deg) translateX(-50%);transform-origin:left;font-weight:500;` - : `left:10px;top:${p.y + p.h / 2}px;transform:rotate(-90deg) translateX(50%);transform-origin:left;font-weight:500;`; + ? `left:${p.x + p.w + 40}px;top:${p.y + p.h / 2}px;transform:rotate(90deg) translateX(-50%);transform-origin:left;font-weight:400;` + : `left:10px;top:${p.y + p.h / 2}px;transform:rotate(-90deg) translateX(50%);transform-origin:left;font-weight:400;`; const placement = this._axisLabelCss(yAxis, "y", fallbackCss); - label(s.y_axis.label, placement.css, yAxis, "label", placement.style); + const title = label(s.y_axis.label, placement.css, yAxis, "label", placement.style); + attachYTitleToTicks(title, yAxis, yAxis.side === "right"); } this._drawAnnotationLabels(updateLabels); // Label layout resolves responsive callout offsets before the pointer is diff --git a/js/src/51_annotations.ts b/js/src/51_annotations.ts index 88303f83..c3920c91 100644 --- a/js/src/51_annotations.ts +++ b/js/src/51_annotations.ts @@ -383,7 +383,7 @@ Object.assign(ChartView.prototype, { const laidOut = []; this._resolvedAnnotationAnchors = new Map(); for (const [annotationIndex, ann] of annotations.entries()) { - const text = typeof ann.text === "string" ? ann.text : ""; + const text: string = typeof ann.text === "string" ? ann.text : ""; if (!text) continue; const style = ann && typeof ann.style === "object" ? ann.style : {}; let px = null; @@ -448,7 +448,24 @@ Object.assign(ChartView.prototype, { continue; } const d = document.createElement("div"); - d.textContent = text; + const mathRanges = String(style.math_italic_ranges || "") + .split(",") + .map((range) => range.split(":").map(Number)) + .filter(([start, end]) => Number.isInteger(start) && Number.isInteger(end) && start >= 0 && start < end); + if (mathRanges.length) { + for (const [index, char] of Array.from(text).entries()) { + if (mathRanges.some(([start, end]) => start <= index && index < end)) { + const italic = document.createElement("span"); + italic.style.fontStyle = "italic"; + italic.textContent = char; + d.appendChild(italic); + } else { + d.appendChild(document.createTextNode(char)); + } + } + } else { + d.textContent = text; + } const dx = Number.isFinite(Number(ann.dx)) ? Number(ann.dx) : 0; const dy = Number.isFinite(Number(ann.dy)) ? Number(ann.dy) : 0; // Rule/band specs carry no anchor; default to the placement that keeps @@ -520,6 +537,7 @@ Object.assign(ChartView.prototype, { const opacityIsShape = ann.kind !== "text" && ann.kind !== "callout"; const labelStyle = {}; for (const [key, value] of Object.entries(style)) { + if (key === "math_italic_ranges") continue; if (key === "opacity" && ann.kind === "text") { labelStyle[key] = value; continue; diff --git a/pr-assets/matplotlib-gallery-consolidation/annotation-basic.png b/pr-assets/matplotlib-gallery-consolidation/annotation-basic.png new file mode 100644 index 0000000000000000000000000000000000000000..b9791109c3dbe7035e7e092e6a99254de4306ccd GIT binary patch literal 199040 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
k#)ud3ZnJM!XaT{etZq1jS^LGzgx%eZ&f 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 literal 0 HcmV?d00001 diff --git a/pr-assets/matplotlib-gallery-consolidation/bar-label-demo.png b/pr-assets/matplotlib-gallery-consolidation/bar-label-demo.png new file mode 100644 index 0000000000000000000000000000000000000000..af9825a47f2324e1f61e254c3bd0e7644126923f GIT binary patch literal 114064 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 z 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 P>2?SAd%IU4Ph9>7>V|4C literal 0 HcmV?d00001 diff --git a/pr-assets/matplotlib-gallery-consolidation/provenance.json b/pr-assets/matplotlib-gallery-consolidation/provenance.json new file mode 100644 index 00000000..4c1c1ab4 --- /dev/null +++ b/pr-assets/matplotlib-gallery-consolidation/provenance.json @@ -0,0 +1,24 @@ +{ + "matplotlib_version": "3.11.0", + "live_base_commit": "077c53f761ae5a9de2324daa527aadc48cd8bb17", + "rendered_base_commit": "58a3782082cb80507033af19a79ec683f6438936", + "head_code_commit": "47871a01db1ad02d1f64bda71fd1a50f9ab89853", + "base_source_tree_note": "The rendered base and live base are byte-identical under js, python/xy, and src; intervening commits only changed release infrastructure and documentation.", + "full_frame": true, + "comparisons": [ + { + "source": "lines_bars_and_markers/bar_label_demo.py", + "figure": 0, + "file": "bar-label-demo.png", + "dimensions": [2304, 670], + "sha256": "a4e3c429176559133f87cc8aecb3b9aeaa2faf1eacc9e2c9de2012632ae83f51" + }, + { + "source": "text_labels_and_annotations/annotation_basic.py", + "figure": 0, + "file": "annotation-basic.png", + "dimensions": [2304, 670], + "sha256": "4a9974b506a41ce36f1b94b1c536fa1460b4acfc097105921b62bad8eab9687f" + } + ] +} diff --git a/python/xy/_figure.py b/python/xy/_figure.py index 80ea37bc..1f1f0c3a 100644 --- a/python/xy/_figure.py +++ b/python/xy/_figure.py @@ -175,6 +175,7 @@ def set_axis( type_: Optional[str] = None, constant: Optional[float] = None, domain: Optional[tuple[float, float]] = None, + margin: Optional[float] = None, bounds: Any = None, reverse: bool = False, format: Optional[str] = None, @@ -202,6 +203,8 @@ def set_axis( domain = self._finite_increasing_pair(domain, f"{axis_id} axis domain") if type_ == "log" and domain[0] <= 0: raise ValueError(f"{axis_id} log axis domain must be positive") + if margin is not None: + margin = self._nonnegative_scalar(margin, f"{axis_id} axis margin") if isinstance(bounds, str): if bounds != "data": raise ValueError(f"{axis_id} axis bounds must be an increasing pair or 'data'") @@ -235,6 +238,7 @@ def set_axis( "type": type_, "constant": constant, "domain": domain, + "margin": margin, "bounds": bounds, "reverse": self._bool_param(reverse, f"{axis_id} axis reverse"), "format": self._optional_text(format, f"{axis_id} axis format"), @@ -1040,21 +1044,35 @@ def _range(self, axis_id: str, *, use_domain: bool = True) -> tuple[float, float if not positive_los: raise ValueError(f"{axis_id} log axis requires at least one positive value") lo, hi = min(positive_los), max(positive_his) - if lo == hi: + margin = opts.get("margin") + if lo == hi and margin is None: pad = abs(lo) * 0.05 or 0.5 lo, hi = lo - pad, hi + pad if scale == "log" and lo <= 0: lo = hi / 10.0 return (hi, lo) if opts.get("reverse") else (lo, hi) - pad = (hi - lo) * 0.03 + if lo == hi: + # Match pyplot's singleton extent: an explicit margin is applied + # to a stable unit interval instead of being silently replaced by + # the core's legacy 5% nonsingular fallback. + hi = lo + 1.0 + if margin is None: + margin = 0.03 + if scale == "log" and opts.get("margin") is not None: + transformed_lo, transformed_hi = np.log10((lo, hi)) + pad = (transformed_hi - transformed_lo) * margin + out_lo = 10.0 ** (transformed_lo - pad) + out_hi = 10.0 ** (transformed_hi + pad) + else: + pad = (hi - lo) * margin + out_lo = lo - pad + out_hi = hi + pad anchor = self._zero_baseline_anchor(axis_id) - out_lo = lo - pad - out_hi = hi + pad if anchor == "lo" and lo == 0.0 and hi > 0.0: out_lo = 0.0 elif anchor == "hi" and hi == 0.0 and lo < 0.0: out_hi = 0.0 - if scale == "log": + if scale == "log" and opts.get("margin") is None: out_lo = max(out_lo, lo / 10.0, np.nextafter(0.0, 1.0)) return (out_hi, out_lo) if opts.get("reverse") else (out_lo, out_hi) @@ -1067,6 +1085,11 @@ def _zero_baseline_anchor(self, axis_id: str) -> Optional[str]: """ axis = self._axis_dim(axis_id) for t in self.traces: + # Only rectangle families have a sticky zero edge. Segment-based + # marks such as stem/errorbar also carry x0/x1/y0/y1 columns, but + # Matplotlib pads their baseline like ordinary line data. + if t.kind not in {"bar", "histogram"}: + continue if axis == "x" and t.x_axis != axis_id: continue if axis == "y" and t.y_axis != axis_id: diff --git a/python/xy/_fontmetrics.py b/python/xy/_fontmetrics.py new file mode 100644 index 00000000..0f599626 --- /dev/null +++ b/python/xy/_fontmetrics.py @@ -0,0 +1,64 @@ +"""Advance widths of the core's embedded DejaVu Sans face. + +@generated by scripts/gen_font.py — do not edit by hand. + +`src/font.rs` bakes the same numbers for the Rust rasterizer that draws the +text; this module is how `_svg.layout()` can size an axis gutter from the ink +it is about to reserve for. DejaVu Sans is also Matplotlib's default face, so +an advance measured here is the advance Matplotlib would lay out. +""" + +from __future__ import annotations + +BASE_PX = 16 +CELL_H = 19 +ASCENT = 15 +DESCENT = 4 +FIRST = 32 +LAST = 126 + +# fmt: off +# Advances at BASE_PX for printable ASCII, `FIRST` first. +ASCII_ADVANCES: tuple[int, ...] = ( + 5, 6, 7, 13, 10, 15, 12, 4, 6, 6, 8, 13, 5, 6, 5, 5, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 5, 5, 13, 13, 13, 8, 16, 11, 11, 11, 12, 10, 9, 12, + 12, 5, 5, 10, 9, 14, 12, 13, 10, 13, 11, 10, 10, 12, 11, 16, 11, 10, 11, 6, + 5, 6, 13, 8, 8, 10, 10, 9, 10, 10, 6, 10, 10, 4, 4, 9, 4, 16, 10, 10, + 10, 10, 7, 8, 6, 10, 9, 13, 9, 9, 8, 10, 5, 10, 13, +) + +# Advances at BASE_PX for the non-ASCII glyphs, keyed by codepoint. +EXTRA_ADVANCES: dict[int, int] = { + 176: 8, 177: 13, 178: 6, 179: 6, 181: 10, 183: 5, 185: 6, 215: 13, + 246: 10, 252: 10, + 915: 9, 916: 11, 920: 13, 923: 11, 926: 10, 928: 12, 931: 10, 933: 10, + 934: 13, 936: 13, 937: 12, 945: 11, 946: 10, 947: 9, 948: 10, 949: 9, + 950: 9, 951: 10, 952: 10, 953: 5, 954: 9, 955: 9, 956: 10, 957: 9, + 958: 9, 959: 10, 960: 10, 961: 10, 963: 10, 964: 10, 965: 9, 966: 11, + 967: 9, 968: 11, 969: 13, 7522: 3, 7523: 4, 7524: 6, 7525: 7, 8211: 8, + 8212: 16, 8216: 5, 8217: 5, 8220: 8, 8221: 8, 8230: 16, 8304: 6, 8305: 3, + 8308: 6, 8309: 6, 8310: 6, 8311: 6, 8312: 6, 8313: 6, 8314: 8, 8315: 8, + 8316: 8, 8317: 4, 8318: 4, 8319: 6, 8320: 6, 8321: 6, 8322: 6, 8323: 6, + 8324: 6, 8325: 6, 8326: 6, 8327: 6, 8328: 6, 8329: 6, 8330: 8, 8331: 8, + 8332: 8, 8333: 4, 8334: 4, 8336: 6, 8337: 7, 8338: 7, 8339: 7, 8341: 6, + 8342: 7, 8343: 3, 8344: 10, 8345: 6, 8346: 7, 8347: 6, 8348: 5, 8592: 13, + 8594: 13, 8706: 8, 8711: 11, 8712: 14, 8722: 13, 8723: 13, 8730: 10, 8733: 11, + 8734: 13, 8747: 8, 8776: 13, 8800: 13, 8804: 13, 8805: 13, +} +# fmt: on + +# Fallback advance for a codepoint the atlas has no glyph for: the +# rasterizer skips it entirely, so it contributes no ink and no advance. +_MISSING = 0 + + +def advance(text: str, font_size: float) -> float: + """Advance width in px of `text` rendered at `font_size`.""" + units = 0 + for char in text: + code = ord(char) + if FIRST <= code <= LAST: + units += ASCII_ADVANCES[code - FIRST] + else: + units += EXTRA_ADVANCES.get(code, _MISSING) + return font_size * units / BASE_PX diff --git a/python/xy/_native.py b/python/xy/_native.py index b9c07c41..cbd07df9 100644 --- a/python/xy/_native.py +++ b/python/xy/_native.py @@ -401,6 +401,7 @@ def _load() -> ctypes.CDLL: ctypes.c_void_p, # y_coords (rows f64s) ctypes.c_void_p, # levels (n_levels f64s) ctypes.c_size_t, # n_levels + ctypes.c_uint8, # corner_mask ctypes.c_void_p, # x0 output ctypes.c_void_p, # x1 output ctypes.c_void_p, # y0 output @@ -1930,6 +1931,8 @@ def marching_squares( x_coords: npt.NDArray[np.float64], y_coords: npt.NDArray[np.float64], levels: npt.NDArray[np.float64], + *, + corner_mask: bool = False, ) -> tuple[ npt.NDArray[np.float64], npt.NDArray[np.float64], @@ -1997,6 +2000,7 @@ def extract(outputs: tuple[npt.NDArray[np.float64], ...]) -> int: _ptr_f64(y_coords), _ptr_f64(levels), len(levels), + int(bool(corner_mask)), *(_ptr_f64(output) for output in outputs), len(outputs[0]), ) diff --git a/python/xy/_paint.py b/python/xy/_paint.py index e072b9e5..e9edcec7 100644 --- a/python/xy/_paint.py +++ b/python/xy/_paint.py @@ -10,6 +10,70 @@ ColumnReader = Callable[[int], np.ndarray] +def triangle_mesh_boundary(*vertices: np.ndarray) -> np.ndarray | None: + """Recover the single exterior ring of a tessellated simple polygon. + + ``Axes.fill`` reaches the shared triangle renderer for WebGL, but static + exporters should paint its triangulation as one polygon. Otherwise each + independently antialiased triangle leaks a hairline of background (and + applies translucent alpha more than once) along internal diagonals. + """ + if len(vertices) != 6: + raise ValueError("triangle mesh boundary requires six coordinate arrays") + arrays = [np.asarray(values, dtype=np.float64).reshape(-1) for values in vertices] + n = min((len(values) for values in arrays), default=0) + if n == 0: + return None + finite = np.concatenate(arrays) + span = float(np.nanmax(finite) - np.nanmin(finite)) + # Each triangle coordinate is transported in an independently offset + # float32 column, so the same source vertex may decode a few ULPs apart in + # x0/x1/x2. The joined-fill flag is only used for one simple polygon; a + # generous relative bucket is still far below meaningful edge spacing. + tolerance = max(span * 2e-5, 1e-12) + + def vertex_key(point: tuple[float, float]) -> tuple[int, int]: + return (round(point[0] / tolerance), round(point[1] / tolerance)) + + edge_counts: dict[tuple[tuple[int, int], tuple[int, int]], int] = {} + points_by_key: dict[tuple[int, int], tuple[float, float]] = {} + for index in range(n): + points = ( + (float(arrays[0][index]), float(arrays[1][index])), + (float(arrays[2][index]), float(arrays[3][index])), + (float(arrays[4][index]), float(arrays[5][index])), + ) + for start, end in zip(points, points[1:] + points[:1], strict=True): + start_key, end_key = vertex_key(start), vertex_key(end) + points_by_key.setdefault(start_key, start) + points_by_key.setdefault(end_key, end) + edge = (start_key, end_key) if start_key <= end_key else (end_key, start_key) + edge_counts[edge] = edge_counts.get(edge, 0) + 1 + boundary = [edge for edge, count in edge_counts.items() if count == 1] + if len(boundary) < 3: + return None + adjacency: dict[tuple[int, int], list[tuple[int, int]]] = {} + for start, end in boundary: + adjacency.setdefault(start, []).append(end) + adjacency.setdefault(end, []).append(start) + if any(len(neighbors) != 2 for neighbors in adjacency.values()): + return None + first = boundary[0][0] + ring = [first] + previous: tuple[int, int] | None = None + current = first + for _ in range(len(boundary)): + neighbors = adjacency[current] + following = neighbors[0] if neighbors[0] != previous else neighbors[1] + if following == first: + if len(ring) != len(boundary): + return None + return np.asarray([points_by_key[key] for key in ring], dtype=np.float64) + ring.append(following) + previous, current = current, following + return None + + def direct_rgba(channel: dict[str, Any], n: int, read_column: ColumnReader) -> np.ndarray | None: """Decode a packed normalized RGBA8 channel to canonical float RGBA.""" if channel.get("mode") != "direct_rgba": diff --git a/python/xy/_raster.py b/python/xy/_raster.py index 2514840a..3ba0dba0 100644 --- a/python/xy/_raster.py +++ b/python/xy/_raster.py @@ -11,8 +11,10 @@ from __future__ import annotations +import math import struct from collections.abc import Callable, Sequence +from itertools import pairwise from os import PathLike from typing import Any, Optional @@ -30,14 +32,18 @@ _axis_label_geometry, _axis_scales, _axis_tick_font_size, + _axis_tick_label_baseline_shift, _axis_tick_label_layout, + _axis_tick_label_offset, _axis_tick_label_strategy, + _box_corner_radius, _colorbar_right_axis_room, _colormap_stops, _column, _corner_radii, _css, _density_column, + _estimated_text_width, _heatmap_rgba_grid, _legend_layout, _lut, @@ -74,12 +80,15 @@ _AFFINE_POINTS, _AFFINE_CHANNEL_POINTS, _STROKED_TRIANGLES, -) = range(17) + _STYLED_TEXT, +) = range(18) # Anchor-byte rotation flags — must match TEXT_ROTATED/TEXT_ROTATED_CW in # src/raster.rs. CCW reads bottom-to-top (y-axis titles), CW top-to-bottom # (right-margin titles, matplotlib rotation=270). _TEXT_ROT_CCW = 0x80 _TEXT_ROT_CW = 0x40 +_TEXT_ITALIC = 0x01 +_TEXT_BOLD = 0x02 _SYMBOLS = { "circle": 0, "square": 1, @@ -601,9 +610,36 @@ def heatmap_image( self.buf += stops.tobytes() def text( - self, x: float, y: float, anchor: int, size: float, color: tuple[int, ...], s: str + self, + x: float, + y: float, + anchor: int, + size: float, + color: tuple[int, ...], + s: str, + *, + angle: float = 0.0, + italic: bool = False, + bold: bool = False, + italic_ranges: Sequence[tuple[int, int]] = (), ) -> None: data = str(s).encode("utf-8") + if angle or italic or bold or italic_ranges: + self.buf.append(_STYLED_TEXT) + self._f(x) + self._f(y) + self.buf.append(anchor & 0x03) + self._f(size) + self._raw_f(angle) + self.buf.append((_TEXT_ITALIC if italic else 0) | (_TEXT_BOLD if bold else 0)) + self._u32(len(italic_ranges)) + for start, end in italic_ranges: + self._u32(start) + self._u32(end) + self._rgba(color) + self._u32(len(data)) + self.buf += data + return self.buf.append(_TEXT_OP) self._f(x) self._f(y) @@ -618,6 +654,35 @@ def _rect_pts(x0: float, y0: float, x1: float, y1: float) -> list[tuple[float, f return [(x0, y0), (x1, y0), (x1, y1), (x0, y1)] +def _round_rect_pts( + x0: float, y0: float, x1: float, y1: float, radius: float, *, steps: int = 4 +) -> list[tuple[float, float]]: + """A rounded rectangle as a closed polygon, corners arc-approximated. + + The rasterizer draws polygons, not paths, so a `boxstyle="round"` bbox is + flattened here: `steps` segments per quarter turn is enough that a 5–8 px + corner reads as round at export scale. Degenerate radii fall back to the + square rect so callers never special-case it. + """ + radius = max(0.0, min(radius, (x1 - x0) / 2.0, (y1 - y0) / 2.0)) + if radius <= 0.0: + return _rect_pts(x0, y0, x1, y1) + pts: list[tuple[float, float]] = [] + # (center, start angle) per corner, walking clockwise in screen space + # (y down) from the top-left so the winding matches _rect_pts. + corners = ( + ((x0 + radius, y0 + radius), math.pi), + ((x1 - radius, y0 + radius), -math.pi / 2.0), + ((x1 - radius, y1 - radius), 0.0), + ((x0 + radius, y1 - radius), math.pi / 2.0), + ) + for (cx, cy), start in corners: + for i in range(steps + 1): + angle = start + (math.pi / 2.0) * (i / steps) + pts.append((cx + radius * math.cos(angle), cy + radius * math.sin(angle))) + return pts + + def _grad_line( space: str, direction: str, @@ -776,9 +841,10 @@ def render_raster( # "none" silences the whole axis chrome (sparklines); "off" hides only the # label text and keeps baselines and the axis title (mpl shared axes). frame_sides = spec.get("frame_sides") + explicit_frame_sides = frame_sides is not None if frame_sides is None: frame_sides = [xa.get("side", "bottom"), ya.get("side", "left")] - if not hide_y: + if not hide_y or explicit_frame_sides: if "left" in frame_sides: cmd.stroke( [(px0, py0), (px0, py1)], @@ -791,7 +857,7 @@ def render_raster( float(ystyle.get("axis_width", 1)), _parse_color(_css(ystyle.get("axis_color"), default_axis)), ) - if not hide_x: + if not hide_x or explicit_frame_sides: if "top" in frame_sides: cmd.stroke( [(px0, py0), (px1, py0)], @@ -905,8 +971,6 @@ def tick_span(style: dict[str, Any]) -> tuple[float, float]: _parse_color(_css(axis_style.get("tick_color"), default_axis)), ) - text_c = _parse_color(default_text) - def rotation_flag(angle: float) -> int: normalized = angle % 360.0 if abs(normalized - 90.0) < 1e-9: @@ -943,6 +1007,18 @@ def emit_tick_labels( ) font_size = _axis_tick_font_size(axis) side = axis.get("side", "bottom" if is_x else "left") + # Unstyled defaults reproduce the pre-`tick_label_pad` placement exactly. + # The bottom gap is 15 here against the SVG exporter's 16: that 1 px has + # always separated the two and is not this seam's to change. + if is_x: + label_offset = ( + _axis_tick_label_offset(axis, 7.0, 0.2) + if side == "top" + else _axis_tick_label_offset(axis, 15.0, 0.8) + ) + else: + label_offset = _axis_tick_label_offset(axis, 8.0) + baseline_shift = _axis_tick_label_baseline_shift(axis) # An explicit tick_label_anchor (axis spec or style) overrides the # side-derived default, matching the browser client and SVG export. explicit_anchor = _tick_label_anchor(axis, axis_style, "") @@ -951,11 +1027,15 @@ def emit_tick_labels( if is_x: row_offset = float(item["row"]) * (font_size + 4) x = float(item["pos"]) - y = py0 - 7 - row_offset if side == "top" else py1 + 15 + row_offset + y = ( + py0 - label_offset - row_offset + if side == "top" + else py1 + label_offset + row_offset + ) anchor = _TEXT_ANCHOR_CODES[explicit_anchor] if explicit_anchor else 1 else: - x = px1 + 8 if side == "right" else px0 - 8 - y = float(item["pos"]) + 4 + x = px1 + label_offset if side == "right" else px0 - label_offset + y = float(item["pos"]) + baseline_shift default_anchor = 0 if side == "right" else 2 anchor = _TEXT_ANCHOR_CODES[explicit_anchor] if explicit_anchor else default_anchor cmd.text(x, y, anchor | flag, font_size, tick_color, item["text"]) @@ -969,13 +1049,25 @@ def emit_tick_labels( _ticks, tick_labels, step = extra_y_ticks[axis_id] emit_tick_labels(axis, tick_labels, step, axis_scale, is_x=False) if spec.get("title"): + title_style = ((spec.get("dom") or {}).get("styles") or {}).get("title") or {} + title_italic, title_bold = _native_font_emphasis( + { + "font_style": title_style.get("font-style"), + # 400 = Matplotlib's `axes.titleweight: normal`; the baked + # atlas only has a bold face, so anything >= 600 rounds up to + # it. Mirrors the SVG/browser title default. + "font_weight": title_style.get("font-weight", 400), + } + ) cmd.text( width / 2, plot["y"] - plot["top_axis_room"] - (10 if compact else 12), 1, - 14, - text_c, + _px_size(title_style.get("font-size"), 14.0), + _parse_color(_css(title_style.get("color"), default_text)), str(spec["title"]), + italic=title_italic, + bold=title_bold, ) def emit_axis_title(axis: dict[str, Any], *, is_x: bool) -> None: @@ -984,14 +1076,29 @@ def emit_axis_title(axis: dict[str, Any], *, is_x: bool) -> None: axis_style = axis.get("style") or {} geometry = _axis_label_geometry(axis, plot, is_x=is_x) anchor = {"start": 0, "middle": 1, "end": 2}[geometry["anchor"]] - cmd.text( + italic, bold = _native_font_emphasis( + { + "font_style": axis_style.get("label_font_style"), + "font_weight": axis_style.get("label_font_weight", 400), + } + ) + args = ( geometry["x"], geometry["y"], - anchor | rotation_flag(float(geometry["angle"])), + anchor, geometry["font_size"], _parse_color(_css(axis_style.get("label_color"), default_text)), str(axis["label"]), ) + if italic or bold: + cmd.text(*args, angle=float(geometry["angle"]), italic=italic, bold=bold) + else: + cmd.text( + args[0], + args[1], + anchor | rotation_flag(float(geometry["angle"])), + *args[3:], + ) emit_axis_title(xa, is_x=True) emit_axis_title(ya, is_x=False) @@ -1001,19 +1108,32 @@ def emit_axis_title(axis: dict[str, Any], *, is_x: bool) -> None: emit_axis_title(axis, is_x=False) named = [t for t in spec["traces"] if t.get("name")] - show_main_legend = spec.get("show_legend", True) and bool(named) + main_legend = spec.get("legend") or {} + main_items = main_legend.get("items") or named + show_main_legend = spec.get("show_legend", True) and bool(main_items) extra_legends = [(extra, extra.get("items") or []) for extra in spec.get("extra_legends") or []] - legend_present = show_main_legend or any(items for _extra, items in extra_legends) - if legend_present: - # The browser scrolls an oversized legend. Static files cannot, so - # clip the bounded/truncated equivalent to the plot rectangle. - cmd.clip(px0, py0, plot["w"], plot["h"]) + legends: list[tuple[list[dict[str, Any]], dict[str, Any]]] = [] if show_main_legend: - _emit_legend(cmd, named, plot, spec.get("legend") or {}, default_text) - for extra, items in extra_legends: - if items: - _emit_legend(cmd, items, plot, extra, default_text) - if legend_present: + legends.append((main_items, main_legend)) + legends.extend((items, extra) for extra, items in extra_legends if items) + # The browser scrolls an oversized legend. Static files cannot, so clip the + # bounded/truncated equivalent to the plot rectangle. The exemption for an + # anchored legend (which is placed relative to, and may sit outside, the + # axes) is scoped per legend exactly as in `_svg.py`: one anchored legend + # must not lift the clip off its non-anchored siblings. The clip is a + # stateful raster command, so only emit it on a transition — an + # all-anchored or all-unanchored figure yields the same stream as before. + clipped_to_plot = False + for items, options in legends: + want_clip = not options.get("anchor") + if want_clip != clipped_to_plot: + if want_clip: + cmd.clip(px0, py0, plot["w"], plot["h"]) + else: + cmd.clip(0, 0, width, height) + clipped_to_plot = want_clip + _emit_legend(cmd, items, plot, options, default_text) + if clipped_to_plot: cmd.clip(0, 0, width, height) if spec.get("colorbar"): _emit_colorbar( @@ -1077,6 +1197,29 @@ def _annotation_point( return float(sx(x)), float(sy(y)) +def _native_font_emphasis(style: dict[str, Any]) -> tuple[bool, bool]: + """Return baked-font italic/bold approximations for an annotation.""" + italic = str(style.get("font_style", "")).lower() in {"italic", "oblique"} + weight = str(style.get("font_weight", "")).lower() + try: + bold = float(weight) >= 600 + except ValueError: + bold = weight in {"bold", "semibold", "demibold", "heavy", "black"} + return italic, bold + + +def _math_italic_ranges(style: dict[str, Any]) -> list[tuple[int, int]]: + ranges: list[tuple[int, int]] = [] + for item in str(style.get("math_italic_ranges", "")).split(","): + try: + start, end = (int(value) for value in item.split(":", 1)) + except ValueError: + continue + if 0 <= start < end: + ranges.append((start, end)) + return ranges + + def _emit_annotations( cmd: _Cmd, annotations: list[dict[str, Any]], @@ -1171,6 +1314,9 @@ def _emit_annotations( ) color = _rgba(label_color, _TEXT, float(label_opacity)) rotation = float(style.get("rotation", 0.0)) % 360.0 + italic, bold = _native_font_emphasis(style) + math_ranges = _math_italic_ranges(style) + line_offset = 0 if rotation in (90.0, 270.0): # Vertical text via the rasterizer's rotated glyph paths. # matplotlib aligns the post-rotation box: vertical_align picks @@ -1188,14 +1334,24 @@ def _emit_annotations( base = {0: ascent, 1: (ascent - descent) / 2, 2: -descent}[anchor] stack = -line_height if cw else line_height # later lines: glyph-down for index, line in enumerate(lines): + line_ranges = [ + (max(0, start - line_offset), min(len(line), end - line_offset)) + for start, end in math_ranges + if start < line_offset + len(line) and end > line_offset + ] cmd.text( x + base + index * stack, y, - along | (_TEXT_ROT_CW if cw else _TEXT_ROT_CCW), + along, font_size, color, line, + angle=90.0 if cw else -90.0, + italic=italic, + bold=bold, + italic_ranges=line_ranges, ) + line_offset += len(line) + 1 continue first_y = y - (len(lines) - 1) * line_height / 2 vertical_align = style.get("vertical_align") @@ -1203,15 +1359,78 @@ def _emit_annotations( first_y += font_size * 0.35 elif vertical_align == "top": first_y += font_size * 0.8 + elif vertical_align == "bottom": + first_y -= font_size * 0.2 + text_x = x + float(ann.get("dx", 0.0)) + text_y = first_y + float(ann.get("dy", 0.0)) + _emit_text_box(cmd, style, lines, text_x, text_y, line_height, font_size, anchor) for index, line in enumerate(lines): + line_ranges = [ + (max(0, start - line_offset), min(len(line), end - line_offset)) + for start, end in math_ranges + if start < line_offset + len(line) and end > line_offset + ] cmd.text( - x + float(ann.get("dx", 0.0)), - first_y + index * line_height + float(ann.get("dy", 0.0)), + text_x, + text_y + index * line_height, anchor, font_size, color, line, + angle=-rotation, + italic=italic, + bold=bold, + italic_ranges=line_ranges, ) + line_offset += len(line) + 1 + + +def _emit_text_box( + cmd: _Cmd, + style: dict[str, Any], + lines: list[str], + x: float, + first_y: float, + line_height: float, + font_size: float, + anchor: int, +) -> None: + """Draw the bounded CSS approximation used by pyplot ``text(bbox=)``.""" + background = style.get("background") + border = str(style.get("border", "")) + if background is None and not border: + return + pad_parts = str(style.get("padding", "0")).split() + + def px(value: str) -> float: + try: + return max(0.0, float(value.removesuffix("px"))) + except ValueError: + return 0.0 + + pad_y = px(pad_parts[0]) if pad_parts else 0.0 + pad_x = px(pad_parts[1]) if len(pad_parts) > 1 else pad_y + text_width = _estimated_text_width(lines, font_size) + left = x - (text_width / 2 if anchor == 1 else text_width if anchor == 2 else 0.0) - pad_x + top = first_y - font_size * 0.8 - pad_y + right = left + text_width + pad_x * 2 + bottom = top + font_size + (len(lines) - 1) * line_height + pad_y * 2 + # `boxstyle="round"`/`round4` set border_radius, which the browser applies + # as CSS border-radius; round the same corners here or the exported box is + # square where the live one is not. + points = _round_rect_pts( + left, top, right, bottom, _box_corner_radius(style, right - left, bottom - top) + ) + if background is not None: + cmd.fill(points, _parse_color(str(background))) + if border: + parts = border.split() + try: + width = max(0.0, float(parts[0].removesuffix("px"))) + except (IndexError, ValueError): + width = 1.0 + if width: + cmd.stroke(points + [points[0]], width, _parse_color(parts[-1])) def _emit_area( @@ -1300,6 +1519,14 @@ def read(index: int) -> np.ndarray: fill_op = _fill_opacity(style, 0.8) stroke_op = _stroke_opacity(style, 0.8) + artist_alpha = style.get("artist_alpha") + if artist_alpha is not None: + # Matplotlib artist alpha replaces the intrinsic paint alpha. Scalar + # alpha does not need a style channel, so retain it in both affine + # scatter fast paths instead of silently painting opaque points. + scalar_alpha = float(artist_alpha) + fill_op *= scalar_alpha + stroke_op *= scalar_alpha sw = float(style.get("stroke_width", 0.0)) sym = _SYMBOLS.get(style.get("symbol", "circle"), 0) # Transparent is the private wire sentinel for edgecolors="face". The @@ -1320,8 +1547,8 @@ def read(index: int) -> np.ndarray: and (t.get("stroke") is None or t["stroke"].get("mode") == "match_fill") and (color_mode in {"continuous", "categorical"} or size_mode == "continuous") ): - alpha = max(0, min(255, int(round(fill_op * 255)))) - rgb = _parse_color(_css(ch.get("color"), color))[:3] + paint = _parse_color(_css(ch.get("color"), color)) + alpha = max(0, min(255, int(round(fill_op * paint[3])))) cmd.affine_channel_points( cols[t["x"]], cols[t["y"]], @@ -1329,7 +1556,7 @@ def read(index: int) -> np.ndarray: sy, ch, size_ch, - (rgb[0], rgb[1], rgb[2], alpha), + (paint[0], paint[1], paint[2], alpha), sym, sw, stroke, @@ -1349,9 +1576,9 @@ def read(index: int) -> np.ndarray: and not t.get("channels") and (t.get("stroke") is None or t["stroke"].get("mode") == "match_fill") ): - alpha = max(0, min(255, int(round(fill_op * 255)))) - rgb = _parse_color(_css(ch.get("color"), color))[:3] - fill = (rgb[0], rgb[1], rgb[2], alpha) + paint = _parse_color(_css(ch.get("color"), color)) + alpha = max(0, min(255, int(round(fill_op * paint[3])))) + fill = (paint[0], paint[1], paint[2], alpha) radius = float(size_ch.get("size", 4.0)) / 2 cmd.affine_points(cols[t["x"]], cols[t["y"]], sx, sy, radius, fill, sym, sw, stroke) return @@ -1544,7 +1771,9 @@ def read(index: int) -> np.ndarray: x0, y0, x1, y1, x2, y2 = vertices widths = _paint.style_values(t, "stroke_width", n, read, float(style.get("stroke_width", 0.0))) - if t.get("stroke") is not None: + if (t.get("stroke") or {}).get("mode") == "match_fill": + stroke_intrinsic = _trace_paint_rgba(t, "color", n, color, read) + elif t.get("stroke") is not None: stroke_intrinsic = _trace_paint_rgba(t, "stroke", n, color, read) elif style.get("stroke") is not None: stroke_intrinsic = np.tile( @@ -1560,6 +1789,14 @@ def read(index: int) -> np.ndarray: projected = (sx(x0[:n]), sy(y0[:n]), sx(x1[:n]), sy(y1[:n]), sx(x2[:n]), sy(y2[:n])) if n == 0: return + if style.get("joined_fill") and np.all(fills == fills[0]) and np.all(widths == 0.0): + boundary = _paint.triangle_mesh_boundary(x0, y0, x1, y1, x2, y2) + if boundary is not None: + cmd.fill( + list(zip(sx(boundary[:, 0]), sy(boundary[:, 1]), strict=True)), + tuple(int(value) for value in fills[0]), + ) + return if np.all(widths == widths[0]) and np.all(strokes == strokes[0]): cmd.triangles( *projected, @@ -1655,7 +1892,9 @@ def _rect_style_arrays( * 255.0 ).astype(np.uint8) style = trace.get("style") or {} - if trace.get("stroke") is not None: + if (trace.get("stroke") or {}).get("mode") == "match_fill": + stroke_face = face + elif trace.get("stroke") is not None: stroke_face = _trace_paint_rgba(trace, "stroke", n, fallback, read) elif style.get("stroke") is not None: stroke_face = np.tile( @@ -1957,8 +2196,10 @@ def _emit_legend( style_opts = legend["style"] pad, handle, gap = legend["pad"], legend["handle"], legend["gap"] line_h, ncols = legend["line_h"], legend["ncols"] + swatch_h = legend["swatch_h"] title, title_h = legend["title"], legend["title_h"] - cell_w = legend["cell_w"] + font_size, text_h = legend["font_size"], legend["text_h"] + column_offsets = legend["column_offsets"] box_w, box_h = legend["box_w"], legend["box_h"] x, y = legend["x"], legend["y"] # frameon=False (background transparent) drops the box entirely (§ mpl parity). @@ -1973,8 +2214,20 @@ def _emit_legend( else (128, 128, 128, round(255 * alpha)) ) cmd.fill(_rect_pts(x, y, x + box_w, y + box_h), frame) + border = _rgba(style_opts.get("borderColor"), "#cccccc", alpha) + # closed=True: _rect_pts is four corners, so an open polyline strokes + # top/right/bottom and silently drops the left edge. Matplotlib's frame + # is a FancyBboxPatch — all four sides — and so is SVG's . + cmd.stroke(_rect_pts(x, y, x + box_w, y + box_h), 1.0, border, closed=True) if title: - cmd.text(x + pad, y + pad / 2 + 11, 0, 11, _parse_color(text_color), str(title)) + cmd.text( + x + box_w / 2, + y + pad / 2 + font_size * 0.82, + 1, + font_size, + _parse_color(text_color), + str(title), + ) for i, t in enumerate(named[: legend["visible_count"]]): style = t.get("style") or {} color_str = _css( @@ -1983,14 +2236,22 @@ def _emit_legend( ) c = _parse_color(color_str) col, row = i % ncols, i // ncols - rx, ry = x + col * cell_w, y + pad / 2 + title_h + row * line_h - hx0, hx1, cy = rx + pad, rx + pad + handle, ry + 7 + rx, ry = x + column_offsets[col], y + pad / 2 + title_h + row * line_h + hx0, hx1, cy = rx, rx + handle, ry + text_h / 2 kind = t.get("kind") if kind == "scatter": sym = _SYMBOLS.get(style.get("symbol", "circle"), 0) sw = float(style.get("stroke_width", 0.0)) stroke = _rgba(style.get("stroke"), color_str) if sw > 0 else (0, 0, 0, 0) - cmd.point((hx0 + hx1) / 2, cy, 4.0, sym, c, sw, stroke) + cmd.point( + (hx0 + hx1) / 2, + cy, + max(0.5, float(style.get("size", 8.0)) / 2.0), + sym, + c, + sw, + stroke, + ) elif kind in _LEGEND_LINE_KINDS: cmd.stroke( [(hx0, cy), (hx1, cy)], @@ -1999,8 +2260,60 @@ def _emit_legend( dash=style.get("dash"), ) else: - cmd.fill(_rect_pts(hx0, cy - 4, hx1, cy + 4), c) - cmd.text(hx1 + gap, ry + 11, 0, 11, _parse_color(text_color), legend["names"][i]) + cmd.fill(_rect_pts(hx0, cy - swatch_h / 2, hx1, cy + swatch_h / 2), c) + hatch = style.get("hatch") + if hatch: + _emit_legend_hatch( + cmd, + hx0, + hx1, + cy - swatch_h / 2, + cy + swatch_h / 2, + str(hatch), + _parse_color(_css(style.get("hatch_color"), "#222222")), + ) + cmd.text( + hx1 + gap, + ry + font_size * 0.82, + 0, + font_size, + _parse_color(text_color), + legend["names"][i], + ) + + +def _emit_legend_hatch( + cmd: _Cmd, + x0: float, + x1: float, + y0: float, + y1: float, + hatch: str, + color: tuple[int, int, int, int], +) -> None: + mid_y = (y0 + y1) / 2 + if "-" in hatch or "*" in hatch: + cmd.stroke([(x0, mid_y), (x1, mid_y)], 1.0, color) + for char, direction in (("/", 1), ("\\", -1)): + count = min(3, hatch.count(char)) + for index in range(count): + center = x0 + (index + 1) * (x1 - x0) / (count + 1) + half = min((x1 - x0) / 4, (y1 - y0) / 2) + cmd.stroke( + [ + (center - half, mid_y + direction * half), + (center + half, mid_y - direction * half), + ], + 1.0, + color, + ) + if "." in hatch: + for fraction in (0.3, 0.7): + x = x0 + fraction * (x1 - x0) + cmd.stroke([(x, mid_y), (x + 0.1, mid_y)], 1.0, color) + if "*" in hatch: + center = (x0 + x1) / 2 + cmd.stroke([(center, y0), (center, y1)], 1.0, color) def _emit_colorbar( @@ -2010,18 +2323,23 @@ def _emit_colorbar( right_axis_room: float = 0.0, text_color: str = _TEXT, ) -> None: - from ._svg import _linear_ticks, _lut + from ._svg import _colorbar_tick_target, _linear_ticks, _lut orientation = options.get("orientation", "vertical") + shrink = float(options.get("shrink", 1.0)) + anchor = options.get("anchor") or [0.5, 0.5] if orientation == "horizontal": - x = plot["x"] + width = plot["w"] * shrink + x = plot["x"] + (plot["w"] - width) * float(anchor[0]) y = plot["y"] + plot["h"] + (plot["bottom_axis_room"] or 10) - width, height = plot["w"], 18 + height = 18 else: # right_axis_room shifts the whole colorbar clear of right-side named # y-axis chrome (layout() reserves room for both additively). x = plot["x"] + plot["w"] + right_axis_room + 24 - y, width, height = plot["y"], 18, plot["h"] + height = plot["h"] * shrink + y = plot["y"] + (plot["h"] - height) * (1.0 - float(anchor[1])) + width = 18 # A discrete (resampled) colormap paints N solid bands; otherwise a smooth # 64-step gradient approximates the continuous ramp. levels = options.get("levels") @@ -2065,8 +2383,19 @@ def _emit_colorbar( h_positions = ( [float(value) for value in ticks if lo <= float(value) <= hi] if ticks is not None - else (_linear_ticks(lo, hi, 8)[0] or [lo, hi]) + else (_linear_ticks(lo, hi, _colorbar_tick_target(width))[0] or [lo, hi]) ) + if options.get("minor_ticks") and len(h_positions) >= 2: + ordered = sorted(set(h_positions)) + for left, right in pairwise(ordered): + for step in range(1, 5): + value = left + (right - left) * step / 5.0 + tx = x + width * (value - lo) / span + cmd.stroke( + [(tx, y + height), (tx, y + height + 3)], + 1, + _parse_color(text_color), + ) for value in h_positions: cmd.text( x + width * (value - lo) / span, @@ -2089,8 +2418,19 @@ def _emit_colorbar( tick_positions = ( [float(value) for value in ticks if lo <= float(value) <= hi] if ticks is not None - else (_linear_ticks(lo, hi, 8)[0] or [lo, hi]) + else (_linear_ticks(lo, hi, _colorbar_tick_target(height))[0] or [lo, hi]) ) + if options.get("minor_ticks") and len(tick_positions) >= 2: + ordered = sorted(set(tick_positions)) + for lower, upper in pairwise(ordered): + for step in range(1, 5): + value = lower + (upper - lower) * step / 5.0 + ty = y + height * (1 - (value - lo) / span) + cmd.stroke( + [(x + width, ty), (x + width + 3, ty)], + 1, + _parse_color(text_color), + ) for value in tick_positions: cmd.text( x + width + 4, @@ -2100,13 +2440,19 @@ def _emit_colorbar( _parse_color(text_color), f"{value:g}", ) - # The native text primitive does not rotate; a compact label above the - # bar remains legible and, crucially, stays inside the export canvas. + # Matplotlib rotates a vertical colorbar's label 90° CCW and centers it + # alongside the bar, outboard of the tick labels. The native glyph + # protocol rotates in quarter turns (_TEXT_ROT_CCW), so 90° is exact + # here; the upright-glyph limitation applies only to arbitrary angles. + # A horizontal label above the bar instead sat at `plot.y - 5`, where + # the glyph ascent overflowed the canvas top edge and was clipped. The + # baseline matches the SVG exporter's `x + width + 38` so both static + # paths agree, inside the room layout() already reserves for a label. if options.get("label"): cmd.text( - x, - y - 5, - 0, + x + width + 38, + y + height / 2, + 1 | _TEXT_ROT_CCW, 10, _parse_color(text_color), str(options["label"]), diff --git a/python/xy/_svg.py b/python/xy/_svg.py index 3f235e58..d39bd46c 100644 --- a/python/xy/_svg.py +++ b/python/xy/_svg.py @@ -22,13 +22,14 @@ import re from collections.abc import Callable, Sequence from datetime import UTC, datetime +from itertools import pairwise from os import PathLike from typing import Any, Optional from xml.sax.saxutils import escape import numpy as np -from . import _native, _paint, _png +from . import _fontmetrics, _native, _paint, _png from ._arrowgeom import arrow_shapes as _arrow_shapes from .config import DEFAULT_PALETTE @@ -46,6 +47,71 @@ def _stroke_opacity(style: dict[str, Any], default: float = 1.0) -> float: # Mirrors js/src/10_colormaps.ts COLORMAP_STOPS (§36) — test-guarded. COLORMAP_STOPS: dict[str, list[tuple[int, int, int]]] = { "binary": [(255, 255, 255), (0, 0, 0)], + "reds": [ + (255, 245, 240), + (254, 229, 216), + (253, 202, 181), + (252, 171, 143), + (252, 138, 106), + (251, 105, 74), + (241, 68, 50), + (217, 37, 35), + (188, 20, 26), + (152, 12, 19), + (103, 0, 13), + ], + "bone": [ + (0, 0, 0), + (22, 22, 30), + (45, 45, 62), + (66, 66, 93), + (89, 92, 121), + (112, 123, 144), + (134, 154, 166), + (157, 185, 188), + (185, 210, 210), + (221, 233, 233), + (255, 255, 255), + ], + "autumn": [ + (255, 0, 0), + (255, 25, 0), + (255, 51, 0), + (255, 76, 0), + (255, 102, 0), + (255, 128, 0), + (255, 153, 0), + (255, 179, 0), + (255, 204, 0), + (255, 230, 0), + (255, 255, 0), + ], + "winter": [ + (0, 0, 255), + (0, 25, 242), + (0, 51, 230), + (0, 76, 217), + (0, 102, 204), + (0, 128, 191), + (0, 153, 178), + (0, 179, 166), + (0, 204, 153), + (0, 230, 140), + (0, 255, 128), + ], + "bupu": [ + (247, 252, 253), + (229, 239, 246), + (204, 221, 236), + (178, 202, 225), + (154, 180, 214), + (140, 149, 198), + (140, 116, 181), + (138, 81, 165), + (133, 45, 144), + (118, 12, 113), + (77, 0, 75), + ], "gray": [ (0, 0, 0), (25, 25, 25), @@ -970,10 +1036,16 @@ def _step_arrays(xv: np.ndarray, yv: np.ndarray, where: str) -> tuple[np.ndarray f' tuple[float, float]: + """(ascent, descent) in px of the core's DejaVu face at `font_size`.""" + return ( + font_size * _fontmetrics.ASCENT / _fontmetrics.BASE_PX, + font_size * _fontmetrics.DESCENT / _fontmetrics.BASE_PX, + ) + + +def _y_title_baseline(axis: dict[str, Any], plot_right: float) -> Optional[float]: + """Baseline x of a quarter-turned y-axis title, or None when it has none. + + ChartView positions the title as a rotated DOM line box *centered* on a + fixed canvas inset; a static exporter emits a baseline. The two differ by + half a line box, which is why the SVG/PNG title used to sit one full ascent + further toward the canvas edge than the browser draws it — the same + box-to-baseline correction the x-axis title already makes with + `font_size * 0.82`. Titles at any other angle keep the raw inset. + """ + if not axis.get("label"): + return None + raw_position = axis.get("label_position") + position = raw_position if isinstance(raw_position, str) else "center" + if position.replace("-", "_").startswith("inside_"): + return None # drawn over the plot; it needs no gutter + style = axis.get("style") or {} + font_size = float(style.get("label_size", 12)) + side = axis.get("side", "left") + angle = float(axis.get("label_angle", 90.0 if side == "right" else -90.0)) + ascent, descent = _text_cell(font_size) + # Ink is [x - ascent, x + descent] at -90° and [x - descent, x + ascent] at + # +90°, so centering the cell on the inset shifts the baseline by half the + # ascent/descent asymmetry, away from the plot in both cases. + shift = (ascent - descent) / 2 if abs(abs(angle) - 90.0) < 0.5 else 0.0 + offset = float(axis.get("label_offset", 0.0)) + if side == "right": + return plot_right + 40.0 - shift + offset + # Clamp so an oversized title cannot be pushed off the canvas by the inset. + return max(_Y_TITLE_MIN_INK + ascent, _Y_TITLE_INSET + shift) - offset + + +def _y_tick_label_room(axis: dict[str, Any], plot_h: float) -> tuple[float, float]: + """(offset from the spine, widest tick-label extent) for a y axis, in px. + + Measured from the advance widths of the strings that will actually be drawn, + using the same DejaVu metrics the Rust rasterizer blits (`src/font.rs`) — + which is also Matplotlib's default face, so an advance measured here is the + advance Matplotlib lays out. + """ + if _axis_tick_label_strategy(axis) in {"none", "off"}: + return 0.0, 0.0 + font_size = _axis_tick_font_size(axis) + ascent, descent = _text_cell(font_size) + raw_angle = axis.get("tick_label_angle") + angle = abs(float(raw_angle or 0.0)) * math.pi / 180.0 + _values, labels, step = axis_ticks(axis, plot_h, False) + room = 0.0 + for value in labels: + advance = _fontmetrics.advance(str(_tick_text(axis, value, step)), font_size) + # A rotated label trades width for height about its pinned edge. + room = max(room, advance * math.cos(angle) + (ascent + descent) * math.sin(angle)) + # Match the SVG y-label placement below. A y label's anchored edge is + # already the glyph-side edge, so unlike an x-label baseline it needs no + # extra font-room term. + return _axis_tick_label_offset(axis, 8.0), room + + +def _y_axis_left_room(spec: dict[str, Any], plot_h: float) -> float: + """Left gutter the y-axis text needs, measured rather than assumed. + + `layout()`'s fixed 46/62 px default fits ordinary numeric ticks under a + 12 px title. Matplotlib's rcParam fonts (13.89 px at 100 dpi), long category + names, and authored tick labels all exceed it, and the shortfall lands as a + title drawn on top of the tick labels — or off the canvas — instead of as a + wider gutter. + + Right-side y axes deliberately keep the flat 42/54 px reservation above: + ChartView pins a right title plot-relative (`plot-right+40`) rather than to + a canvas inset, so widening only the static exporters' right gutter would + move their title away from the browser's. That asymmetry is recorded in + `spec/api/styling.md`, not silently fixed here. + """ + room = 0.0 + for axis_id, axis in _axes_by_id(spec).items(): + if not axis_id.startswith("y") or axis.get("side", "left") == "right": + continue + tick_offset, tick_room = _y_tick_label_room(axis, plot_h) + baseline = _y_title_baseline(axis, 0.0) + if baseline is None: + room = max(room, _AXIS_TEXT_EDGE_PAD + tick_offset + tick_room) + continue + label_size = float((axis.get("style") or {}).get("label_size", 12)) + _ascent, descent = _text_cell(label_size) + gap = _Y_TITLE_TICK_GAP * label_size if tick_room else 0.0 + room = max(room, baseline + descent + gap + tick_offset + tick_room) + return room + + def layout(spec: dict[str, Any]) -> tuple[int, int, bool, dict[str, float]]: """Concrete pixel dimensions + plot rect from a spec — shared by the SVG and native-PNG exporters so their chrome/plot geometry stays identical.""" @@ -1176,6 +1362,14 @@ def layout(spec: dict[str, Any]) -> tuple[int, int, bool, dict[str, float]]: # secondary-y tick labels/title. Multiple right axes intentionally # overlay in both renderers until offset axes become part of the API. right += 42 if compact else 54 + # Measured y-axis text room, applied last. The vertical extent is already + # final (only top/bottom feed it), so the tick density the reservation + # measures is the density that will be drawn. This raises a *floor*: an + # authored `padding` and the 46/62 default both stand whenever they already + # fit, exactly as the colorbar/right-axis room above is additive rather + # than authoritative. Reserving less than the ink is not an option — a + # static export has no ellipsis to fall back on the way the DOM does. + left = max(left, _y_axis_left_room(spec, max(40, height - top - bottom))) plot = { "x": left, "y": top, @@ -1244,6 +1438,54 @@ def _axis_tick_font_size(axis: dict[str, Any]) -> float: return max(8.0, float(style.get("tick_label_size", style.get("tick_size", 11)))) +def _axis_tick_geometry_authored(axis: dict[str, Any]) -> bool: + """True when the axis authored tick geometry (label pad or mark length). + + Core's default ``tick_length`` is 0 and it has no default ``tick_padding``, + so deriving the spine-to-label distance from tick geometry unconditionally + would move the tick labels of *every* chart that styles no ticks. Charts + that author neither key therefore keep the historical placement, and only + authored geometry — an explicit ``tick_length``/``tick_padding``, or + pyplot's rc-supplied ``{x,y}tick.major.pad`` — opts into matplotlib's rule. + """ + style = axis.get("style") or {} + return "tick_padding" in style or "tick_length" in style + + +def _axis_tick_label_offset(axis: dict[str, Any], unstyled: float, font_room: float = 0.0) -> float: + """Distance from the axis spine to a tick label's anchor point, in px. + + Matplotlib measures tick padding from the outward end of the tick mark + rather than from the spine, and the anchor then sits ``font_room`` times the + tick font size further out (the SVG/raster anchor is the text baseline, so + an x label below the plot must clear the ascent). Axes that author no tick + geometry keep `unstyled`, the caller's historical gap for that side — see + `_axis_tick_geometry_authored`. Those gaps were already asymmetric per side + (16/7/8 px for bottom/top/y here), so per-side defaults reproduce the + existing contract rather than approximate it. + """ + if not _axis_tick_geometry_authored(axis): + return unstyled + style = axis.get("style") or {} + length = max(0.0, float(style.get("tick_length", 0))) + direction = str(style.get("tick_direction", "out")) + outward = 0.0 if direction == "in" else length / 2 if direction == "inout" else length + pad = outward + float(style.get("tick_padding", 4)) + return pad + _axis_tick_font_size(axis) * font_room + + +def _axis_tick_label_baseline_shift(axis: dict[str, Any]) -> float: + """Baseline nudge that centers a y tick label on its tick, in px. + + Font-proportional once tick geometry is authored (matplotlib centers the + label on its cap height); unstyled axes keep the historical flat 4 px so + core charts do not shift. See `_axis_tick_geometry_authored`. + """ + if not _axis_tick_geometry_authored(axis): + return 4.0 + return _axis_tick_font_size(axis) * 0.35 + + def _axis_tick_label_layout( axis: dict[str, Any], values: list[float], @@ -1398,10 +1640,34 @@ def _axis_label_geometry( text_anchor = "start" if anchor == "start" else "end" if anchor == "end" else "middle" angle = float(axis.get("label_angle", 0.0)) else: - outside_x = plot["x"] + plot["w"] + 40 if side == "right" else 10 - inside_x = plot["x"] + plot["w"] - 12 if side == "right" else plot["x"] + 12 - x = inside_x if inside else outside_x - x += (-offset if inside else offset) if side == "right" else (offset if inside else -offset) + if inside: + inside_x = plot["x"] + plot["w"] - 12 if side == "right" else plot["x"] + 12 + x = inside_x + (-offset if side == "right" else offset) + else: + # The rotated title's *line box* is centered on ChartView's inset + # (`left:10px` / `plot-right+40px`); a static exporter emits a + # baseline. `_y_title_baseline` applies that half-line-box + # correction and the axis's own `label_offset`, and is the same + # function `layout()` reserves the gutter from. + baseline = _y_title_baseline(axis, plot["x"] + plot["w"]) + if baseline is not None and side != "right": + # Matplotlib positions a left title from the tick-label ink, + # not from the canvas edge. This matters when an explicit + # axes rectangle reserves more left room than the minimum + # measured gutter: keep the title attached to the ticks + # instead of leaving the extra frame padding between them. + tick_offset, tick_room = _y_tick_label_room(axis, plot["h"]) + ascent, descent = _text_cell(font_size) + angle = float(axis.get("label_angle", -90.0)) + title_inner_ink = ascent if angle > 0 else descent + gap = _Y_TITLE_TICK_GAP * font_size if tick_room else 0.0 + attached = plot["x"] - tick_offset - tick_room - gap - title_inner_ink - offset + baseline = max(baseline, attached) + x = ( + baseline + if baseline is not None + else (plot["x"] + plot["w"] + 40 + offset if side == "right" else 10 - offset) + ) y = plot["y"] + plot["h"] * (1.0 - anchor_fraction) text_anchor = "middle" angle = float(axis.get("label_angle", 90.0 if side == "right" else -90.0)) @@ -1485,6 +1751,16 @@ def append_tick_labels( ) font_size = _axis_tick_font_size(axis) side = axis.get("side", "bottom" if is_x else "left") + # Unstyled defaults reproduce the pre-`tick_label_pad` placement exactly. + if is_x: + label_offset = ( + _axis_tick_label_offset(axis, 7.0, 0.2) + if side == "top" + else _axis_tick_label_offset(axis, 16.0, 0.8) + ) + else: + label_offset = _axis_tick_label_offset(axis, 8.0) + baseline_shift = _axis_tick_label_baseline_shift(axis) # An explicit tick_label_anchor (axis spec or style) overrides the # angle/side-derived default. Anchored labels rotate about the tick # point (the rotate() pivot below), so anchor and rotation compose — @@ -1496,9 +1772,9 @@ def append_tick_labels( row_offset = float(item["row"]) * (font_size + 4) x = float(item["pos"]) y = ( - plot["y"] - 7 - row_offset + plot["y"] - label_offset - row_offset if side == "top" - else plot["y"] + plot["h"] + 16 + row_offset + else plot["y"] + plot["h"] + label_offset + row_offset ) if explicit_anchor: anchor = _TEXT_ANCHORS[explicit_anchor] @@ -1509,8 +1785,12 @@ def append_tick_labels( else: anchor = "start" else: - x = plot["x"] + plot["w"] + 8 if side == "right" else plot["x"] - 8 - y = float(item["pos"]) + 4 + x = ( + plot["x"] + plot["w"] + label_offset + if side == "right" + else plot["x"] - label_offset + ) + y = float(item["pos"]) + baseline_shift if explicit_anchor: anchor = _TEXT_ANCHORS[explicit_anchor] else: @@ -1623,11 +1903,27 @@ def line_attrs(style: dict[str, Any], color: str) -> str: # -- chrome text ---------------------------------------------------------- chrome: list[str] = [] if spec.get("title"): + title_style = ((spec.get("dom") or {}).get("styles") or {}).get("title") or {} + title_size = _px_size(title_style.get("font-size"), 14.0) + # Matplotlib's `axes.titleweight`/`axes.labelweight` both default to + # "normal", so chrome text stays at 400 unless a style or rcParam asks + # for more. Keep this in step with the `title`/`axis_title` slot rules + # in js/src/20_theme.ts and the raster defaults in _raster.py. + title_weight = title_style.get("font-weight", 400) + title_family = title_style.get("font-family") + title_font_style = title_style.get("font-style") + title_font_attrs = ( + f' font-family="{escape(str(title_family))}"' if title_family is not None else "" + ) + ( + f' font-style="{escape(str(title_font_style))}"' if title_font_style is not None else "" + ) chrome.append( f'{escape(str(spec["title"]))}' + f'text-anchor="middle" font-size="{_num(title_size)}" ' + f'font-weight="{escape(str(title_weight))}"{title_font_attrs} ' + f'fill="{escape(_css(title_style.get("color"), default_text))}">' + f"{escape(str(spec['title']))}" ) def append_axis_title(axis: dict[str, Any], *, is_x: bool) -> None: @@ -1638,9 +1934,15 @@ def append_axis_title(axis: dict[str, Any], *, is_x: bool) -> None: x, y = float(geometry["x"]), float(geometry["y"]) angle = float(geometry["angle"]) transform = f' transform="rotate({_num(angle)} {_num(x)} {_num(y)})"' if angle else "" + family = axis_style.get("label_font_family") + font_style = axis_style.get("label_font_style") + font_attrs = (f' font-family="{escape(str(family))}"' if family is not None else "") + ( + f' font-style="{escape(str(font_style))}"' if font_style is not None else "" + ) chrome.append( f'' f"{escape(str(axis['label']))}" ) @@ -1652,8 +1954,10 @@ def append_axis_title(axis: dict[str, Any], *, is_x: bool) -> None: for _axis_id, axis, _axis_scale in extra_y_axes: append_axis_title(axis, is_x=False) named = [t for t in spec["traces"] if t.get("name")] - if spec.get("show_legend", True) and named: - chrome.append(_legend(named, plot, spec.get("legend") or {}, clip_id, default_text)) + main_legend = spec.get("legend") or {} + main_items = main_legend.get("items") or named + if spec.get("show_legend", True) and main_items: + chrome.append(_legend(main_items, plot, main_legend, clip_id, default_text)) for extra in spec.get("extra_legends") or []: items = extra.get("items") or [] if items: @@ -1677,9 +1981,10 @@ def append_axis_title(axis: dict[str, Any], *, is_x: bool) -> None: # baselines above the marks, matching the client's overlay rules baselines = "" frame_sides = spec.get("frame_sides") + explicit_frame_sides = frame_sides is not None if frame_sides is None: frame_sides = [xa.get("side", "bottom"), ya.get("side", "left")] - if not hide_y: + if not hide_y or explicit_frame_sides: for side, x in (("left", plot["x"]), ("right", plot["x"] + plot["w"])): if side in frame_sides: baselines += ( @@ -1688,7 +1993,7 @@ def append_axis_title(axis: dict[str, Any], *, is_x: bool) -> None: f'stroke="{escape(_css(ystyle.get("axis_color"), default_axis))}" ' f'stroke-width="{_num(float(ystyle.get("axis_width", 1)))}"/>' ) - if not hide_x: + if not hide_x or explicit_frame_sides: for side, y in (("top", plot["y"]), ("bottom", plot["y"] + plot["h"])): if side in frame_sides: baselines += ( @@ -1960,15 +2265,18 @@ def _annotation_svg( style.get("opacity", 1.0) if kind == "text" else 1.0, ) ) + line_offset = 0 for index, line in enumerate(lines): bx = tx + float(ann.get("dx", 0)) + base + index * stack + styled_line = _svg_mathtext_spans(line, style, line_offset) labels.append( f'{escape(line)}' + + f'fill="{color}">{styled_line}' ) + line_offset += len(line) + 1 continue x_text = tx + float(ann.get("dx", 0)) y_text = ty + float(ann.get("dy", 0)) - (len(lines) - 1) * line_height / 2 @@ -1977,11 +2285,18 @@ def _annotation_svg( y_text += font_size * 0.35 elif vertical_align == "top": y_text += font_size * 0.8 - tspans = "".join( - f'' - f"{escape(line)}" - for index, line in enumerate(lines) - ) + elif vertical_align == "bottom": + y_text -= font_size * 0.2 + line_offset = 0 + tspan_parts = [] + for index, line in enumerate(lines): + styled_line = _svg_mathtext_spans(line, style, line_offset) + tspan_parts.append( + f'' + f"{styled_line}" + ) + line_offset += len(line) + 1 + tspans = "".join(tspan_parts) text_opacity = float( style.get( "label_opacity", @@ -1990,14 +2305,155 @@ def _annotation_svg( ) # A callout's `color` paints its arrow; the label prefers its own. label_color = escape(_css(style.get("label_color"), "")) or color + labels.extend( + _svg_text_box(style, lines, x_text, y_text, line_height, font_size, anchor) + ) + font_attrs = _svg_font_attrs(style) + rotation_attr = ( + f' transform="rotate({_num(-rotation)} {_num(x_text)} {_num(y_text)})"' + if rotation + else "" + ) labels.append( - f'{tspans}' ) return marks, labels +def _svg_font_attrs(style: dict[str, Any]) -> str: + attrs = [] + for key, attribute in ( + ("font_family", "font-family"), + ("font_weight", "font-weight"), + ("font_style", "font-style"), + ): + if style.get(key) is not None: + attrs.append(f' {attribute}="{escape(str(style[key]))}"') + return "".join(attrs) + + +def _svg_mathtext_spans(line: str, style: dict[str, Any], offset: int) -> str: + ranges: list[tuple[int, int]] = [] + for item in str(style.get("math_italic_ranges", "")).split(","): + try: + start, end = (int(value) for value in item.split(":", 1)) + except ValueError: + continue + start, end = max(0, start - offset), min(len(line), end - offset) + if start < end: + ranges.append((start, end)) + if not ranges: + return escape(line) + out: list[str] = [] + cursor = 0 + for start, end in ranges: + if cursor < start: + out.append(escape(line[cursor:start])) + out.append(f'{escape(line[start:end])}') + cursor = end + out.append(escape(line[cursor:])) + return "".join(out) + + +def _svg_text_box( + style: dict[str, Any], + lines: list[str], + x: float, + first_y: float, + line_height: float, + font_size: float, + anchor: str, +) -> list[str]: + """SVG counterpart of the pyplot text-bbox CSS approximation.""" + background = style.get("background") + border = str(style.get("border", "")) + if background is None and not border: + return [] + pad_parts = str(style.get("padding", "0")).split() + + def px(value: str) -> float: + try: + return max(0.0, float(value.removesuffix("px"))) + except ValueError: + return 0.0 + + pad_y = px(pad_parts[0]) if pad_parts else 0.0 + pad_x = px(pad_parts[1]) if len(pad_parts) > 1 else pad_y + text_width = _estimated_text_width(lines, font_size) + left = ( + x + - (text_width / 2 if anchor == "middle" else text_width if anchor == "end" else 0.0) + - pad_x + ) + top = first_y - font_size * 0.8 - pad_y + height = font_size + (len(lines) - 1) * line_height + pad_y * 2 + fill = "none" if background is None else escape(str(background)) + stroke = "none" + stroke_width = 0.0 + if border: + parts = border.split() + stroke = escape(parts[-1]) + try: + stroke_width = max(0.0, float(parts[0].removesuffix("px"))) + except (IndexError, ValueError): + stroke_width = 1.0 + # `boxstyle="round"`/`round4` set border_radius; the browser gets it as CSS + # border-radius, so the exporters have to round the same corners or an + # exported box is square where the live one is not. + radius = _box_corner_radius(style, text_width + pad_x * 2, height) + radius_attr = f' rx="{_num(radius)}"' if radius > 0 else "" + return [ + f'' + ] + + +def _box_corner_radius(style: dict[str, Any], width: float, height: float) -> float: + """`border_radius` in px, clamped to the box like CSS does. + + Shared by the SVG and native raster text-box emitters so an exported + ``boxstyle="round"`` bbox is rounded exactly once, the same way. + """ + try: + radius = float(str(style.get("border_radius", 0) or 0).removesuffix("px")) + except (TypeError, ValueError): + return 0.0 + return max(0.0, min(radius, width / 2.0, height / 2.0)) + + +def _estimated_text_width(lines: list[str], font_size: float) -> float: + """Dependency-free label-box width using glyph-shaped em advances. + + Static SVG leaves final glyph layout to the viewer and the native stream + owns its atlas in Rust, so neither Python emitter has a browser text + measurer. A flat character count made narrow and wide strings equally + wide and visibly let labels such as ``Thanksgiving`` escape their box. + These bounded advances follow ordinary sans-serif proportions closely + enough to keep boxes readable without shipping a second font table. + """ + + def line_width(line: str) -> float: + advance = 0.0 + for char in line: + if char in " !'.,:;|ijlI": + advance += 0.28 + elif char in "MW@%&": + advance += 0.9 + elif char.isupper(): + advance += 0.66 + elif char.isdigit(): + advance += 0.64 + else: + advance += 0.56 + return advance * font_size + + return max((line_width(line) for line in lines), default=0.0) + + def _segment_marks( t: dict[str, Any], blob: bytes, cols: list, sx: _Scale, sy: _Scale, style: dict, color: str ) -> str: @@ -2285,7 +2741,9 @@ def read(index: int) -> np.ndarray: face = _trace_paint_rgba(t, "color", n, fallback, read) fills = _paint.effective_rgba(face, t, read, component="fill", default_opacity=1.0) - if t.get("stroke") is not None: + if (t.get("stroke") or {}).get("mode") == "match_fill": + stroke_face = face + elif t.get("stroke") is not None: stroke_face = _trace_paint_rgba(t, "stroke", n, fallback, read) elif style.get("stroke") is not None: stroke_face = np.tile( @@ -2299,6 +2757,21 @@ def read(index: int) -> np.ndarray: t, "stroke_width", n, read, float(style.get("stroke_width", 0.0)) ) x0, y0, x1, y1, x2, y2 = vertices + if ( + style.get("joined_fill") + and n + and np.all(fills == fills[0]) + and np.all(stroke_widths == 0.0) + ): + boundary = _paint.triangle_mesh_boundary(x0, y0, x1, y1, x2, y2) + if boundary is not None: + points = " ".join(f"{_num(float(sx(x)))},{_num(float(sy(y)))}" for x, y in boundary) + fill = fills[0] + return ( + f'' + ) out = [""] for i in range(n): points = " ".join( @@ -2368,7 +2841,9 @@ def _rect_svg_styles( face = _trace_paint_rgba(trace, "color", n, fallback, read) fills_rgba = _paint.effective_rgba(face, trace, read, component="fill", default_opacity=0.85) - if trace.get("stroke") is not None: + if (trace.get("stroke") or {}).get("mode") == "match_fill": + stroke_face = face + elif trace.get("stroke") is not None: stroke_face = _trace_paint_rgba(trace, "stroke", n, fallback, read) elif style.get("stroke") is not None: stroke_face = np.tile( @@ -2649,19 +3124,91 @@ def _heatmap_image(hm: dict, blob: bytes, cols: list, sx: _Scale, sy: _Scale, st _LEGEND_CHAR_WIDTH = 6.2 +#: Font size the legend emitters set labels at, and the size at which +#: ``_LEGEND_CHAR_WIDTH`` is the nominal *average* advance. +_LEGEND_FONT_PX = 11.0 +#: Exact-fit comparisons are made against a measured float sum, so absorb the +#: binary-float underflow at the boundary rather than ellipsizing a label that +#: fits to the last subpixel. +_LEGEND_FIT_EPS = 1e-9 + + +def _legend_font_size(style: dict[str, Any]) -> float: + """Resolve the bounded pixel font size used by static legend geometry.""" + value = str(style.get("fontSize", "")).strip() + if value.endswith("px"): + try: + return max(1.0, float(value[:-2])) + except ValueError: + pass + return 11.0 + + +def _legend_em(style: dict[str, Any], key: str, default: float) -> float: + value = str(style.get(key, "")).strip() + if value.endswith("em"): + try: + return max(0.0, float(value[:-2])) + except ValueError: + pass + return default + + +def _legend_text_width(value: Any, char_width: float = _LEGEND_CHAR_WIDTH) -> float: + """Measured advance width, in pixels, of a static legend string. + + Legend columns used to be sized as ``len(text) * _LEGEND_CHAR_WIDTH``. A + flat average cannot bound a proportional face — DejaVu's ``m`` is over + three times the width of its ``l`` — so ``"gamma"`` really sets 42.6 px at + 11 px against a 31.0 px estimate, and a frame sized from the estimate was + narrower than its own labels. Advances come from the same face the native + rasterizer blits (``_fontmetrics``, generated beside ``src/font.rs`` by + ``scripts/gen_font.py``), which is what makes a frame sized from this + actually contain the text the SVG and raster emitters draw. It is also what + the browser does natively, sizing each legend column to ``max-content``. + ``char_width`` carries the nominal average advance, so scaling the legend + font scales the measurement with it. -def _legend_text(value: Any, max_width: float) -> str: - """Conservatively ellipsize a static legend string to a pixel budget.""" + A codepoint the atlas lacks reserves the nominal ``char_width`` instead of + the rasterizer's zero advance: SVG resolves it against the viewer's own + fonts and does paint it, and over-reserving only widens the frame, which + can never spill a label. + """ + scale = char_width * (_LEGEND_FONT_PX / _LEGEND_CHAR_WIDTH) / _fontmetrics.BASE_PX + total = 0.0 + for ch in str(value): + code = ord(ch) + if _fontmetrics.FIRST <= code <= _fontmetrics.LAST: + total += _fontmetrics.ASCII_ADVANCES[code - _fontmetrics.FIRST] * scale + else: + advance = _fontmetrics.EXTRA_ADVANCES.get(code) + total += char_width if advance is None else advance * scale + return total + + +def _legend_text(value: Any, max_width: float, char_width: float = _LEGEND_CHAR_WIDTH) -> str: + """Conservatively ellipsize a static legend string to a pixel budget. + + The budget is measured, not counted, so the returned string's own advance + width is ``<= max_width`` and therefore fits the column it was sized for. + """ text = str(value) - # ``cell_w`` is itself derived from ``len(text) * _LEGEND_CHAR_WIDTH``; - # compensate for the tiny binary-float underflow at exact-fit boundaries. - max_chars = max(0, int((max_width + 1e-9) / _LEGEND_CHAR_WIDTH)) - if len(text) <= max_chars: + if _legend_text_width(text, char_width) <= max_width + _LEGEND_FIT_EPS: return text - if max_chars <= 3: - return "." * max_chars - return text[: max_chars - 3] + "..." + # Longest prefix that still leaves room for the ellipsis. + keep = 0 + for index in range(1, len(text)): + if _legend_text_width(f"{text[:index]}...", char_width) > max_width + _LEGEND_FIT_EPS: + break + keep = index + if keep: + return f"{text[:keep]}..." + # Too narrow for even one glyph plus an ellipsis: emit the dots that fit. + for count in (3, 2, 1): + if _legend_text_width("." * count, char_width) <= max_width + _LEGEND_FIT_EPS: + return "." * count + return "" def _legend_layout(named: list[dict], plot: dict, options: dict) -> dict[str, Any]: @@ -2669,84 +3216,167 @@ def _legend_layout(named: list[dict], plot: dict, options: dict) -> dict[str, An Static files cannot offer the browser legend's scrollbar, so an oversized legend is kept inside the plot and its labels are visibly ellipsized. A - legend that already fits keeps its historical geometry byte-for-byte. + Columns follow Matplotlib's handle/text/column spacing and size to their + own labels rather than inheriting the width of the longest label. """ style_opts = options.get("style") or {} - pad, handle, gap, line_h = 8.0, 20.0, 5.0, 16.0 - if str(style_opts.get("padding", "")).endswith("em"): - pad = 11.0 * float(str(style_opts["padding"])[:-2]) - if str(style_opts.get("rowGap", "")).endswith("em"): - line_h = 11.0 * (1.0 + float(str(style_opts["rowGap"])[:-2])) + font_size = _legend_font_size(style_opts) + char_width = font_size * (_LEGEND_CHAR_WIDTH / 11.0) + text_h = font_size * 1.03 + borderpad = _legend_em(style_opts, "padding", 0.4) + labelspacing = _legend_em(style_opts, "rowGap", 0.5) + # Matplotlib's legend dimensions are expressed in font-size units: + # borderpad is applied on both sides, handlelength=2, handletextpad=.8, + # columnspacing=2, and labelspacing=.5 by default. + pad = 2.0 * borderpad * font_size + handle = 2.0 * font_size + gap = 0.8 * font_size + column_gap = 2.0 * font_size + row_gap = labelspacing * font_size + line_h = text_h + row_gap + requested_handleheight = options.get("handleheight") + swatch_h = 8.0 + if requested_handleheight is not None: + swatch_h = max(8.0, 11.0 * float(requested_handleheight)) + line_h = max(line_h, swatch_h + 2.0) requested_cols = min(len(named), max(1, int(options.get("ncols", 1)))) title = options.get("title") - title_h = 16.0 if title else 0.0 - natural_cell_w = ( - max(len(str(t.get("name", ""))) for t in named) * _LEGEND_CHAR_WIDTH - + handle - + gap - + 2 * pad - ) + title_h = line_h if title else 0.0 inset = 6.0 available_w = max(1.0, float(plot["w"]) - 2 * inset) ncols = requested_cols - if ncols * natural_cell_w + pad > available_w: - # A cell must at least retain its handle and a visible ellipsis. Reduce - # an impossible column count before shortening the individual labels. - min_cell_w = handle + gap + 2 * pad + 4 * _LEGEND_CHAR_WIDTH - max_fit_cols = max(1, int(max(0.0, available_w - pad) // min_cell_w)) + min_column_w = handle + gap + 4 * char_width + if ncols * min_column_w + (ncols - 1) * column_gap + pad > available_w: + # A column must at least retain its handle and a visible ellipsis. + max_fit_cols = max( + 1, + int(max(0.0, available_w - pad + column_gap) // (min_column_w + column_gap)), + ) ncols = min(ncols, max_fit_cols) - cell_w = min(natural_cell_w, max(1.0, (available_w - pad) / ncols)) - box_w = min(available_w, ncols * cell_w + pad) + + natural_text_widths = [ + max( + _legend_text_width(named[index].get("name", ""), char_width) + for index in range(column, len(named), ncols) + ) + for column in range(ncols) + ] + available_text_w = max( + 0.0, + available_w - pad - ncols * (handle + gap) - (ncols - 1) * column_gap, + ) + minimum_text_w = 4 * char_width + text_widths = [min(width, minimum_text_w) for width in natural_text_widths] + remaining = max(0.0, available_text_w - sum(text_widths)) + needs = [ + max(0.0, width - current) + for width, current in zip(natural_text_widths, text_widths, strict=True) + ] + needed = sum(needs) + if needed: + scale = min(1.0, remaining / needed) + text_widths = [ + current + need * scale for current, need in zip(text_widths, needs, strict=True) + ] + column_widths = [handle + gap + width for width in text_widths] + box_w = min(available_w, sum(column_widths) + (ncols - 1) * column_gap + pad) + if title: + # ``pad`` is the sum of the two side pads. The previous one-sided + # calculation expanded the box to the title's glyph width but then + # ellipsized against ``box_w - 2 * pad`` (e.g. "Classes" -> "Cl..."). + title_w = _legend_text_width(title, char_width) + pad + if title_w > box_w: + extra = min(available_w - box_w, title_w - box_w) + column_widths = [width + extra / ncols for width in column_widths] + text_widths = [width + extra / ncols for width in text_widths] + box_w += extra + column_offsets = [] + cursor = pad / 2 + for width in column_widths: + column_offsets.append(cursor) + cursor += width + column_gap nrows = (len(named) + ncols - 1) // ncols available_h = max(1.0, float(plot["h"]) - 2 * inset) visible_rows = nrows - natural_box_h = nrows * line_h + pad + title_h + content_rows = nrows + (1 if title else 0) + natural_box_h = content_rows * text_h + max(0, content_rows - 1) * row_gap + pad if natural_box_h > available_h: - visible_rows = max(0, int((available_h - pad - title_h) // line_h)) + title_room = text_h + row_gap if title else 0.0 + available_entries_h = max(0.0, available_h - pad - title_room) + visible_rows = max(0, int((available_entries_h + row_gap) // line_h)) visible_count = min(len(named), visible_rows * ncols) - box_h = min(available_h, visible_rows * line_h + pad + title_h) + visible_content_rows = visible_rows + (1 if title else 0) + box_h = min( + available_h, + visible_content_rows * text_h + max(0, visible_content_rows - 1) * row_gap + pad, + ) loc = options.get("loc") or "upper right" - if "left" in loc: - x = float(plot["x"]) + inset - elif "right" in loc: - x = float(plot["x"]) + float(plot["w"]) - box_w - inset + anchor = options.get("anchor") + if anchor and len(anchor) in (2, 4): + ax, ay = float(anchor[0]), float(anchor[1]) + aw, ah = (0.0, 0.0) if len(anchor) == 2 else (float(anchor[2]), float(anchor[3])) + hx = 0.0 if "left" in loc else 1.0 if "right" in loc else 0.5 + vy = 0.0 if "lower" in loc else 1.0 if "upper" in loc else 0.5 + target_x = float(plot["x"]) + (ax + hx * aw) * float(plot["w"]) + target_y = float(plot["y"]) + (1.0 - ay - vy * ah) * float(plot["h"]) + x = target_x - hx * box_w + y = target_y - (1.0 - vy) * box_h + border_axes_pad = max(0.0, float(options.get("border_pad", 0.0))) + x += border_axes_pad if hx == 0.0 else -border_axes_pad if hx == 1.0 else 0.0 + # SVG/raster coordinates increase downward, so a "lower" legend is + # moved upward from its anchor and an "upper" legend moves downward. + y += border_axes_pad if vy == 1.0 else -border_axes_pad if vy == 0.0 else 0.0 else: - x = float(plot["x"]) + (float(plot["w"]) - box_w) / 2 - if "upper" in loc: - y = float(plot["y"]) + inset - elif "lower" in loc: - y = float(plot["y"]) + float(plot["h"]) - box_h - inset - else: - y = float(plot["y"]) + (float(plot["h"]) - box_h) / 2 - x = min( - max(x, float(plot["x"]) + inset), - float(plot["x"]) + float(plot["w"]) - box_w - inset, - ) - y = min( - max(y, float(plot["y"]) + inset), - float(plot["y"]) + float(plot["h"]) - box_h - inset, - ) + if "left" in loc: + x = float(plot["x"]) + inset + elif "right" in loc: + x = float(plot["x"]) + float(plot["w"]) - box_w - inset + else: + x = float(plot["x"]) + (float(plot["w"]) - box_w) / 2 + if "upper" in loc: + y = float(plot["y"]) + inset + elif "lower" in loc: + y = float(plot["y"]) + float(plot["h"]) - box_h - inset + else: + y = float(plot["y"]) + (float(plot["h"]) - box_h) / 2 + x = min( + max(x, float(plot["x"]) + inset), + float(plot["x"]) + float(plot["w"]) - box_w - inset, + ) + y = min( + max(y, float(plot["y"]) + inset), + float(plot["y"]) + float(plot["h"]) - box_h - inset, + ) - text_width = max(0.0, cell_w - handle - gap - 2 * pad) return { "style": style_opts, "pad": pad, "handle": handle, "gap": gap, + "column_gap": column_gap, + "row_gap": row_gap, + "font_size": font_size, + "text_h": text_h, "line_h": line_h, + "swatch_h": swatch_h, "ncols": ncols, - "title": _legend_text(title, max(0.0, box_w - 2 * pad)) if title else None, + "title": _legend_text(title, max(0.0, box_w - pad), char_width) if title else None, "title_h": title_h, - "cell_w": cell_w, + "cell_w": max(column_widths), + "column_widths": column_widths, + "column_offsets": column_offsets, "box_w": box_w, "box_h": box_h, "x": x, "y": y, "visible_count": visible_count, - "names": [_legend_text(t.get("name", ""), text_width) for t in named[:visible_count]], + "names": [ + _legend_text(t.get("name", ""), text_widths[index % ncols], char_width) + for index, t in enumerate(named[:visible_count]) + ], } @@ -2761,8 +3391,10 @@ def _legend( style_opts = legend["style"] pad, handle, gap = legend["pad"], legend["handle"], legend["gap"] line_h, ncols = legend["line_h"], legend["ncols"] + swatch_h = legend["swatch_h"] title, title_h = legend["title"], legend["title_h"] - cell_w = legend["cell_w"] + font_size, text_h = legend["font_size"], legend["text_h"] + column_offsets = legend["column_offsets"] box_w, box_h = legend["box_w"], legend["box_h"] x, y = legend["x"], legend["y"] if style_opts.get("background") != "transparent": @@ -2779,14 +3411,18 @@ def _legend( else: background = _css(background_value, "#808080") fill_attrs = f'fill="{escape(background)}" fill-opacity="{_num(alpha)}"' + border = _css(style_opts.get("borderColor"), "#cccccc") rows.append( f'' + f'rx="{radius}" {fill_attrs} stroke="{escape(border)}" ' + f'stroke-opacity="{_num(alpha)}" stroke-width="1"/>' ) if title: rows.append( - f'{escape(str(title))}' + f'{escape(str(title))}' ) for i, t in enumerate(named[: legend["visible_count"]]): style = t.get("style") or {} @@ -2795,12 +3431,13 @@ def _legend( DEFAULT_PALETTE[i % len(DEFAULT_PALETTE)], ) col, row = i % ncols, i // ncols - rx, ry = x + col * cell_w, y + pad / 2 + title_h + row * line_h - hx0, hx1, cy = rx + pad, rx + pad + handle, ry + 7 + rx, ry = x + column_offsets[col], y + pad / 2 + title_h + row * line_h + hx0, hx1, cy = rx, rx + handle, ry + text_h / 2 kind = t.get("kind") if kind == "scatter": symbol = style.get("symbol", "circle") builder = _SYMBOL_BUILDERS.get(symbol) + radius = max(0.5, float(style.get("size", 8.0)) / 2.0) stroke_w = float(style.get("stroke_width", 0.0)) line_symbol = symbol in {"plus_line", "x_line"} if line_symbol and stroke_w <= 0: @@ -2812,12 +3449,13 @@ def _legend( cxm = (hx0 + hx1) / 2 if builder is None: rows.append( - f'' ) else: rows.append( - builder(float(cxm), float(cy), 4.0) + f' fill="{escape(color)}"{stroke_attr}/>' + builder(float(cxm), float(cy), radius) + + f' fill="{escape(color)}"{stroke_attr}/>' ) elif kind in _LEGEND_LINE_KINDS: rows.append( @@ -2827,14 +3465,53 @@ def _legend( ) else: rows.append( - f'' ) + if style.get("hatch"): + rows.append( + _legend_hatch_svg( + hx0, + hx1, + cy - swatch_h / 2, + cy + swatch_h / 2, + str(style["hatch"]), + _css(style.get("hatch_color"), "#222222"), + ) + ) rows.append( - f'{escape(legend["names"][i])}' ) - return f'{"".join(rows)}' + clip = "" if options.get("anchor") else f' clip-path="url(#{clip_id})"' + return f"{''.join(rows)}" + + +def _legend_hatch_svg(x0: float, x1: float, y0: float, y1: float, hatch: str, color: str) -> str: + """Small, bounded hatch sample for explicit patch legend handles.""" + paths: list[str] = [] + mid_y = (y0 + y1) / 2 + if "-" in hatch or "*" in hatch: + paths.append(f"M{_num(x0)},{_num(mid_y)} L{_num(x1)},{_num(mid_y)}") + for char, direction in (("/", 1), ("\\", -1)): + count = min(3, hatch.count(char)) + for index in range(count): + center = x0 + (index + 1) * (x1 - x0) / (count + 1) + half = min((x1 - x0) / 4, (y1 - y0) / 2) + paths.append( + f"M{_num(center - half)},{_num(mid_y + direction * half)} " + f"L{_num(center + half)},{_num(mid_y - direction * half)}" + ) + if "." in hatch: + for fraction in (0.3, 0.7): + paths.append(f"M{_num(x0 + fraction * (x1 - x0))},{_num(mid_y)} l0.1,0") + if "*" in hatch: + paths.append(f"M{_num((x0 + x1) / 2)},{_num(y0)} L{_num((x0 + x1) / 2)},{_num(y1)}") + if not paths: + return "" + return f'' def _colorbar( @@ -2849,17 +3526,22 @@ def _colorbar( for index, (r, g, b) in enumerate(stops) ) orientation = options.get("orientation", "vertical") + shrink = float(options.get("shrink", 1.0)) + anchor = options.get("anchor") or [0.5, 0.5] domain = options.get("domain", [0.0, 1.0]) if orientation == "horizontal": - x = plot["x"] + width = plot["w"] * shrink + x = plot["x"] + (plot["w"] - width) * float(anchor[0]) y = plot["y"] + plot["h"] + (plot["bottom_axis_room"] or 10) - width, height = plot["w"], 18 + height = 18 gradient_attrs = 'x1="0" y1="0" x2="100%" y2="0"' else: # right_axis_room shifts the whole colorbar clear of right-side named # y-axis chrome (layout() reserves room for both additively). x = plot["x"] + plot["w"] + right_axis_room + 24 - y, width, height = plot["y"], 18, plot["h"] + height = plot["h"] * shrink + y = plot["y"] + (plot["h"] - height) * (1.0 - float(anchor[1])) + width = 18 gradient_attrs = 'x1="0" y1="100%" x2="0" y2="0"' label = str(options.get("label") or "") label_node = ( @@ -2880,7 +3562,14 @@ def _colorbar( tick_positions = ( [float(value) for value in ticks if lo <= float(value) <= hi] if ticks is not None - else (_linear_ticks(lo, hi, 8)[0] or [lo, hi]) + else ( + _linear_ticks( + lo, + hi, + _colorbar_tick_target(width if orientation == "horizontal" else height), + )[0] + or [lo, hi] + ) ) tick_nodes = ( "".join( @@ -2897,6 +3586,32 @@ def _colorbar( for value in tick_positions ) ) + minor_nodes = "" + if options.get("minor_ticks") and len(tick_positions) >= 2: + ordered = sorted(set(tick_positions)) + minor_positions = [ + left + (right - left) * step / 5.0 + for left, right in pairwise(ordered) + for step in range(1, 5) + ] + if orientation != "horizontal": + minor_nodes = "".join( + f'' + for value in minor_positions + ) + else: + minor_nodes = "".join( + f'' + for value in minor_positions + ) extend = options.get("extend") extend_nodes = "" if extend in ("max", "both"): @@ -2922,10 +3637,15 @@ def _colorbar( f'' f"{stop_nodes}" f"{_colorbar_body(options, x, y, width, height, orientation, gradient_id)}" - f"{extend_nodes}{tick_nodes}{label_node}" + f"{extend_nodes}{minor_nodes}{tick_nodes}{label_node}" ) +def _colorbar_tick_target(length: float) -> int: + """Major-tick budget for the rendered colorbar length in CSS pixels.""" + return max(2, min(8, int(max(0.0, float(length)) // 48.0) + 1)) + + def _colorbar_body( options: dict, x: float, diff --git a/python/xy/channels.py b/python/xy/channels.py index e6b16329..dd1798e9 100644 --- a/python/xy/channels.py +++ b/python/xy/channels.py @@ -30,6 +30,7 @@ "plasma", "inferno", "cividis", + "autumn", "gray", "turbo", "coolwarm", @@ -45,6 +46,10 @@ "rdbu", "jet", "binary", + "reds", + "bone", + "winter", + "bupu", ) diff --git a/python/xy/components.py b/python/xy/components.py index 5d3eb15b..a1e8a897 100644 --- a/python/xy/components.py +++ b/python/xy/components.py @@ -215,6 +215,7 @@ class Axis(Component): type_: Optional[str] = None # "linear" | "time" | "log" | "symlog" constant: Optional[float] = None domain: Optional[tuple[float, float]] = None + margin: Optional[float] = None bounds: Union[tuple[float, float], Literal["data"], None] = None reverse: bool = False format: Optional[str] = None @@ -235,6 +236,7 @@ class Legend(Component): show: bool = True loc: Optional[str] = None + anchor: Optional[tuple[float, ...]] = None ncols: int = 1 title: Optional[str] = None class_name: Optional[str] = None @@ -858,6 +860,7 @@ def segments( domain: Optional[tuple[float, float]] = None, width: Any = 1.2, opacity: Any = 1.0, + dash: Union[str, Sequence[float], None] = None, style: Optional[dict[str, StyleValue]] = None, class_name: Optional[str] = None, x_axis: str = "x", @@ -877,6 +880,7 @@ def segments( domain: Explicit minimum and maximum for continuous colors. width: Segment width in pixels. opacity: Segment opacity from zero to one. + dash: Optional line dash pattern. style: Mark style overrides. class_name: Adapter-only trace metadata; it does not style canvas geometry. x_axis: Identifier of the x axis used by this mark. @@ -898,6 +902,7 @@ def segments( "domain": domain, "width": width, "opacity": opacity, + "dash": dash, "x_axis": x_axis, "y_axis": y_axis, }, @@ -920,6 +925,7 @@ def triangle_mesh( opacity: Any = 1.0, stroke: Any = None, stroke_width: Any = 0.0, + _joined_fill: bool = False, style: Optional[dict[str, StyleValue]] = None, class_name: Optional[str] = None, x_axis: str = "x", @@ -942,6 +948,7 @@ def triangle_mesh( opacity: Triangle opacity from zero to one. stroke: Optional triangle outline color. stroke_width: Triangle outline width in pixels. + _joined_fill: Internal pyplot hint for suppressing shared triangle edges. style: Mark style overrides. class_name: Adapter-only trace metadata; it does not style canvas geometry. x_axis: Identifier of the x axis used by this mark. @@ -966,6 +973,7 @@ def triangle_mesh( "opacity": opacity, "stroke": stroke, "stroke_width": stroke_width, + "_joined_fill": _joined_fill, "x_axis": x_axis, "y_axis": y_axis, }, @@ -1254,7 +1262,7 @@ def violin( group: Union[str, ArrayLike, None] = None, name: Optional[str] = None, color: Optional[str] = None, - width: float = 0.8, + width: Any = 0.8, bins: int = 64, opacity: float = 0.55, orientation: str = "vertical", @@ -1374,10 +1382,12 @@ def contour( filled: bool = False, name: Optional[str] = None, colormap: str = channels.DEFAULT_COLORMAP, - color: Optional[str] = None, - width: float = 1.1, + color: Any = None, + width: Any = 1.1, opacity: float = 0.9, dash_negative: bool = False, + extend: str = "neither", + corner_mask: bool = False, style: Optional[dict[str, StyleValue]] = None, class_name: Optional[str] = None, x_axis: str = "x", @@ -1394,10 +1404,12 @@ def contour( filled: Whether to fill intervals between contours. name: Series label used by legends and tooltips. colormap: Colormap used for contour values. - color: Constant isoline color. - width: Isoline width in pixels. + color: Constant isoline color or direct RGBA colors cycled by level. + width: Isoline width in pixels, scalar or cycled by contour level. opacity: Contour opacity from zero to one. dash_negative: Whether negative isolines use a dashed stroke. + extend: Whether filled contours paint values below or above the levels. + corner_mask: Preserve the valid triangle of a quad with one missing corner. style: Mark style overrides. class_name: Adapter-only trace metadata; it does not style canvas geometry. x_axis: Identifier of the x axis used by this mark. @@ -1420,6 +1432,8 @@ def contour( "width": width, "opacity": opacity, "dash_negative": dash_negative, + "extend": extend, + "corner_mask": corner_mask, "x_axis": x_axis, "y_axis": y_axis, }, @@ -1573,7 +1587,7 @@ def bar( name: Series label used by legends and tooltips. color: Constant color, values, or a column name. colors: Colors assigned to multiple series. - width: Bar width in category units. + width: Scalar or per-bar widths in category units. base: Baseline value, values, or a column name. mode: ``grouped``, ``stacked``, or ``normalized`` layout. orientation: ``vertical`` or ``horizontal`` orientation. @@ -1629,7 +1643,7 @@ def column( name: Optional[str] = None, color: Union[str, Sequence[str], None] = None, colors: Optional[list[str]] = None, - width: float = 0.8, + width: Any = 0.8, base: Union[str, Scalar, ArrayLike] = 0.0, mode: str = "grouped", orientation: str = "vertical", @@ -2204,6 +2218,7 @@ def x_axis( type_: Optional[str] = None, constant: Optional[float] = None, domain: Optional[tuple[float, float]] = None, + margin: Optional[float] = None, bounds: Union[tuple[float, float], Literal["data"], None] = None, reverse: bool = False, format: Optional[str] = None, @@ -2228,6 +2243,7 @@ def x_axis( type_: Scale type, such as ``linear``, ``time``, ``log``, or ``symlog``. constant: Width of the linear region around zero for ``symlog``. domain: Explicit minimum and maximum scale values. + margin: Fractional padding around an automatic domain. bounds: Hard navigation limits, or ``"data"`` to use the data range. Pan and zoom are clamped within these limits; ``None`` leaves navigation unrestricted. @@ -2263,6 +2279,7 @@ def x_axis( type_=type_, constant=_axis_constant(constant, type_, "x_axis constant"), domain=_axis_domain(domain, "x_axis domain"), + margin=_optional_nonnegative_number(margin, "x_axis margin"), bounds=_axis_bounds(bounds, "x_axis bounds"), reverse=_strict_bool(reverse, "x_axis reverse"), format=_optional_string(format, "x_axis format"), @@ -2292,6 +2309,7 @@ def y_axis( type_: Optional[str] = None, constant: Optional[float] = None, domain: Optional[tuple[float, float]] = None, + margin: Optional[float] = None, bounds: Union[tuple[float, float], Literal["data"], None] = None, reverse: bool = False, format: Optional[str] = None, @@ -2316,6 +2334,7 @@ def y_axis( type_: Scale type, such as ``linear``, ``time``, ``log``, or ``symlog``. constant: Width of the linear region around zero for ``symlog``. domain: Explicit minimum and maximum scale values. + margin: Fractional padding around an automatic domain. bounds: Hard navigation limits, or ``"data"`` to use the data range. Pan and zoom are clamped within these limits; ``None`` leaves navigation unrestricted. @@ -2351,6 +2370,7 @@ def y_axis( type_=type_, constant=_axis_constant(constant, type_, "y_axis constant"), domain=_axis_domain(domain, "y_axis domain"), + margin=_optional_nonnegative_number(margin, "y_axis margin"), bounds=_axis_bounds(bounds, "y_axis bounds"), reverse=_strict_bool(reverse, "y_axis reverse"), format=_optional_string(format, "y_axis format"), @@ -2374,6 +2394,7 @@ def legend( *children: Any, show: bool = True, loc: Optional[str] = None, + anchor: Optional[tuple[float, ...]] = None, ncols: int = 1, title: Optional[str] = None, highlight: bool = True, @@ -2388,6 +2409,7 @@ def legend( *children: Optional opaque replacement content. show: Whether to display the legend. loc: Legend placement within or around the plot. + anchor: Two- or four-value normalized plot-coordinate anchor. ncols: Number of legend columns. title: Optional legend title. highlight: Whether hovering a legend entry emphasizes its series by @@ -2399,9 +2421,16 @@ def legend( style: Legend style overrides. """ show, render = _chrome_render_args(children, show, render, "legend") + if anchor is not None: + if isinstance(anchor, (str, bytes)) or len(anchor) not in (2, 4): + raise ValueError("legend anchor must contain 2 or 4 finite numbers") + anchor = tuple(float(value) for value in anchor) + if not all(math.isfinite(value) for value in anchor): + raise ValueError("legend anchor must contain 2 or 4 finite numbers") return Legend( show=_strict_bool(show, "legend show"), loc=_optional_string(loc, "legend loc"), + anchor=anchor, ncols=_optional_positive_int(ncols, "legend ncols") or 1, title=_optional_string(title, "legend title"), highlight=_strict_bool(highlight, "legend highlight"), @@ -3040,6 +3069,7 @@ def figure(self) -> Figure: type_=axis.type_, constant=axis.constant, domain=axis.domain, + margin=axis.margin, bounds=axis.bounds, reverse=axis.reverse, format=axis.format, @@ -3198,6 +3228,8 @@ def figure(self) -> Figure: node = legends[-1] _apply_chrome_node(fig, "legend", node.class_name, node.style) fig.legend_options = {"loc": node.loc, "ncols": node.ncols} + if node.anchor is not None: + fig.legend_options["anchor"] = list(node.anchor) if node.title is not None: fig.legend_options["title"] = node.title if not _strict_bool(node.highlight, "legend highlight"): @@ -4675,6 +4707,7 @@ def _apply_segments(fig: Figure, m: Mark, data: Any) -> None: domain=m.props["domain"], width=m.props["width"], opacity=m.props["opacity"], + dash=m.props["dash"], style=m.style, ) @@ -4695,6 +4728,7 @@ def _apply_triangle_mesh(fig: Figure, m: Mark, data: Any) -> None: opacity=m.props["opacity"], stroke=m.props["stroke"], stroke_width=m.props["stroke_width"], + _joined_fill=m.props["_joined_fill"], style=m.style, ) @@ -4825,6 +4859,8 @@ def _apply_contour(fig: Figure, m: Mark, data: Any) -> None: width=m.props["width"], opacity=m.props["opacity"], dash_negative=m.props.get("dash_negative", False), + extend=m.props.get("extend", "neither"), + corner_mask=m.props.get("corner_mask", False), style=m.style, ) diff --git a/python/xy/marks.py b/python/xy/marks.py index 1db275ab..f3cccb3d 100644 --- a/python/xy/marks.py +++ b/python/xy/marks.py @@ -323,6 +323,7 @@ def segments( domain: Optional[tuple[float, float]] = None, width: Any = 1.2, opacity: Any = 1.0, + dash: Union[str, Sequence[float], None] = None, style: styles.StyleMapping | None = None, ) -> "Figure": """Add independent line segments through the shared instanced renderer.""" @@ -330,6 +331,7 @@ def segments( color = css.get("color", color) width = css.get("width", width) opacity = css.get("opacity", opacity) + dash = css.get("dash", dash) arrays = [self._as_1d_float(values, "segments color geometry") for values in (x0, y0, x1, y1)] if len({len(values) for values in arrays}) != 1: raise ValueError("segments coordinate columns must have equal length") @@ -342,6 +344,7 @@ def segments( raise ValueError("segments domain requires a continuous numeric color array") color_ch.domain = self._finite_increasing_pair(domain, "segments domain") constant = color_ch.constant if color_ch.mode == "constant" else None + dash_spec = _validate.dash(dash, "segments dash") self._append_segment_trace( "segments", arrays[0], @@ -353,6 +356,7 @@ def segments( opacity=opacity, width=width, role="segments", + dash=dash_spec, color_ch=None if color_ch.mode == "constant" else color_ch, extra_style=styles._opacity_channels(css), ) @@ -375,6 +379,7 @@ def triangle_mesh( opacity: Any = 1.0, stroke: Any = None, stroke_width: Any = 0.0, + _joined_fill: bool = False, style: styles.StyleMapping | None = None, ) -> "Figure": """Add independently colored filled triangles as one instanced mesh.""" @@ -431,10 +436,22 @@ def triangle_mesh( if color_ch.mode != "continuous": raise ValueError("triangle_mesh domain requires a continuous numeric color array") color_ch.domain = self._finite_increasing_pair(domain, "triangle_mesh domain") + # A width without an explicit stroke means "outline in the face color". + # Constant paints already get that fallback from the renderer; direct and + # semantic color channels need the explicit buffer-free match mode. + if ( + stroke_value is None + and stroke_ch is None + and color_ch.mode != "constant" + and (stroke_width_value or "stroke_width" in style_channels) + ): + stroke_ch = channels.ColorChannel(mode="match_fill") checkpoint = self._checkpoint() try: x0c, y0c, x1c, y1c, x2c, y2c = [self.store.ingest(values) for values in arrays] style: dict[str, Any] = {"opacity": opacity_value, "role": "triangle-mesh"} + if _joined_fill: + style["joined_fill"] = True style.update(styles._opacity_channels(css)) if stroke_value is not None: style["stroke"] = stroke_value @@ -585,10 +602,15 @@ def _distribution_stats(group: np.ndarray) -> tuple[float, float, float, float, def _contour_segments( - z: np.ndarray, x_coords: np.ndarray, y_coords: np.ndarray, levels: np.ndarray + z: np.ndarray, + x_coords: np.ndarray, + y_coords: np.ndarray, + levels: np.ndarray, + *, + corner_mask: bool = False, ) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]: """Extract flat contour segments through the native marching-squares kernel.""" - return kernels.marching_squares(z, x_coords, y_coords, levels) + return kernels.marching_squares(z, x_coords, y_coords, levels, corner_mask=corner_mask) def _bar_like( @@ -600,7 +622,7 @@ def _bar_like( name: Optional[str], color: Any, colors: Optional[list[str]], - width: float, + width: Any, base: Union[Scalar, ArrayLike], mode: str, orientation: str, @@ -614,13 +636,29 @@ def _bar_like( style_extra: Optional[dict[str, Any]] = None, ) -> "Figure": name = self._optional_text(name, f"{kind} name") - width = self._positive_scalar(width, f"{kind} width") if mode not in {"grouped", "stacked", "normalized"}: raise ValueError(f"{kind} mode must be 'grouped', 'stacked', or 'normalized'") if orientation not in {"vertical", "horizontal"}: raise ValueError(f"{kind} orientation must be 'vertical' or 'horizontal'") category_axis = "x" if orientation == "vertical" else "y" pos, category_labels = self._axis_positions_with_labels(x, category_axis) + raw_width_array = np.asarray(width) + if np.issubdtype(raw_width_array.dtype, np.bool_): + raise ValueError(f"{kind} width must be scalar or contain numeric values") + width_array = np.asarray(width, dtype=np.float64) + if width_array.ndim == 0: + width_values: float | np.ndarray = self._positive_scalar( + float(width_array), f"{kind} width" + ) + else: + try: + width_values = np.broadcast_to(width_array, (len(pos),)).astype(np.float64, copy=False) + except ValueError: + raise ValueError( + f"{kind} width must be scalar or broadcast to the {len(pos)} bars" + ) from None + if not np.isfinite(width_values).all() or np.any(width_values <= 0.0): + raise ValueError(f"{kind} width values must be finite and positive") vals = self._bar_value_matrix(y, len(pos), kind) n_series, n_items = vals.shape if mode == "normalized": @@ -698,11 +736,22 @@ def _bar_like( mark_style["artist_alpha"] = alpha_values[index] series_styles.append(mark_style) series_channels.append(merged_channels) + if direct_strokes is None and direct_colors is not None: + resolved_strokes: list[Optional[channels.ColorChannel]] = [ + ( + channels.ColorChannel(mode="match_fill") + if stroke_width_values[index] or "stroke_width" in series_channels[index] + else None + ) + for index in range(n_series) + ] + else: + resolved_strokes = [None] * n_series if direct_strokes is None else list(direct_strokes) checkpoint = self._checkpoint() try: if category_labels is not None: self._commit_category_labels(category_labels, category_axis) - half = width / 2.0 + half = width_values / 2.0 if vals.shape[0] == 1: self._append_bar_rect( kind, @@ -719,11 +768,11 @@ def _bar_like( role=f"{kind}-normalized" if mode == "normalized" else kind, extra_style=series_styles[0], color_ch=None if direct_colors is None else direct_colors[0], - stroke_ch=None if direct_strokes is None else direct_strokes[0], + stroke_ch=resolved_strokes[0], style_channels=series_channels[0], ) elif mode == "grouped": - slot = width / vals.shape[0] + slot = width_values / vals.shape[0] for i, row in enumerate(vals): p0 = pos - half + i * slot self._append_bar_rect( @@ -739,7 +788,7 @@ def _bar_like( role=f"{kind}-grouped", extra_style=series_styles[i], color_ch=None if direct_colors is None else direct_colors[i], - stroke_ch=None if direct_strokes is None else direct_strokes[i], + stroke_ch=resolved_strokes[i], style_channels=series_channels[i], ) else: @@ -761,7 +810,7 @@ def _bar_like( role=f"{kind}-{mode}", extra_style=series_styles[i], color_ch=None if direct_colors is None else direct_colors[i], - stroke_ch=None if direct_strokes is None else direct_strokes[i], + stroke_ch=resolved_strokes[i], style_channels=series_channels[i], ) pos_base = np.where(row >= 0, y1, pos_base) @@ -2087,16 +2136,24 @@ def hexbin( def _interpolate_contourf_grid( - arr: np.ndarray, xpos: np.ndarray, ypos: np.ndarray + arr: np.ndarray, + xpos: np.ndarray, + ypos: np.ndarray, + *, + corner_mask: bool = False, ) -> tuple[np.ndarray, np.ndarray, np.ndarray]: """Bilinearly densify a contour field before assigning discrete bands.""" rows, cols = arr.shape def sample_count(size: int) -> int: - # Eight samples per source interval removes visible cell stair-steps for - # common scientific grids. The 512 target keeps the shipped grid bounded; - # inputs already larger than that are never downsampled. - return min((size - 1) * 8 + 1, max(size, 512)) + # Eight samples per source interval is sufficient for ordinary grids, + # but very small masked grids need a pixel-like floor or their diagonal + # corner-mask boundaries become visibly stair-stepped in static output. + # The floor/cap keeps that approximation bounded at 256²–512² samples; + # already-larger inputs are never downsampled. + if size > 512: + return size + return min(512, max(256, (size - 1) * 8 + 1)) out_rows, out_cols = sample_count(rows), sample_count(cols) if (out_rows, out_cols) == (rows, cols): @@ -2115,7 +2172,11 @@ def sample_count(size: int) -> int: z10 = arr[row0[:, None], col1[None, :]] z01 = arr[row1[:, None], col0[None, :]] z11 = arr[row1[:, None], col1[None, :]] - valid = np.isfinite(z00) & np.isfinite(z10) & np.isfinite(z01) & np.isfinite(z11) + finite00 = np.isfinite(z00) + finite10 = np.isfinite(z10) + finite01 = np.isfinite(z01) + finite11 = np.isfinite(z11) + valid = finite00 & finite10 & finite01 & finite11 interpolated = ( z00 * (1.0 - row_weight) * (1.0 - col_weight) + z10 * (1.0 - row_weight) * col_weight @@ -2123,6 +2184,44 @@ def sample_count(size: int) -> int: + z11 * row_weight * col_weight ) interpolated[~valid] = np.nan + if corner_mask: + # contourpy's corner_mask=True retains the triangle opposite a single + # masked vertex instead of discarding the whole quad. Interpolate + # that valid triangle in barycentric coordinates; quads with two or + # more missing vertices remain wholly masked. + finite_count = ( + finite00.astype(np.uint8) + + finite10.astype(np.uint8) + + finite01.astype(np.uint8) + + finite11.astype(np.uint8) + ) + u = np.broadcast_to(col_weight, interpolated.shape) + v = np.broadcast_to(row_weight, interpolated.shape) + safe00 = np.nan_to_num(z00) + safe10 = np.nan_to_num(z10) + safe01 = np.nan_to_num(z01) + safe11 = np.nan_to_num(z11) + triangular = finite_count == 3 + cases = ( + ( + triangular & ~finite00 & (u + v >= 1.0), + safe10 * (1.0 - v) + safe01 * (1.0 - u) + safe11 * (u + v - 1.0), + ), + ( + triangular & ~finite10 & (v >= u), + safe00 * (1.0 - v) + safe01 * (v - u) + safe11 * u, + ), + ( + triangular & ~finite01 & (u >= v), + safe00 * (1.0 - u) + safe10 * (u - v) + safe11 * v, + ), + ( + triangular & ~finite11 & (u + v <= 1.0), + safe00 * (1.0 - u - v) + safe10 * u + safe01 * v, + ), + ) + for keep, values in cases: + interpolated[keep] = values[keep] dense_x = np.interp(col_at, np.arange(cols), xpos) dense_y = np.interp(row_at, np.arange(rows), ypos) return interpolated, dense_x, dense_y @@ -2138,10 +2237,12 @@ def contour( filled: bool = False, name: Optional[str] = None, colormap: str = channels.DEFAULT_COLORMAP, - color: Optional[str] = None, - width: float = 1.1, + color: Any = None, + width: Any = 1.1, opacity: float = 0.9, dash_negative: bool = False, + extend: str = "neither", + corner_mask: bool = False, style: styles.StyleMapping | None = None, ) -> "Figure": """Add regular-grid contour isolines, optionally over a filled heatmap. @@ -2188,9 +2289,45 @@ def contour( if not channels.is_colormap(colormap): raise ValueError(f"unknown colormap {colormap!r}; known: {channels.COLORMAPS}") name = self._optional_text(name, "contour name") - color = self._optional_css_color(color, "contour color") - width = self._positive_scalar(width, "contour width") + if extend not in ("neither", "min", "max", "both"): + raise ValueError("contour extend must be 'neither', 'min', 'max', or 'both'") + extend_min = filled and extend in ("min", "both") + extend_max = filled and extend in ("max", "both") + color_table: Optional[np.ndarray] + if color is None or isinstance(color, str): + color = self._optional_css_color(color, "contour color") + color_table = None + else: + expected = ( + len(level_values) - 1 + int(extend_min) + int(extend_max) + if filled + else len(level_values) + ) + color_channel = channels.resolve_color( + color, + expected, + colormap=colormap, + default_constant=default_palette_color(len(self.traces)), + ) + if color_channel.mode != "direct_rgba" or color_channel.rgba is None: + raise ValueError("contour color arrays must contain direct RGB/RGBA rows") + color_table = color_channel.rgba + color = None + if np.isscalar(width): + width = self._positive_scalar(width, "contour width") + width_values = None + else: + width_values = self._as_1d_float(width, "contour width") + if ( + not len(width_values) + or not np.isfinite(width_values).all() + or np.any(width_values <= 0) + ): + raise ValueError("contour width must contain positive finite values") + width = float(width_values[0]) opacity = self._opacity(opacity, "contour opacity") + if not isinstance(corner_mask, (bool, np.bool_)): + raise TypeError("contour corner_mask must be boolean") # Checkpoint spans the optional filled heatmap too: a level set that never # intersects the grid must not leave a stray heatmap trace behind. checkpoint = self._checkpoint() @@ -2203,21 +2340,44 @@ def contour( # Values outside the level range stay unpainted (extend='neither'). edges = np.asarray(level_values, dtype=np.float64) if len(edges) >= 2 and edges[0] < edges[-1]: - dense, dense_x, dense_y = _interpolate_contourf_grid(arr, xpos, ypos) + dense, dense_x, dense_y = _interpolate_contourf_grid( + arr, xpos, ypos, corner_mask=bool(corner_mask) + ) band = np.searchsorted(edges, dense, side="right") - 1 mids = (edges[:-1] + edges[1:]) * 0.5 - banded = np.full(dense.shape, np.nan, dtype=np.float64) inside = np.isfinite(dense) & (band >= 0) & (band < len(edges) - 1) - banded[inside] = mids[np.clip(band, 0, len(edges) - 2)][inside] - self.heatmap( - banded, - x=dense_x, - y=dense_y, - name=name, - colormap=colormap, - domain=(float(edges[0]), float(edges[-1])), - opacity=min(opacity, 0.9), - ) + if color_table is None: + banded = np.full(dense.shape, np.nan, dtype=np.float64) + banded[inside] = mids[np.clip(band, 0, len(edges) - 2)][inside] + self.heatmap( + banded, + x=dense_x, + y=dense_y, + name=name, + colormap=colormap, + domain=(float(edges[0]), float(edges[-1])), + opacity=min(opacity, 0.9), + ) + else: + # Listed contour colors are discrete paint, not a request + # for the named colormap. Carry exact RGBA through the + # truecolor heatmap path so every renderer sees the same + # per-band cycle. + rgba = np.zeros(dense.shape + (4,), dtype=np.float64) + offset = int(extend_min) + rgba[inside] = color_table[offset + band[inside]] + finite_dense = np.isfinite(dense) + if extend_min: + rgba[finite_dense & (dense < edges[0])] = color_table[0] + if extend_max: + rgba[finite_dense & (dense > edges[-1])] = color_table[-1] + self.heatmap( + rgba, + x=dense_x, + y=dense_y, + name=name, + opacity=opacity, + ) else: self.heatmap( arr, @@ -2227,28 +2387,55 @@ def contour( colormap=colormap, opacity=min(opacity, 0.7), ) - x0, x1, y0, y1, level_values = _contour_segments(arr, xpos, ypos, level_values) + contour_levels = level_values + x0, x1, y0, y1, segment_levels = _contour_segments( + arr, + xpos, + ypos, + contour_levels, + corner_mask=bool(corner_mask), + ) if len(x0) == 0: raise ValueError("contour levels do not intersect the finite grid") - domain = self._auto_domain((float(np.min(level_values)), float(np.max(level_values)))) - color_ch = ( - channels.ColorChannel( - mode="continuous", values=level_values, domain=domain, colormap=colormap + domain = self._auto_domain((float(np.min(segment_levels)), float(np.max(segment_levels)))) + if color_table is not None and not filled: + level_indices = np.searchsorted(contour_levels, segment_levels) + level_indices = np.clip(level_indices, 0, len(contour_levels) - 1) + color_ch = channels.ColorChannel( + mode="direct_rgba", + rgba=np.ascontiguousarray(color_table[level_indices]), + ) + else: + color_ch = ( + channels.ColorChannel( + mode="continuous", values=segment_levels, domain=domain, colormap=colormap + ) + if color is None and color_table is None + else None ) - if color is None - else None - ) # contourf paints bands without outlining their boundaries. Users can # explicitly overlay contour() when isolines are desired. if not filled: # Matplotlib dashes negative isolines for a single-color contour. Split # the segment set by level sign so the negative group ships dashed; a # colormapped contour keeps every level solid. - lv = np.asarray(level_values) + lv = np.asarray(segment_levels) + if width_values is not None: + level_indices = np.searchsorted(contour_levels, lv) + level_indices = np.clip(level_indices, 0, len(contour_levels) - 1) + segment_widths = width_values[level_indices % len(width_values)] + else: + segment_widths = width if dash_negative and color is not None and np.any(lv < 0) and np.any(lv >= 0): # Matplotlib's dashed preset is scaled by the contour linewidth: # 3.7 on / 1.6 off times the rendered width. - groups = ((lv >= 0, None), (lv < 0, [3.7 * width, 1.6 * width])) + if width_values is None: + groups = ((lv >= 0, None), (lv < 0, [3.7 * width, 1.6 * width])) + else: + # Per-level widths cannot share one dash array. Splitting + # by sign still retains the correct widths; the native + # renderer uses its standard dashed contour preset. + groups = ((lv >= 0, None), (lv < 0, [3.7, 1.6])) else: groups = ((np.ones(len(lv), dtype=bool), None),) for mask, dash in groups: @@ -2261,7 +2448,11 @@ def contour( name=name if dash is None else None, color=color, opacity=opacity, - width=width, + width=( + np.asarray(segment_widths, dtype=np.float64)[mask] + if isinstance(segment_widths, np.ndarray) + else segment_widths + ), role="contour", color_ch=color_ch, dash=dash, @@ -2281,7 +2472,7 @@ def bar( name: Optional[str] = None, color: Any = None, colors: Optional[list[str]] = None, - width: float = 0.8, + width: Any = 0.8, base: Union[Scalar, ArrayLike] = 0.0, mode: str = "grouped", orientation: str = "vertical", @@ -2338,7 +2529,7 @@ def column( name: Optional[str] = None, color: Union[str, Sequence[str], None] = None, colors: Optional[list[str]] = None, - width: float = 0.8, + width: Any = 0.8, base: Union[Scalar, ArrayLike] = 0.0, mode: str = "grouped", orientation: str = "vertical", diff --git a/python/xy/pyplot/__init__.py b/python/xy/pyplot/__init__.py index 5afbf7fc..987b94ac 100644 --- a/python/xy/pyplot/__init__.py +++ b/python/xy/pyplot/__init__.py @@ -305,6 +305,7 @@ def subplots( gridspec_kw = kwargs.pop("gridspec_kw", None) or {} subplot_kw = kwargs.pop("subplot_kw", None) or {} toolbar = kwargs.pop("toolbar", None) + layout = kwargs.pop("layout", None) # Remaining kwargs are matplotlib's **fig_kw, forwarded to figure(). fig = figure(figsize=figsize, dpi=dpi, toolbar=toolbar, **kwargs) if fig._axes and any(ax._entries for ax in fig._axes): @@ -323,6 +324,7 @@ def subplots( if subplot_kw: for ax in np.atleast_1d(np.asarray(axes, dtype=object)).ravel(): ax.set(**subplot_kw) + _apply_factory_layout(fig, layout) return fig, axes @@ -345,8 +347,24 @@ def subplot_mosaic(mosaic: str | list[Any], **kwargs: Any) -> tuple[Figure, dict """ figsize = kwargs.pop("figsize", None) dpi = kwargs.pop("dpi", None) + layout = kwargs.pop("layout", None) fig = figure(None, figsize=figsize, dpi=dpi) - return fig, fig.subplot_mosaic(mosaic, **kwargs) + axes = fig.subplot_mosaic(mosaic, **kwargs) + _apply_factory_layout(fig, layout) + return fig, axes + + +def _apply_factory_layout(fig: Figure, layout: Any) -> None: + """Apply Matplotlib's figure-factory layout option after axes exist.""" + if layout is None or layout == "none": + return + if layout in {"tight", "constrained", "compressed"}: + # The shim's deterministic tight-layout pass reserves the native + # panels' tick/title chrome. Apply it after the factory has created + # the grid; applying it in figure() would run against an empty figure. + fig.tight_layout() + return + raise ValueError(f"Invalid value for 'layout': {layout!r}") def axes(arg: Sequence[float] | None = None, **kwargs: Any) -> Axes: @@ -2833,12 +2851,16 @@ def get_cmap(name: str | None = None, lut: int | None = None) -> Cmap: return get_cmap(name, lut) def __getattr__(self, name: str) -> Any: - from ._colors import CMAPS + from ._colors import resolve_cmap if name == "ScalarMappable": return type("ScalarMappable", (), {"__init__": lambda self, **kwargs: None}) - if name.lower() in CMAPS: + try: + resolve_cmap(name) + except ValueError: + pass + else: return name raise AttributeError(f"colormap {name!r} is not supported; see spec/matplotlib/compat.md") diff --git a/python/xy/pyplot/_artists.py b/python/xy/pyplot/_artists.py index cbbb5e6f..b2cf5d38 100644 --- a/python/xy/pyplot/_artists.py +++ b/python/xy/pyplot/_artists.py @@ -10,7 +10,6 @@ import warnings from collections.abc import Iterator -from itertools import pairwise from operator import index as operator_index from typing import Any, Optional @@ -357,17 +356,45 @@ def set_linewidth(self, w: float) -> None: set_lw = set_linewidth def set_dashes(self, sequence: Any) -> None: - self._entry["kwargs"]["dash"] = [float(value) for value in sequence] + self._entry["kwargs"]["dash"] = self._axes._mpl_dash( + [float(value) for value in sequence], + self._entry["kwargs"].get("width", 1.5), + ) self._touch() def set_dash_capstyle(self, style: Any) -> None: - raise NotImplementedError("xy.pyplot does not support dash cap style mutation") + value = str(style) + if value != "round": + raise NotImplementedError( + "xy.pyplot's renderers currently support only round dash cap mutation" + ) + self._entry["kwargs"]["dash_capstyle"] = value + self._touch() + + def get_dash_capstyle(self) -> str: + return str(self._entry["kwargs"].get("dash_capstyle", "round")) def set_solid_capstyle(self, style: Any) -> None: raise NotImplementedError("xy.pyplot does not support solid cap style mutation") def set_gapcolor(self, color: Any) -> None: - raise NotImplementedError("xy.pyplot does not support gapcolor mutation") + from ._translate import resolve_color + + if color is None: + self._entry["kwargs"].pop("_gapcolor", None) + else: + self._entry["kwargs"]["_gapcolor"] = resolve_color(color) + self._touch() + + def get_gapcolor(self) -> Any: + return self._entry["kwargs"].get("_gapcolor") + + +class _LegendElementHandle: + """Synthetic collection handle used only to build explicit legend items.""" + + def __init__(self, entry: dict[str, Any]) -> None: + self._entry = entry class PathCollection(Artist): @@ -467,24 +494,82 @@ def set_sizes(self, sizes: Any, dpi: Any = 72.0) -> None: self._touch() def get_sizes(self) -> np.ndarray: + if "source_sizes" in self._entry: + return np.atleast_1d(np.asarray(self._entry["source_sizes"], dtype=np.float64)) sizes = np.asarray(self._entry["kwargs"].get("size", 0.0), dtype=np.float64) return np.atleast_1d(sizes**2) def legend_elements( self, prop: str = "colors", num: Any = "auto", **kwargs: Any - ) -> tuple[list["PathCollection"], list[str]]: - import numpy as np - - del kwargs - values = self._entry["kwargs"].get("size" if prop == "sizes" else "color") + ) -> tuple[list[Any], list[str]]: + if prop not in {"colors", "sizes"}: + raise ValueError("prop must be 'colors' or 'sizes'") + func = kwargs.pop("func", lambda value: value) + fmt = kwargs.pop("fmt", None) + alpha = kwargs.pop("alpha", self.get_alpha()) + color_override = kwargs.pop("color", None) + values = self.get_sizes() if prop == "sizes" else self.get_array() try: array = np.asarray(values, dtype=np.float64).reshape(-1) except (TypeError, ValueError): - array = np.arange(1, dtype=np.float64) + array = np.asarray([], dtype=np.float64) unique = np.unique(array[np.isfinite(array)]) - count = 5 if num == "auto" else max(1, int(num)) - chosen = unique if len(unique) <= count else np.linspace(unique.min(), unique.max(), count) - return [self] * len(chosen), [f"{value:g}" for value in chosen] + if not unique.size: + return [], [] + transformed = np.asarray(func(unique), dtype=np.float64) + if num == "auto" and len(unique) <= 9: + chosen = unique + label_values = transformed + elif not np.isscalar(num): + label_values = np.asarray(num, dtype=np.float64).reshape(-1) + chosen = np.interp(label_values, transformed, unique) + else: + from ._ticker import MaxNLocator + + count = 9 if num == "auto" else max(1, int(num)) + ticks = MaxNLocator(count).tick_values( + float(transformed.min()), float(transformed.max()) + ) + label_values = ticks[(ticks >= transformed.min()) & (ticks <= transformed.max())] + chosen = np.interp(label_values, transformed, unique) + base = self._entry.get("kwargs", {}) + lo, hi = self._entry.get("kwargs", {}).get( + "domain", (float(unique.min()), float(unique.max())) + ) + handles = [] + for value in chosen: + handle_kwargs = { + "symbol": base.get("symbol", "circle"), + "stroke": base.get("stroke"), + "stroke_width": base.get("stroke_width", 0.0), + "opacity": 1.0 if alpha is None else float(alpha), + } + if prop == "sizes": + from ._translate import marker_size_to_scatter_size + + handle_kwargs["size"] = marker_size_to_scatter_size( + float(value), point_scale=self._axes._point_scale() + ) + handle_kwargs["color"] = resolve_color( + color_override + if color_override is not None + else base.get("color") + if isinstance(base.get("color"), str) + else "#1f77b4" + ) + else: + normalized = 0.5 if hi == lo else (float(value) - lo) / (hi - lo) + handle_kwargs["color"] = resolve_color(self.cmap(normalized)) + handles.append(_LegendElementHandle({"kind": "scatter", "kwargs": handle_kwargs})) + + def format_label(value: float) -> str: + if callable(fmt): + return str(fmt(value)) + if isinstance(fmt, str): + return fmt.format(x=value) + return f"{value:g}" + + return handles, [format_label(float(value)) for value in label_values] @property def cmap(self) -> Any: @@ -835,18 +920,32 @@ def get_data(self) -> tuple[Any, Any, Any]: class StemContainer: """Small tuple-compatible analogue of matplotlib's StemContainer.""" - def __init__(self, artist: Artist) -> None: - self.markerline = artist - self.stemlines = artist - self.baseline = artist - artist._axes._register_container(self) + def __init__( + self, + markerline: Artist, + stemlines: Optional[Artist] = None, + baseline: Optional[Artist] = None, + ) -> None: + # Older callers supplied one compact artist for all three handles. + # Keep that form working while allowing the pyplot stem adapter to + # expose independently mutable marker, stem, and baseline artists. + self.markerline = markerline + self.stemlines = markerline if stemlines is None else stemlines + self.baseline = markerline if baseline is None else baseline + markerline._axes._register_container(self) def __iter__(self) -> Iterator[Any]: return iter((self.markerline, self.stemlines, self.baseline)) def remove(self) -> None: - self.stemlines.remove() - self.stemlines._axes._unregister_container(self) + axes = self.markerline._axes + seen: set[int] = set() + for artist in (self.markerline, self.stemlines, self.baseline): + if id(artist) in seen: + continue + seen.add(id(artist)) + artist.remove() + axes._unregister_container(self) class ErrorbarContainer: @@ -876,9 +975,37 @@ def levels(self) -> Any: @property def cmap(self) -> Any: - from ._colors import Cmap - - return Cmap(self._entry["kwargs"].get("colormap", "viridis")) + from ._colors import Cmap, resolve_rgba + + contour = self + + class BoundContourCmap(Cmap): + """Colormap facade whose extended listed colors remain live.""" + + def _set_extreme(self, end: int, color: object, alpha: object) -> None: + table = contour._entry["kwargs"].get("color") + if isinstance(table, str) or table is None: + return + values = np.asarray(table, dtype=np.float64) + if values.ndim != 2 or values.shape[1] != 4 or not len(values): + return + rgba = resolve_rgba(color if alpha is None else (color, alpha)) + updated = values.copy() + updated[end] = rgba + contour._entry["kwargs"]["color"] = updated + contour._touch() + + def set_under(self, color: object = "transparent", alpha: object = None) -> None: + super().set_under(color, alpha) + if contour._entry["kwargs"].get("extend") in ("min", "both"): + self._set_extreme(0, color, alpha) + + def set_over(self, color: object = "transparent", alpha: object = None) -> None: + super().set_over(color, alpha) + if contour._entry["kwargs"].get("extend") in ("max", "both"): + self._set_extreme(-1, color, alpha) + + return BoundContourCmap(self._entry["kwargs"].get("colormap", "viridis")) def set(self, **kwargs: Any) -> "ContourSet": path_effects = kwargs.pop("path_effects", None) @@ -932,23 +1059,129 @@ def set(self, **kwargs: Any) -> "ContourSet": return self def get_linewidth(self) -> list[float]: - return [float(self._entry["kwargs"].get("width", 1.1))] + return np.asarray(self._entry["kwargs"].get("width", 1.1), dtype=float).reshape(-1).tolist() def set_linewidth(self, width: Any) -> None: - self._entry["kwargs"]["width"] = float(np.asarray(width).reshape(-1)[0]) + values = np.asarray(width, dtype=float).reshape(-1) + if not len(values) or not np.isfinite(values).all() or np.any(values <= 0): + raise ValueError("contour linewidth must contain positive finite values") + self._entry["kwargs"]["width"] = float(values[0]) if len(values) == 1 else values self._touch() def set_linestyle(self, style: Any) -> None: self._entry["linestyle"] = style self._touch() - def legend_elements(self, **kwargs: Any) -> tuple[list["ContourSet"], list[str]]: + def legend_elements(self, **kwargs: Any) -> tuple[list[Any], list[str]]: + """Return independent legend proxies for every line or filled band. + + Matplotlib deliberately returns lightweight ``Line2D``/``Rectangle`` + artists here, not the contour collection itself. Keeping that + distinction is important for hatched contour legends: each band needs + its own color and hatch even though all bands belong to one mark. + """ + variable_name = kwargs.pop("variable_name", "x") formatter = kwargs.pop("str_format", str) + if kwargs: + raise TypeError( + f"legend_elements() got an unexpected keyword argument {next(iter(kwargs))!r}" + ) levels = np.asarray(self.levels).reshape(-1) - labels = [ - f"{formatter(float(lo))} < x <= {formatter(float(hi))}" for lo, hi in pairwise(levels) + entry = self._entry + mark_kwargs = entry.get("kwargs", {}) + filled = bool(mark_kwargs.get("filled", False)) + if not filled: + widths = np.asarray(mark_kwargs.get("width", 1.1), dtype=float).reshape(-1) + colors = _contour_legend_colors(entry, len(levels)) + artists = [ + _LegendProxy( + { + "kind": "line", + "kwargs": { + "color": colors[index], + "width": float(widths[index % len(widths)]), + "opacity": mark_kwargs.get("opacity", 1.0), + }, + } + ) + for index in range(len(levels)) + ] + labels = [f"${variable_name} = {formatter(float(level))}$" for level in levels] + return artists, labels + + extend = entry.get("extend") or mark_kwargs.get("extend") or "neither" + private_levels = levels.tolist() + if extend in ("min", "both"): + private_levels.insert(0, -1e250) + if extend in ("max", "both"): + private_levels.append(1e250) + lowers = np.asarray(private_levels[:-1], dtype=float) + uppers = np.asarray(private_levels[1:], dtype=float) + source = np.asarray(entry.get("source_z", []), dtype=float) + finite = source[np.isfinite(source)] + if len(lowers) and finite.size and float(finite.min()) == float(lowers[0]): + lowers = lowers.copy() + lowers[0] -= 1.0 + n_bands = len(lowers) + colors = _contour_legend_colors(entry, n_bands) + hatches = entry.get("hatches") or [None] + artists = [ + _LegendProxy( + { + "kind": "bar", + "kwargs": { + "color": colors[index], + "opacity": mark_kwargs.get("opacity", 1.0), + "hatch": hatches[index % len(hatches)], + }, + } + ) + for index in range(n_bands) ] - return [self] * len(labels), labels + labels: list[str] = [] + for index, (lower, upper) in enumerate(zip(lowers, uppers, strict=True)): + lower_text, upper_text = formatter(float(lower)), formatter(float(upper)) + if index == 0 and extend in ("min", "both"): + labels.append(f"${variable_name} <= {lower_text}s$") + elif index == n_bands - 1 and extend in ("max", "both"): + labels.append(f"${variable_name} > {upper_text}s$") + else: + labels.append(f"${lower_text} < {variable_name} <= {upper_text}$") + return artists, labels + + +class _LegendProxy: + """Unregistered artist-like handle used by ``ContourSet.legend_elements``.""" + + def __init__(self, entry: dict[str, Any]) -> None: + self._entry = entry + + +def _contour_legend_colors(entry: dict[str, Any], count: int) -> list[str]: + """Resolve a contour's scalar/listed color channel to CSS proxy colors.""" + if count <= 0: + return [] + kwargs = entry.get("kwargs", {}) + value = kwargs.get("color") + if isinstance(value, str): + return [value] * count + if value is not None: + array = np.asarray(value) + if array.ndim == 1 and array.size in (3, 4): + array = np.tile(array, (count, 1)) + if array.ndim == 2 and array.shape[1] in (3, 4) and len(array): + if array.shape[1] == 3: + array = np.column_stack((array, np.ones(len(array)))) + return [_rgba_css(array[index % len(array)]) for index in range(count)] + from ._colors import Cmap + + rgba = np.asarray(Cmap(kwargs.get("colormap", "viridis"))((np.arange(count) + 0.5) / count)) + return [_rgba_css(row) for row in rgba] + + +def _rgba_css(value: Any) -> str: + red, green, blue, alpha = np.clip(np.asarray(value, dtype=float), 0.0, 1.0) + return f"rgba({round(255 * red)},{round(255 * green)},{round(255 * blue)},{float(alpha):g})" class PolyCollection(Artist): @@ -976,14 +1209,28 @@ def __init__( import numpy as np self.wedges = wedges - self.values = np.asarray(values, dtype=np.float64) - total = float(np.sum(self.values)) if normalize else 1.0 - self.fracs = self.values / total + # Matplotlib keeps the input dtype here. In particular, integer pie + # data must remain integers so pie_label("{absval:d}") is valid. + self._values = np.asarray(values).copy() self.normalize = bool(normalize) self._texts: list[list[Text]] = [texts] if autotexts: self._texts.append(autotexts) + @property + def values(self) -> Any: + result = self._values.copy() + result.flags.writeable = False + return result + + @property + def fracs(self) -> Any: + import numpy as np + + result = self._values / np.sum(self._values) if self.normalize else self._values.copy() + result.flags.writeable = False + return result + @property def texts(self) -> list[list["Text"]]: return self._texts @@ -1089,6 +1336,10 @@ def _legend_item_from_entry( opacity = kw.get("opacity") if opacity is not None: style["opacity"] = float(opacity) + hatch = kw.get("hatch") + if hatch: + style["hatch"] = str(hatch) + style["hatch_color"] = str(kw.get("hatch_color", "#222222")) # Rule annotations keep renderer-specific geometry inside ``style`` while # ordinary line/step entries keep it at the top level. Accept both shapes # so explicit Legend handles preserve the plotted dash. @@ -1113,7 +1364,7 @@ def _legend_item_from_entry( symbol = kw.get("symbol") if symbol: style["symbol"] = symbol - for key in ("stroke", "stroke_width"): + for key in ("size", "stroke", "stroke_width"): if kw.get(key) is not None: style[key] = kw[key] return {"name": str(label), "kind": kind, "style": style} diff --git a/python/xy/pyplot/_axes.py b/python/xy/pyplot/_axes.py index 3b04d605..2a7b0dc2 100644 --- a/python/xy/pyplot/_axes.py +++ b/python/xy/pyplot/_axes.py @@ -14,7 +14,7 @@ # Runtime imports, not TYPE_CHECKING: `typing.get_type_hints()` on the public # Axes methods must resolve these annotation names (all stdlib or xy-local). -from collections.abc import Callable, Iterator, Sequence +from collections.abc import Callable, Iterator, Mapping, Sequence from contextlib import suppress from datetime import datetime, timedelta from itertools import pairwise @@ -36,9 +36,16 @@ Text, unit_converted_values, ) -from ._colors import PROP_CYCLE, resolve_cmap, resolve_color, resolve_rgba_array, scalar_float +from ._colors import ( + PROP_CYCLE, + resolve_cmap, + resolve_color, + resolve_rgba, + resolve_rgba_array, + scalar_float, +) from ._fmt import parse_fmt -from ._mathtext import mathtext_to_unicode +from ._mathtext import mathtext_italic_ranges, mathtext_to_unicode from ._plot_types import PlotTypeMixin from ._rc import RcParams, rcParams from ._ticker import AutoLocator, Locator, NullLocator, ScalarFormatter, as_formatter @@ -60,6 +67,115 @@ "text_color": "#262626", } _MPL_GRID_COLOR = "#b0b0b0" +# The 1x1 axes rectangle implied by the rcParams figure.subplot.* defaults +# (left .125, bottom .11, right .9, top .88). `_mplfig` owns the general +# gridspec resolution; this is the last-resort answer for a detached axes. +_DEFAULT_AXES_RECT = (0.125, 0.11, 0.775, 0.77) + +# Matplotlib's candidate order for ``loc="best"``: `Legend.codes` 1..10, scored +# in order, first zero-badness box wins, lower code wins a tie. Code 5 +# ("right") anchors identically to code 7 ("center right") — offsetbox resolves +# both to its 'E' corner — so the pair is folded onto the single canonical name +# at code 5's position. The order `min()` observes is unchanged and no redundant +# box is scored. Do not reorder: this *is* the tie-break contract. +_LEGEND_LOC_ANCHORS = { + "upper right": (1.0, 1.0), + "upper left": (0.0, 1.0), + "lower left": (0.0, 0.0), + "lower right": (1.0, 0.0), + "right": (1.0, 0.5), + "center left": (0.0, 0.5), + "center right": (1.0, 0.5), + "lower center": (0.5, 0.0), + "upper center": (0.5, 1.0), + "center": (0.5, 0.5), +} +_BEST_LOC_ORDER = ( + "upper right", + "upper left", + "lower left", + "lower right", + "right", + "center left", + "lower center", + "upper center", + "center", +) +# Per-series vertex budget for occupancy scoring (§28: decimation is specified, +# never silent). Matplotlib counts every vertex and says so in its own +# `loc="best"` slowness warning; the shim strides instead and weights the count +# back up, so relative badness survives but a lone excursion into an otherwise +# empty candidate box can be missed on a series far longer than this. +_BEST_LOC_SAMPLE = 4096 +# Plot box of the default 640x480 figure, for direct `_best_legend_loc` callers +# that have no chart geometry to hand. +_DEFAULT_BEST_PLOT_SIZE = (564.0, 428.0) + + +def _path_intersects_boxes( + x: np.ndarray, + y: np.ndarray, + boxes: Sequence[tuple[float, float, float, float]], +) -> list[bool]: + """Whether a polyline touches each box, including edge-only crossings. + + Matplotlib adds one badness point per artist path intersecting the + candidate legend rectangle, independently of the number of contained + vertices. Liang-Barsky clipping gives the same segment/rectangle question + without materializing a Matplotlib ``Path``. Segment coordinates and deltas + are shared across all nine legend candidates; a bounding-box rejection + keeps the exact clipping solve off segments that cannot touch a candidate. + """ + boxes = tuple(boxes) + if x.size < 2 or y.size < 2: + return [False] * len(boxes) + x0, y0, x1, y1 = x[:-1], y[:-1], x[1:], y[1:] + finite = np.isfinite(x0) & np.isfinite(y0) & np.isfinite(x1) & np.isfinite(y1) + if not finite.any(): + return [False] * len(boxes) + x0, y0, x1, y1 = x0[finite], y0[finite], x1[finite], y1[finite] + segment_x_lo, segment_x_hi = np.minimum(x0, x1), np.maximum(x0, x1) + segment_y_lo, segment_y_hi = np.minimum(y0, y1), np.maximum(y0, y1) + result: list[bool] = [] + for x_lo, x_hi, y_lo, y_hi in boxes: + possible = ( + (segment_x_hi >= x_lo) + & (segment_x_lo <= x_hi) + & (segment_y_hi >= y_lo) + & (segment_y_lo <= y_hi) + ) + if not possible.any(): + result.append(False) + continue + hit = False + for index in np.flatnonzero(possible): + ax0, ay0, ax1, ay1 = x0[index], y0[index], x1[index], y1[index] + if (x_lo <= ax0 <= x_hi and y_lo <= ay0 <= y_hi) or ( + x_lo <= ax1 <= x_hi and y_lo <= ay1 <= y_hi + ): + hit = True + break + adx, ady = ax1 - ax0, ay1 - ay0 + if adx: + for boundary in (x_lo, x_hi): + ratio = (boundary - ax0) / adx + if 0.0 <= ratio <= 1.0 and y_lo <= ay0 + ratio * ady <= y_hi: + hit = True + break + if hit: + break + if ady: + for boundary in (y_lo, y_hi): + ratio = (boundary - ay0) / ady + if 0.0 <= ratio <= 1.0 and x_lo <= ax0 + ratio * adx <= x_hi: + hit = True + break + if hit: + hit = True + break + result.append(hit) + return result + # Theme/axis children are immutable declarative specs, so identical ones are # shared across charts — the theme's CSS tokens validate through the native @@ -102,12 +218,14 @@ def _rc_chrome_snapshot(dpi: float) -> dict[str, Any]: f"{_font_size(rcParams['axes.titlesize'], rcParams['font.size'], dpi):g}px" ), "color": theme_tokens["text_color"], + **_rc_font_weight(rcParams["axes.titleweight"]), }, "axis_title": { "font-size": ( f"{_font_size(rcParams['axes.labelsize'], rcParams['font.size'], dpi):g}px" ), "color": resolve_color(rcParams["axes.labelcolor"]), + **_rc_font_weight(rcParams["axes.labelweight"]), }, "tick_label": { "font-size": ( @@ -172,6 +290,48 @@ def _scale_values(values: Any, spec: Optional[dict[str, Any]], *, inverse: bool return values +def _clip_infinite_line( + point: tuple[float, float], + direction: tuple[float, float], + xlim: tuple[float, float], + ylim: tuple[float, float], +) -> tuple[np.ndarray, np.ndarray]: + """Clip one infinite data-space line to a rectangular view.""" + xlo, xhi = sorted(map(float, xlim)) + ylo, yhi = sorted(map(float, ylim)) + px, py = map(float, point) + dx, dy = map(float, direction) + if (dx == 0.0 and dy == 0.0) or not np.isfinite([px, py]).all(): + raise ValueError("Cannot draw a line through two identical or non-finite points") + xtol = max(1.0, xhi - xlo) * 1e-12 + ytol = max(1.0, yhi - ylo) * 1e-12 + candidates: list[tuple[float, float, float]] = [] + if dx != 0.0: + for x in (xlo, xhi): + t = (x - px) / dx + y = py + t * dy + if ylo - ytol <= y <= yhi + ytol: + candidates.append((t, x, min(yhi, max(ylo, y)))) + if dy != 0.0: + for y in (ylo, yhi): + t = (y - py) / dy + x = px + t * dx + if xlo - xtol <= x <= xhi + xtol: + candidates.append((t, min(xhi, max(xlo, x)), y)) + candidates.sort(key=lambda item: item[0]) + unique: list[tuple[float, float, float]] = [] + for candidate in candidates: + if not unique or not np.allclose(candidate[1:], unique[-1][1:], rtol=0.0, atol=1e-11): + unique.append(candidate) + if len(unique) < 2: + return np.empty(0, dtype=np.float64), np.empty(0, dtype=np.float64) + start, stop = unique[0], unique[-1] + return ( + np.asarray([start[1], stop[1]], dtype=np.float64), + np.asarray([start[2], stop[2]], dtype=np.float64), + ) + + def _transform_entry_axis(entry: dict[str, Any], axis: str, old: Any, new: Any) -> None: def convert(values: Any) -> Any: return _scale_values(_scale_values(values, old, inverse=True), new) @@ -186,7 +346,11 @@ def convert(values: Any) -> Any: indexes = { "segments": (0, 2) if axis == "x" else (1, 3), "triangle_mesh": (0, 2, 4) if axis == "x" else (1, 3, 5), + "area": (0,) if axis == "x" else (1,), "step": (0,) if axis == "x" else (1,), + # Compact stairs store (values, edges), the reverse of ordinary + # Cartesian (x, y) argument order. + "stairs": (1,) if axis == "x" else (0,), "stem": (0,) if axis == "x" else (1,), "errorbar": (0,) if axis == "x" else (1,), "hexbin": (0,) if axis == "x" else (1,), @@ -195,6 +359,103 @@ def convert(values: Any) -> Any: for index in indexes: args[index] = convert(args[index]) entry["args"] = tuple(args) + if factory == "area" and axis == "y" and "base" in entry.get("kwargs", {}): + entry["kwargs"]["base"] = convert(entry["kwargs"]["base"]) + + +def _heatmap_span(entry: dict[str, Any], axis: str) -> Optional[np.ndarray]: + """The outer cell edges a ``@mark``/``heatmap`` entry occupies on *axis*. + + ``hist2d``/``pcolormesh``/``specgram`` register their cell **centers** + inside ``kwargs``, so the autoscale scan's generic top-level ``entry[key]`` + probe never sees them. Mirror `Figure._heatmap_axis_positions` plus + `Figure._cell_edges` exactly rather than re-deriving the geometry: absent + centers default to ``arange(n)``, and the drawn span reaches half a cell + beyond the first and last center, which is what recovers the original + ``hist2d`` bin edges from its centers. + """ + from xy._figure import Figure + + args = entry.get("args", ()) + if not args: + return None + z = np.asarray(args[0]) + if z.ndim < 2: + return None + # Both (rows, cols) and RGB(A) (rows, cols, bands) grids index the same way. + count = z.shape[1 if axis == "x" else 0] + centers = entry.get("kwargs", {}).get(axis) + if centers is None: + positions = np.arange(count, dtype=np.float64) + else: + try: + positions = np.asarray(unit_converted_values(centers), dtype=np.float64).reshape(-1) + except (TypeError, ValueError): + # String/object centers become first-seen ordinals in the core. + positions = np.arange(np.asarray(centers).size, dtype=np.float64) + if positions.size != count or not np.all(np.isfinite(positions)): + return None + try: + edges = Figure._cell_edges(positions, f"heatmap {axis}") + except ValueError: + # A build with these centers will raise for the same reason; leave the + # decision to the core instead of guessing a span here. + return None + return np.asarray([edges[0], edges[-1]], dtype=np.float64) + + +def _box_spans(entry: dict[str, Any], axis: str) -> Iterator[np.ndarray]: + """The spans a ``@mark``/``box`` entry occupies on *axis*. + + The value axis mirrors `marks.box`: Tukey whiskers plus, when outliers are + drawn, the flier points beyond them. The category axis follows + Matplotlib's ``manage_ticks=True`` contract, which reserves position +/- + 0.5 regardless of the drawn box width. + """ + from xy.marks import _distribution_stats + + args = entry.get("args", ()) + if not args: + return + kwargs = entry.get("kwargs", {}) + orientation = kwargs.get("orientation", "vertical") + values = args[0] + if ( + isinstance(values, (list, tuple)) + and len(values) + and all(not isinstance(item, str) and np.ndim(item) == 1 for item in values) + ): + groups = [np.asarray(item, dtype=np.float64) for item in values] + else: + array = np.asarray(values, dtype=np.float64) + groups = ( + [array[:, index] for index in range(array.shape[1])] + if array.ndim == 2 + else [array.reshape(-1)] + ) + positions = kwargs.get("x") + ordinals = np.arange(len(groups), dtype=np.float64) + if positions is None: + # marks.box defaults absent positions to arange(len(groups)). + centers = ordinals + else: + try: + centers = np.asarray(unit_converted_values(positions), dtype=np.float64).reshape(-1) + except (TypeError, ValueError): + # String categories become their first-seen ordinal positions. + centers = ordinals + if centers.size != len(groups) or not np.all(np.isfinite(centers)): + centers = ordinals + category_axis = "x" if orientation == "vertical" else "y" + if axis == category_axis: + yield centers - 0.5 + yield centers + 0.5 + return + stats = [_distribution_stats(group) for group in groups] + spans = [np.asarray([stat[3], stat[4]], dtype=np.float64) for stat in stats] + if kwargs.get("show_outliers", True): + spans.extend(np.asarray(stat[5], dtype=np.float64) for stat in stats) + yield from spans def _nonlinear_ticks(domain: tuple[float, float], spec: dict[str, Any]) -> np.ndarray: @@ -292,6 +553,28 @@ def set_minor_formatter(self, formatter: Any) -> None: host, key = self._ticker_slot() host._tickers[(key, "minor_formatter")] = as_formatter(formatter, "set_minor_formatter()") + def grid(self, visible: bool | None = None, which: str = "major", **kwargs: Any) -> None: + """Configure grid lines for only this axis. + + This is Matplotlib's ``Axis.grid`` surface: unlike ``Axes.grid`` it + has no ``axis=`` argument because the proxy already identifies the + target dimension. + """ + which = str(which).lower() + if which not in {"major", "minor", "both"}: + raise ValueError("grid() which must be 'major', 'minor', or 'both'") + if which == "minor": + supported = {"color", "c", "linestyle", "ls", "linewidth", "lw", "alpha"} + unsupported = set(kwargs) - supported + if unsupported: + raise TypeError( + f"grid() got unsupported keyword argument {sorted(unsupported)[0]!r}" + ) + # Minor tick marks are outside the native axis contract. + self.axes._invalidate() + return + self.axes.grid(visible, which=which, axis=self.axis, **kwargs) + def tick_bottom(self) -> None: pass # exact no-op: the engine only draws bottom x ticks @@ -425,9 +708,21 @@ def set_color(self, color: ColorLike) -> None: self._axes._invalidate() def set_rotation(self, angle: float) -> None: - self._axes._axis_props(self._axis)["tick_label_angle"] = float(angle) + angle = float(angle) + self._axes._axis_props(self._axis)["tick_label_angle"] = angle + self._axes._apply_tick_rotation_mode(self._axis, angle) + self._axes._invalidate() + + def get_rotation(self) -> float: + return float(self._axes._axis_props(self._axis).get("tick_label_angle", 0.0)) + + def set_rotation_mode(self, mode: str | None) -> None: + self._axes._set_tick_rotation_mode(self._axis, mode) self._axes._invalidate() + def get_rotation_mode(self) -> str: + return self._axes._tick_rotation_modes.get(self._axis) or "default" + class _SharedAxesGroup: """matplotlib's shared-axes Grouper over the shim's shared props dicts.""" @@ -462,7 +757,21 @@ def __init__( self.axes, self.names = axes, names def __getitem__(self, key: Any) -> "_SpineProxy": - names = (key,) if isinstance(key, str) else tuple(key) + if isinstance(key, str): + names = (key,) + elif isinstance(key, list): + names = tuple(key) + elif isinstance(key, tuple): + raise ValueError("Multiple spines must be passed as a single list") + elif isinstance(key, slice): + if key.start is not None or key.stop is not None or key.step is not None: + raise ValueError( + "Spines does not support slicing except for the fully " + "open slice [:] to access all spines." + ) + names = self.names + else: + raise TypeError(f"spine key must be a string, list, or open slice, got {type(key)!r}") unknown = set(names) - {"left", "bottom", "top", "right"} if unknown: raise KeyError(next(iter(unknown))) @@ -526,8 +835,12 @@ def __init__(self, figure: Any, *, y2_of: Optional["Axes"] = None) -> None: self._containers: list[Any] = [] self._axis: dict[str, dict[str, Any]] = {"x": {}, "y": {}, "y2": {}} self._title: Optional[str] = None + self._title_style: dict[str, Any] = {} self._legend = False self._legend_options: dict[str, Any] = {} + self._legend_items: Optional[list[dict[str, Any]]] = None + self._legend_handle: Optional[Legend] = None + self._legend_artist: Optional[Legend] = None self._extra_legends: list[Any] = [] self._colorbar: Optional[dict[str, Any]] = None self._colorbar_source: Optional[dict[str, Any]] = None # entry the colorbar reads @@ -540,11 +853,33 @@ def __init__(self, figure: Any, *, y2_of: Optional["Axes"] = None) -> None: # The originating gridspec span, when _figure_rect came from one — # subplots_adjust() re-resolves the rect instead of keeping it frozen. self._subplot_spec: Optional[Any] = None + # Stable row-major cell identity for an ordinary subplot. Figure.axes + # is a draw-order list, so removing an earlier axes must not slide + # every later subplot into the preceding cell. + self._subplot_index: Optional[int] = None self._absolute_plot_ratio: Optional[float] = None + # The plot rectangle the exporter demands, in chart pixels + # (left, top, width, height). Set by the grid compositor for a panel, + # whose chart is the panel and not the whole figure; otherwise the + # chart *is* the figure and the rectangle comes from get_position(). + self._plot_box_px: Optional[tuple[float, float, float, float]] = None self._padding: Optional[list[float]] = None - self._xmargin = 0.0 - self._ymargin = 0.0 + # Matplotlib snapshots the rc autoscale margins when an Axes is + # created. Keep those values on the axes so ordinary get_*lim() and + # rendering use the advertised 5% defaults without requiring an + # explicit margins() call. + self._xmargin = float(rcParams["axes.xmargin"]) + self._ymargin = float(rcParams["axes.ymargin"]) + self._rc_margins = { + "x": self._xmargin, + "y": self._ymargin, + } self._margin_overrides: set[str] = set() + # Edge annotations (notably bar_label) need more than the raw 5% data + # margin to contain a 10 pt glyph plus point padding. Keep that + # renderer-independent reservation separate so an explicit margins() + # call still wins. + self._annotation_margins: dict[str, float] = {"x": 0.0, "y": 0.0} self._explicit_domains: set[str] = set() self._secondary_axes: list[SecondaryAxis] = [] self._scale_specs: dict[str, dict[str, Any]] = { @@ -554,8 +889,19 @@ def __init__(self, figure: Any, *, y2_of: Optional["Axes"] = None) -> None: } self._auto_scale_axis_ticks: set[str] = set() self._tickers: dict[tuple[str, str], Any] = {} + self._tick_rotation_modes: dict[str, str | None] = {"x": None, "y": None} + self._tick_sides: dict[str, dict[str, bool]] = { + "x": {"bottom": True, "top": False}, + "y": {"left": y2_of is None, "right": y2_of is not None}, + } + self._tick_label_sides: dict[str, dict[str, bool]] = { + "x": {"labelbottom": True, "labeltop": False}, + "y": {"labelleft": y2_of is None, "labelright": y2_of is not None}, + } + self._tick_lengths: dict[str, float] = {} self._hidden_spines: set[str] = set() self._grid = bool(rcParams["axes.grid"]) + self._grid_axes = {"x": self._grid, "y": self._grid} self._grid_color = _MPL_GRID_COLOR self._grid_axis = "both" self._grid_style: dict[str, Any] = {} @@ -576,9 +922,16 @@ def __init__(self, figure: Any, *, y2_of: Optional["Axes"] = None) -> None: style = _rc_axis_style(axis, dpi) if style: self._axis[axis]["style"] = style + self._tick_lengths[axis] = float(style["tick_length"]) # -- lifecycle ----------------------------------------------------------- + def remove(self) -> None: + """Remove this axes from its figure.""" + if self.figure is None or self not in self.figure._axes: + raise ValueError("Axes is not attached to a figure") + self.figure.delaxes(self) + def _load_rc_chrome(self) -> None: """Snapshot the rcParams-derived color cycle, theme, and chrome styles. @@ -614,17 +967,21 @@ def _point_scale(self) -> float: return dpi / 72.0 def _mpl_dash(self, dash: Any, linewidth: Any) -> Any: - """Scale a named dash pattern the way Matplotlib does, or pass through. + """Scale a Matplotlib dash pattern from points into output pixels. Named patterns ("dashed"/"dotted"/"dashdot") become an on/off pixel list scaled by the line width and figure DPI, matching Matplotlib's - ``scale_dashes`` plus point sizing. ``None``, the ``"none"`` sentinel, - and explicit numeric sequences are returned unchanged. + ``scale_dashes`` plus point sizing. Explicit numeric sequences use the + same scale; only ``None`` and the ``"none"`` sentinel pass through. """ - if not isinstance(dash, str) or dash not in MPL_DASH_PATTERN: + if dash is None or dash == "none": return dash + if isinstance(dash, str): + if dash not in MPL_DASH_PATTERN: + return dash + dash = MPL_DASH_PATTERN[dash] scale = float(linewidth) * self._point_scale() - return [round(value * scale, 4) for value in MPL_DASH_PATTERN[dash]] + return [round(float(value) * scale, 4) for value in dash] def _remove_entry(self, entry: dict[str, Any]) -> None: host = self._y2_of or self @@ -775,6 +1132,12 @@ def _add(self, kind: str, entry: dict[str, Any]) -> dict[str, Any]: _transform_entry_axis(entry, axis, {"name": "linear"}, spec) nonlinear_axes.append((axis, spec)) host._entries.append(entry) + # Aspect modes may be selected before any data is added (the + # Matplotlib fill gallery does exactly this with ``axis("equal")``). + # Keep their bounds tied to the current autoscaled data until the user + # explicitly pins a domain instead of freezing the empty (0, 1) view. + if host._aspect_equal and not host._explicit_domains: + host._set_aspect_equal_from_current() for axis, spec in nonlinear_axes: # scale-generated ticks were derived from the extent at # set_*scale time; new data must refresh them (user-set ticks @@ -812,10 +1175,24 @@ def clear(self) -> None: } self._auto_scale_axis_ticks = set() self._tickers = {} + self._tick_rotation_modes = {"x": None, "y": None} + self._tick_sides = { + "x": {"bottom": True, "top": False}, + "y": {"left": self._y2_of is None, "right": self._y2_of is not None}, + } + self._tick_label_sides = { + "x": {"labelbottom": True, "labeltop": False}, + "y": {"labelleft": self._y2_of is None, "labelright": self._y2_of is not None}, + } + self._tick_lengths = {} self._hidden_spines = set() self._title = None + self._title_style = {} self._legend = False self._legend_options = {} + self._legend_items = None + self._legend_handle = None + self._legend_artist = None self._extra_legends = [] self._colorbar = None self._colorbar_source = None @@ -825,8 +1202,19 @@ def clear(self) -> None: self._insets = [] self._insets_materialized = False self._absolute_plot_ratio = None + self._plot_box_px = None self._padding = None + self._annotation_margins = {"x": 0.0, "y": 0.0} + self._xmargin = float(rcParams["axes.xmargin"]) + self._ymargin = float(rcParams["axes.ymargin"]) + self._rc_margins = { + "x": self._xmargin, + "y": self._ymargin, + } + self._margin_overrides = set() + self._explicit_domains = set() self._grid = bool(rcParams["axes.grid"]) + self._grid_axes = {"x": self._grid, "y": self._grid} self._grid_color = _MPL_GRID_COLOR self._grid_axis = "both" self._grid_style = {} @@ -837,10 +1225,12 @@ def clear(self) -> None: self.xaxis = _AxisProxy(self, "x") self.yaxis = _AxisProxy(self, "y") self.spines = _SpineProxy(self) + dpi = float(self.figure._dpi if self.figure._dpi is not None else rcParams["figure.dpi"]) for axis in ("x", "y"): - style = _rc_axis_style(axis) + style = _rc_axis_style(axis, dpi) if style: self._axis[axis]["style"] = style + self._tick_lengths[axis] = float(style["tick_length"]) self._invalidate() cla = clear @@ -887,6 +1277,8 @@ def plot(self, *args: Any, **kwargs: Any) -> list[Line2D]: transform = kwargs.pop("transform", None) if transform is not None and not hasattr(transform, "transform"): raise TypeError("plot transform must provide transform(xy)") + if drawstyle == "steps": + drawstyle = "steps-pre" if drawstyle not in (None, "default", "steps-pre", "steps-mid", "steps-post"): raise ValueError(f"unsupported drawstyle: {drawstyle!r}") check_unsupported(kwargs, "plot()") @@ -934,9 +1326,15 @@ def _plot_series( if transform is not None: x, y = self._transform_points(x, y, transform) if np.ma.isMaskedArray(x): - x = np.ma.asarray(x).filled(np.nan) + masked_x = np.ma.asarray(x) + if masked_x.dtype.kind in "iub": + masked_x = masked_x.astype(np.float64) + x = masked_x.filled(np.nan) if np.ma.isMaskedArray(y): - y = np.ma.asarray(y).filled(np.nan) + masked_y = np.ma.asarray(y) + if masked_y.dtype.kind in "iub": + masked_y = masked_y.astype(np.float64) + y = masked_y.filled(np.nan) per = dict(base) this_marker = marker if fmt: @@ -964,6 +1362,8 @@ def _plot_series( "opacity": per.get("opacity", 1.0), "name": per.get("name"), } + if per.get("_gapcolor") is not None: + entry_kwargs["_gapcolor"] = per["_gapcolor"] marker_size_pt = float(rcParams["lines.markersize"] if markersize is None else markersize) marker_edge_visible = not ( isinstance(markeredgecolor, str) and markeredgecolor.lower() == "none" @@ -1325,6 +1725,9 @@ def scatter( entry = self._add("scatter", {"x": x, "y": y, "kwargs": entry_kwargs}) if source_color is not None: entry["source_array"] = source_color + entry["source_sizes"] = np.asarray( + rcParams["lines.markersize"] ** 2 if s is None else s, dtype=np.float64 + ).reshape(-1) if "colormap" in entry_kwargs: levels = _discrete_levels(cmap) if levels is not None: @@ -1375,7 +1778,7 @@ def _bar_like( self, cats: Any, vals: Any, - thickness: float, + thickness: Any, base: Any, orientation: str, kwargs: dict[str, Any], @@ -1417,13 +1820,36 @@ def _bar_like( align = kwargs.pop("align", "center") if align not in {"center", "edge"}: raise ValueError("bar()/barh() align must be 'center' or 'edge'") + n_bars = int(np.asarray(vals).size) + thickness_array = np.asarray(thickness, dtype=np.float64) + if thickness_array.ndim == 0: + thickness_value: float | np.ndarray = float(thickness_array) + else: + try: + thickness_value = np.broadcast_to(thickness_array, (n_bars,)).astype( + np.float64, copy=False + ) + except ValueError: + raise ValueError( + f"bar thickness must be scalar or broadcast to the {n_bars} bars" + ) from None + if not np.isfinite(thickness_value).all() or np.any(thickness_value <= 0.0): + raise ValueError("bar thickness values must be finite and positive") if align == "edge": try: - cats = np.asarray(cats, dtype=np.float64) + float(thickness) / 2.0 + cats = np.asarray(cats, dtype=np.float64) + thickness_value / 2.0 except (TypeError, ValueError): raise ValueError("bar align='edge' requires numeric positions") from None check_unsupported(kwargs, "bar()/barh()") n_bars = int(np.asarray(vals).size) + patch_labels: Optional[list[str]] = None + if label is not None and not isinstance(label, str) and np.iterable(label): + patch_labels = [_plain_text(value) for value in label] + if len(patch_labels) != n_bars: + raise ValueError( + f"number of labels ({len(patch_labels)}) " + f"does not match number of bars ({n_bars})." + ) def paint(value: Any, label_text: str, default: Optional[str] = None) -> Any: if value is None: @@ -1435,16 +1861,21 @@ def paint(value: Any, label_text: str, default: Optional[str] = None) -> Any: array.ndim == 1 and array.shape in {(3,), (4,)} and np.issubdtype(array.dtype, np.number) - and isinstance(value, (tuple, list)) ): return resolve_color(value) return resolve_rgba_array(value, n_bars, label_text) entry_kwargs: dict[str, Any] = { "color": paint(color, "bar color", self._next_color()), - "width": float(thickness), + "width": thickness_value, "opacity": 1.0, - "name": str(label) if label is not None else None, + # A sequence labels the individual Rectangle patches in + # Matplotlib, not the BarContainer. Keep the batched data trace + # unnamed; _chart_children emits empty, named bar proxies for the + # visible legend entries without splitting the bar geometry. + "name": ( + None if patch_labels is not None else str(label) if label is not None else None + ), "orientation": orientation, } if alpha is not None: @@ -1466,7 +1897,15 @@ def paint(value: Any, label_text: str, default: Optional[str] = None) -> Any: if not np.isscalar(linewidth) else scalar_float(linewidth) ) - entry = self._add("bar", {"x": cats, "y": vals, "kwargs": entry_kwargs}) + entry = self._add( + "bar", + { + "x": cats, + "y": vals, + "kwargs": entry_kwargs, + **({"patch_labels": patch_labels} if patch_labels is not None else {}), + }, + ) container = BarContainer(self, entry) if xerr is not None or yerr is not None: positions = np.asarray(cats) @@ -1475,7 +1914,7 @@ def paint(value: Any, label_text: str, default: Optional[str] = None) -> Any: if orientation == "vertical": ex, ey, exerr, eyerr = positions, bases + values, xerr, yerr else: - ex, ey, exerr, eyerr = bases + values, positions, yerr, xerr + ex, ey, exerr, eyerr = bases + values, positions, xerr, yerr err_kwargs = { "xerr": exerr, "yerr": eyerr, @@ -1491,7 +1930,7 @@ def hist( bins: int | ArrayLike | str = 10, range: Any = None, # noqa: A002 - matplotlib's own signature density: bool = False, - cumulative: bool = False, + cumulative: bool | int = False, **kwargs: Any, ) -> tuple[Any, np.ndarray, Any]: """A histogram of ``x``. @@ -1506,6 +1945,8 @@ def hist( ``(counts, bin_edges, patches)`` as matplotlib does. """ color = kwargs.pop("color", None) + facecolor = kwargs.pop("facecolor", None) + fill = kwargs.pop("fill", None) alpha = kwargs.pop("alpha", None) label = kwargs.pop("label", None) histtype = kwargs.pop("histtype", "bar") @@ -1513,6 +1954,10 @@ def hist( orientation = kwargs.pop("orientation", "vertical") stacked = bool(kwargs.pop("stacked", False)) edgecolor = kwargs.pop("edgecolor", None) + linewidth = kwargs.pop("linewidth", kwargs.pop("lw", None)) + linestyle = kwargs.pop("linestyle", kwargs.pop("ls", None)) + rwidth = kwargs.pop("rwidth", None) + hatch = kwargs.pop("hatch", None) if ( edgecolor is None and histtype in ("bar", "barstacked") @@ -1525,7 +1970,9 @@ def hist( if histtype not in {"bar", "barstacked", "step", "stepfilled"}: raise ValueError(f"unsupported histtype {histtype!r}") - if isinstance(x, np.ndarray) and x.ndim == 1 and x.dtype.kind in "fiub": + if np.isscalar(x): + datasets = [np.atleast_1d(np.asarray(x, dtype=np.float64))] + elif isinstance(x, np.ndarray) and x.ndim == 1 and x.dtype.kind in "fiub": # The common numeric-array call must not round-trip through an # object array: boxing every element just to sniff the input shape # is an O(n) cost per build (tests/pyplot/test_perf_guardrail.py). @@ -1568,16 +2015,42 @@ def hist( for values, w in zip(datasets, weight_sets, strict=True) ] if cumulative: + reverse = isinstance(cumulative, (int, float, np.number)) and cumulative < 0 counts = [ - np.cumsum(values * np.diff(edges)) if density else np.cumsum(values) + ( + np.cumsum((values * np.diff(edges) if density else values)[::-1])[::-1] + if reverse + else np.cumsum(values * np.diff(edges) if density else values) + ) for values in counts ] stacked = stacked or histtype == "barstacked" - colors = ( - color - if isinstance(color, (list, tuple)) and len(datasets) > 1 - else [color] * len(datasets) - ) + + def dataset_values(value: Any, name: str, *, color_value: bool = False) -> list[Any]: + if value is None: + return [None] * len(datasets) + if color_value: + try: + resolve_color(value) + except (TypeError, ValueError): + pass + else: + return [value] * len(datasets) + if np.isscalar(value): + return [value] * len(datasets) + values = list(value) + if len(values) != len(datasets): + raise ValueError( + f"hist {name} sequence must have length {len(datasets)}, got {len(values)}" + ) + return values + + colors = dataset_values(color, "color", color_value=True) + facecolors = dataset_values(facecolor, "facecolor", color_value=True) + edgecolors = dataset_values(edgecolor, "edgecolor", color_value=True) + linewidths = dataset_values(linewidth, "linewidth") + linestyles = dataset_values(linestyle, "linestyle") + hatches = dataset_values(hatch, "hatch") labels = label if isinstance(label, (list, tuple)) else [label] * len(datasets) containers: list[BarContainer] = [] base = np.zeros(len(edges) - 1, dtype=np.float64) @@ -1586,16 +2059,44 @@ def hist( # bin so adjacent bars touch; only multiple side-by-side series shrink # to 0.8 of the bin, split evenly. The shim previously applied the 0.8 # factor to single-series hists too, leaving visible gaps. - binwidth = float(np.min(np.diff(edges))) - rel_width = 1.0 if (stacked or len(datasets) == 1) else 0.8 - width = binwidth * rel_width / (1 if stacked else len(datasets)) + binwidths = np.diff(edges) + rel_width = ( + float(np.clip(float(rwidth), 0.0, 1.0)) + if rwidth is not None + else (1.0 if (stacked or len(datasets) == 1) else 0.8) + ) + width = binwidths * rel_width / (1 if stacked else len(datasets)) for index, values in enumerate(counts): positions = centers if stacked else centers + (index - (len(datasets) - 1) / 2) * width current_base = base.copy() if stacked else np.zeros_like(values) - resolved_color = ( + series_color = ( resolve_color(colors[index]) if colors[index] is not None else self._next_color() ) - if orientation == "horizontal" and histtype == "stepfilled": + resolved_color = ( + resolve_color(facecolors[index]) if facecolors[index] is not None else series_color + ) + resolved_edge = ( + resolve_color(edgecolors[index]) if edgecolors[index] is not None else None + ) + resolved_width = ( + float(linewidths[index]) + if linewidths[index] is not None + else float(rcParams["patch.linewidth"]) * self._point_scale() + ) + linestyle_value = "-" if linestyles[index] is None else str(linestyles[index]) + if linestyle_value not in LINESTYLE_TO_DASH: + raise ValueError(f"unsupported histogram linestyle: {linestyle_value!r}") + dash = self._mpl_dash(LINESTYLE_TO_DASH[linestyle_value], resolved_width) + filled = histtype == "stepfilled" if fill is None else bool(fill) + if not filled and resolved_edge is None: + resolved_edge = ( + series_color + if histtype == "step" + else resolve_color(rcParams["patch.edgecolor"]) + ) + elif filled and histtype == "step" and resolved_edge is None: + resolved_edge = series_color + if orientation == "horizontal" and histtype.startswith("step") and filled: # The core area primitive fills along y. Horizontal filled # steps are equivalently represented by touching horizontal # bars, preserving the exact bins/counts without rotating a @@ -1612,7 +2113,8 @@ def hist( "color": resolved_color, "opacity": 1.0 if alpha is None else float(alpha), "name": None if labels[index] is None else str(labels[index]), - "stroke": resolve_color(edgecolor) if edgecolor is not None else None, + "stroke": resolved_edge, + "stroke_width": resolved_width, }, }, ) @@ -1626,19 +2128,22 @@ def hist( "factory": "segments", "args": (path_x[:-1], path_y[:-1], path_x[1:], path_y[1:]), "kwargs": { - "color": resolved_color, - "width": 1.2, + "color": resolved_edge or series_color, + "width": resolved_width, + "dash": dash, "name": None if labels[index] is None else str(labels[index]), "opacity": 1.0 if alpha is None else float(alpha), }, }, ) - elif histtype == "stepfilled": + elif histtype.startswith("step") and filled: # matplotlib fills the step polygon down to the baseline; the # area mark takes the pre-expanded step vertices verbatim. tops = values + current_base - no_edge = edgecolor is None or ( - isinstance(edgecolor, str) and edgecolor.lower() == "none" + no_edge = resolved_edge in (None, "transparent") or ( + isinstance(resolved_edge, str) + and resolved_edge.startswith("rgba(") + and resolved_edge.endswith(",0)") ) entry = self._add( "@mark", @@ -1648,14 +2153,11 @@ def hist( "kwargs": { "base": np.repeat(current_base, 2), "color": resolved_color, - "line_color": None if no_edge else resolve_color(edgecolor), - "line_width": ( - 0.0 - if no_edge - else float(rcParams["patch.linewidth"]) * self._point_scale() - ), + "line_color": None if no_edge else resolved_edge, + "line_width": 0.0 if no_edge else resolved_width, "line_opacity": 1.0 if alpha is None else float(alpha), "stroke_perimeter": not no_edge, + "dash": dash, "name": None if labels[index] is None else str(labels[index]), "opacity": 1.0 if alpha is None else float(alpha), }, @@ -1669,7 +2171,9 @@ def hist( "factory": "stairs", "args": (step_values, edges), "kwargs": { - "color": resolved_color, + "color": resolved_edge or series_color, + "width": resolved_width, + "dash": dash, "name": None if labels[index] is None else str(labels[index]), "opacity": 1.0 if alpha is None else float(alpha), }, @@ -1685,13 +2189,57 @@ def hist( "base": current_base, "width": width, "orientation": orientation, - "color": resolved_color, + "color": "transparent" if fill is False else resolved_color, "opacity": 1.0 if alpha is None else float(alpha), "name": None if labels[index] is None else str(labels[index]), - "stroke": resolve_color(edgecolor) if edgecolor is not None else None, + "stroke": resolved_edge if dash is None else None, + "stroke_width": resolved_width, }, }, ) + if dash not in (None, "none") and resolved_edge is not None: + half_width = width / 2.0 + low = positions - half_width + high = positions + half_width + top = current_base + values + if orientation == "vertical": + x0 = np.concatenate((low, high, high, low)) + y0 = np.concatenate((current_base, current_base, top, top)) + x1 = np.concatenate((high, high, low, low)) + y1 = np.concatenate((current_base, top, top, current_base)) + else: + x0 = np.concatenate((current_base, current_base, top, top)) + y0 = np.concatenate((low, high, high, low)) + x1 = np.concatenate((current_base, top, top, current_base)) + y1 = np.concatenate((high, high, low, low)) + self._add( + "@mark", + { + "factory": "segments", + "args": (x0, y0, x1, y1), + "kwargs": { + "color": resolved_edge, + "width": resolved_width, + "dash": dash, + "opacity": 1.0 if alpha is None else float(alpha), + "name": None, + }, + }, + ) + if hatches[index]: + self._stairs_hatch( + values + current_base, + positions - width / 2.0, + current_base, + orientation, + { + "color": resolved_edge or series_color, + "facecolor": resolved_color, + "opacity": 1.0 if alpha is None else float(alpha), + }, + hatch=str(hatches[index]), + right_edges=positions + width / 2.0, + ) containers.append(BarContainer(self, entry)) if stacked: base += values @@ -1918,8 +2466,8 @@ def imshow(self, z: ArrayLike, cmap: Any = None, **kwargs: Any) -> AxesImage: } if interpolation not in supported_interpolation: raise ValueError(f"unsupported imshow interpolation: {interpolation!r}") - if interpolation_stage not in (None, "data"): - raise not_implemented(f"imshow(interpolation_stage={interpolation_stage!r})") + if interpolation_stage not in (None, "auto", "data", "rgba"): + raise ValueError("imshow interpolation_stage must be 'auto', 'data', 'rgba', or None") if clip_on is not True: raise not_implemented("imshow(clip_on=False)") if transform not in (None, self.transData, self.transAxes): @@ -2036,17 +2584,33 @@ def extreme(name: str, default: tuple[float, float, float, float]) -> np.ndarray ) grid = np.dstack((rgb.reshape(grid.shape + (3,)) / 255.0, alpha_array)) truecolor = True + effective_interpolation = ( + rcParams["image.interpolation"] if interpolation is None else interpolation + ) if ( not truecolor - and interpolation not in (None, "none", "nearest") - and min(grid.shape) >= 2 + and interpolation_stage == "rgba" + and effective_interpolation not in ("none", "nearest") ): + grid = _scalar_grid_rgba( + grid, + cmap if cmap is not None else rcParams["image.cmap"], + vmin, + vmax, + ) + truecolor = True + if effective_interpolation not in ("none", "nearest") and min(grid.shape[:2]) >= 2: # The notebook's ordinary image box is ~369 px per side. A 128² # intermediate left each interpolated sample covering about 3×3 # display pixels because heatmaps intentionally use nearest texture # sampling. Keep a bounded 512² surface so non-nearest imshow output # is at least display-resolution while nearest retains source cells. - grid = _upsample_grid(grid, max(512, grid.shape[1]), max(512, grid.shape[0])) + grid = _resample_grid( + grid, + max(512, grid.shape[1]), + max(512, grid.shape[0]), + effective_interpolation, + ) if transform == self.transAxes and extent is not None: xlo, xhi = self._axis_props("x").get("domain", self._entry_extent("x")) ylo, yhi = self._axis_props("y").get("domain", self._entry_extent("y")) @@ -2277,22 +2841,33 @@ def text( transform = kwargs.pop("transform", None) fontweight = kwargs.pop("fontweight", kwargs.pop("weight", None)) fontfamily = kwargs.pop("fontfamily", kwargs.pop("family", None)) + fontstyle = kwargs.pop("fontstyle", kwargs.pop("style", None)) rotation = kwargs.pop("rotation", None) + bbox = kwargs.pop("bbox", None) check_unsupported(kwargs, "text()") akw = {"color": resolve_color(color)} if color is not None else {} + if bbox is not None: + if not isinstance(bbox, Mapping): + raise TypeError("text() bbox must be a mapping or None") + akw["bbox"] = dict(bbox) if ha is not None: akw["anchor"] = {"left": "start", "center": "middle", "right": "end"}.get( str(ha), "start" ) style: dict[str, Any] = {} if fontsize is not None: - style["font_size"] = float(fontsize) + style["font_size"] = _font_size_points(fontsize, rcParams["font.size"]) if va is not None: style["vertical_align"] = str(va) if fontweight is not None: style["font_weight"] = str(fontweight) if fontfamily is not None: style["font_family"] = str(fontfamily) + if fontstyle is not None: + fontstyle = str(fontstyle) + if fontstyle not in {"normal", "italic", "oblique"}: + raise ValueError("text() style must be 'normal', 'italic', or 'oblique'") + style["font_style"] = fontstyle if rotation is not None: style["rotation"] = 90.0 if rotation == "vertical" else float(rotation) if transform is self.transAxes or transform == "axes fraction": @@ -2301,7 +2876,15 @@ def text( style["coordinate_space"] = "figure_fraction" if style: akw["style"] = style - return Text(self, self._add("@text", {"args": (x, y, _plain_text(s)), "kwargs": akw})) + plain_text, math_italic_ranges = _plain_text_with_math_italic_ranges(s) + if math_italic_ranges: + akw["style"] = { + **(akw.get("style") or {}), + "math_italic_ranges": ",".join( + f"{start}:{end}" for start, end in math_italic_ranges + ), + } + return Text(self, self._add("@text", {"args": (x, y, plain_text), "kwargs": akw})) def annotate(self, text: str, xy: tuple, xytext: Optional[tuple] = None, **kwargs: Any) -> Text: """Annotate the point ``xy`` with text, optionally offset at ``xytext``. @@ -2443,7 +3026,7 @@ def set_xlabel(self, label: str, **kwargs: Any) -> None: """ props = self._axis_props("x") props["label"] = _plain_text(label) - _apply_axis_label_kwargs(props, kwargs, "set_xlabel()") + _apply_axis_label_kwargs(props, kwargs, "set_xlabel()", point_scale=self._point_scale()) self._invalidate() def set_ylabel(self, label: str, **kwargs: Any) -> None: @@ -2453,7 +3036,7 @@ def set_ylabel(self, label: str, **kwargs: Any) -> None: """ props = self._axis_props("y") props["label"] = _plain_text(label) - _apply_axis_label_kwargs(props, kwargs, "set_ylabel()") + _apply_axis_label_kwargs(props, kwargs, "set_ylabel()", point_scale=self._point_scale()) self._invalidate() def set_title(self, title: str, **kwargs: Any) -> None: @@ -2463,8 +3046,11 @@ def set_title(self, title: str, **kwargs: Any) -> None: are accepted as compatibility inputs; anything else raises loudly. Basic mathtext (``$...$``) is rendered. """ - _consume_text_kwargs(kwargs, "set_title()") host = self._y2_of or self + host._title_style = _title_css_style( + _pop_text_style_kwargs(kwargs, "set_title()"), + point_scale=self._point_scale(), + ) host._title = _plain_text(title) host._invalidate() @@ -2590,9 +3176,50 @@ def get_ylim(self) -> tuple[float, float]: return (hi, lo) if self._axis_props("y").get("reverse") else (lo, hi) def get_position(self, original: bool = False) -> Bbox: - """The axes rectangle in figure fractions, as a `Bbox`.""" - del original # compat-noop: shim axes have no active/original position split - return Bbox.from_bounds(*(self._figure_rect or (0.125, 0.11, 0.775, 0.77))) + """The axes rectangle in figure fractions, as a `Bbox`. + + Grid-aware: a subplot without an explicit rect reports its gridspec + cell under the figure's SubplotParams, so the panels of an ``n x m`` + grid report ``n * m`` distinct boxes exactly as matplotlib does. + ``original=False`` applies adjustable-box aspect geometry, while + ``original=True`` returns the allocated subplot rectangle. + """ + if self._figure_rect is not None: + rect = self._figure_rect + elif self.figure is not None: + rect = self.figure._axes_rect(self) + if rect is None: + rect = _DEFAULT_AXES_RECT + else: + rect = _DEFAULT_AXES_RECT + if original or not ( + self._aspect_equal + and self._aspect_adjustable == "box" + and self._aspect_bounds is not None + and self.figure is not None + ): + return Bbox.from_bounds(*rect) + + x0, x1, y0, y1 = self._aspect_bounds + x0, x1 = self._axis["x"].get("domain", (x0, x1)) + y0, y1 = self._axis["y"].get("domain", (y0, y1)) + data_ratio = abs(x1 - x0) / max(abs(y1 - y0), np.finfo(float).eps) + fig_width, fig_height = self.figure.get_size_inches() + left, bottom, width, height = rect + physical_ratio = width * fig_width / max(height * fig_height, np.finfo(float).eps) + if physical_ratio > data_ratio: + active_width = height * fig_height * data_ratio / fig_width + active_height = height + else: + active_width = width + active_height = width * fig_width / (data_ratio * fig_height) + anchor_x, anchor_y = self._aspect_anchor() + return Bbox.from_bounds( + left + (width - active_width) * anchor_x, + bottom + (height - active_height) * anchor_y, + active_width, + active_height, + ) def set_position(self, position: Bbox | tuple[float, float, float, float]) -> None: """Place the axes at a figure-fraction rectangle. @@ -2637,24 +3264,111 @@ def _data_coordinates(self, xy: tuple) -> Optional[tuple[float, float]]: def _iter_entry_arrays(self, axis: str) -> Iterator[tuple[np.ndarray, bool]]: """Yield each (array, needs_finite_filter) an entry contributes to *axis*.""" - for entry in self._entries: - key = "x" if axis == "x" else "y" - if key in entry: + from xy.channels import category_label + + host = self._y2_of or self + y_axis = "y2" if self._y2_of is not None else "y" + category_positions: dict[str, float] = {} + + def numeric_or_categorical(values: Any) -> np.ndarray: + """Mirror the core's first-seen categorical coordinate mapping. + + Pyplot materializes its own auto view before the core Figure is + built. String coordinates therefore cannot simply be skipped: + doing so pins categorical line/scatter axes to the dataless + ``(0, 1)`` view and clips every category after the second. + """ + array = np.asarray(values).reshape(-1) + try: + return np.asarray(unit_converted_values(array), dtype=np.float64).reshape(-1) + except (TypeError, ValueError): + if array.dtype.kind not in {"U", "S", "O", "b"}: + raise + labels = ( + array.tolist() + if array.dtype.kind == "U" + else [category_label(value) for value in array.astype(object)] + ) + positions = np.empty(len(labels), dtype=np.float64) + for index, label in enumerate(labels): + text = str(label) + positions[index] = category_positions.setdefault( + text, float(len(category_positions)) + ) + return positions + + for entry in host._entries: + if axis == "y" and entry.get("y_axis", "y") != y_axis: + continue + if entry.get("kind") == "@axline": + # Matplotlib includes only untransformed defining points in + # data limits (one anchor for slope form, both for two-point + # form). Axes-fraction anchors never affect autoscale. + if entry.get("transform_space") is None: + index = 0 if axis == "x" else 1 + points = [entry["xy1"]] + if entry.get("xy2") is not None: + points.append(entry["xy2"]) + yield np.asarray([point[index] for point in points], dtype=np.float64), True + continue + if entry.get("kind") == "bar": + kwargs = entry.get("kwargs", {}) + orientation = kwargs.get("orientation", "vertical") + centers = np.asarray(entry.get("x", ())).reshape(-1) try: - array = np.asarray(unit_converted_values(entry[key]), dtype=np.float64).reshape( + centers = np.asarray(unit_converted_values(centers), dtype=np.float64).reshape( -1 ) + except (TypeError, ValueError): + # The core provisions one categorical bar trace in this + # same first-seen order, so its extent is the ordinal + # range directly. Keep this hot path free of a duplicate + # Python label-map pass. + centers = np.arange(centers.size, dtype=np.float64) + values = np.asarray(entry.get("y", ()), dtype=np.float64).reshape(-1) + bases = np.asarray(kwargs.get("base", 0.0), dtype=np.float64) + bases = np.broadcast_to(bases, values.shape).reshape(-1) + thickness = np.asarray(kwargs.get("width", 0.8), dtype=np.float64) + thickness = np.broadcast_to(thickness, centers.shape).reshape(-1) + if (orientation == "vertical" and axis == "x") or ( + orientation == "horizontal" and axis == "y" + ): + yield centers - thickness * 0.5, True + yield centers + thickness * 0.5, True + else: + yield bases, True + yield bases + values, True + continue + key = "x" if axis == "x" else "y" + if key in entry: + try: + array = numeric_or_categorical(entry[key]) except (TypeError, ValueError): continue yield array, True + mpl_extent = entry.get("_mpl_extent", {}).get(axis) + if mpl_extent is not None: + yield np.asarray(mpl_extent, dtype=np.float64).reshape(-1), True if entry.get("kind") == "@mark": factory = entry.get("factory") indexes = { "segments": (0, 2) if axis == "x" else (1, 3), "triangle_mesh": (0, 2, 4) if axis == "x" else (1, 3, 5), + "stem": (0,) if axis == "x" else (1,), + "area": (0,) if axis == "x" else (1,), + # xy.stairs(values, edges) is compact and deliberately + # reverses the ordinary x/y argument order. + "stairs": (1,) if axis == "x" else (0,), + "step": (0,) if axis == "x" else (1,), }.get(factory, ()) for index in indexes: yield np.asarray(entry["args"][index], dtype=np.float64).reshape(-1), True + if factory == "area" and axis == "y": + base = entry.get("kwargs", {}).get("base") + if base is not None: + yield np.asarray(base, dtype=np.float64).reshape(-1), True + if factory == "stem" and axis == "y": + yield np.asarray(entry.get("kwargs", {}).get("base", 0.0)).reshape(-1), True if factory == "contour": z = np.asarray(entry["args"][0]) coordinates = entry.get("kwargs", {}).get(key) @@ -2662,6 +3376,21 @@ def _iter_entry_arrays(self, axis: str) -> Iterator[tuple[np.ndarray, bool]]: coordinates = np.arange(z.shape[1 if axis == "x" else 0], dtype=float) if coordinates is not None: yield np.asarray(coordinates, dtype=np.float64).reshape(-1), True + elif factory == "heatmap": + # NB: distinct from the `kind == "heatmap"` branch below, + # which is imshow's explicit-extent entry shape. + span = _heatmap_span(entry, key) + if span is not None: + yield span, False + elif factory == "ecdf": + if axis == "x": + yield np.asarray(entry["args"][0], dtype=np.float64).reshape(-1), True + else: + # marks.ecdf steps from 0 to cumulative mass 1. + yield np.asarray([0.0, 1.0], dtype=np.float64), False + elif factory == "box": + for span in _box_spans(entry, axis): + yield span, True elif entry.get("kind") == "heatmap" and entry.get("extent") is not None: bounds = entry["extent"] yield np.asarray(bounds[:2] if axis == "x" else bounds[2:], dtype=float), False @@ -2698,14 +3427,124 @@ def _entry_extent(self, axis: str) -> tuple[float, float]: lo, hi = float(np.min(finite)), float(np.max(finite)) return (lo, hi if hi > lo else lo + 1.0) - def _auto_domain(self, axis: str) -> tuple[float, float]: + def _entry_sticky_edges(self, axis: str) -> np.ndarray: + """Matplotlib-style sticky bar baselines on the value axis.""" + edges: list[np.ndarray] = [] + host = self._y2_of or self + y_axis = "y2" if self._y2_of is not None else "y" + for entry in host._entries: + if axis == "y" and entry.get("y_axis", "y") != y_axis: + continue + mpl_sticky = entry.get("_mpl_sticky_edges", {}).get(axis) + if mpl_sticky is not None: + edges.append(np.asarray(mpl_sticky, dtype=np.float64).reshape(-1)) + if entry.get("kind") == "bar": + kwargs = entry.get("kwargs", {}) + orientation = kwargs.get("orientation", "vertical") + value_axis = "y" if orientation == "vertical" else "x" + if axis != value_axis: + continue + values = np.asarray(entry.get("y", ()), dtype=np.float64).reshape(-1) + bases = np.asarray(kwargs.get("base", 0.0), dtype=np.float64) + edges.append(np.broadcast_to(bases, values.shape).reshape(-1)) + elif entry.get("kind") == "@mark" and entry.get("factory") == "contour": + z = np.asarray(entry["args"][0]) + coordinates = entry.get("kwargs", {}).get(axis) + if coordinates is None and z.ndim >= 2: + coordinates = np.arange(z.shape[1 if axis == "x" else 0], dtype=float) + if coordinates is not None: + values = np.asarray(coordinates, dtype=np.float64).reshape(-1) + finite = values[np.isfinite(values)] + if finite.size: + edges.append(np.asarray([finite.min(), finite.max()])) + elif entry.get("kind") == "@mark" and entry.get("factory") == "heatmap": + # Matplotlib gives pcolormesh/hist2d/specgram sticky edges: the + # view hugs the outer cell edge with no margin at all. + span = _heatmap_span(entry, axis) + if span is not None: + edges.append(span) + elif entry.get("kind") == "@mark" and entry.get("factory") == "ecdf": + if axis == "y": + # An ECDF is sticky at both 0 and full cumulative mass. + edges.append(np.asarray([0.0, 1.0], dtype=np.float64)) + elif entry.get("kind") == "@mark" and entry.get("factory") == "box": + kwargs = entry.get("kwargs", {}) + orientation = kwargs.get("orientation", "vertical") + category_axis = "x" if orientation == "vertical" else "y" + if axis == category_axis: + box_edges = [values[np.isfinite(values)] for values in _box_spans(entry, axis)] + finite_box_edges = [values for values in box_edges if values.size] + if finite_box_edges: + combined = np.concatenate(finite_box_edges) + edges.append(np.asarray([combined.min(), combined.max()])) + elif entry.get("kind") == "heatmap" and entry.get("extent") is not None: + # imshow's explicit extent is likewise sticky on both axes. + bounds = entry["extent"] + edges.append(np.asarray(bounds[:2] if axis == "x" else bounds[2:], dtype=float)) + if not edges: + return np.array([], dtype=np.float64) + combined = np.concatenate(edges) + return combined[np.isfinite(combined)] + + def _fully_sticky_domain(self, axis: str) -> Optional[tuple[float, float]]: + """The raw extent when sticky edges pin *both* ends of *axis*. + + Image- and mesh-like marks (imshow/pcolormesh/hist2d/specgram) hug + their outer cell edge in Matplotlib, and an ECDF hugs 0 and 1. The + core only knows the rectangle zero-baseline anchor, so it would pad + such an axis by the ordinary margin. `_build_chart` materializes this + domain instead of a margin so the renderer cannot widen the view. + + Deliberately requires *both* ends: a one-sided sticky edge is the bar + and histogram baseline, which the core already anchors itself. + """ + if self._axis_is_dataless(axis): + return None + sticky = self._entry_sticky_edges(axis) + if not sticky.size: + return None lo, hi = self._entry_extent(axis) - margin = self._xmargin if axis == "x" else self._ymargin + tolerance = np.finfo(np.float64).eps * max(1.0, abs(lo), abs(hi)) * 8 + pinned_lo = np.any(np.isclose(sticky, lo, rtol=0.0, atol=tolerance)) + pinned_hi = np.any(np.isclose(sticky, hi, rtol=0.0, atol=tolerance)) + return (lo, hi) if pinned_lo and pinned_hi else None + + def _auto_domain(self, axis: str) -> tuple[float, float]: + host = self._y2_of or self + key = "y2" if axis == "y" and self._y2_of is not None else axis + spec = host._scale_specs[key] + if self._axis_is_dataless(axis): + return (1.0, 10.0) if spec["name"] == "log" else (0.0, 1.0) + if spec["name"] == "log": + # The core consumes log domains in the original positive data + # space, while Matplotlib applies margins after transforming to + # log space. Do that transform locally rather than feeding a + # linearly padded (and possibly negative) domain to the core. + values = self._entry_values(axis) + positive = values[values > 0.0] + if positive.size == 0: + return (1.0, 10.0) + lo, hi = float(positive.min()), float(positive.max()) + transformed_lo, transformed_hi = np.log10((lo, hi)) + else: + lo, hi = self._entry_extent(axis) + transformed_lo, transformed_hi = lo, hi + margin = self._effective_margin(axis) if margin == 0.0: return lo, hi - span = hi - lo - pad = span * margin if span > 0 else abs(lo) * margin or margin - return lo - pad, hi + pad + span = transformed_hi - transformed_lo + pad = span * margin if span > 0 else abs(transformed_lo) * margin or margin + lower, upper = transformed_lo - pad, transformed_hi + pad + if spec["name"] == "log": + lower, upper = 10.0**lower, 10.0**upper + sticky = self._entry_sticky_edges(axis) + tolerance = np.finfo(np.float64).eps * max(1.0, abs(lo), abs(hi)) * 8 + if sticky.size: + if np.any(np.isclose(sticky, lo, rtol=0.0, atol=tolerance)): + lower = lo + if np.any(np.isclose(sticky, hi, rtol=0.0, atol=tolerance)): + upper = hi + return lower, upper def axis( self, arg: str | bool | tuple[float, float, float, float] | None = None, **kwargs: Any @@ -2743,9 +3582,16 @@ def axis( self._aspect_equal = False self._aspect_adjustable = "box" self._aspect_bounds = None - self._set_tight_domains() + # Calling an aspect/autoscale mode on an empty Axes must not turn + # the placeholder (0, 1) view into explicit limits. Matplotlib + # continues autoscaling when artists are added afterwards. + if self._entries: + self._set_tight_domains() if arg in {"equal", "scaled", "image", "square"}: - self._set_aspect_equal_from_current() + if self._entries: + self._set_aspect_equal_from_current() + else: + self._aspect_equal = True if arg == "equal": # Matplotlib spells axis("equal") as # set_aspect("equal", adjustable="datalim"): retain the axes @@ -2794,18 +3640,22 @@ def axis( y0, y1 = self.get_ylim() return float(x0), float(x1), float(y0), float(y1) - def set_aspect(self, aspect: str | float, **kwargs: Any) -> None: + def set_aspect( + self, + aspect: str | float, + adjustable: Optional[str] = None, + anchor: Any = None, + share: bool = False, + **kwargs: Any, + ) -> None: """Set the data aspect ratio: ``"equal"``/``1`` or ``"auto"``. ``adjustable`` is ``"box"`` (resize the axes rectangle) or - ``"datalim"`` (expand a data limit at draw time); ``anchor`` and - ``share`` are accepted compat-noops. Anything else raises loudly. + ``"datalim"`` (expand a data limit at draw time); ``anchor`` controls + where a box adjustment lands and ``share`` is accepted as a compat + hint. Anything else raises loudly. """ - adjustable = kwargs.pop("adjustable", None) - # anchor/share are accepted compatibility hints; the shim has no - # independent Artist layout graph on which to apply them. - kwargs.pop("anchor", None) # compat-noop: axes anchoring has no separate layout graph - kwargs.pop("share", None) # compat-noop: aspect sharing is resolved by shared axis state + del share # compat-noop: aspect sharing is resolved by shared axis state if kwargs: raise TypeError( f"set_aspect() got an unexpected keyword argument {next(iter(kwargs))!r}" @@ -2814,6 +3664,8 @@ def set_aspect(self, aspect: str | float, **kwargs: Any) -> None: if adjustable not in {"box", "datalim"}: raise ValueError("adjustable must be 'box' or 'datalim'") self._aspect_adjustable = adjustable + if anchor is not None: + self.set_anchor(anchor) self._aspect_equal = aspect in ("equal", 1, 1.0) if self._aspect_equal: self._set_aspect_equal_from_current() @@ -2821,12 +3673,56 @@ def set_aspect(self, aspect: str | float, **kwargs: Any) -> None: self._aspect_bounds = None self._invalidate() + def get_gridspec(self) -> Any: + """Return the GridSpec that placed this subplot, or ``None``. + + Uniform grids are stored compactly by the shim. Materialize their + shared GridSpec lazily so gallery idioms can remove cells and replace + them with a spanning subplot through ``fig.add_subplot(gs[...])``. + """ + if self._subplot_spec is not None: + return self._subplot_spec.gridspec + figure = self.figure + if figure is None or self not in figure._axes: + return None + nrows, ncols = figure._nrows, figure._ncols + cell_count = nrows * ncols + if cell_count <= 0 or len(figure._axes) < cell_count: + return None + from ._mplfig import _GridSpec, _SubplotSpec + + grid = _GridSpec( + figure, + nrows, + ncols, + width_ratios=figure._width_ratios, + height_ratios=figure._height_ratios, + ) + for index, axes in enumerate(figure._axes[:cell_count]): + row, col = divmod(index, ncols) + spec = _SubplotSpec( + grid, + (row, row + 1), + (col, col + 1), + ) + axes._subplot_spec = spec + # Once callers can remove arbitrary cells, list position no longer + # identifies a subplot's row and column. Freeze every existing + # cell to its GridSpec rect before the first removal. + axes._figure_rect = grid.cell_rect(spec.rows, spec.cols) + return grid + + def get_subplotspec(self) -> Any: + """Return this axes' SubplotSpec, materializing a uniform one if needed.""" + self.get_gridspec() + return self._subplot_spec + def margins(self, *args: Any, **kwargs: Any) -> None: """Set the autoscaling padding around the data, as axis fractions. Call as ``margins(m)``, ``margins(x, y)``, or with ``x=``/``y=``; - values must be finite and non-negative. ``tight`` is accepted and - ignored; explicitly set limits are left alone. + values must be finite and greater than -0.5 (negative margins clip). + ``tight`` is accepted and ignored; explicitly set limits are left alone. """ tight = kwargs.pop("tight", None) del tight @@ -2854,6 +3750,33 @@ def margins(self, *args: Any, **kwargs: Any) -> None: self._axis_props("y").pop("domain", None) self._invalidate() + def _effective_margin(self, axis: str) -> float: + configured = self._xmargin if axis == "x" else self._ymargin + if axis in self._margin_overrides: + return configured + return max(configured, self._annotation_margins[axis]) + + def _reserve_annotation_margin(self, axis: str, margin: float) -> None: + """Reserve autoscale space for an annotation outside a data mark.""" + target = self._y2_of if axis == "x" and self._y2_of is not None else self + target._annotation_margins[axis] = max(target._annotation_margins[axis], float(margin)) + + def get_xmargin(self) -> float: + """Return the configured x-axis autoscale margin.""" + return self._xmargin if "x" in self._margin_overrides else self._rc_margins["x"] + + def get_ymargin(self) -> float: + """Return the configured y-axis autoscale margin.""" + return self._ymargin if "y" in self._margin_overrides else self._rc_margins["y"] + + def set_xmargin(self, margin: float) -> None: + """Set x-axis autoscale padding as a fraction of the data interval.""" + self.margins(x=margin) + + def set_ymargin(self, margin: float) -> None: + """Set y-axis autoscale padding as a fraction of the data interval.""" + self.margins(y=margin) + def relim(self, visible_only: bool = False) -> None: """Recompute the data limits from the plotted entries. @@ -3065,7 +3988,8 @@ def set_axisbelow(self, b: bool) -> None: def get_legend(self) -> Any: """A truthy legend handle when a legend is shown, else None.""" - return self if (self._y2_of or self)._legend else None + host = self._y2_of or self + return (host._legend_handle or self) if host._legend else None def get_legend_handles_labels(self) -> tuple[list[Artist], list[str]]: """Handles and labels of the entries that would appear in the legend. @@ -3076,6 +4000,23 @@ def get_legend_handles_labels(self) -> tuple[list[Artist], list[str]]: handles: list[Artist] = [] labels: list[str] = [] for entry in (self._y2_of or self)._entries: + patch_labels = entry.get("patch_labels") + if patch_labels is not None: + container = next( + ( + item + for item in (self._y2_of or self)._containers + if isinstance(item, BarContainer) and item._entry is entry + ), + None, + ) + for index, label in enumerate(patch_labels): + if label and not str(label).startswith("_"): + handles.append( + container[index] if container is not None else Artist(self, entry) + ) + labels.append(str(label)) + continue label = entry.get("kwargs", {}).get("name") if label and not str(label).startswith("_"): handles.append(Artist(self, entry)) @@ -3157,15 +4098,7 @@ def _set_tight_domains(self) -> None: # axes.xmargin/axes.ymargin (5% by default). "Tight" suppresses tick # locator expansion; it does not mean raw data extrema. for axis in ("x", "y"): - margin = ( - (self._xmargin if axis == "x" else self._ymargin) - if axis in self._margin_overrides - else float(rcParams[f"axes.{axis}margin"]) - ) - lo, hi = self._entry_extent(axis) - span = hi - lo - pad = span * margin if span > 0 else abs(lo) * margin or margin - self._axis_props(axis)["domain"] = (lo - pad, hi + pad) + self._axis_props(axis)["domain"] = self._auto_domain(axis) self._explicit_domains.update({"x", "y"}) self._invalidate() @@ -3177,14 +4110,7 @@ def _materialize_axis_view_domains(self) -> None: for axis in ("x", "y"): if "domain" in self._axis_props(axis): continue - margin = ( - (self._xmargin if axis == "x" else self._ymargin) - if axis in self._margin_overrides - else float(rcParams[f"axes.{axis}margin"]) - ) - lo, hi = self._entry_extent(axis) - pad = (hi - lo) * margin - self._axis_props(axis)["domain"] = (lo - pad, hi + pad) + self._axis_props(axis)["domain"] = self._auto_domain(axis) changed = True if changed: self._invalidate() @@ -3362,6 +4288,8 @@ def add_artist(self, artist: Any) -> Any: host = self._y2_of or self artist._attach(host) host._extra_legends.append(artist) + if artist is host._legend_artist: + host._legend_artist = None host._invalidate() return artist if hasattr(artist, "get_array"): @@ -3736,26 +4664,106 @@ def invert_xaxis(self) -> None: props["reverse"] = not props.get("reverse", False) self._invalidate() + def _set_tick_rotation_mode(self, axis: str, mode: str | None) -> None: + if mode is None or mode == "default": + normalized = None + elif mode in {"anchor", "xtick", "ytick"}: + normalized = mode + else: + raise ValueError( + f"{mode!r} is not a valid value for rotation_mode; " + "supported values are 'anchor', 'default', 'xtick', and 'ytick'" + ) + self._tick_rotation_modes[axis] = normalized + angle = float(self._axis_props(axis).get("tick_label_angle", 0.0)) + self._apply_tick_rotation_mode(axis, angle) + + def _apply_tick_rotation_mode(self, axis: str, angle: float) -> None: + """Translate Matplotlib's special tick rotation pivot when expressible.""" + props = self._axis_props(axis) + mode = self._tick_rotation_modes.get(axis) + if mode == "anchor": + props["tick_label_anchor"] = "center" + return + if mode != "xtick" or axis != "x": + props.pop("tick_label_anchor", None) + return + # Matplotlib Text._ha_for_angle: bottom labels have verticalalignment + # "top", while top labels use "bottom". Convert its left/right result + # to XY's start/end anchor vocabulary. + value = float(angle) % 360.0 + anchor_at_bottom = props.get("side", "bottom") == "top" + if ( + value <= 10 + or 85 <= value <= 95 + or value >= 350 + or 170 <= value <= 190 + or 265 <= value <= 275 + ): + anchor = "center" + elif 10 < value < 85 or 190 < value < 265: + anchor = "start" if anchor_at_bottom else "end" + else: + anchor = "end" if anchor_at_bottom else "start" + props["tick_label_anchor"] = anchor + + def _apply_tick_side_visibility( + self, axis: str, side_updates: dict[str, bool], length: float | None + ) -> None: + sides = self._tick_sides[axis] + sides.update({key: value for key, value in side_updates.items() if key in sides}) + props = self._axis_props(axis) + style = props.setdefault("style", {}) + if length is not None: + self._tick_lengths[axis] = float(length) * self._point_scale() + if any(sides.values()): + style["tick_length"] = self._tick_lengths[axis] + visible_sides = [side for side, shown in sides.items() if shown] + if len(visible_sides) == 1: + props["side"] = visible_sides[0] + else: + # The native axis has one tick side, so zero length is its exact + # representation of Matplotlib's tick1On=False/tick2On=False. + style["tick_length"] = 0.0 + + def _apply_tick_label_side_visibility(self, axis: str, side_updates: dict[str, bool]) -> None: + sides = self._tick_label_sides[axis] + sides.update({key: value for key, value in side_updates.items() if key in sides}) + self._axis_props(axis)["tick_label_strategy"] = None if any(sides.values()) else "off" + def tick_params(self, axis: str = "both", **kwargs: Any) -> None: """Change tick, tick-label, and axis-color appearance. ``axis`` selects ``"x"``/``"y"``/``"both"``. Supported keywords: ``labelrotation``/``rotation``, ``colors``, ``color``, - ``labelcolor``, ``length``, ``width``, ``direction`` + ``labelcolor``, ``length``, ``width``, ``pad``, ``direction`` (``"in"``/``"out"``/``"inout"``), and the ``labelbottom``/ - ``labeltop``/``labelleft``/``labelright`` visibility flags; anything - else raises loudly. + ``labeltop``/``labelleft``/``labelright`` and ``bottom``/``top``/ + ``left``/``right`` visibility flags. ``rotation_mode`` and + ``labelrotation_mode`` support Matplotlib 3.11's special tick-label + anchors; anything else raises loudly. """ if axis not in {"both", "x", "y"}: raise ValueError("tick_params() axis must be 'both', 'x', or 'y'") rotation = kwargs.pop("labelrotation", kwargs.pop("rotation", None)) + rotation_mode = kwargs.pop("labelrotation_mode", kwargs.pop("rotation_mode", None)) colors = kwargs.pop("colors", None) color = kwargs.pop("color", colors) labelcolor = kwargs.pop("labelcolor", colors) length = kwargs.pop("length", None) + pad = kwargs.pop("pad", None) width = kwargs.pop("width", None) direction = kwargs.pop("direction", None) - label_visible = _tick_label_visibility(kwargs) + side_updates = { + key: bool(kwargs.pop(key)) + for key in ("bottom", "top", "left", "right") + if key in kwargs + } + label_side_updates = { + key: bool(kwargs.pop(key)) + for key in ("labelbottom", "labeltop", "labelleft", "labelright") + if key in kwargs + } if kwargs: raise TypeError( f"tick_params() got unsupported keyword argument {next(iter(kwargs))!r}" @@ -3764,21 +4772,27 @@ def tick_params(self, axis: str = "both", **kwargs: Any) -> None: props = self._axis_props(ax) if rotation is not None: props["tick_label_angle"] = float(rotation) + if rotation_mode is not None: + self._set_tick_rotation_mode(ax, rotation_mode) + elif rotation is not None: + self._apply_tick_rotation_mode(ax, float(rotation)) style = props.setdefault("style", {}) if color is not None: style["tick_color"] = resolve_color(color) if labelcolor is not None: style["tick_label_color"] = resolve_color(labelcolor) - if length is not None: - style["tick_length"] = float(length) * self._point_scale() + if length is not None or side_updates: + self._apply_tick_side_visibility(ax, side_updates, length) + if pad is not None: + style["tick_padding"] = float(pad) * self._point_scale() if width is not None: style["tick_width"] = float(width) * self._point_scale() if direction is not None: if direction not in {"in", "out", "inout"}: raise ValueError("tick_params() direction must be 'in', 'out', or 'inout'") style["tick_direction"] = direction - if label_visible is not None: - props["tick_label_strategy"] = None if label_visible else "off" + if label_side_updates: + self._apply_tick_label_side_visibility(ax, label_side_updates) self._invalidate() def set_xticks( @@ -3861,6 +4875,104 @@ def set_yticks( props["tick_label_angle"] = float(rotation) self._invalidate() + def _set_ticklabels( + self, + axis: str, + labels: Sequence[str], + *, + minor: bool, + fontdict: dict[str, Any] | None, + kwargs: dict[str, Any], + ) -> list[_TickLabel]: + if minor: + # Minor ticks are outside the native axis contract. + return [] + if fontdict is not None and not isinstance(fontdict, dict): + raise TypeError("fontdict must be a dict or None") + options = {} if fontdict is None else dict(fontdict) + options.update(kwargs) + texts = [_plain_text(value) for value in labels] + props = self._axis_props(axis) + current_ticks = self._computed_ticks(axis, False) + fixed_ticks = props.get("tick_values") + if fixed_ticks is not None and texts and len(texts) != len(fixed_ticks): + raise ValueError( + f"The number of FixedLocator locations ({len(fixed_ticks)}) does not match " + f"the number of labels ({len(texts)})." + ) + if not texts: + # FixedFormatter([]) yields one empty Text per current tick. The + # native equivalent hides labels while preserving tick positions. + props.pop("tick_labels", None) + props["tick_label_strategy"] = "off" + handles = [_TickLabel(self, axis, "") for _ in current_ticks] + else: + rendered = list(texts[: len(current_ticks)]) + rendered.extend("" for _ in range(len(current_ticks) - len(rendered))) + setter = self.set_xticks if axis == "x" else self.set_yticks + setter(current_ticks, rendered) + props["tick_label_strategy"] = None + handles = [_TickLabel(self, axis, text) for text in rendered] + + color = options.pop("color", options.pop("c", None)) + size = options.pop("fontsize", options.pop("size", None)) + rotation = options.pop("rotation", None) + rotation_mode = options.pop("labelrotation_mode", options.pop("rotation_mode", None)) + alignment = options.pop("horizontalalignment", options.pop("ha", None)) + # These Text properties have no independent axis-wide native chrome + # representation, but accepting them preserves Matplotlib's static + # gallery call surface. + _pop_text_style_kwargs(options, f"set_{axis}ticklabels()") + style = props.setdefault("style", {}) + if color is not None: + style["tick_label_color"] = resolve_color(color) + if size is not None: + dpi = float( + self.figure._dpi if self.figure._dpi is not None else rcParams["figure.dpi"] + ) + style["tick_label_size"] = _font_size(size, rcParams["font.size"], dpi) + if rotation is not None: + props["tick_label_angle"] = float(rotation) + if rotation_mode is not None: + self._set_tick_rotation_mode(axis, rotation_mode) + elif rotation is not None: + self._apply_tick_rotation_mode(axis, float(rotation)) + if alignment is not None: + anchors = { + "left": "start", + "center": "center", + "right": "end", + "start": "start", + "end": "end", + } + if alignment not in anchors: + raise ValueError("horizontalalignment must be 'left', 'center', or 'right'") + props["tick_label_anchor"] = anchors[alignment] + self._invalidate() + return handles + + def set_xticklabels( + self, + labels: Sequence[str], + *, + minor: bool = False, + fontdict: dict[str, Any] | None = None, + **kwargs: Any, + ) -> list[_TickLabel]: + """Set x tick labels without changing the current tick locations.""" + return self._set_ticklabels("x", labels, minor=minor, fontdict=fontdict, kwargs=kwargs) + + def set_yticklabels( + self, + labels: Sequence[str], + *, + minor: bool = False, + fontdict: dict[str, Any] | None = None, + **kwargs: Any, + ) -> list[_TickLabel]: + """Set y tick labels without changing the current tick locations.""" + return self._set_ticklabels("y", labels, minor=minor, fontdict=fontdict, kwargs=kwargs) + def get_xticks(self, *, minor: bool = False) -> np.ndarray: """The x tick positions in data space. @@ -3980,7 +5092,7 @@ def twiny(self) -> "Axes": self.figure._invalidate() return twin - def legend(self, *args: Any, **kwargs: Any) -> None: + def legend(self, *args: Any, **kwargs: Any) -> Any: """Show the legend for this axes. Call forms: ``legend()`` (labeled artists), ``legend(labels)`` @@ -3992,13 +5104,28 @@ def legend(self, *args: Any, **kwargs: Any) -> None: raise loudly. ``loc="best"`` picks the least occupied corner. """ host = self._y2_of or self + returned: Any = self if len(args) >= 2: - # legend(handles, labels): relabel the artists the caller passed. - handles, labels = args[0], args[1] - for handle, label in zip(handles, labels, strict=False): - entry = getattr(handle, "_entry", None) - if entry is not None: - entry.setdefault("kwargs", {})["name"] = _plain_text(label) + handles = list(args[0]) + labels = [_plain_text(label) for label in args[1]] + legend_artist = Legend(host, handles, labels, **kwargs) + returned = legend_artist + host._legend_handle = legend_artist + # An explicit handles/labels call defines the primary legend even + # when the handles are proxy artists rather than plotted entries. + # Freeze those items without renaming the underlying traces: + # subsequent legend calls and secondary ``add_artist`` legends + # must remain independent. + host._legend_options = dict(legend_artist._options) + if host._extra_legends: + # Once a prior legend has been retained with add_artist(), + # keep the replacement primary legend in the same explicit + # artist layer so both boxes preserve their independent items. + host._legend_artist = legend_artist + host._legend_items = None + else: + host._legend_artist = None + host._legend_items = list(legend_artist.spec()["items"]) elif len(args) == 1: # legend(labels): assign labels positionally to the plotted artists, # skipping marker overlays that share their line's legend slot. @@ -4006,9 +5133,18 @@ def legend(self, *args: Any, **kwargs: Any) -> None: eligible = [entry for entry in host._entries if not entry.get("_legend_skip")] for entry, label in zip(eligible, labels, strict=False): entry.setdefault("kwargs", {})["name"] = _plain_text(label) + host._legend_artist = None + host._legend_options = self._compose_legend_options(kwargs) + host._legend_items = None + host._legend_handle = None + else: + host._legend_artist = None + host._legend_options = self._compose_legend_options(kwargs) + host._legend_items = None + host._legend_handle = None host._legend = True - host._legend_options = self._compose_legend_options(kwargs) host._invalidate() + return returned def _compose_legend_options(self, kwargs: dict[str, Any]) -> dict[str, Any]: """Translate legend() keyword styling into the engine's option dict. @@ -4017,6 +5153,16 @@ def _compose_legend_options(self, kwargs: dict[str, Any]) -> dict[str, Any]: second, manually added legend honors the same loc/frame/font keywords. """ loc = kwargs.pop("loc", rcParams["legend.loc"]) + if not isinstance(loc, str) or loc not in {"best", *_LEGEND_LOC_ANCHORS}: + raise ValueError(f"legend loc must be one of {['best', *sorted(_LEGEND_LOC_ANCHORS)]}") + bbox_to_anchor = kwargs.pop("bbox_to_anchor", None) + if bbox_to_anchor is not None: + bounds = getattr(bbox_to_anchor, "bounds", bbox_to_anchor) + if isinstance(bounds, (str, bytes)) or len(bounds) not in (2, 4): + raise ValueError("legend bbox_to_anchor must contain 2 or 4 finite numbers") + bbox_to_anchor = tuple(float(value) for value in bounds) + if not all(np.isfinite(value) for value in bbox_to_anchor): + raise ValueError("legend bbox_to_anchor must contain 2 or 4 finite numbers") ncols = kwargs.pop("ncols", kwargs.pop("ncol", 1)) title = kwargs.pop("title", None) fontsize = kwargs.pop("fontsize", None) @@ -4038,11 +5184,13 @@ def _compose_legend_options(self, kwargs: dict[str, Any]) -> dict[str, Any]: frameon = kwargs.pop("frameon", rcParams["legend.frameon"]) facecolor = kwargs.pop("facecolor", rcParams["legend.facecolor"]) edgecolor = kwargs.pop("edgecolor", rcParams["legend.edgecolor"]) - framealpha = kwargs.pop("framealpha", None) + framealpha = kwargs.pop("framealpha", rcParams["legend.framealpha"]) fancybox = kwargs.pop("fancybox", False) shadow = kwargs.pop("shadow", False) - borderpad = kwargs.pop("borderpad", None) - labelspacing = kwargs.pop("labelspacing", None) + borderpad = kwargs.pop("borderpad", rcParams["legend.borderpad"]) + labelspacing = kwargs.pop("labelspacing", rcParams["legend.labelspacing"]) + borderaxespad = kwargs.pop("borderaxespad", rcParams["legend.borderaxespad"]) + handleheight = kwargs.pop("handleheight", None) # Remaining handle/title geometry is not expressible yet and stays # loud; the frame and row-layout options above map directly to CSS and # the static exporters. @@ -4068,11 +5216,10 @@ def _compose_legend_options(self, kwargs: dict[str, Any]) -> dict[str, Any]: unsupported = set(kwargs) if unsupported: raise TypeError(f"legend() got unsupported keyword argument {sorted(unsupported)[0]!r}") + font_px = _font_size(fontsize, rcParams["font.size"], self._point_scale() * 72.0) style: dict[str, Any] = {} if fontsize is not None: - style["fontSize"] = ( - f"{_font_size(fontsize, rcParams['font.size'], self._point_scale() * 72.0):g}px" - ) + style["fontSize"] = f"{font_px:g}px" if labelcolor is not None: style["color"] = resolve_color(labelcolor) if frameon is False: @@ -4086,6 +5233,7 @@ def _compose_legend_options(self, kwargs: dict[str, Any]) -> dict[str, Any]: if edgecolor is not None: style["borderColor"] = resolve_color(edgecolor) style["borderStyle"] = "solid" + style["borderWidth"] = "1px" if framealpha is not None: alpha_value = float(framealpha) if not 0.0 <= alpha_value <= 1.0: @@ -4095,17 +5243,32 @@ def _compose_legend_options(self, kwargs: dict[str, Any]) -> dict[str, Any]: style["borderRadius"] = "4px" if bool(shadow): style["boxShadow"] = "2px 2px 4px rgba(0,0,0,0.3)" - if borderpad is not None: - padding = float(borderpad) - if padding < 0: - raise ValueError("legend borderpad must be non-negative") - style["padding"] = f"{padding:g}em" - if labelspacing is not None: - spacing = float(labelspacing) - if spacing < 0: - raise ValueError("legend labelspacing must be non-negative") - style["rowGap"] = f"{spacing:g}em" - options: dict[str, Any] = {"loc": loc, "ncols": max(1, int(ncols))} + padding = float(borderpad) + if padding < 0: + raise ValueError("legend borderpad must be non-negative") + style["padding"] = f"{padding:g}em" + spacing = float(labelspacing) + if spacing < 0: + raise ValueError("legend labelspacing must be non-negative") + style["rowGap"] = f"{spacing:g}em" + axes_padding = float(borderaxespad) + if axes_padding < 0: + raise ValueError("legend borderaxespad must be non-negative") + options: dict[str, Any] = { + "loc": loc, + "ncols": max(1, int(ncols)), + # Matplotlib measures borderaxespad in legend-font em. The wire + # carries pixels so all three renderers place anchored legends at + # the same physical distance from the axes. + "border_pad": axes_padding * font_px, + } + if bbox_to_anchor is not None: + options["anchor"] = bbox_to_anchor + if handleheight is not None: + handleheight_value = float(handleheight) + if not np.isfinite(handleheight_value) or handleheight_value <= 0: + raise ValueError("legend handleheight must be a positive finite number") + options["handleheight"] = handleheight_value if title is not None: options["title"] = _plain_text(title) if style: @@ -4115,14 +5278,14 @@ def _compose_legend_options(self, kwargs: dict[str, Any]) -> dict[str, Any]: def grid(self, visible: bool | None = True, **kwargs: Any) -> None: """Toggle and style the grid. - ``visible=None`` toggles the current state; ``which`` must be - ``"major"``/``"both"`` (minor grids are unsupported) and ``axis`` - restricts to ``"x"`` or ``"y"``. ``color``/``c``, + ``visible=None`` toggles the current state; ``which`` accepts + ``"major"``/``"both"`` and ``axis`` restricts to ``"x"`` or ``"y"``. + ``color``/``c``, ``linestyle``/``ls``, ``linewidth``/``lw``, and ``alpha`` style the lines; anything else raises loudly. """ host = self._y2_of or self - which = kwargs.pop("which", "major") + which = str(kwargs.pop("which", "major")).lower() axis = kwargs.pop("axis", "both") if which not in {"major", "both"}: raise ValueError("grid() only supports major grid lines") @@ -4134,8 +5297,15 @@ def grid(self, visible: bool | None = True, **kwargs: Any) -> None: alpha = kwargs.pop("alpha", None) if kwargs: raise TypeError(f"grid() got unsupported keyword argument {next(iter(kwargs))!r}") - host._grid = bool(visible) if visible is not None else not host._grid - host._grid_axis = axis + has_style = any(value is not None for value in (color, linestyle, linewidth, alpha)) + if has_style and visible is None: + visible = True + selected = ("x", "y") if axis == "both" else (axis,) + for item in selected: + host._grid_axes[item] = not host._grid_axes[item] if visible is None else bool(visible) + host._grid = any(host._grid_axes.values()) + visible_axes = [item for item, enabled in host._grid_axes.items() if enabled] + host._grid_axis = "both" if len(visible_axes) != 1 else visible_axes[0] style = host._grid_style = {} if color is not None and (resolved_grid := resolve_color(color)) is not None: host._grid_color = resolved_grid @@ -4147,17 +5317,18 @@ def grid(self, visible: bool | None = True, **kwargs: Any) -> None: style["grid_dash"] = dash if alpha is not None: style["grid_opacity"] = float(alpha) - grid_color = host._grid_color if host._grid else "transparent" for item in ("x", "y"): props = host._axis_props(item) axis_style = props.setdefault("style", {}) - for stale in ("grid_width", "grid_dash", "grid_opacity"): - axis_style.pop(stale, None) - if axis in {"both", item}: - axis_style["grid_color"] = grid_color + if item in selected: + for stale in ("grid_width", "grid_dash", "grid_opacity"): + axis_style.pop(stale, None) + axis_style["grid_color"] = ( + host._grid_color if host._grid_axes[item] else "transparent" + ) axis_style.update(style) else: - axis_style["grid_color"] = "transparent" + axis_style.setdefault("grid_color", "transparent") host._invalidate() def _axis_props(self, axis: str) -> dict[str, Any]: @@ -4250,6 +5421,28 @@ def _apply_tickers( # -- materialization ----------------------------------------------------------- + def _axline_data(self, entry: dict[str, Any]) -> tuple[np.ndarray, np.ndarray]: + """Resolve deferred axline point transforms and clip to the final view.""" + xlim, ylim = self.get_xlim(), self.get_ylim() + xy1 = entry["xy1"] + xy2 = entry.get("xy2") + if entry.get("transform_space") == "axes_fraction": + xy1 = ( + xlim[0] + float(xy1[0]) * (xlim[1] - xlim[0]), + ylim[0] + float(xy1[1]) * (ylim[1] - ylim[0]), + ) + if xy2 is not None: + xy2 = ( + xlim[0] + float(xy2[0]) * (xlim[1] - xlim[0]), + ylim[0] + float(xy2[1]) * (ylim[1] - ylim[0]), + ) + if xy2 is not None: + direction = (float(xy2[0]) - float(xy1[0]), float(xy2[1]) - float(xy1[1])) + else: + slope = float(entry["slope"]) + direction = (0.0, 1.0) if np.isinf(slope) else (1.0, slope) + return _clip_infinite_line(xy1, direction, xlim, ylim) + def _chart_children(self) -> list[Any]: children: list[Any] = [] for e in self._entries: @@ -4264,7 +5457,38 @@ def _chart_children(self) -> list[Any]: kw["width"] = ( float(kw.get("width", rcParams["lines.linewidth"])) * self._point_scale() ) + gapcolor = kw.pop("_gapcolor", None) + if gapcolor is not None and kw.get("dash"): + children.append( + xy.line( + x=e["x"], + y=e["y"], + color=gapcolor, + width=kw["width"], + opacity=kw.get("opacity", 1.0), + **axis_kw, + ) + ) children.append(xy.line(x=e["x"], y=e["y"], **kw, **axis_kw)) + elif kind == "@axline": + kw = dict(kw) + kw["width"] = ( + float(kw.get("width", rcParams["lines.linewidth"])) * self._point_scale() + ) + gapcolor = kw.pop("_gapcolor", None) + x, y = self._axline_data(e) + if gapcolor is not None and kw.get("dash"): + children.append( + xy.line( + x=x, + y=y, + color=gapcolor, + width=kw["width"], + opacity=kw.get("opacity", 1.0), + **axis_kw, + ) + ) + children.append(xy.line(x=x, y=y, **kw, **axis_kw)) elif kind == "scatter": kw = dict(kw) if "_artist_alpha" in kw: @@ -4290,6 +5514,31 @@ def _chart_children(self) -> list[Any]: children.append(xy.scatter(x=e["x"], y=e["y"], **kw, **axis_kw)) elif kind == "bar": children.append(xy.bar(x=e["x"], y=e["y"], **kw, **axis_kw)) + patch_labels = e.get("patch_labels") + if patch_labels is not None: + colors = resolve_rgba_array( + kw.get("color", "transparent"), + len(patch_labels), + "bar legend color", + ) + orientation = kw.get("orientation", "vertical") + for index, label in enumerate(patch_labels): + if not label or str(label).startswith("_"): + continue + # Named zero-mark proxies give the core legend one + # correctly colored swatch per labeled patch while the + # actual bars remain a single vectorized trace. + children.append( + xy.bar( + x=np.empty(0, dtype=np.float64), + y=np.empty(0, dtype=np.float64), + name=str(label), + color=resolve_color(colors[index]), + opacity=1.0, + orientation=orientation, + **axis_kw, + ) + ) elif kind == "area": children.append(xy.area(x=e["x"], y=e["y"], **kw, **axis_kw)) elif kind == "histogram": @@ -4358,6 +5607,7 @@ def _chart_children(self) -> list[Any]: **_bbox_label_style( kw["bbox"], font_size=float((text_kw.get("style") or {}).get("font_size", 11.0)), + point_scale=self._point_scale(), ), **(text_kw.get("style") or {}), } @@ -4420,22 +5670,157 @@ def _chart_children(self) -> list[Any]: ) ) else: + # matplotlib paints Text with rcParams["text.color"] + # (black by default). The engine's own annotation-label + # fallback is a design token that differs per renderer + # (SVG #667085, native rgba(32,32,32,.85), browser + # --chart-annotation-text), so an uncoloured pyplot label + # renders grey in the exporters. Pin matplotlib's default + # here — the same thing the callout branch above already + # does — so all three renderers agree without moving the + # engine's non-pyplot defaults. + text_kw["style"] = { + "label_color": text_kw.get("color") + or resolve_color(rcParams.get("text.color", "black")) + or "black", + **(text_kw.get("style") or {}), + } children.append(xy.text(x, y, *e["args"][2:], **text_kw)) return children + def _plot_rect_px( + self, + width: int, + height: int, + padding: Optional[Sequence[float]] = None, + x_side: Optional[str] = None, + ) -> tuple[float, float]: + """Estimated ``(w, h)`` of the plot box in pixels. + + Both the tick-space heuristic and ``best`` legend placement have to know + how large the plot box will be, and both run before the chart exists, so + they share this one padding model instead of estimating it twice. + """ + compact = width < 520 + if padding is None: + top, right, bottom, left = ( + (6.0, 8.0, 36.0, 46.0) if compact else (10.0, 14.0, 42.0, 62.0) + ) + else: + top, right, bottom, left = map(float, padding) + if self._title: + top += 26.0 if compact else 30.0 + if x_side == "top": + top += 26.0 if compact else 32.0 + return ( + max(40.0, float(width) - left - right), + max(40.0, float(height) - top - bottom), + ) + + def _displayed_ranges( + self, + figure: Any, + x_props: dict[str, Any], + y_props: dict[str, Any], + ) -> tuple[Optional[tuple[float, float]], Optional[tuple[float, float]]]: + """The x/y view the built figure will actually render. + + ``best`` placement has to score against the *displayed* limits, not the + raw data extent: an autoranged view is padded by the engine, so the + corner a mark reaches on screen is not the corner it reaches in data + space. The built figure already knows both (an explicit domain is + returned verbatim), so ask it rather than re-deriving the padding. + """ + try: + return tuple(figure.x_range()), tuple(figure.y_range()) # type: ignore[return-value] + except (ValueError, TypeError): + # A log axis with no positive value cannot report a range; the + # declared domains are the best available fallback. + return x_props.get("domain"), y_props.get("domain") + + @staticmethod + def _displayed_plot_size(figure: Any) -> tuple[float, float]: + """The plot rectangle the static/browser layout model will display. + + Legend placement runs after the core figure exists, so estimating this + from a second list of default paddings is both unnecessary and wrong + once titles, anchored legends, measured gutters, or an explicit axes + rectangle alter the frame. Ask the same layout function used by the + static exporters instead. The browser consumes the same resolved + ``spec.padding`` contract. + """ + from .._svg import layout + + spec, _ = figure.build_payload() + *_, plot = layout(spec) + return float(plot["w"]), float(plot["h"]) + + def _legend_footprint( + self, + legend_options: Optional[dict[str, Any]], + items: Optional[list[dict[str, Any]]], + plot_size: tuple[float, float], + ) -> tuple[float, float, float, float]: + """Measured legend box and border inset, as fractions of the plot box. + + Returns ``(box_w, box_h, pad_x, pad_y)``. The box comes from + ``_svg._legend_layout`` — the *same* geometry the SVG and raster + exporters lay the legend out with, derived from the legend font size and + the real label extents — so ``best`` scores the box that actually gets + drawn. ``pad_*`` is Matplotlib's ``borderaxespad``, which insets the + container every candidate is anchored inside. + """ + from .._svg import _legend_layout + + options = dict(legend_options or {}) + # Size is independent of placement, and placement is exactly what has + # not been decided yet — drop both keys so the layout's own resolver is + # never handed the unresolved "best" we are here to replace. + options.pop("loc", None) + options.pop("anchor", None) + if items is None: + items = [ + {"name": str((entry.get("kwargs") or {}).get("name"))} + for entry in self._entries + if (entry.get("kwargs") or {}).get("name") + ] + # A legend with no labelled entry still has a frame; measure it as one + # empty row rather than dividing by zero inside the layout. + measured = _legend_layout( + items or [{"name": ""}], + {"x": 0.0, "y": 0.0, "w": plot_size[0], "h": plot_size[1]}, + options, + ) + border_pad = max(0.0, float(options.get("border_pad") or 0.0)) + return ( + measured["box_w"] / plot_size[0], + measured["box_h"] / plot_size[1], + border_pad / plot_size[0], + border_pad / plot_size[1], + ) + def _best_legend_loc( self, x_domain: Optional[tuple[float, float]] = None, y_domain: Optional[tuple[float, float]] = None, + *, + legend_options: Optional[dict[str, Any]] = None, + items: Optional[list[dict[str, Any]]] = None, + plot_size: tuple[float, float] = _DEFAULT_BEST_PLOT_SIZE, ) -> str: - """Choose the least occupied corner using bounded data-space samples. - - Matplotlib tests artist extents against several candidate boxes and - keeps the first candidate (upper right) on ties. The shim has no Artist - layout graph, but its canonical entry arrays are enough to make the - same decision: for each corner, count sampled marks that fall inside a - legend-box-sized region there — not the whole quadrant, so a curve - crossing the middle no longer taints every corner. The domains passed + """Choose the least occupied candidate box, as Matplotlib does. + + Matplotlib's ``Legend._find_best_position`` walks location codes 1..10 + in order, scores each anchored box by how many artist vertices it + contains, stops at the first box scoring zero, and breaks ties by + preferring the lower code. The shim has no Artist layout graph, but its + canonical entry arrays plus the *measured* legend geometry are enough to + make the same decision. + + The footprint being measured rather than estimated is the whole point: + a linear guess from row count and label length ran ~3x too wide and ~2x + too tall, which tainted corners the real legend never reaches and threw + the choice to a different corner than Matplotlib's. The domains passed in are the *displayed* limits (after equal-aspect expansion), which is what decides whether the data actually reaches a corner. """ @@ -4450,44 +5835,130 @@ def _best_legend_loc( return "upper right" if xhi <= xlo or yhi <= ylo: return "upper right" - # Fractional footprint of the legend box, grown by row count and the - # longest label so a crowded legend guards a larger corner region. - labels = [ - str(entry.get("kwargs", {}).get("name", "")) - for entry in self._entries - if entry.get("kwargs", {}).get("name") - ] - rows = max(1, len(labels)) - max_len = max((len(text) for text in labels), default=4) - box_h = min(0.6, 0.10 + 0.07 * rows) - box_w = min(0.6, 0.12 + 0.03 * max_len) - # Every Matplotlib candidate box, in Matplotlib's own preference order - # (corners, then the mid-edges, then dead center) so min() keeps the - # first on ties. Each tuple is (name, x_lo, x_hi, y_lo, y_hi) in the - # normalized [0, 1] plot box with y pointing up. Including the centered - # edges is what lets a full-amplitude oscillation park the legend on the - # sparse zero-crossing band, exactly like Matplotlib. ('right' is code 5 - # in Matplotlib and aliases 'center right'; keeping the single canonical - # name here preserves the tie order without a redundant candidate.) - cx_lo, cx_hi = 0.5 - box_w / 2.0, 0.5 + box_w / 2.0 - cy_lo, cy_hi = 0.5 - box_h / 2.0, 0.5 + box_h / 2.0 - candidates = ( - ("upper right", 1.0 - box_w, 1.0, 1.0 - box_h, 1.0), - ("upper left", 0.0, box_w, 1.0 - box_h, 1.0), - ("lower left", 0.0, box_w, 0.0, box_h), - ("lower right", 1.0 - box_w, 1.0, 0.0, box_h), - ("center right", 1.0 - box_w, 1.0, cy_lo, cy_hi), - ("center left", 0.0, box_w, cy_lo, cy_hi), - ("lower center", cx_lo, cx_hi, 0.0, box_h), - ("upper center", cx_lo, cx_hi, 1.0 - box_h, 1.0), - ("center", cx_lo, cx_hi, cy_lo, cy_hi), - ) + box_w, box_h, pad_x, pad_y = self._legend_footprint(legend_options, items, plot_size) + # Matplotlib anchors every candidate inside the plot box inset by + # borderaxespad on all four sides (offsetbox._get_anchored_bbox), so the + # travel available to the box is the inset span minus the box itself. + span_x = max(0.0, 1.0 - 2.0 * pad_x - box_w) + span_y = max(0.0, 1.0 - 2.0 * pad_y - box_h) + candidates = [] + for name in _BEST_LOC_ORDER: + hx, vy = _LEGEND_LOC_ANCHORS[name] + x_lo = pad_x + hx * span_x + y_lo = pad_y + vy * span_y + candidates.append((name, x_lo, x_lo + box_w, y_lo, y_lo + box_h)) scores = {name: 0.0 for name, *_ in candidates} entries_used = 0 x_reverse = bool(self._axis["x"].get("reverse")) y_reverse = bool(self._axis["y"].get("reverse")) + + category_maps: dict[str, dict[str, float]] = {} + + def axis_values(values: Any, axis: str) -> np.ndarray: + """Entry coordinates in the engine's numeric data space.""" + try: + return np.asarray(unit_converted_values(values), dtype=np.float64).reshape(-1) + except (TypeError, ValueError): + array = np.asanyarray(values).reshape(-1) + if not all(isinstance(value, str) for value in array): + raise + mapping = category_maps.setdefault(axis, {}) + for entry in self._entries: + key = "x" if axis == "x" else "y" + source = entry.get(key) + if source is None: + continue + for value in np.asanyarray(source).reshape(-1): + if isinstance(value, str) and value not in mapping: + mapping[value] = float(len(mapping)) + return np.asarray([mapping[value] for value in array], dtype=np.float64) + + def normalize(values: Any, axis: str) -> np.ndarray: + array = axis_values(values, axis) + lo, hi = (xlo, xhi) if axis == "x" else (ylo, yhi) + result = (array - lo) / (hi - lo) + if x_reverse if axis == "x" else y_reverse: + result = 1.0 - result + return result + for entry in self._entries: + kind = entry.get("kind") + kwargs = entry.get("kwargs") or {} + + # Matplotlib treats each bar as a Rectangle and counts overlapping + # rectangle bboxes, not the four corner vertices. Preserve the + # same distinction: a legend covering the middle of a wide bar + # must be disqualified even when no rectangle corner lies inside. + if kind == "bar": + try: + categories = axis_values( + entry["x"], "x" if kwargs.get("orientation") != "horizontal" else "y" + ) + values = axis_values( + entry["y"], "y" if kwargs.get("orientation") != "horizontal" else "x" + ) + categories, values = np.broadcast_arrays(categories, values) + base = np.broadcast_to( + np.asarray(kwargs.get("base", 0.0), dtype=np.float64), + values.shape, + ) + thickness = np.broadcast_to( + np.asarray(kwargs.get("width", 0.8), dtype=np.float64), + values.shape, + ) + except (KeyError, TypeError, ValueError): + continue + if kwargs.get("orientation") == "horizontal": + bx0 = normalize(base, "x") + bx1 = normalize(base + values, "x") + by0 = normalize(categories - thickness / 2.0, "y") + by1 = normalize(categories + thickness / 2.0, "y") + else: + bx0 = normalize(categories - thickness / 2.0, "x") + bx1 = normalize(categories + thickness / 2.0, "x") + by0 = normalize(base, "y") + by1 = normalize(base + values, "y") + rect_x0, rect_x1 = np.minimum(bx0, bx1), np.maximum(bx0, bx1) + rect_y0, rect_y1 = np.minimum(by0, by1), np.maximum(by0, by1) + finite = ( + np.isfinite(rect_x0) + & np.isfinite(rect_x1) + & np.isfinite(rect_y0) + & np.isfinite(rect_y1) + ) + if not finite.any(): + continue + entries_used += 1 + for name, xl, xh, yl, yh in candidates: + overlaps = ( + (rect_x0[finite] < xh) + & (rect_x1[finite] > xl) + & (rect_y0[finite] < yh) + & (rect_y1[finite] > yl) + ) + scores[name] += float(np.count_nonzero(overlaps)) + continue + x_values, y_values = entry.get("x"), entry.get("y") + if kind == "@arrow": + args = entry.get("args") or () + if len(args) >= 4: + x_values, y_values = (args[0], args[2]), (args[1], args[3]) + elif kind == "area" and x_values is not None and y_values is not None: + # PolyCollection contributes the complete closed polygon path: + # top edge followed by the reversed baseline. + try: + top_x = axis_values(x_values, "x") + top_y = axis_values(y_values, "y") + top_x, top_y = np.broadcast_arrays(top_x, top_y) + base = np.broadcast_to( + np.asarray(kwargs.get("base", 0.0), dtype=np.float64), + top_y.shape, + ) + x_values = np.concatenate((top_x, top_x[::-1], top_x[:1])) + y_values = np.concatenate((top_y, base[::-1], top_y[:1])) + except (TypeError, ValueError): + continue if x_values is None or y_values is None: args: Any = entry.get("args") if args is not None and len(args) >= 2: @@ -4496,13 +5967,15 @@ def _best_legend_loc( continue try: xv, yv = np.broadcast_arrays( - np.asarray(x_values, dtype=np.float64), - np.asarray(y_values, dtype=np.float64), + axis_values(x_values, "x"), + axis_values(y_values, "y"), ) except (TypeError, ValueError): continue xv, yv = xv.reshape(-1), yv.reshape(-1) - if len(xv) > 4096: + total = len(xv) + sampled = total + if total > _BEST_LOC_SAMPLE: # Stride down before the finite scan: occupancy scoring is # already sampled, so the full-array isfinite pass was pure # O(n) per-build cost on large legended series. Sparse finite @@ -4510,39 +5983,134 @@ def _best_legend_loc( # a sample with no finite pair falls back to the full array — # a series the old full-array pass scored still scores instead # of vanishing from placement. - strided = np.linspace(0, len(xv) - 1, 4096, dtype=np.intp) + strided = np.linspace(0, total - 1, _BEST_LOC_SAMPLE, dtype=np.intp) sampled_x, sampled_y = xv[strided], yv[strided] if (np.isfinite(sampled_x) & np.isfinite(sampled_y)).any(): xv, yv = sampled_x, sampled_y - finite = np.flatnonzero(np.isfinite(xv) & np.isfinite(yv)) - if len(finite) > 512: - finite = finite[np.linspace(0, len(finite) - 1, 512, dtype=np.intp)] - if not len(finite): - continue - xn = np.clip((xv[finite] - xlo) / (xhi - xlo), 0.0, 1.0) - yn = np.clip((yv[finite] - ylo) / (yhi - ylo), 0.0, 1.0) + sampled = _BEST_LOC_SAMPLE + path_xn = (xv - xlo) / (xhi - xlo) + path_yn = (yv - ylo) / (yhi - ylo) if x_reverse: - xn = 1.0 - xn + path_xn = 1.0 - path_xn if y_reverse: - yn = 1.0 - yn - n = float(len(finite)) + path_yn = 1.0 - path_yn + finite = np.flatnonzero(np.isfinite(path_xn) & np.isfinite(path_yn)) + if not len(finite): + continue + # Unclipped: a point outside the view is outside every candidate + # box, exactly as Matplotlib sees it in display space. Clipping used + # to pin such points onto the nearest edge and count them there. + xn = path_xn[finite] + yn = path_yn[finite] + # Matplotlib's badness is a raw vertex count summed over artists, so + # a long series legitimately outweighs a short one. Scale a strided + # series back to its true length to preserve that weighting. + weight = total / float(sampled) entries_used += 1 - for name, xl, xh, yl, yh in candidates: - inside = (xn >= xl) & (xn <= xh) & (yn >= yl) & (yn <= yh) - scores[name] += float(np.count_nonzero(inside)) / n + path_hits = ( + [False] * len(candidates) + if kind == "scatter" + else _path_intersects_boxes( + path_xn, + path_yn, + ((xl, xh, yl, yh) for _, xl, xh, yl, yh in candidates), + ) + ) + for (name, xl, xh, yl, yh), path_hit in zip(candidates, path_hits, strict=True): + # Strict, mirroring Bbox.count_contains. + inside = (xn > xl) & (xn < xh) & (yn > yl) & (yn < yh) + scores[name] += float(np.count_nonzero(inside)) * weight + # ``Line2D``, Patch paths, and PolyCollection paths contribute + # one additional badness point when a segment crosses the + # legend even if neither endpoint is contained. Scatter is a + # Collection and contributes offsets only. + if path_hit: + scores[name] += 1.0 if not entries_used: return "upper right" - # Normalize to a mean occupancy in [0, 1] so the tolerance below is - # independent of series count. Matplotlib's integer badness makes - # near-equal boxes exact ties broken by candidate order; our continuous - # metric would otherwise let a sub-percent sampling difference override - # that order (e.g. picking "center left" over "center right" on a - # symmetric oscillation). Treat boxes within a small band as tied and - # keep the first — which is Matplotlib's preference. - for name in scores: - scores[name] /= entries_used + # Matplotlib compares exact integer badness and prefers the lower code + # on a tie; dict order here *is* that code order, so the first minimum + # wins. The only slack absorbs the float stride weight above — an + # unsampled series scores whole numbers and ties exactly, as it must. best = min(scores.values()) - return next(name for name, score in scores.items() if score <= best + 0.02) + return next(name for name, score in scores.items() if score <= best * (1.0 + 1e-9)) + + def _outside_padding(self, compact: bool) -> tuple[float, float, float]: + """The top/right/bottom gutters the renderers reserve *outside* the + chart's ``padding``. + + `_svg.layout()` and the browser's ``ChartView._layout()`` both add the + title band, a top-side x axis, the colorbar strip, and the shared + right-side gutter for a secondary y axis on top of whatever padding the + spec carries. This is the shim's single mirror of that rule: + `_frame_padding()` subtracts it so an explicit padding still lands the + plot rect where Matplotlib puts the axes, the grid compositor adds it to + the panel it allocates so that subtraction always fits, and the + equal-aspect solve measures the real plot rect with it. + """ + top = 0.0 + if self._title: + top += 26.0 if compact else 30.0 + if self._axis["x"].get("side") == "top": + top += 26.0 if compact else 32.0 + right = 0.0 + bottom = 0.0 + if self._colorbar is not None: + if self._colorbar.get("orientation") == "horizontal": + bottom += 38.0 + (16.0 if self._colorbar.get("label") else 0.0) + else: + right += 86.0 + (18.0 if self._colorbar.get("label") else 0.0) + if self._twin is not None or any( + secondary._axis == "y" and secondary._side == "right" + for secondary in self._secondary_axes + ): + right += 42.0 if compact else 54.0 + return top, right, bottom + + def _aspect_anchor(self) -> tuple[float, float]: + """Normalized anchor of an aspect-shrunk box within its allocation.""" + anchor = self._anchor or "C" + x = 0.0 if "W" in anchor else 1.0 if "E" in anchor else 0.5 + y = 0.0 if "S" in anchor else 1.0 if "N" in anchor else 0.5 + return x, y + + def _frame_padding(self, width: int, height: int) -> Optional[list[float]]: + """Explicit ``padding`` that renders the axes frame where Matplotlib + draws it — the rectangle `get_position()` reports. + + Without this the renderers fell back to label-aware default margins + (62/14/10/42 px at ordinary export sizes), which have nothing to do with + the ``figure.subplot.*`` frame: a default 640x480 figure drew its frame + at x 0.0969..0.9781 (13.8 % too wide) with its top edge at y 0.0208 + instead of 0.1208. Returns None when the wanted rectangle cannot be + expressed as non-negative padding, leaving the defaults in charge. + """ + if self._colorbar is not None: + # Matplotlib's colorbar() steals its strip from the parent axes + # rectangle, while the renderers reserve it outside the padding. + # Reconciling the two is colorbar-placement work, not framing work. + return None + if self._plot_box_px is not None: + left, top, plot_width, plot_height = self._plot_box_px + else: + # Padding describes the original allocation. Adjustable-box + # aspect handling below shrinks it once; using the active position + # here would apply the aspect solve twice. + x0, y0, rect_width, rect_height = self.get_position(original=True).bounds + left = x0 * width + top = (1.0 - y0 - rect_height) * height + plot_width = rect_width * width + plot_height = rect_height * height + extra_top, extra_right, extra_bottom = self._outside_padding(width < 520) + padding = [ + top - extra_top, + width - left - plot_width - extra_right, + height - top - plot_height - extra_bottom, + left, + ] + if any(value < 0.0 for value in padding): + return None + return padding def _build_chart(self, width: int, height: int) -> Any: if self._y2_of is not None: @@ -4553,7 +6121,9 @@ def _build_chart(self, width: int, height: int) -> Any: children = self._chart_children() if self._twin is not None: children.extend(self._twin._chart_children()) - chart_padding = None if self._padding is None else list(self._padding) + chart_padding = ( + self._frame_padding(width, height) if self._padding is None else list(self._padding) + ) adjusted_aspect = False aspect_domains: Optional[tuple[tuple[float, float], tuple[float, float]]] = None if self._aspect_equal and self._aspect_bounds is not None: @@ -4567,14 +6137,13 @@ def _build_chart(self, width: int, height: int) -> Any: ) else: top, right, bottom, left = map(float, chart_padding) - layout_top = top + ((26.0 if compact else 30.0) if self._title else 0.0) - layout_right = right - layout_bottom = bottom - if self._colorbar is not None: - if self._colorbar.get("orientation") == "horizontal": - layout_bottom += 38.0 + (16.0 if self._colorbar.get("label") else 0.0) - else: - layout_right += 86.0 + (18.0 if self._colorbar.get("label") else 0.0) + # Solve over the rect the renderers will actually draw, gutters and + # all — a top-side x axis (matshow) otherwise made the equal-unit + # solve believe the plot box was 26 px taller than it is. + extra_top, extra_right, extra_bottom = self._outside_padding(compact) + layout_top = top + extra_top + layout_right = right + extra_right + layout_bottom = bottom + extra_bottom plot_width = max(40.0, width - left - layout_right) plot_height = max(40.0, height - layout_top - layout_bottom) data_ratio = abs(x1 - x0) / max(abs(y1 - y0), np.finfo(float).eps) @@ -4595,14 +6164,15 @@ def _build_chart(self, width: int, height: int) -> Any: else: # adjustable='box' preserves image limits and changes the axes # rectangle to maintain equal data-unit scaling. + anchor_x, anchor_y = self._aspect_anchor() if plot_ratio > data_ratio: extra = plot_width - plot_height * data_ratio - left += extra * 0.5 - right += extra * 0.5 + left += extra * anchor_x + right += extra * (1.0 - anchor_x) else: extra = plot_height - plot_width / data_ratio - top += extra * 0.5 - bottom += extra * 0.5 + top += extra * (1.0 - anchor_y) + bottom += extra * anchor_y chart_padding = [top, right, bottom, left] # Image-like entries carry their extent outside the ordinary # axis property dictionaries. Materialize it so the renderer's @@ -4610,11 +6180,7 @@ def _build_chart(self, width: int, height: int) -> Any: self._axis["x"]["domain"] = (x0, x1) self._axis["y"]["domain"] = (y0, y1) adjusted_aspect = True - if not adjusted_aspect and self._xmargin != 0.0 and "x" not in self._explicit_domains: - self._axis["x"]["domain"] = self._auto_domain("x") - if not adjusted_aspect and self._ymargin != 0.0 and "y" not in self._explicit_domains: - self._axis["y"]["domain"] = self._auto_domain("y") - if chart_padding is None and any( + if self._padding is None and any( entry["kind"] == "@text" and (entry["kwargs"].get("style") or {}).get("coordinate_space") == "axes_fraction" and _is_number(entry["args"][0]) @@ -4625,9 +6191,61 @@ def _build_chart(self, width: int, height: int) -> Any: # axes-fraction x > 1) needs room the label-aware default margins # don't reserve; mirror layout()'s defaults and widen the right side. compact = width < 520 - chart_padding = ( - [6.0, 8.0 + 26.0, 36.0, 46.0] if compact else [10.0, 14.0 + 26.0, 42.0, 62.0] - ) + if chart_padding is None: + chart_padding = ( + [6.0, 8.0 + 26.0, 36.0, 46.0] if compact else [10.0, 14.0 + 26.0, 42.0, 62.0] + ) + else: + chart_padding = list(map(float, chart_padding)) + chart_padding[1] += 26.0 + anchored_legends: list[tuple[dict[str, Any], list[dict[str, Any]]]] = [] + if self._legend and self._legend_artist is None and self._legend_options.get("anchor"): + _, labels = self.get_legend_handles_labels() + if labels: + anchored_legends.append( + (self._legend_options, [{"name": label} for label in labels]) + ) + extra_legend_artists = list(self._extra_legends) + if self._legend_artist is not None: + extra_legend_artists.append(self._legend_artist) + for legend_artist in extra_legend_artists: + legend_spec = legend_artist.spec() + if legend_spec.get("anchor") and legend_spec.get("items"): + anchored_legends.append((legend_spec, list(legend_spec["items"]))) + if anchored_legends: + from .._svg import _legend_layout + + compact = width < 520 + if chart_padding is None: + chart_padding = [6.0, 8.0, 36.0, 46.0] if compact else [10.0, 14.0, 42.0, 62.0] + top, right, bottom, left = map(float, chart_padding) + for legend_options, legend_items in anchored_legends: + anchor = legend_options["anchor"] + loc = str(legend_options.get("loc") or "upper right") + ax, ay = float(anchor[0]), float(anchor[1]) + aw, ah = (0.0, 0.0) if len(anchor) == 2 else (float(anchor[2]), float(anchor[3])) + # Ask the shared static geometry for the legend's natural + # bounded size. A very tall provisional plot prevents entry + # truncation from hiding the amount of outside room required. + provisional_plot = { + "x": left, + "y": top, + "w": max(40.0, width - left - right), + "h": max(10_000.0, height - top - bottom), + } + legend_box = _legend_layout(legend_items, provisional_plot, legend_options) + border_axes_pad = max(0.0, float(legend_options.get("border_pad", 0.0))) + vertical_room = legend_box["box_h"] + border_axes_pad + 6.0 + horizontal_room = legend_box["box_w"] + border_axes_pad + 6.0 + if ay >= 1.0 and "lower" in loc: + top = max(top, vertical_room) + if ay + ah <= 0.0 and "upper" in loc: + bottom = max(bottom, vertical_room) + if ax >= 1.0 and "left" in loc: + right = max(right, min(220.0, horizontal_room)) + if ax + aw <= 0.0 and "right" in loc: + left = max(left, min(220.0, horizontal_room)) + chart_padding = [top, right, bottom, left] # A dataless matplotlib axis views exactly (0, 1) — margins never apply. # Pin it so the engine's autorange padding cannot widen the empty view # (padding turns the 0.5 midpoint tick into a bare 0/1 pair). Render @@ -4642,6 +6260,19 @@ def _build_chart(self, width: int, height: int) -> Any: } x_props = {k: v for k, v in self._axis["x"].items() if v is not None} y_props = {k: v for k, v in self._axis["y"].items() if v is not None} + for axis, props in (("x", x_props), ("y", y_props)): + if adjusted_aspect or axis in self._explicit_domains: + continue + # Mesh and image spans are sticky on both ends: materialize the + # domain so the renderer's generic margin padding cannot widen an + # axis Matplotlib pins flush to the outer cell edge. `margin` and + # `domain` never combine (spec/design/pan-and-zoom-configuration.md + # §9), so send exactly one of them. + pinned = None if props.get("domain") is not None else self._fully_sticky_domain(axis) + if pinned is not None: + props["domain"] = pinned + else: + props["margin"] = self._effective_margin(axis) if "x" in empty_view: x_props["domain"] = (0.0, 1.0) if "y" in empty_view: @@ -4649,24 +6280,48 @@ def _build_chart(self, width: int, height: int) -> Any: if aspect_domains is not None: x_props["domain"], y_props["domain"] = aspect_domains auto_tick_counts = self._auto_tick_counts(x_props, width, height) + if rcParams["axes.autolimit_mode"] == "round_numbers" and not adjusted_aspect: + self._apply_round_number_domains(x_props, y_props, auto_tick_counts) self._apply_tickers("x", x_props, auto_tick_counts["x"]) self._apply_tickers("y", y_props, auto_tick_counts["y"]) self._apply_auto_tick_density(x_props, y_props, auto_tick_counts) + # The left gutter is no longer reserved here. `_svg.layout()` measures + # it from the axis's own tick/title extents once the range is resolved, + # which covers numeric ticks (this shim's 13.89 px rcParam fonts overrun + # the 62 px default) as well as the categorical labels this branch used + # to special-case, and applies to an authored `padding` too. children.append(_cached_axis("x", x_props)) children.append(_cached_axis("y", y_props)) for index, secondary in enumerate(self._secondary_axes, 1): children.append(secondary._component(index)) if self._twin is not None: y2_props = {k: v for k, v in self._axis["y2"].items() if v is not None} + if "y" not in self._twin._explicit_domains: + if self._twin._axis_is_dataless("y"): + y2_props["domain"] = (0.0, 1.0) + else: + y2_props["margin"] = self._twin._effective_margin("y") self._apply_tickers("y2", y2_props, auto_tick_counts["y"]) children.append(xy.y_axis(id="y2", side="right", **y2_props)) - if self._legend: + legend_needs_best = False + if self._legend and self._legend_artist is not None: + children.append(xy.legend(show=False)) + elif self._legend: legend_options = dict(self._legend_options) if legend_options.get("loc") in (None, "best"): - legend_options["loc"] = self._best_legend_loc( - x_props.get("domain"), y_props.get("domain") - ) - children.append(xy.legend(**legend_options)) + # Left unresolved here on purpose and filled in below, once the + # built figure can report the view it will actually display: + # `best` is a question about which corner the marks reach on + # screen, and an autoranged view is padded by the engine. + legend_needs_best = True + legend_options["loc"] = None + # ``border_pad`` is an internal pixel-resolved Matplotlib wire + # option; core's public legend component intentionally remains in + # its declarative units. It is restored on the built Figure below. + component_legend_options = dict(legend_options) + component_legend_options.pop("border_pad", None) + component_legend_options.pop("handleheight", None) + children.append(xy.legend(**component_legend_options)) elif not any(entry.get("kwargs", {}).get("name") for entry in self._entries): # Core XY can auto-create a continuous-color "value" legend. # An unlabeled Matplotlib collection must not acquire one. @@ -4685,15 +6340,36 @@ def _build_chart(self, width: int, height: int) -> Any: tokens = dict(theme_tokens) tokens["grid_color"] = self._grid_color if self._grid else "transparent" children.append(xy.theme(style=self._theme_style, **tokens)) + chrome_styles = self._chrome_styles + if self._title_style: + chrome_styles = { + **chrome_styles, + "title": {**chrome_styles.get("title", {}), **self._title_style}, + } self._chart = xy.chart( *children, title=self._title, width=width, height=height, padding=chart_padding, - styles=self._chrome_styles, + styles=chrome_styles, ) core_figure = self._chart.figure() + if self._legend and self._legend_artist is None and "border_pad" in self._legend_options: + core_figure.legend_options["border_pad"] = self._legend_options["border_pad"] + if self._legend_items is not None: + core_figure.legend_options["items"] = list(self._legend_items) + best_ranges = self._displayed_ranges(core_figure, x_props, y_props) + best_plot_size: Optional[tuple[float, float]] = None + if legend_needs_best: + best_plot_size = self._displayed_plot_size(core_figure) + core_figure.legend_options["loc"] = self._best_legend_loc( + *best_ranges, + legend_options=self._legend_options, + plot_size=best_plot_size, + ) + if "handleheight" in self._legend_options: + core_figure.legend_options["handleheight"] = self._legend_options["handleheight"] core_figure.frame_sides = [ side for side in ("left", "bottom", "top", "right") if side not in self._hidden_spines ] @@ -4705,13 +6381,21 @@ def _build_chart(self, width: int, height: int) -> Any: if derived is not None: options["domain"] = [derived[0], derived[1]] figure.colorbar_options = options - if self._extra_legends: + legends = list(self._extra_legends) + if self._legend_artist is not None: + legends.append(self._legend_artist) + if legends: + if best_plot_size is None: + best_plot_size = self._displayed_plot_size(core_figure) extras = [] - for leg in self._extra_legends: + for leg in legends: spec = leg.spec() if spec.get("loc") in (None, "best"): spec["loc"] = self._best_legend_loc( - x_props.get("domain"), y_props.get("domain") + *best_ranges, + legend_options=spec, + items=list(spec.get("items") or []) or None, + plot_size=best_plot_size, ) extras.append(spec) core_figure.extra_legends = extras @@ -4725,18 +6409,9 @@ def _auto_tick_counts( ) -> dict[str, int]: """Matplotlib's ``Axis.get_tick_space()`` per axis: how many tick intervals fit the estimated plot rect at the tick-label font size.""" - compact = width < 520 - if self._padding is None: - left, right = (46.0, 8.0) if compact else (62.0, 14.0) - top, bottom = (6.0, 36.0) if compact else (10.0, 42.0) - else: - top, right, bottom, left = map(float, self._padding) - if self._title: - top += 26.0 if compact else 30.0 - if x_props.get("side") == "top": - top += 26.0 if compact else 32.0 - plot_width = max(40.0, float(width) - left - right) - plot_height = max(40.0, float(height) - top - bottom) + plot_width, plot_height = self._plot_rect_px( + width, height, self._padding, x_props.get("side") + ) dpi = float(self.figure._dpi if self.figure._dpi is not None else rcParams["figure.dpi"]) base = float(rcParams["font.size"]) x_font = _font_size_points(rcParams["xtick.labelsize"], base) @@ -4746,6 +6421,41 @@ def _auto_tick_counts( "y": max(1, min(9, int(np.floor(plot_height * 72.0 / dpi / (y_font * 2.0))))), } + def _apply_round_number_domains( + self, + x_props: dict[str, Any], + y_props: dict[str, Any], + counts: dict[str, int], + ) -> None: + """Expand automatic linear views to the default locator's edge ticks. + + Matplotlib applies ``axes.autolimit_mode='round_numbers'`` at draw + time, after the configured data margin and with the axes-size tick + budget available. Keep the expansion on the render snapshot so an rc + context cannot permanently turn an automatic view into an explicit + one. + """ + for axis, props in (("x", x_props), ("y", y_props)): + if axis in self._explicit_domains or self._axis_is_dataless(axis): + continue + spec = self._scale_specs.get(axis) or {"name": "linear"} + if spec.get("name") != "linear": + continue + if axis in self._margin_overrides: + domain = props.get("domain", self._auto_domain(axis)) + else: + lo, hi = self._entry_extent(axis) + margin = self._rc_margins[axis] + pad = (hi - lo) * margin + domain = (lo - pad, hi + pad) + locator = self._tickers.get((axis, "major_locator")) or AutoLocator() + if not hasattr(locator, "view_limits"): + continue + if isinstance(locator, Locator): + locator._nbins_hint = counts[axis] + lo, hi = locator.view_limits(*map(float, domain)) + props["domain"] = (float(lo), float(hi)) + def _apply_auto_tick_density( self, x_props: dict[str, Any], @@ -4946,7 +6656,14 @@ def _arrow_visuals( ) style: dict[str, Any] = {} if fancy: - style["head_size"] = float(arrowprops.get("headwidth", 12.0)) + # Matplotlib's legacy YAArrow default has a substantially broader head + # and a filled shaft, rather than the thin stroked ``->`` + # FancyArrowPatch style. Matplotlib's defaults are a 4-point shaft and + # a 12-point head base, so retain that one-third proportion. + head_size = float(arrowprops.get("headwidth", 20.0)) + style["head_size"] = head_size + style["shaft_width_start"] = head_size / 3.0 + style["shaft_width_end"] = head_size / 3.0 else: name = str(arrowstyle).split(",")[0].strip() tail, head = _ARROWSTYLE_ENDS.get(name, ("none", "triangle")) @@ -4977,43 +6694,59 @@ def _arrow_visuals( return color, width, style -def _bbox_label_style(bbox: dict[str, Any], font_size: float = 11.0) -> dict[str, Any]: +def _bbox_label_style( + bbox: dict[str, Any], + font_size: float = 11.0, + point_scale: float = 1.0, +) -> dict[str, Any]: """matplotlib text ``bbox`` patch → annotation-label box styles. - A CSS approximation drawn by the render client's DOM label; the static - exporters keep the plain label (recorded in spec/matplotlib/compat.md). + A CSS approximation shared by the browser and static exporters. """ style: dict[str, Any] = {} - face = bbox.get("fc", bbox.get("facecolor", "C0")) alpha = bbox.get("alpha") + + def with_alpha(resolved: str) -> str: + """Apply the patch ``alpha`` to one resolved colour. + + Matplotlib's ``bbox`` ``alpha`` is the *patch* alpha, not a face + alpha: the SVG backend emits it as element ``opacity``, which dims + the face and the edge together (so ``alpha=0.1`` leaves the default + black edge effectively invisible). CSS paints ``background`` and + ``border`` separately, so each has to carry the alpha itself. + + ``Patch.set_alpha`` *overrides* any alpha embedded in the face or edge + colour; it does not multiply the two values. Resolve through xy's + native CSS Color 4 parser so Matplotlib/CSS names such as ``gray`` and + ``rebeccapurple`` receive the same treatment as hex and rgb() forms. + """ + if alpha is None: + return resolved + r, g, b, a = resolve_rgba((resolved, float(alpha))) + return f"rgba({round(r * 255)},{round(g * 255)},{round(b * 255)},{a:.3g})" + + face = bbox.get("fc", bbox.get("facecolor", "C0")) if face is not None and face != "none": resolved = resolve_color(face) if resolved is not None: - if alpha is not None: - from ._colors import _rgba_floats - - try: - r, g, b, a = _rgba_floats(resolved) - except ValueError: # exotic CSS name: keep the fill, lose alpha - style["background"] = resolved - else: - style["background"] = ( - f"rgba({round(r * 255)},{round(g * 255)},{round(b * 255)}," - f"{float(alpha) * a:.3g})" - ) - else: - style["background"] = resolved + style["background"] = with_alpha(resolved) edge = bbox.get("ec", bbox.get("edgecolor", "black")) if edge is not None and edge != "none": - line_width = float(bbox.get("lw", bbox.get("linewidth", 1.0))) - style["border"] = f"{line_width:g}px solid {resolve_color(edge)}" + resolved_edge = resolve_color(edge) + if resolved_edge is not None: + line_width = float(bbox.get("lw", bbox.get("linewidth", 1.0))) + style["border"] = f"{line_width:g}px solid {with_alpha(resolved_edge)}" boxstyle = str(bbox.get("boxstyle", "square")) name = boxstyle.split(",")[0].strip() if "round" in name: style["border_radius"] = 8.0 if name == "round4" else 5.0 - # matplotlib pads the patch pad×fontsize around the text. - pad = max(0.0, _parse_style_options(boxstyle).get("pad", 0.3)) * float(font_size) - style["padding"] = f"{pad:.3g}px {pad * 1.3:.3g}px" + # With an explicit boxstyle, Matplotlib's pad is a fraction of the font + # size. Without one, top-level ``pad`` is in points (default 4 pt). + if "boxstyle" in bbox: + pad = max(0.0, _parse_style_options(boxstyle).get("pad", 0.3)) * float(font_size) + else: + pad = max(0.0, float(bbox.get("pad", 4.0))) * float(point_scale) + style["padding"] = f"{pad:.3g}px" return style @@ -5041,6 +6774,19 @@ def _font_size(value: Any, base: Any, dpi: float = 96.0) -> float: return _font_size_points(value, base) * float(dpi) / 72.0 +def _rc_font_weight(value: Any, key: str = "font-weight") -> dict[str, Any]: + """Carry a weight rcParam only when it asks for something other than normal. + + Matplotlib's ``axes.titleweight``/``axes.labelweight`` default to + ``"normal"``, which is also every xy renderer's own default, so the + default case needs nothing on the wire — the same rule the neighbouring + ``axes.labelcolor`` check uses. An explicit weight (``"bold"``, ``"light"``, + a numeric string) travels through to the browser, SVG, and raster paths. + """ + weight = str(value) + return {} if weight == "normal" else {key: weight} + + def _rc_axis_style(axis: str, dpi: float = 96.0) -> dict[str, Any]: prefix = "xtick" if axis == "x" else "ytick" point_scale = float(dpi) / 72.0 @@ -5049,6 +6795,7 @@ def _rc_axis_style(axis: str, dpi: float = 96.0) -> dict[str, Any]: result: dict[str, Any] = {} result["axis_width"] = float(rcParams["axes.linewidth"]) * point_scale result["tick_length"] = float(rcParams[f"{prefix}.major.size"]) * point_scale + result["tick_padding"] = float(rcParams[f"{prefix}.major.pad"]) * point_scale result["tick_width"] = float(rcParams[f"{prefix}.major.width"]) * point_scale if tick_color != "black": result["tick_color"] = resolve_color(tick_color) @@ -5065,6 +6812,10 @@ def _rc_axis_style(axis: str, dpi: float = 96.0) -> dict[str, Any]: if rcParams["axes.labelcolor"] != "black": result["label_color"] = resolve_color(rcParams["axes.labelcolor"]) result["label_size"] = _font_size(rcParams["axes.labelsize"], rcParams["font.size"], dpi) + # The browser reads the weight off `chrome_styles["axis_title"]`; the SVG + # and native raster exporters read it off the axis style, so `axes.labelweight` + # has to be published in both places to reach all three renderers. + result.update(_rc_font_weight(rcParams["axes.labelweight"], "label_font_weight")) return result @@ -5121,15 +6872,32 @@ def _convert_timedelta_axis(values: np.ndarray) -> np.ndarray: def _validate_margin(value: Any, axis: str) -> float: margin = float(value) - if not np.isfinite(margin) or margin < 0: - raise ValueError(f"{axis} margin must be a finite non-negative number") + if not np.isfinite(margin) or margin <= -0.5: + raise ValueError("margin must be finite and greater than -0.5") return margin -def _apply_axis_label_kwargs(props: dict[str, Any], kwargs: dict[str, Any], context: str) -> None: +def _apply_axis_label_kwargs( + props: dict[str, Any], + kwargs: dict[str, Any], + context: str, + *, + point_scale: float, +) -> None: labelpad = kwargs.pop("labelpad", None) loc = kwargs.pop("loc", None) - _consume_text_kwargs(kwargs, context) + text_style = _pop_text_style_kwargs(kwargs, context) + axis_style = props.setdefault("style", {}) + for source, target in ( + ("color", "label_color"), + ("font_size", "label_size"), + ("font_family", "label_font_family"), + ("font_weight", "label_font_weight"), + ("font_style", "label_font_style"), + ): + if source in text_style: + value = text_style[source] + axis_style[target] = float(value) * point_scale if source == "font_size" else value if labelpad is not None: props["label_offset"] = float(labelpad) if loc is not None: @@ -5145,21 +6913,28 @@ def _apply_axis_label_kwargs(props: dict[str, Any], kwargs: dict[str, Any], cont props["label_position"] = positions[loc] -def _consume_text_kwargs(kwargs: dict[str, Any], context: str) -> None: - # Accepted for Matplotlib-flavoured scripts. The native engine currently - # inherits font styling from the chart theme, so these kwargs are validated - # and retained as compatibility inputs rather than silently acting on data. +def _pop_text_style_kwargs(kwargs: dict[str, Any], context: str) -> dict[str, Any]: + """Consume Matplotlib text kwargs and return renderer-backed font style.""" + fontdict = kwargs.pop("fontdict", None) + if fontdict is not None: + if not isinstance(fontdict, Mapping): + raise TypeError(f"{context} fontdict must be a mapping or None") + kwargs = {**fontdict, **kwargs} + + def pop_alias(primary: str, *aliases: str) -> Any: + value = kwargs.pop(primary, None) + for alias in aliases: + alias_value = kwargs.pop(alias, None) + if value is None: + value = alias_value + return value + + size = pop_alias("fontsize", "size") + weight = pop_alias("fontweight", "weight") + family = pop_alias("fontfamily", "family") + font_style = pop_alias("fontstyle", "style") + color = kwargs.pop("color", None) for key in ( - "fontsize", - "size", - "fontdict", - "fontweight", - "weight", - "fontstyle", - "style", - "fontfamily", - "family", - "color", "horizontalalignment", "ha", "verticalalignment", @@ -5174,15 +6949,37 @@ def _consume_text_kwargs(kwargs: dict[str, Any], context: str) -> None: if kwargs: raise TypeError(f"{context} got unsupported keyword argument {next(iter(kwargs))!r}") + style: dict[str, Any] = {} + if size is not None: + style["font_size"] = _font_size_points(size, rcParams["font.size"]) + if weight is not None: + style["font_weight"] = str(weight) + if family is not None: + style["font_family"] = str(family) + if font_style is not None: + font_style = str(font_style) + if font_style not in {"normal", "italic", "oblique"}: + raise ValueError(f"{context} style must be 'normal', 'italic', or 'oblique'") + style["font_style"] = font_style + if color is not None: + style["color"] = resolve_color(color) + return style -def _tick_label_visibility(kwargs: dict[str, Any]) -> Optional[bool]: - values = [] - for key in ("labelbottom", "labeltop", "labelleft", "labelright"): - if key in kwargs: - values.append(bool(kwargs.pop(key))) - if not values: - return None - return any(values) + +def _title_css_style(style: dict[str, Any], *, point_scale: float) -> dict[str, Any]: + """Translate renderer text style keys to the chart title's CSS slot.""" + result: dict[str, Any] = {} + for source, target in ( + ("color", "color"), + ("font_family", "font-family"), + ("font_weight", "font-weight"), + ("font_style", "font-style"), + ): + if source in style: + result[target] = style[source] + if "font_size" in style: + result["font-size"] = f"{float(style['font_size']) * point_scale:g}px" + return result def _marker_symbol(marker: Any) -> str: @@ -5210,6 +7007,10 @@ def _plain_text(value: Any) -> str: return converted if "$" not in text and "\\" not in text: return text + # Matplotlib treats an odd number of dollar signs as literal text. This is + # used by gallery formatters such as ``fmt="$ {x:.2f}"`` for currency. + if text.count("$") % 2: + return text # ASCII fallback for TeX outside the unicode subset — approximate, never raw. text = text.replace("$", "") replacements = { @@ -5226,20 +7027,120 @@ def _plain_text(value: Any) -> str: return text.replace("_{", "").replace("^{", "^").replace("}", "") +def _plain_text_with_math_italic_ranges(value: Any) -> tuple[str, list[tuple[int, int]]]: + """Flatten simple mathtext while retaining its default italic spans.""" + converted, ranges = mathtext_italic_ranges(str(value)) + if converted != str(value): + return converted, ranges + return _plain_text(value), [] + + def _masked_float(value: Any) -> np.ndarray: return np.ma.asarray(value, dtype=np.float64).filled(np.nan) -def _upsample_grid(grid: np.ndarray, width: int, height: int) -> np.ndarray: - """Small dependency-free bilinear resampler for interpolated imshow gradients.""" - source_y = np.linspace(0.0, 1.0, grid.shape[0]) - source_x = np.linspace(0.0, 1.0, grid.shape[1]) - target_y = np.linspace(0.0, 1.0, height) - target_x = np.linspace(0.0, 1.0, width) - horizontal = np.vstack([np.interp(target_x, source_x, row) for row in grid]) - return np.vstack( - [np.interp(target_y, source_y, horizontal[:, column]) for column in range(width)] - ).T +def _interpolation_weights(source: int, target: int, method: str) -> np.ndarray: + """Return a normalized target-by-source matrix for a separable filter.""" + positions = np.linspace(0.0, source - 1.0, target)[:, None] + distance = positions - np.arange(source, dtype=np.float64)[None, :] + absolute = np.abs(distance) + + def keys(a: float) -> np.ndarray: + first = (a + 2.0) * absolute**3 - (a + 3.0) * absolute**2 + 1.0 + second = a * absolute**3 - 5.0 * a * absolute**2 + 8.0 * a * absolute - 4.0 * a + return np.where(absolute <= 1.0, first, np.where(absolute < 2.0, second, 0.0)) + + if method == "bilinear": + weights = np.maximum(0.0, 1.0 - absolute) + elif method == "hanning": + weights = np.where(absolute < 1.0, 0.5 + 0.5 * np.cos(np.pi * absolute), 0.0) + elif method == "hamming": + weights = np.where(absolute < 1.0, 0.54 + 0.46 * np.cos(np.pi * absolute), 0.0) + elif method == "gaussian": + weights = np.where(absolute < 2.0, np.exp(-2.0 * absolute**2), 0.0) + elif method == "kaiser": + radius = 3.0 + weights = np.where( + absolute < radius, + np.i0(5.0 * np.sqrt(np.maximum(0.0, 1.0 - (absolute / radius) ** 2))) / np.i0(5.0), + 0.0, + ) + elif method == "sinc": + weights = np.where(absolute < 4.0, np.sinc(distance), 0.0) + elif method == "lanczos": + weights = np.where(absolute < 3.0, np.sinc(distance) * np.sinc(distance / 3.0), 0.0) + elif method == "bessel": + # A windowed-sinc approximation keeps this dependency-free; unlike the + # old bilinear alias it still preserves the filter's ringing character. + weights = np.where(absolute < 4.0, np.sinc(distance) * np.sinc(distance / 4.0), 0.0) + elif method == "mitchell": + b = c = 1.0 / 3.0 + first = ( + (12 - 9 * b - 6 * c) * absolute**3 + (-18 + 12 * b + 6 * c) * absolute**2 + (6 - 2 * b) + ) / 6.0 + second = ( + (-b - 6 * c) * absolute**3 + + (6 * b + 30 * c) * absolute**2 + + (-12 * b - 48 * c) * absolute + + (8 * b + 24 * c) + ) / 6.0 + weights = np.where(absolute < 1.0, first, np.where(absolute < 2.0, second, 0.0)) + else: + cubic_a = { + "bicubic": -0.75, + "catrom": -0.5, + "hermite": 0.0, + "quadric": -0.25, + "spline16": -1.0, + "spline36": -0.35, + "antialiased": -0.5, + }.get(method, -0.5) + weights = keys(cubic_a) + totals = weights.sum(axis=1, keepdims=True) + return weights / np.where(np.abs(totals) > 1e-12, totals, 1.0) + + +def _resample_grid(grid: np.ndarray, width: int, height: int, method: str) -> np.ndarray: + """Dependency-free separable resampling for scalar and RGB(A) images.""" + values = np.asarray(grid, dtype=np.float64) + wy = _interpolation_weights(values.shape[0], height, method) + wx = _interpolation_weights(values.shape[1], width, method) + + def resample(channel: np.ndarray) -> np.ndarray: + finite = np.isfinite(channel) + if finite.all(): + return wy @ channel @ wx.T + # Renormalize around masked samples instead of allowing IEEE + # ``0 * nan`` terms to poison every output pixel touched by a filter. + numerator = wy @ np.where(finite, channel, 0.0) @ wx.T + denominator = wy @ finite.astype(np.float64) @ wx.T + return np.divide( + numerator, + denominator, + out=np.full_like(numerator, np.nan), + where=np.abs(denominator) > 1e-12, + ) + + if values.ndim == 2: + return resample(values) + channels = [resample(values[..., index]) for index in range(values.shape[2])] + return np.stack(channels, axis=-1) + + +def _scalar_grid_rgba(grid: np.ndarray, cmap: Any, vmin: Any, vmax: Any) -> np.ndarray: + """Map scalar samples before RGBA-stage interpolation.""" + from xy._svg import _lut + + values = np.asarray(grid, dtype=np.float64) + finite = values[np.isfinite(values)] + lo = float(vmin) if vmin is not None else (float(finite.min()) if finite.size else 0.0) + hi = float(vmax) if vmax is not None else (float(finite.max()) if finite.size else 1.0) + normalized = np.clip((values - lo) / ((hi - lo) or 1.0), 0.0, 1.0) + rgb = _lut(resolve_cmap(cmap), np.nan_to_num(normalized, nan=0.0).reshape(-1)).reshape( + values.shape + (3,) + ) + alpha = np.where(np.isfinite(values), 1.0, 0.0) + return np.dstack((rgb / 255.0, alpha)) def _marked_values(x: Any, y: Any, markevery: Any) -> tuple[Any, Any]: diff --git a/python/xy/pyplot/_colors.py b/python/xy/pyplot/_colors.py index 6aa20083..6d8a4941 100644 --- a/python/xy/pyplot/_colors.py +++ b/python/xy/pyplot/_colors.py @@ -72,6 +72,7 @@ def scalar_float(value: Any) -> float: "inferno": "inferno", "magma": "magma", "cividis": "cividis", + "autumn": "autumn", "gray": "gray", "grey": "gray", "greys": "gray", @@ -91,6 +92,10 @@ def scalar_float(value: Any) -> float: "rdgy": "rdgy", "jet": "jet", "binary": "binary", + "reds": "reds", + "bone": "bone", + "winter": "winter", + "bupu": "bupu", } diff --git a/python/xy/pyplot/_grid.py b/python/xy/pyplot/_grid.py index c60c8d3c..1a24d8b9 100644 --- a/python/xy/pyplot/_grid.py +++ b/python/xy/pyplot/_grid.py @@ -10,8 +10,12 @@ them. PNG: each panel renders through the engine's native rasterizer to an RGBA -array; NumPy pastes them onto one canvas and the engine's PNG encoder writes -the file. This module and `_mplfig.savefig` are the only places the shim +array; NumPy composites them onto one canvas and the engine's PNG encoder +writes the file. Absolutely placed panels are rendered on a transparent canvas +and alpha-composited, because a panel is wider than its gridspec cell — its +tick labels and title live outside the plot rect — and an opaque paste made +each column erase the one to its left. This module and `_mplfig.savefig` are +the only places the shim reaches past the public API (via `Chart.figure()` + the `_raster`/`_png` modules); everything else goes through `xy`' public surface. """ @@ -24,6 +28,72 @@ import numpy as np +def _composite_rgba(destination: np.ndarray, source: np.ndarray) -> None: + """Composite a straight-alpha RGBA tile over ``destination`` in place. + + Matplotlib draws every axes onto one canvas, so a panel's chrome may hang + over a neighbour's without erasing it. Alpha compositing is the equivalent + for panel-per-render composition; an opaque paste is not. + """ + source_alpha = source[:, :, 3] + opaque = source_alpha == 255 + destination[opaque] = source[opaque] + partial = (source_alpha != 0) & ~opaque + if not np.any(partial): + return + src = source[partial].astype(np.float32) + dst = destination[partial].astype(np.float32) + src_alpha_f = src[:, 3:4] / 255.0 + dst_alpha_f = dst[:, 3:4] / 255.0 + out_alpha = src_alpha_f + dst_alpha_f * (1.0 - src_alpha_f) + out_rgb = np.divide( + src[:, :3] * src_alpha_f + dst[:, :3] * dst_alpha_f * (1.0 - src_alpha_f), + out_alpha, + out=np.zeros_like(src[:, :3]), + where=out_alpha != 0, + ) + destination[partial, :3] = np.rint(out_rgb).astype(np.uint8) + destination[partial, 3] = np.rint(out_alpha[:, 0] * 255.0).astype(np.uint8) + + +def _compose_canvas( + tiles: list[np.ndarray], + positions: list[tuple[float, float, float, float]], + canvas_size: tuple[int, int], + facecolor: str, + scale: float, +) -> np.ndarray: + """Alpha-composite absolutely placed panel tiles onto one RGBA figure canvas. + + `positions` are whole-panel [left, bottom, width, height] figure fractions, + bottom-origin like matplotlib; document order stacks later axes above + earlier ones, as matplotlib draws. + """ + from xy import _raster + + background = np.asarray(_raster._parse_color(facecolor), dtype=np.uint8) + canvas = np.empty( + (round(canvas_size[1] * scale), round(canvas_size[0] * scale), 4), dtype=np.uint8 + ) + canvas[...] = background + for tile, (left, bottom, _width, height) in zip(tiles, positions, strict=True): + x = round(left * canvas.shape[1]) + y = round((1.0 - bottom - height) * canvas.shape[0]) + dest_x0, dest_y0 = max(0, x), max(0, y) + src_x0, src_y0 = max(0, -x), max(0, -y) + dest_x1 = min(canvas.shape[1], x + tile.shape[1]) + dest_y1 = min(canvas.shape[0], y + tile.shape[0]) + if dest_x1 > dest_x0 and dest_y1 > dest_y0: + _composite_rgba( + canvas[dest_y0:dest_y1, dest_x0:dest_x1], + tile[ + src_y0 : src_y0 + dest_y1 - dest_y0, + src_x0 : src_x0 + dest_x1 - dest_x0, + ], + ) + return canvas + + def compose_html( charts: list[Any], nrows: int, @@ -230,7 +300,13 @@ def stitch_png( ) -> bytes: from xy import _png, _raster # sanctioned escape hatch (see module doc) - scale = 2.0 + # pyplot charts are already built at ``figsize * dpi`` logical pixels. + # Rasterizing those pixels at the core exporter's 2x quality default made + # savefig silently double both output dimensions and every point-sized + # artist compared with Matplotlib. The pyplot compatibility boundary is + # physical pixels, so keep its raster scale at one; callers that use the + # native Figure API directly retain that API's explicit 2x default. + scale = 1.0 if ( len(charts) == 1 and positions is None @@ -253,11 +329,16 @@ def stitch_png( return rendered return _png.encode(rendered) + absolute = positions is not None and canvas_size is not None tiles: list[np.ndarray] = [] for chart in charts: fig = chart.figure() spec, blob, borrowed = fig._build_raster_payload(px_width=max(256, int(fig.width))) - spec["canvas_background"] = facecolor + # Absolute panels include their own surrounding chrome and therefore + # overlap in the gutters. Keep only that outer canvas transparent so + # a later panel cannot erase an earlier panel's right/bottom spine or + # terminal tick label. The axes patch (--chart-bg) remains opaque. + spec["canvas_background"] = "none" if absolute else facecolor img = _raster.render_raster(spec, blob, scale, borrowed=borrowed) if isinstance(img, bytes): raise RuntimeError("pyplot grid rasterizer unexpectedly returned encoded PNG bytes") @@ -265,22 +346,17 @@ def stitch_png( if not tiles: raise ValueError("figure has no axes to save") - if positions is not None and canvas_size is not None: - background = np.asarray(_raster._parse_color(facecolor), dtype=np.uint8) - canvas = np.empty((canvas_size[1] * 2, canvas_size[0] * 2, 4), dtype=np.uint8) - canvas[...] = background - for tile, (left, bottom, _width, height) in zip(tiles, positions, strict=True): - x = round(left * canvas.shape[1]) - y = round((1.0 - bottom - height) * canvas.shape[0]) - dest_x0, dest_y0 = max(0, x), max(0, y) - src_x0, src_y0 = max(0, -x), max(0, -y) - dest_x1 = min(canvas.shape[1], x + tile.shape[1]) - dest_y1 = min(canvas.shape[0], y + tile.shape[0]) - if dest_x1 > dest_x0 and dest_y1 > dest_y0: - canvas[dest_y0:dest_y1, dest_x0:dest_x1] = tile[ - src_y0 : src_y0 + dest_y1 - dest_y0, - src_x0 : src_x0 + dest_x1 - dest_x0, - ] + if absolute: + assert positions is not None and canvas_size is not None + canvas = _compose_canvas(tiles, positions, canvas_size, facecolor, scale) + if suptitle: + _blend_raster_suptitle( + canvas, + suptitle, + suptitle_style, + scale=scale, + title_h=min(48, canvas.shape[0]), + ) return _png.encode(canvas) col_widths = [ @@ -305,23 +381,13 @@ def stitch_png( x = sum(col_widths[:c]) canvas[y : y + tile.shape[0], x : x + tile.shape[1]] = tile if suptitle: - from xy import kernels - - cmd = _raster._Cmd(scale) - style = suptitle_style or {} - cmd.text( - canvas.shape[1] * float(style.get("x", 0.5)) / scale, - 17, - 1, - float(style.get("size", 14)), - _raster._parse_color(str(style.get("color", "#262626"))), + _blend_raster_suptitle( + canvas, suptitle, + suptitle_style, + scale=scale, + title_h=title_h, ) - overlay = kernels.rasterize(bytes(cmd.buf), canvas.shape[1], title_h) - alpha = overlay[:, :, 3:4].astype(np.float64) / 255.0 - canvas[:title_h, :, :3] = np.round( - overlay[:, :, :3] * alpha + canvas[:title_h, :, :3] * (1.0 - alpha) - ).astype(np.uint8) if colorbar: from xy._svg import _lut @@ -343,3 +409,33 @@ def stitch_png( y1 = min(canvas.shape[0], int(ys.max()) + pad_pixels + 1) canvas = canvas[y0:y1, x0:x1] return _png.encode(canvas) + + +def _blend_raster_suptitle( + canvas: np.ndarray, + suptitle: str, + style: Optional[dict[str, Any]], + *, + scale: float, + title_h: int, +) -> None: + """Draw a figure suptitle onto either grid or absolute-position PNGs.""" + from xy import _raster, kernels + + resolved = style or {} + cmd = _raster._Cmd(scale) + cmd.text( + canvas.shape[1] * float(resolved.get("x", 0.5)) / scale, + 17, + 1, + float(resolved.get("size", 14)), + _raster._parse_color(str(resolved.get("color", "#262626"))), + suptitle, + bold=str(resolved.get("weight", "normal")).lower() + in {"bold", "semibold", "demibold", "heavy", "black"}, + ) + overlay = kernels.rasterize(bytes(cmd.buf), canvas.shape[1], title_h) + alpha = overlay[:, :, 3:4].astype(np.float64) / 255.0 + canvas[:title_h, :, :3] = np.round( + overlay[:, :, :3] * alpha + canvas[:title_h, :, :3] * (1.0 - alpha) + ).astype(np.uint8) diff --git a/python/xy/pyplot/_mathtext.py b/python/xy/pyplot/_mathtext.py index 50d618c1..195020a1 100644 --- a/python/xy/pyplot/_mathtext.py +++ b/python/xy/pyplot/_mathtext.py @@ -73,12 +73,50 @@ "in": "∈", "percent": "%", "%": "%", - ",": " ", - ";": " ", - " ": " ", + # TeX ignores ordinary spaces in math mode. Explicit spacing commands + # survive through a sentinel until that whitespace has been removed. + ",": "\x01", + ";": "\x01", + " ": "\x01", "!": "", + # Matplotlib's named functions are upright roman glyph runs, not unknown + # TeX commands and not italic variables. + "arccos": "arccos", + "arcsin": "arcsin", + "arctan": "arctan", + "arg": "arg", + "cos": "cos", + "cosh": "cosh", + "cot": "cot", + "csc": "csc", + "deg": "deg", + "det": "det", + "dim": "dim", + "exp": "exp", + "gcd": "gcd", + "hom": "hom", + "ker": "ker", + "lg": "lg", + "lim": "lim", + "liminf": "liminf", + "limsup": "limsup", + "ln": "ln", + "log": "log", + "max": "max", + "min": "min", + "sec": "sec", + "sin": "sin", + "sinh": "sinh", + "sup": "sup", + "tan": "tan", } +_UPRIGHT_WORDS = frozenset( + value + for name, value in _COMMANDS.items() + if name.isalpha() and value.isascii() and value.isalpha() +) + # Wrappers whose braces disappear and whose contents pass through. _WRAPPERS = ("mathdefault", "mathrm", "mathit", "mathbf", "text", "textrm", "operatorname") @@ -130,7 +168,10 @@ def command(match: re.Match[str]) -> str: out = _COMMAND.sub(command, out) if "\x00" in out or "\\" in out: return None - return out.replace("{", "").replace("}", "") + # Unescaped spaces are insignificant in math mode. Match Matplotlib's + # Unicode minus while retaining deliberate ``\,``/``\;``/``\ `` gaps. + out = re.sub(r"\s+", "", out) + return out.replace("-", "−").replace("\x01", " ").replace("{", "").replace("}", "") def mathtext_to_unicode(text: str) -> str: @@ -148,3 +189,40 @@ def mathtext_to_unicode(text: str) -> str: last = match.end() pieces.append(text[last:]) return "".join(pieces) + + +def mathtext_italic_ranges(text: str) -> tuple[str, list[tuple[int, int]]]: + r"""Flatten mathtext and return output ranges that use math italics. + + Matplotlib defaults variables (including Greek letters) to italics while + named functions such as ``\cos`` and ``\exp`` remain upright. The + renderer-facing range list preserves that distinction without exposing a + full TeX layout engine. + """ + converted = mathtext_to_unicode(text) + if converted == text or "$" not in text: + return converted, [] + + ranges: list[tuple[int, int]] = [] + output_cursor = 0 + source_cursor = 0 + for match in _MATH_SPAN.finditer(text): + prefix = text[source_cursor : match.start()] + output_cursor += len(prefix) + body = _convert_math(match.group(1)) + if body is None: # guarded by ``converted == text`` above + return converted, [] + token_start: int | None = None + for index, character in enumerate(body + "\0"): + if character.isalpha(): + if token_start is None: + token_start = index + continue + if token_start is not None: + token = body[token_start:index] + if token not in _UPRIGHT_WORDS: + ranges.append((output_cursor + token_start, output_cursor + index)) + token_start = None + output_cursor += len(body) + source_cursor = match.end() + return converted, ranges diff --git a/python/xy/pyplot/_mplfig.py b/python/xy/pyplot/_mplfig.py index 262bd6af..0a5f183d 100644 --- a/python/xy/pyplot/_mplfig.py +++ b/python/xy/pyplot/_mplfig.py @@ -15,13 +15,49 @@ import numpy as np from ._artists import Text -from ._axes import Axes, _plain_text +from ._axes import _DEFAULT_AXES_RECT, Axes, _plain_text from ._colors import resolve_color from ._rc import rc_figsize_px, rcParams from ._transforms import CoordinateTransform from ._translate import check_unsupported, not_implemented +def _panel_chrome(ax: Axes, plot_w: int) -> tuple[float, float, float, float]: + """``(left, top, right, bottom)`` px of chrome around a free-form panel. + + One definition for the whole absolute-placement path: `_charts` sizes the + panel with it, `_panel_positions` places the panel with it, and + `Axes._frame_padding` pins the plot rect inside the panel with it. When + those three disagree the plot box drifts off its gridspec cell. + + The chrome includes the gutters the renderers reserve outside the padding — + the axes title, a top-side x axis (`matshow`), the secondary-y band — so the + panel is always large enough to hold them without moving the plot rect. The + title is the case matplotlib makes obvious: it draws above the axes without + changing its position. + """ + compact = plot_w + 54 < 520 + left, top = (46.0, 6.0) if compact else (62.0, 10.0) + right, bottom = (8.0, 36.0) if compact else (14.0, 42.0) + extra_top, extra_right, extra_bottom = ax._outside_padding(compact) + return left, top + extra_top, right + extra_right, bottom + extra_bottom + + +def _measured_left_gutter(ax: Axes, width: int, height: int) -> float: + """The left gutter `_svg.layout()` will reserve for `ax`'s y-axis text. + + Probes the real spec because the reservation is measured from the tick + labels the resolved range produces, which only exist after the payload is + built. The probe costs one extra payload build on the notebook display path; + the browser needs the number *before* the chart it renders is built, and a + second implementation of the measurement is the thing this must not become. + """ + from .. import _svg + + spec, _buffers = ax._build_chart(width, height).figure().build_payload_split() + return float(_svg.layout(spec)[3]["x"]) + + def _png_with_metadata(data: bytes, metadata: dict[Any, Any]) -> bytes: """Insert standards-compliant PNG text chunks before IEND.""" from xy import _png @@ -119,6 +155,10 @@ def add_subplot(self, *args: Any, **kwargs: Any) -> Axes: # Spans and custom spacing become explicit figure rectangles. # The spec is kept so subplots_adjust() can re-resolve them. ax = self.add_axes(spec.gridspec.cell_rect(spec.rows, spec.cols)) + # add_axes() models unrelated free-form panels as a 1×N row. + # A GridSpec-backed span still belongs to its original grid; + # retain that geometry for tight_layout/subplots_adjust. + self._nrows, self._ncols = spec.nrows, spec.ncols ax._subplot_spec = spec elif args and args != (1, 1, 1) and args != (111,): nrows, ncols, index = _parse_subplot_args(args) @@ -263,15 +303,18 @@ def add_gridspec(self, nrows: int = 1, ncols: int = 1, **kwargs: Any) -> "_GridS ) def _ensure_grid(self, nrows: int, ncols: int) -> None: - if ( - (nrows, ncols) != (self._nrows, self._ncols) - and self._axes - and any(ax._entries for ax in self._axes) - ): + reshaping = (nrows, ncols) != (self._nrows, self._ncols) + if reshaping and self._axes and any(ax._entries for ax in self._axes): raise ValueError("cannot reshape a figure that already has plotted axes") self._nrows, self._ncols = nrows, ncols + if reshaping: + for index, ax in enumerate(self._axes): + if ax._figure_rect is None: + ax._subplot_index = index while len(self._axes) < nrows * ncols: - self._axes.append(Axes(self)) + ax = Axes(self) + ax._subplot_index = len(self._axes) + self._axes.append(ax) def _axes_at(self, index: int) -> Axes: self._ensure_grid(self._nrows, self._ncols) @@ -409,6 +452,64 @@ def tight_layout(self, **kwargs: Any) -> None: "w_pad": w_pad, "rect": rect, } + # The native panels carry their own tick/title chrome, while the + # GridSpec rectangles describe plot boxes only. Reserve enough + # figure-edge and inter-panel room for that chrome so adjacent panels + # do not overlap. This is the same job Matplotlib's tight-layout + # engine performs from artist extents; the shim uses its deterministic + # renderer margins instead of a second text-layout engine. + if self._axes and not any( + ax._figure_rect is not None and ax._subplot_spec is None for ax in self._axes + ): + canvas_w, canvas_h = rc_figsize_px(self._figsize, self._dpi) + compact = canvas_w / max(1, self._ncols) < 520 + left_px, right_px = (46.0, 20.0) if compact else (62.0, 26.0) + bottom_px = 36.0 if compact else 42.0 + title_px = 26.0 if compact else 30.0 + top_px = max(20.0, (6.0 if compact else 10.0) + title_px) + has_title = any(ax._title for ax in self._axes) + horizontal_gap = 58.0 if compact else 76.0 + vertical_gap = (68.0 if compact else 82.0) if has_title else (44.0 if compact else 56.0) + # Explicit *_pad values are font-size multiples in Matplotlib. + point_px = float(rcParams["font.size"]) * float(self._dpi or 100.0) / 72.0 + base_pad = 1.08 if pad is None else float(pad) + if w_pad is not None: + horizontal_gap += (float(w_pad) - base_pad) * point_px + if h_pad is not None: + vertical_gap += (float(h_pad) - base_pad) * point_px + if pad is not None: + extra = (float(pad) - 1.08) * point_px + left_px += extra + right_px += extra + bottom_px += extra + top_px += extra + + frame = (0.0, 0.0, 1.0, 1.0) if rect is None else tuple(map(float, rect)) + if len(frame) != 4: + raise ValueError("tight_layout(rect=...) must be [left, bottom, right, top]") + frame_left, frame_bottom, frame_right, frame_top = frame + left = frame_left + max(0.0, left_px) / canvas_w + right = frame_right - max(0.0, right_px) / canvas_w + bottom = frame_bottom + max(0.0, bottom_px) / canvas_h + top = frame_top - max(0.0, top_px) / canvas_h + inner_w = max(1.0, (right - left) * canvas_w) + inner_h = max(1.0, (top - bottom) * canvas_h) + cell_w = max( + 1.0, + (inner_w - horizontal_gap * max(0, self._ncols - 1)) / max(1, self._ncols), + ) + cell_h = max( + 1.0, + (inner_h - vertical_gap * max(0, self._nrows - 1)) / max(1, self._nrows), + ) + self.subplots_adjust( + left=left, + right=right, + bottom=bottom, + top=top, + wspace=horizontal_gap / cell_w, + hspace=vertical_gap / cell_h, + ) self._invalidate() def subplots_adjust( @@ -442,12 +543,24 @@ def subplots_adjust( if merged["bottom"] >= merged["top"]: raise ValueError("bottom cannot be >= top") self._subplot_adjust.update(material) + grid = _GridSpec( + self, + self._nrows, + self._ncols, + width_ratios=self._width_ratios, + height_ratios=self._height_ratios, + ) for ax in self._axes: if ax._subplot_spec is not None: # Gridspec-derived rectangles track the moved SubplotParams # frame (matplotlib re-resolves subplot positions on draw). spec = ax._subplot_spec ax._figure_rect = spec.gridspec.cell_rect(spec.rows, spec.cols) + elif ax._subplot_index is not None: + # Matplotlib's subplots_adjust() restores a subplot whose + # position was set explicitly to its SubplotSpec cell. + row, col = divmod(ax._subplot_index, self._ncols) + ax._figure_rect = grid.cell_rect((row, row + 1), (col, col + 1)) ax._invalidate() self._invalidate() @@ -523,11 +636,35 @@ def colorbar(self, mappable: Any = None, cax: Any = None, ax: Any = None, **kwar cmap_obj = mappable.get_cmap() colormap = getattr(cmap_obj, "name", cmap_obj) try: - numeric = np.asarray(mapped_values, dtype=np.float64) - finite = numeric[np.isfinite(numeric)] + numeric = np.ma.asarray(mapped_values, dtype=np.float64) + finite = np.asarray(numeric.compressed(), dtype=np.float64) + finite = finite[np.isfinite(finite)] except (TypeError, ValueError): finite = np.asarray([], dtype=np.float64) explicit_domain = entry.get("domain", props.get("domain")) + orientation_arg = kwargs.pop("orientation", None) + location = kwargs.pop("location", None) + if location is not None: + location = str(location).lower() + if location not in {"right", "bottom"}: + raise not_implemented( + f"colorbar(location={location!r})", + "right or bottom colorbar placement", + ) + located_orientation = "vertical" if location == "right" else "horizontal" + if orientation_arg is not None and str(orientation_arg) != located_orientation: + raise ValueError("location and orientation select incompatible colorbar sides") + orientation_arg = located_orientation + orientation = str(orientation_arg or "vertical") + if orientation not in {"vertical", "horizontal"}: + raise ValueError("colorbar() orientation must be 'vertical' or 'horizontal'") + shrink = float(kwargs.pop("shrink", 1.0)) + if not np.isfinite(shrink) or not 0.0 < shrink <= 1.0: + raise ValueError("colorbar() shrink must be finite and in (0, 1]") + anchor_arg = kwargs.pop("anchor", (0.5, 0.5)) + anchor_values = np.asarray(anchor_arg, dtype=np.float64).reshape(-1) + if len(anchor_values) != 2 or not np.all(np.isfinite(anchor_values)): + raise ValueError("colorbar() anchor must be a finite (x, y) pair") options = { "colormap": colormap or "viridis", "domain": ( @@ -536,8 +673,12 @@ def colorbar(self, mappable: Any = None, cax: Any = None, ax: Any = None, **kwar else ([float(finite.min()), float(finite.max())] if finite.size else [0.0, 1.0]) ), "label": _plain_text(kwargs.pop("label", "")), - "orientation": str(kwargs.pop("orientation", "vertical")), + "orientation": orientation, } + if shrink != 1.0: + options["shrink"] = shrink + if not np.array_equal(anchor_values, [0.5, 0.5]): + options["anchor"] = [float(anchor_values[0]), float(anchor_values[1])] # When the mappable's value domain is not knowable at colorbar() time # (e.g. hexbin counts are binned inside the mark), defer to the compiled # figure's color domain at render time instead of the 0..1 placeholder. @@ -604,6 +745,14 @@ def set_ticks(self, ticks: Any, labels: Any = None, **kwargs: Any) -> None: self._options["ticks"] = [float(value) for value in np.asarray(ticks).reshape(-1)] self.ax._invalidate() + def minorticks_on(self) -> None: + self._options["minor_ticks"] = True + self.ax._invalidate() + + def minorticks_off(self) -> None: + self._options["minor_ticks"] = False + self.ax._invalidate() + return _Colorbar(axes, options) def figimage( @@ -673,18 +822,38 @@ def _effective_rects(self) -> Optional[list[tuple[float, float, float, float]]]: """ if not self._axes: return None - rects = [ax._figure_rect for ax in self._axes] - if any(rect is not None for rect in rects): - default = ( - _GridSpec(self, 1, 1, **self._subplot_adjust).cell_rect((0, 1), (0, 1)) - if self._subplot_adjust - else (0.125, 0.11, 0.775, 0.77) - ) - return [rect if rect is not None else default for rect in rects] - if not self._subplot_adjust and len(self._axes) <= 1: + if ( + all(ax._figure_rect is None for ax in self._axes) + and not self._subplot_adjust + and len(self._axes) <= 1 + ): + return None + return [self._axes_rect(ax) or _DEFAULT_AXES_RECT for ax in self._axes] + + def _axes_rect(self, ax: Axes) -> Optional[tuple[float, float, float, float]]: + """One axes' matplotlib rectangle (figure fractions), or None if foreign. + + The single resolver behind both `_effective_rects` (what the exporters + place) and `Axes.get_position` (what scripts read), so the reported box + and the rendered box cannot drift apart. + """ + if ax._figure_rect is not None: + return ax._figure_rect + if ax not in self._axes: return None - # A uniform grid (adjusted or default SubplotParams): every panel + if any(other._figure_rect is not None for other in self._axes): + # Free-form figure (add_axes/insets): matplotlib leaves a rect-less + # axes at the SubplotParams frame instead of dragging it onto the + # panel grid, which `add_axes` has already redefined as 1 x n. + if not self._subplot_adjust: + return _DEFAULT_AXES_RECT + return _GridSpec(self, 1, 1, **self._subplot_adjust).cell_rect((0, 1), (0, 1)) + # A uniform grid (adjusted or default SubplotParams): the panel # resolves to its gridspec cell rectangle under the frame and spacing. + index = ax._subplot_index + if index is None: + index = self._axes.index(ax) + row, col = divmod(index, self._ncols) grid = _GridSpec( self, self._nrows, @@ -693,13 +862,7 @@ def _effective_rects(self) -> Optional[list[tuple[float, float, float, float]]]: height_ratios=self._height_ratios, **self._subplot_adjust, ) - return [ - grid.cell_rect( - (index // self._ncols, index // self._ncols + 1), - (index % self._ncols, index % self._ncols + 1), - ) - for index in range(len(self._axes)) - ] + return grid.cell_rect((row, row + 1), (col, col + 1)) def _grid_cell_sizes(self) -> tuple[list[int], list[int]]: """Per-column widths and per-row heights of the CSS-grid panel layout. @@ -730,12 +893,15 @@ def _charts(self) -> list[Any]: # figure buffer, matching Matplotlib add_axes semantics — # including the axes title, which matplotlib draws above the # axes without moving its position. - compact = plot_w + 54 < 520 - margin_w, margin_h = (54, 42) if compact else (76, 52) - if ax._title: - margin_h += 26 if compact else 30 + left, top, right, bottom = _panel_chrome(ax, plot_w) ax._absolute_plot_ratio = plot_w / plot_h - charts.append(ax._build_chart(plot_w + margin_w, plot_h + margin_h)) + # Pin the plot rect inside the panel: the exporters place the + # panel assuming its plot box sits at exactly this inset, so + # the renderers must not pick their own label-aware margins. + ax._plot_box_px = (left, top, plot_w, plot_h) + charts.append( + ax._build_chart(round(plot_w + left + right), round(plot_h + top + bottom)) + ) else: widths, heights = self._grid_cell_sizes() charts = [ @@ -806,19 +972,16 @@ def _panel_positions( """ positions = [] for ax, rect in zip(self._axes, rects, strict=True): - compact = round(canvas_size[0] * rect[2]) + 54 < 520 - left, bottom = (46, 36) if compact else (62, 42) - width, height = (54, 42) if compact else (76, 52) - if ax._title: - # The panel was built taller for its title (`_charts`); grow - # the placement upward so the plot box stays on the rect. - height += 26 if compact else 30 + # The same chrome `_charts` built the panel with — including the + # axes title, which grows the panel upward so the plot box stays + # on the rect. + left, top, right, bottom = _panel_chrome(ax, max(1, round(canvas_size[0] * rect[2]))) positions.append( ( rect[0] - left / canvas_size[0], rect[1] - bottom / canvas_size[1], - rect[2] + width / canvas_size[0], - rect[3] + height / canvas_size[1], + rect[2] + (left + right) / canvas_size[0], + rect[3] + (top + bottom) / canvas_size[1], ) ) return positions @@ -950,7 +1113,7 @@ def _to_png(self, *, bbox_tight: bool = False, pad_inches: float = 0.1) -> bytes canvas_size=canvas_size if positions is not None else None, facecolor=self._facecolor, bbox_tight=bbox_tight, - pad_pixels=max(0, round(pad_inches * float(self._dpi or 100.0) * 2.0)), + pad_pixels=max(0, round(pad_inches * float(self._dpi or 100.0))), ) def _to_html(self) -> str: @@ -1023,6 +1186,23 @@ def _to_notebook_html(self) -> tuple[str, int, int]: ) tight_width = max(120, min(tight_width, round(aspect_width))) ax._padding = notebook_padding + # Matplotlib's inline bbox is derived from the ink, so the y + # title can never land on the tick labels there — but pinning a + # padding also pins the browser's gutter, and 41 px does not + # hold this shim's 13.89 px tick labels under a rotated title. + # Ask the shared static-layout path what the axis text measures + # (`_svg.layout` is the single authority for that reservation, + # so browser, SVG, and PNG stay on one number) and, when the pin + # is short, widen the *canvas* by the shortfall so the plot box + # keeps Matplotlib's 0.775 fraction instead of losing width. + measured_left = _measured_left_gutter(ax, tight_width, tight_height) + if measured_left > notebook_padding[3]: + tight_width = max( + 120, tight_width + int(round(measured_left - notebook_padding[3])) + ) + notebook_padding[3] = measured_left + ax._chart = None + ax._padding = notebook_padding doc = ax._build_chart(tight_width, tight_height).to_html() finally: ax._chart = old_chart diff --git a/python/xy/pyplot/_plot_types.py b/python/xy/pyplot/_plot_types.py index 5fd23ef2..777c91ad 100644 --- a/python/xy/pyplot/_plot_types.py +++ b/python/xy/pyplot/_plot_types.py @@ -35,9 +35,10 @@ Text, Wedge, ) -from ._colors import PROP_CYCLE, resolve_cmap, resolve_color +from ._colors import PROP_CYCLE, resolve_cmap, resolve_color, resolve_rgba from ._fmt import parse_fmt -from ._rc import rcParams +from ._mathtext import mathtext_to_unicode +from ._rc import rc_figsize_px, rcParams from ._translate import ( LINESTYLE_TO_DASH, MARKER_TO_SYMBOL, @@ -126,6 +127,14 @@ def _textprops_kwargs(textprops: Any, where: str) -> dict[str, Any]: fontsize = source.pop("fontsize", source.pop("size", None)) ha = source.pop("ha", source.pop("horizontalalignment", None)) va = source.pop("va", source.pop("verticalalignment", None)) + weight = source.pop("fontweight", source.pop("weight", None)) + family = source.pop("fontfamily", source.pop("family", None)) + fontstyle = source.pop("fontstyle", source.pop("style", None)) + rotation = source.pop("rotation", None) + # Axes.pie_label creates unclipped labels before applying textprops. + # Accepting the matching default keeps that implementation detail from + # becoming a gallery incompatibility while non-default clipping stays loud. + _reject_non_default(where, "clip_on", source.pop("clip_on", None), False) check_unsupported(source, where) out: dict[str, Any] = {} if color is not None: @@ -134,14 +143,51 @@ def _textprops_kwargs(textprops: Any, where: str) -> dict[str, Any]: out["anchor"] = {"left": "start", "center": "middle", "right": "end"}.get(str(ha), "start") style: dict[str, Any] = {} if fontsize is not None: - style["font_size"] = float(fontsize) + style["font_size"] = _text_font_size_points(fontsize) if va is not None: style["vertical_align"] = str(va) + if weight is not None: + style["font_weight"] = str(weight) + if family is not None: + style["font_family"] = str(family) + if fontstyle is not None: + style["font_style"] = _validated_font_style(fontstyle) + if rotation is not None: + style["rotation"] = 90.0 if rotation == "vertical" else float(rotation) if style: out["style"] = style return out +def _text_font_size_points(value: Any) -> float: + """Resolve Matplotlib's named font sizes against the current base size.""" + relative = { + "xx-small": 0.6, + "x-small": 0.75, + "small": 0.85, + "medium": 1.0, + "large": 1.2, + "x-large": 1.45, + "xx-large": 1.75, + } + if isinstance(value, str): + try: + return float(rcParams["font.size"]) * relative[value] + except KeyError as exc: + raise ValueError(f"unsupported relative font size {value!r}") from exc + result = float(value) + if result <= 0: + raise ValueError("font size must be positive") + return result + + +def _validated_font_style(value: Any) -> str: + result = str(value) + if result not in {"normal", "italic", "oblique"}: + raise ValueError("font style must be 'normal', 'italic', or 'oblique'") + return result + + def _bilinear_grid_sample( x_coords: np.ndarray, y_coords: np.ndarray, grid: np.ndarray, px: Any, py: Any ) -> np.ndarray: @@ -170,16 +216,49 @@ def _integrate_streamlines( seeds: np.ndarray, direction: str, max_steps: int, + max_length: float, + min_length: float = 0.1, + broken_streamlines: bool = True, + density: float | tuple[float, float] = 1.0, + step_scale: float = 1.0, + error_scale: float = 1.0, + skip_occupied_seeds: bool = True, ) -> list[np.ndarray]: - """Fixed-step field-line integration matching the native kernel's scheme.""" - step = 0.35 * min(float(np.min(np.diff(x_coords))), float(np.min(np.diff(y_coords)))) + """Integrate field lines with an adaptive second-order Heun step. + + Matplotlib exposes multipliers for both its maximum integration step and + accepted local error. Keeping those controls here (rather than silently + accepting them at the public API) also gives explicit seeds and unbroken + streamlines the same accuracy contract. + """ + x_span = max(float(np.ptp(x_coords)), np.finfo(float).eps) + y_span = max(float(np.ptp(y_coords)), np.finfo(float).eps) + density_x, density_y = np.broadcast_to(np.asarray(density, dtype=np.float64), 2) + mask_width = max(1, int(30 * density_x)) + mask_height = max(1, int(30 * density_y)) + max_step = min(x_span / mask_width, y_span / mask_height) * step_scale + max_error = 0.003 * error_scale + occupied: set[tuple[int, int]] = set() + + def mask_cell(px: float, py: float) -> tuple[int, int]: + mx = int(np.clip(round((px - x_coords[0]) / x_span * (mask_width - 1)), 0, mask_width - 1)) + my = int( + np.clip(round((py - y_coords[0]) / y_span * (mask_height - 1)), 0, mask_height - 1) + ) + return mx, my + signs = {"forward": (1.0,), "backward": (-1.0,), "both": (-1.0, 1.0)}[direction] lines: list[np.ndarray] = [] for seed_x, seed_y in seeds: + if skip_occupied_seeds and mask_cell(float(seed_x), float(seed_y)) in occupied: + continue + trajectory_cells: set[tuple[int, int]] = set() branches: list[list[tuple[float, float]]] = [] for sign in signs: px, py = float(seed_x), float(seed_y) points = [(px, py)] + step = max_step + path_length = 0.0 for _ in range(max_steps): su = float(_bilinear_grid_sample(x_coords, y_coords, u, px, py)) sv = float(_bilinear_grid_sample(x_coords, y_coords, v, px, py)) @@ -188,16 +267,58 @@ def _integrate_streamlines( speed = float(np.hypot(su, sv)) if speed <= np.finfo(float).eps: break - nx = px + sign * step * su / speed - ny = py + sign * step * sv / speed + k1x, k1y = sign * su / speed, sign * sv / speed + trial_x, trial_y = px + step * k1x, py + step * k1y + tu = float(_bilinear_grid_sample(x_coords, y_coords, u, trial_x, trial_y)) + tv = float(_bilinear_grid_sample(x_coords, y_coords, v, trial_x, trial_y)) + trial_speed = float(np.hypot(tu, tv)) + if not (np.isfinite(tu) and np.isfinite(tv)) or trial_speed <= np.finfo(float).eps: + break + k2x, k2y = sign * tu / trial_speed, sign * tv / trial_speed + nx = px + 0.5 * step * (k1x + k2x) + ny = py + 0.5 * step * (k1y + k2y) + error = float( + np.hypot( + (nx - trial_x) / x_span, + (ny - trial_y) / y_span, + ) + ) + if error >= max_error: + step = max( + max_step * 1e-4, + min(max_step, 0.85 * step * np.sqrt(max_error / error)), + ) + continue if not (x_coords[0] <= nx <= x_coords[-1] and y_coords[0] <= ny <= y_coords[-1]): break + cell = mask_cell(nx, ny) + if broken_streamlines and cell in occupied and cell not in trajectory_cells: + break + path_length += float(np.hypot((nx - px) / x_span, (ny - py) / y_span)) px, py = nx, ny points.append((px, py)) + trajectory_cells.add(cell) + if path_length >= max_length: + break + if error == 0.0: + step = max_step + else: + step = min(max_step, 0.85 * step * np.sqrt(max_error / error)) branches.append(points) combined = branches[0][::-1] + branches[1][1:] if len(branches) == 2 else branches[0] - if len(combined) >= 2: - lines.append(np.asarray(combined, dtype=np.float64)) + combined_array = np.asarray(combined, dtype=np.float64) + if len(combined_array) >= 2: + length = float( + np.hypot( + np.diff(combined_array[:, 0]) / x_span, + np.diff(combined_array[:, 1]) / y_span, + ).sum() + ) + else: + length = 0.0 + if length >= min_length: + lines.append(combined_array) + occupied.update(trajectory_cells) return lines @@ -277,6 +398,18 @@ def _limit_error(error: Any, lower_limits: Any, upper_limits: Any, size: int) -> return np.vstack((low, high)) +def _error_sides(error: Any, size: int) -> tuple[np.ndarray, np.ndarray]: + """Return broadcast lower and upper error magnitudes.""" + raw = np.asarray(error, dtype=np.float64) + if raw.ndim >= 2 and raw.shape[0] == 2: + return ( + np.broadcast_to(raw[0], (size,)), + np.broadcast_to(raw[1], (size,)), + ) + values = np.broadcast_to(raw, (size,)) + return values, values + + def _plain_label(value: Any) -> str: text = str(value).replace("$", "") for source, target in { @@ -356,6 +489,41 @@ def centers(values: np.ndarray, size: int, name: str) -> Optional[np.ndarray]: return x_centers, y_centers +def _gouraud_rect_axes( + x: Any, y: Any, shape: tuple[int, int] +) -> Optional[tuple[np.ndarray, np.ndarray]]: + """Return same-shape, uniform rectilinear vertices for Gouraud shading.""" + rows, cols = shape + xa, ya = np.asarray(x, dtype=np.float64), np.asarray(y, dtype=np.float64) + if xa.ndim == ya.ndim == 2: + if xa.shape != shape or ya.shape != shape: + raise ValueError("pcolormesh Gouraud X, Y, and C must have matching shapes") + if not np.allclose(xa, xa[:1, :], equal_nan=True) or not np.allclose( + ya, ya[:, :1], equal_nan=True + ): + return None + xa, ya = xa[0], ya[:, 0] + elif xa.shape != (cols,) or ya.shape != (rows,): + raise ValueError("pcolormesh Gouraud X, Y, and C must have matching shapes") + if (len(xa) > 2 and not np.allclose(np.diff(xa), np.diff(xa)[0])) or ( + len(ya) > 2 and not np.allclose(np.diff(ya), np.diff(ya)[0]) + ): + return None + return xa, ya + + +def _bilinear_grid(grid: np.ndarray, width: int, height: int) -> np.ndarray: + """Small NumPy-only bilinear expansion used by regular Gouraud meshes.""" + source_y = np.linspace(0.0, 1.0, grid.shape[0]) + source_x = np.linspace(0.0, 1.0, grid.shape[1]) + target_y = np.linspace(0.0, 1.0, height) + target_x = np.linspace(0.0, 1.0, width) + horizontal = np.vstack([np.interp(target_x, source_x, row) for row in grid]) + return np.vstack( + [np.interp(target_y, source_y, horizontal[:, column]) for column in range(width)] + ).T + + def _regular_mesh_axes(x: Any, y: Any, shape: tuple[int, int]) -> tuple[np.ndarray, np.ndarray]: """Return axes for a rectilinear grid, including non-uniform spacing.""" rows, cols = shape @@ -847,6 +1015,7 @@ def fill(self, *args: Any, data: TableLike = None, **kwargs: Any) -> list[PolyCo "color": resolve_color(chosen) if chosen is not None else self._next_color(), "name": None if label is None else str(label), "opacity": 1.0 if alpha is None else float(alpha), + "_joined_fill": True, } entry = self._add( "@mark", @@ -946,23 +1115,49 @@ def axline( """ if (xy2 is None) == (slope is None): raise TypeError("axline() requires exactly one of xy2 or slope") - if xy2 is None: - xy2 = (float(xy1[0]) + 1.0, float(xy1[1]) + float(slope)) + if slope is not None and any( + self._scale_specs[axis]["name"] != "linear" for axis in ("x", "y") + ): + raise TypeError("'slope' cannot be used with non-linear scales") transform = kwargs.pop("transform", None) - if transform is not None: - tx, ty = self._transform_points([xy1[0], xy2[0]], [xy1[1], xy2[1]], transform) - xy1, xy2 = (float(tx[0]), float(ty[0])), (float(tx[1]), float(ty[1])) + transform_space = None + if transform is self.transAxes: + # Resolve against the final view at materialization time: callers + # commonly set limits after adding axlines, and Matplotlib applies + # the transform to the point(s) but never to the data-space slope. + transform_space = "axes_fraction" + elif transform is not None: + points = [xy1] if xy2 is None else [xy1, xy2] + tx, ty = self._transform_points( + [point[0] for point in points], + [point[1] for point in points], + transform, + ) + points = [(float(x), float(y)) for x, y in zip(tx, ty, strict=True)] + xy1, xy2 = points[0], None if xy2 is None else points[1] props = _line_props(self, kwargs) check_unsupported(kwargs, "axline()") + width = props.get("width", rcParams["lines.linewidth"]) + if props.get("dash") is not None: + props["dash"] = self._mpl_dash(props["dash"], width) entry = self._add( - "@mark", + "@axline", { - "factory": "segments", - "args": ([xy1[0]], [xy1[1]], [xy2[0]], [xy2[1]]), + "xy1": (float(xy1[0]), float(xy1[1])), + "xy2": (None if xy2 is None else (float(xy2[0]), float(xy2[1]))), + "slope": None if slope is None else float(slope), + "transform_space": transform_space, "kwargs": { "color": props.get("color"), "opacity": props.get("opacity", 1.0), - "width": props.get("width", 1.2), + "width": width, + "name": props.get("name"), + **({"dash": props["dash"]} if props.get("dash") is not None else {}), + **( + {"_gapcolor": props["_gapcolor"]} + if props.get("_gapcolor") is not None + else {} + ), }, }, ) @@ -1191,6 +1386,13 @@ def bar_label( if kwargs.pop("fontproperties", None) is not None: raise not_implemented("bar_label(fontproperties=...)", alternative="fontsize=") check_unsupported(kwargs, "bar_label()") + if label_type == "edge": + value_axis = "y" if container.orientation == "vertical" else "x" + # Matplotlib's Annotation does not contribute its text bbox to + # dataLim. Its default 5% margin therefore leaves a padded 10 pt + # bar label on (or fractionally beyond) the top spine. Reserve a + # small label-aware default while preserving explicit margins(). + self._reserve_annotation_margin(value_axis, 0.075) result: list[Text] = [] for index, value in enumerate(values): if raw_labels[index] is not None: @@ -1209,26 +1411,35 @@ def bar_label( if container.orientation == "vertical" else (coordinate, centers[index]) ) - pixel_padding = float(padding) * (4.0 / 3.0) + pixel_padding = float(padding) * self._point_scale() + positive = value >= 0 if container.orientation == "vertical": anchor = "middle" dx = 0.0 - dy = 4.0 if label_type == "center" else -(4.0 + pixel_padding) + dy = pixel_padding * (1.0 if positive else -1.0) + # SVG/browser y grows downward, so matplotlib's positive + # point offset is an upward (negative) screen-space offset. + dy *= -1.0 + vertical_align = ( + "center" if label_type == "center" else ("bottom" if positive else "top") + ) elif label_type == "center": - anchor, dx, dy = "middle", 0.0, 4.0 + anchor, dx, dy = "middle", pixel_padding * (1.0 if positive else -1.0), 0.0 + vertical_align = "center" else: - positive = value >= 0 anchor = "start" if positive else "end" - dx = (4.0 + pixel_padding) * (1.0 if positive else -1.0) - dy = 4.0 + dx = pixel_padding * (1.0 if positive else -1.0) + dy = 0.0 + vertical_align = "center" text_kwargs: dict[str, Any] = { "color": resolve_color(color) if color is not None else None, "anchor": anchor, "dx": dx, "dy": dy, + "style": {"vertical_align": vertical_align}, } if fontsize is not None: - text_kwargs["style"] = {"font_size": float(fontsize)} + text_kwargs["style"]["font_size"] = float(fontsize) entry = self._add("@text", {"args": (x, y, label), "kwargs": text_kwargs}) result.append(Text(self, entry)) return result @@ -1420,7 +1631,14 @@ def specgram( check_unsupported(kwargs, "specgram()") mark_kwargs: dict[str, Any] = { "x": time, - "y": frequency, + # Matplotlib draws the spectrogram through imshow with the + # frequency *endpoints* as its extent, not as cell centers. Pick + # centers whose reconstructed cell edges land on those endpoints. + "y": np.linspace( + frequency[0] + (frequency[-1] - frequency[0]) / (2 * len(frequency)), + frequency[-1] - (frequency[-1] - frequency[0]) / (2 * len(frequency)), + len(frequency), + ), "colormap": resolve_cmap(cmap) if cmap is not None else "viridis", "opacity": 1.0 if alpha is None else float(alpha), } @@ -1501,9 +1719,7 @@ def stem( Call as ``stem(y)`` or ``stem(x, y)``. ``linefmt``/``markerfmt`` are ``plot``-style fmt strings for the stems and heads, ``bottom`` moves - the baseline, and ``orientation`` may be ``"horizontal"``. Only the - default ``basefmt`` (``"C3-"``) is honored — the shim renders no - baseline rule. + the baseline, and ``orientation`` may be ``"horizontal"``. """ if len(args) == 1: y = _from_data(args[0], data) @@ -1519,42 +1735,55 @@ def stem( color = resolve_color(color_spec) if color_spec else None dash_pattern = _dash_segment_pattern("stem", linestyle) symbol = "circle" + marker_color = None if markerfmt: - marker_color, _linestyle, marker = parse_fmt(str(markerfmt)) - color = color or (resolve_color(marker_color) if marker_color else None) + marker_color_spec, _linestyle, marker = parse_fmt(str(markerfmt)) + marker_color = resolve_color(marker_color_spec) if marker_color_spec else None from ._translate import MARKER_TO_SYMBOL symbol = MARKER_TO_SYMBOL.get(marker or "o", "circle") - # The shim renders no baseline rule, so only the default basefmt passes. - _reject_non_default("stem", "basefmt", basefmt, "C3-") chosen = color or self._next_color() + if orientation not in ("vertical", "horizontal"): + raise ValueError("stem orientation must be 'vertical' or 'horizontal'") + + xv = np.asarray(x, dtype=np.float64) + yv = np.asarray(y, dtype=np.float64) + if xv.ndim != 1 or yv.ndim != 1 or xv.shape != yv.shape: + raise ValueError("stem x and y must be equally sized 1-D arrays") + base = np.full_like(xv, float(bottom)) + if orientation == "vertical": + segments = (xv, base, xv, yv) + marker_x, marker_y = xv, yv + baseline_x = np.asarray([xv.min(), xv.max()]) if xv.size else np.asarray([]) + baseline_y = np.full(2 if xv.size else 0, float(bottom)) + else: + segments = (base, xv, yv, xv) + marker_x, marker_y = yv, xv + baseline_x = np.full(2 if xv.size else 0, float(bottom)) + baseline_y = np.asarray([xv.min(), xv.max()]) if xv.size else np.asarray([]) + if dash_pattern is not None: + segments = _dashed_segments(*segments, dash_pattern) + if orientation == "vertical" and dash_pattern is None: - entry = self._add( + # Retain the compact native stem primitive (and its public trace + # kind), but render markers separately so the returned markerline + # can be styled independently like Matplotlib's Line2D. + stem_entry = self._add( "@mark", { "factory": "stem", - "args": (x, y), + "args": (xv, yv), "kwargs": { "base": bottom, + "marker": False, "name": str(label) if label is not None else None, "color": chosen, - "symbol": symbol, + "width": 1.2, }, }, ) - elif orientation in ("vertical", "horizontal"): - xv = np.asarray(x, dtype=np.float64) - yv = np.asarray(y, dtype=np.float64) - base = np.full_like(xv, float(bottom)) - if orientation == "vertical": - segments = (xv, base, xv, yv) - marker_x, marker_y = xv, yv - else: - segments = (base, xv, yv, xv) - marker_x, marker_y = yv, xv - if dash_pattern is not None: - segments = _dashed_segments(*segments, dash_pattern) - entry = self._add( + else: + stem_entry = self._add( "@mark", { "factory": "segments", @@ -1566,17 +1795,47 @@ def stem( }, }, ) - self._add( - "scatter", - { - "x": marker_x, - "y": marker_y, - "kwargs": {"color": chosen, "symbol": symbol, "size": 5.0}, + edge_width = float(rcParams["lines.markeredgewidth"]) * self._point_scale() + marker_size = float(rcParams["lines.markersize"]) * self._point_scale() + edge_width + marker_entry = self._add( + "scatter", + { + "x": marker_x, + "y": marker_y, + "kwargs": { + "color": marker_color or chosen, + "stroke": marker_color or chosen, + "stroke_width": edge_width, + "symbol": symbol, + "size": marker_size, + "opacity": 1.0, }, - ) - else: - raise ValueError("stem orientation must be 'vertical' or 'horizontal'") - return StemContainer(Artist(self, entry)) + }, + ) + + base_color, base_linestyle, _base_marker = parse_fmt(str(basefmt or "C3-")) + base_dash = _dash_segment_pattern("stem", base_linestyle) + baseline_entry = self._add( + "line", + { + "x": baseline_x, + "y": baseline_y, + "kwargs": { + "color": resolve_color(base_color or "C3"), + # The axes spine is painted after marks. Matplotlib's + # baseline remains visible when it coincides with that + # spine, so give the colored rule enough width to remain + # visible on either side of the 1 px frame. + "width": 1.5, + **({"dash": list(base_dash)} if base_dash is not None else {}), + }, + }, + ) + return StemContainer( + Line2D(self, marker_entry), + Artist(self, stem_entry), + Line2D(self, baseline_entry), + ) def stairs( self, @@ -1641,7 +1900,9 @@ def stairs( entry = entry or item assert entry is not None if hatch: - self._stairs_hatch(vals, edge_values, base_values, orientation, props) + self._stairs_hatch( + vals, edge_values, base_values, orientation, props, hatch=str(hatch) + ) return StepPatch(self, entry) if orientation == "horizontal": x0 = np.concatenate((vals, vals[:-1])) @@ -1668,7 +1929,9 @@ def stairs( base_values = np.broadcast_to( np.asarray(0.0 if baseline is None else baseline, dtype=np.float64), vals.shape ) - self._stairs_hatch(vals, edge_values, base_values, orientation, props) + self._stairs_hatch( + vals, edge_values, base_values, orientation, props, hatch=str(hatch) + ) return StepPatch(self, entry) entry = self._add( "@mark", @@ -1689,41 +1952,134 @@ def _stairs_hatch( bases: np.ndarray, orientation: str, props: dict[str, Any], + *, + hatch: str = "/", + right_edges: np.ndarray | None = None, ) -> None: - """Approximate Matplotlib slash hatching with clipped bin-local strokes.""" + """Approximate Matplotlib hatch families with bin-local geometry.""" x0: list[float] = [] y0: list[float] = [] x1: list[float] = [] y1: list[float] = [] - for value, base, edge0, edge1 in zip(values, bases, edges[:-1], edges[1:], strict=True): + dot_x: list[float] = [] + dot_y: list[float] = [] + ring_x: list[float] = [] + ring_y: list[float] = [] + left_edges = np.asarray(edges, dtype=np.float64) + if right_edges is None: + right_values = left_edges[1:] + left_edges = left_edges[:-1] + else: + right_values = np.asarray(right_edges, dtype=np.float64) + if not (len(values) == len(bases) == len(left_edges) == len(right_values)): + raise ValueError("hatch geometry must have one rectangle per value") + pattern = set(hatch) + density = max(1, min(3, max((hatch.count(char) for char in pattern), default=1))) + line_count = 4 + density * 3 + + for value, base, edge0, edge1 in zip(values, bases, left_edges, right_values, strict=True): if orientation == "vertical": rx0, rx1 = edge0, edge1 ry0, ry1 = sorted((base, value)) else: rx0, rx1 = sorted((base, value)) ry0, ry1 = edge0, edge1 - for offset in np.linspace(-0.75, 0.75, 7): - u0, u1 = max(0.0, -offset), min(1.0, 1.0 - offset) - if u1 <= u0: - continue - v0, v1 = u0 + offset, u1 + offset - x0.append(float(rx0 + u0 * (rx1 - rx0))) - y0.append(float(ry0 + v0 * (ry1 - ry0))) - x1.append(float(rx0 + u1 * (rx1 - rx0))) - y1.append(float(ry0 + v1 * (ry1 - ry0))) - self._add( - "@mark", - { - "factory": "segments", - "args": (x0, y0, x1, y1), - "kwargs": { - "color": props.get("color"), - "width": 0.8, - "opacity": props.get("opacity", 1.0), - "name": None, + + def segment( + u0: float, + v0: float, + u1: float, + v1: float, + *, + _rx0: float = float(rx0), + _rx1: float = float(rx1), + _ry0: float = float(ry0), + _ry1: float = float(ry1), + ) -> None: + x0.append(_rx0 + u0 * (_rx1 - _rx0)) + y0.append(_ry0 + v0 * (_ry1 - _ry0)) + x1.append(_rx0 + u1 * (_rx1 - _rx0)) + y1.append(_ry0 + v1 * (_ry1 - _ry0)) + + def diagonals(reverse: bool) -> None: + for offset in np.linspace(-0.85, 0.85, line_count): + u0, u1 = max(0.0, -offset), min(1.0, 1.0 - offset) + if u1 <= u0: + continue + v0, v1 = u0 + offset, u1 + offset + if reverse: + v0, v1 = 1.0 - v0, 1.0 - v1 + segment(u0, v0, u1, v1) + + if "/" in pattern or "x" in pattern or "*" in pattern: + diagonals(False) + if "\\" in pattern or "x" in pattern or "*" in pattern: + diagonals(True) + if "|" in pattern or "+" in pattern or "*" in pattern: + for position in np.linspace(0.1, 0.9, line_count): + segment(float(position), 0.0, float(position), 1.0) + if "-" in pattern or "+" in pattern or "*" in pattern: + for position in np.linspace(0.1, 0.9, line_count): + segment(0.0, float(position), 1.0, float(position)) + if "." in pattern: + grid = np.linspace(0.12, 0.88, 3 + density) + for u in grid: + for v in grid: + dot_x.append(float(rx0 + u * (rx1 - rx0))) + dot_y.append(float(ry0 + v * (ry1 - ry0))) + if "o" in pattern or "O" in pattern: + grid = np.linspace(0.14, 0.86, 3 + density) + for u in grid: + for v in grid: + ring_x.append(float(rx0 + u * (rx1 - rx0))) + ring_y.append(float(ry0 + v * (ry1 - ry0))) + + color = props.get("color") + opacity = props.get("opacity", 1.0) + if x0: + self._add( + "@mark", + { + "factory": "segments", + "args": (x0, y0, x1, y1), + "kwargs": { + "color": color, + "width": 0.8, + "opacity": opacity, + "name": None, + }, }, - }, - ) + ) + if dot_x: + self._add( + "scatter", + { + "x": dot_x, + "y": dot_y, + "kwargs": { + "color": color, + "size": 2.0, + "symbol": "circle", + "opacity": opacity, + }, + }, + ) + if ring_x: + self._add( + "scatter", + { + "x": ring_x, + "y": ring_y, + "kwargs": { + "color": props.get("facecolor", "transparent"), + "stroke": color, + "stroke_width": 0.8, + "size": 13.0 if "O" in pattern else 10.0, + "symbol": "circle", + "opacity": opacity, + }, + }, + ) def ecdf( self, @@ -1771,7 +2127,13 @@ def ecdf( else: raise ValueError("ecdf orientation must be 'vertical' or 'horizontal'") entry = self._add( - "@mark", {"factory": "step", "args": args, "kwargs": {"where": "post", **props}} + "@mark", + { + "factory": "step", + "args": args, + "kwargs": {"where": "post", **props}, + "_mpl_sticky_edges": {"y" if orientation == "vertical" else "x": (0.0, 1.0)}, + }, ) return Artist(self, entry) @@ -1851,6 +2213,17 @@ def boxplot( ) if not advanced: color = self._next_color() + if positions is None: + if ( + isinstance(values, (list, tuple)) + and values + and all(np.ndim(value) == 1 for value in values) + ): + count = len(values) + else: + array = np.asarray(values) + count = array.shape[1] if array.ndim == 2 else 1 + positions = np.arange(1, count + 1, dtype=np.float64) entry = self._add( "@mark", { @@ -2201,9 +2574,38 @@ def subset_limit(flag: Any) -> Any: lolims, uplims = subset_limit(lolims), subset_limit(uplims) xlolims, xuplims = subset_limit(xlolims), subset_limit(xuplims) - yerr = _limit_error(yerr, lolims, uplims, len(np.asarray(y))) - xerr = _limit_error(xerr, xlolims, xuplims, len(np.asarray(x))) + x_values = np.asarray(x) + y_values = np.asarray(y) + limit_markers: list[tuple[np.ndarray, np.ndarray, str]] = [] + if yerr is not None: + lower, upper = _error_sides(yerr, len(y_values)) + lower_flags = np.broadcast_to(np.asarray(lolims, dtype=bool), y_values.shape) + upper_flags = np.broadcast_to(np.asarray(uplims, dtype=bool), y_values.shape) + if lower_flags.any(): + limit_markers.append( + (x_values[lower_flags], y_values[lower_flags] + upper[lower_flags], "^") + ) + if upper_flags.any(): + limit_markers.append( + (x_values[upper_flags], y_values[upper_flags] - lower[upper_flags], "v") + ) + if xerr is not None: + lower, upper = _error_sides(xerr, len(x_values)) + lower_flags = np.broadcast_to(np.asarray(xlolims, dtype=bool), x_values.shape) + upper_flags = np.broadcast_to(np.asarray(xuplims, dtype=bool), x_values.shape) + if lower_flags.any(): + limit_markers.append( + (x_values[lower_flags] + upper[lower_flags], y_values[lower_flags], ">") + ) + if upper_flags.any(): + limit_markers.append( + (x_values[upper_flags] - lower[upper_flags], y_values[upper_flags], "<") + ) + yerr = _limit_error(yerr, lolims, uplims, len(y_values)) + xerr = _limit_error(xerr, xlolims, xuplims, len(x_values)) base = line_kwargs(kwargs) + marker = kwargs.pop("marker", None) + markersize = kwargs.pop("markersize", kwargs.pop("ms", None)) check_unsupported(kwargs, "errorbar()") # When ecolor is omitted, the bars inherit the resolved data-series # color, exactly as matplotlib does: an explicit color kwarg wins, then @@ -2223,6 +2625,10 @@ def subset_limit(flag: Any) -> Any: if line_color is None: line_color = self._next_color() color = line_color + resolved_capsize = float(rcParams["errorbar.capsize"] if capsize is None else capsize) + errorbar_width = float( + elinewidth if elinewidth is not None else base.get("width", rcParams["lines.linewidth"]) + ) entry = self._add( "@mark", { @@ -2233,12 +2639,23 @@ def subset_limit(flag: Any) -> Any: "xerr": xerr, "name": base.get("name"), "color": color, - "width": float(elinewidth or base.get("width", 1.2)), - "cap_size": None if capsize is None else float(capsize), + "width": errorbar_width, + "cap_size": resolved_capsize, "opacity": base.get("opacity", 1.0), }, }, ) + marker_area = float(max(float(rcParams["lines.markersize"]), 2.0 * resolved_capsize) ** 2) + for marker_x, marker_y, marker_symbol in limit_markers: + self.scatter( + marker_x, + marker_y, + s=marker_area, + c=color, + marker=marker_symbol, + edgecolors=color, + linewidths=0.0, + ) data_line: Optional[Line2D] = None if fmt.lower() != "none": line_kwargs_for_plot: dict[str, Any] = {} @@ -2254,6 +2671,14 @@ def subset_limit(flag: Any) -> Any: line_kwargs_for_plot["alpha"] = base["opacity"] if "name" in base: line_kwargs_for_plot["label"] = base["name"] + if "linestyle" in base: + line_kwargs_for_plot["linestyle"] = base["linestyle"] + if "dash" in base: + line_kwargs_for_plot["dashes"] = base["dash"] + if marker is not None: + line_kwargs_for_plot["marker"] = marker + if markersize is not None: + line_kwargs_for_plot["markersize"] = markersize data_line = self.plot(x, y, fmt, **line_kwargs_for_plot)[0] return ErrorbarContainer(Artist(self, entry), data_line) @@ -2340,11 +2765,13 @@ def hexbin( return PathCollection(self, entry) def _contour(self, filled: bool, args: tuple[Any, ...], kwargs: dict[str, Any]) -> ContourSet: + inherited_corner_mask: bool | None = None if args and isinstance(args[0], ContourSet): source = args[0]._entry z = source["args"][0] x = source["kwargs"].get("x") y = source["kwargs"].get("y") + inherited_corner_mask = source.get("corner_mask") positional_levels = args[1] if len(args) > 1 else None args = () elif len(args) in (1, 2): @@ -2378,23 +2805,67 @@ def _contour(self, filled: bool, args: tuple[Any, ...], kwargs: dict[str, Any]) colors = kwargs.pop("colors", None) linewidths = kwargs.pop("linewidths", None) alpha = kwargs.pop("alpha", None) - if kwargs.pop("origin", None) is not None: - raise not_implemented("contour(origin=...)") + origin = kwargs.pop("origin", None) + if origin == "image": + origin = rcParams["image.origin"] + if origin not in (None, "lower", "upper"): + raise ValueError("origin must be None, 'lower', 'upper', or 'image'") extent = kwargs.pop("extent", None) norm = kwargs.pop("norm", None) - if kwargs.pop("linestyles", None) is not None: + linestyles = kwargs.pop("linestyles", None) + if linestyles not in (None, "-", "solid"): raise not_implemented("contour(linestyles=...)") - _reject_non_default("contour", "corner_mask", kwargs.pop("corner_mask", None), True) + corner_mask = kwargs.pop("corner_mask", inherited_corner_mask) + if corner_mask is None: + corner_mask = rcParams["contour.corner_mask"] + if not isinstance(corner_mask, (bool, np.bool_)): + raise TypeError("corner_mask must be a boolean") extend = kwargs.pop("extend", None) + if extend is None: + extend = "neither" + if extend not in ("neither", "min", "max", "both"): + raise ValueError("extend must be 'neither', 'min', 'max', or 'both'") hatches = kwargs.pop("hatches", None) locator = kwargs.pop("locator", None) za = np.asarray(z, dtype=np.float64) - if extent is not None and x is None and za.ndim == 2: - # origin=None semantics: extent gives the positions of Z[0, 0] and - # Z[-1, -1]; extent is documented to be ignored when X/Y are given. - x0_extent, x1_extent, y0_extent, y1_extent = map(float, extent) - x = np.linspace(x0_extent, x1_extent, za.shape[1]) - y = np.linspace(y0_extent, y1_extent, za.shape[0]) + if x is None and za.ndim == 2: + rows, cols = za.shape + if origin is None: + if extent is not None: + # Without image-oriented origin, extent gives the exact + # positions of Z[0, 0] and Z[-1, -1]. + x0_extent, x1_extent, y0_extent, y1_extent = map(float, extent) + x = np.linspace(x0_extent, x1_extent, cols) + y = np.linspace(y0_extent, y1_extent, rows) + else: + # Matplotlib places contour samples at image-pixel centers. + # For origin='upper', the first Z row belongs at the top. + x0_extent, x1_extent, y0_extent, y1_extent = ( + (0.0, float(cols), 0.0, float(rows)) + if extent is None + else tuple(map(float, extent)) + ) + dx = (x1_extent - x0_extent) / cols + dy = (y1_extent - y0_extent) / rows + x = x0_extent + (np.arange(cols, dtype=float) + 0.5) * dx + y = y0_extent + (np.arange(rows, dtype=float) + 0.5) * dy + if origin == "upper": + y = y[::-1] + # The native regular-grid contour kernel intentionally requires + # increasing coordinates. Matplotlib's origin='upper' represents the + # same field with descending y centers; reverse both the centers and + # the corresponding data rows so geometry and public axis direction + # remain identical while satisfying the kernel contract. + if x is not None and np.asarray(x).ndim == 1 and len(x) > 1: + x_values = np.asarray(x, dtype=np.float64) + if np.all(np.diff(x_values) < 0): + x = x_values[::-1] + za = za[:, ::-1] + if y is not None and np.asarray(y).ndim == 1 and len(y) > 1: + y_values = np.asarray(y, dtype=np.float64) + if np.all(np.diff(y_values) < 0): + y = y_values[::-1] + za = za[::-1, :] if np.isscalar(levels): finite = za[np.isfinite(za)] if locator is not None and "LogLocator" in type(locator).__name__: @@ -2409,7 +2880,7 @@ def _contour(self, filled: bool, args: tuple[Any, ...], kwargs: dict[str, Any]) count = int(np.asarray(levels, dtype=np.float64).item()) levels = _nice_contour_levels(float(finite.min()), float(finite.max()), count) public_levels = np.asarray(levels, dtype=np.float64) - rendered_z = z + rendered_z = za rendered_levels = public_levels if norm is not None and callable(norm): rendered_z = np.ma.asarray(norm(za), dtype=np.float64).filled(np.nan) @@ -2418,17 +2889,59 @@ def _contour(self, filled: bool, args: tuple[Any, ...], kwargs: dict[str, Any]) rendered_z = np.where(za > 0, np.log10(za), np.nan) rendered_levels = np.log10(public_levels) check_unsupported(kwargs, "contour()/contourf()") - color = None + color: Any = None + monochrome = False if colors is not None: - color = resolve_color(colors if isinstance(colors, str) else next(iter(colors))) + scalar_color = isinstance(colors, str) or ( + isinstance(colors, tuple) + and len(colors) in (3, 4) + and all( + np.isscalar(value) and not isinstance(value, (str, bytes)) for value in colors + ) + ) + color_values = [colors] if scalar_color else list(colors) + if not color_values: + raise ValueError("colors must contain at least one color") + monochrome = len(color_values) == 1 + if not filled and monochrome: + color = resolve_color(color_values[0]) + else: + # Matplotlib resizes the supplied sequence to one color per + # isoline (or one per filled band), repeating short sequences + # and truncating long ones. Filled contours may additionally + # reserve the first/last colors for extended regions. + ncolors = len(public_levels) - int(filled) + extend_min = filled and extend in ("min", "both") + extend_max = filled and extend in ("max", "both") + total = ncolors + int(extend_min) + int(extend_max) + use_extreme_colors = len(color_values) == total and (extend_min or extend_max) + interior_source = ( + color_values[1:] if use_extreme_colors and extend_min else color_values + ) + interior = [ + interior_source[index % len(interior_source)] for index in range(ncolors) + ] + resolved = [resolve_rgba(value) for value in interior] + if extend_min: + resolved.insert( + 0, + resolve_rgba(color_values[0]) if use_extreme_colors else resolved[0], + ) + if extend_max: + resolved.append( + resolve_rgba(color_values[-1]) if use_extreme_colors else resolved[-1], + ) + color = np.ascontiguousarray(resolved, dtype=np.float64) # Matplotlib contour linewidths are points. The browser renderer uses # CSS pixels, so the 1.5 pt default becomes 2 px at 96 dpi. - width_pt = ( - _float(linewidths) - if np.isscalar(linewidths) and linewidths is not None - else float(rcParams["lines.linewidth"]) - ) - width = width_pt * (4.0 / 3.0) + if linewidths is None: + width: Any = float(rcParams["lines.linewidth"]) * (4.0 / 3.0) + elif np.isscalar(linewidths): + width = _float(linewidths) * (4.0 / 3.0) + else: + width = np.asarray(linewidths, dtype=float).reshape(-1) * (4.0 / 3.0) + if not len(width): + raise ValueError("linewidths must contain at least one value") transparent_fill = filled and isinstance(colors, str) and colors.lower() == "none" entry = self._add( "@mark", @@ -2443,14 +2956,21 @@ def _contour(self, filled: bool, args: tuple[Any, ...], kwargs: dict[str, Any]) "colormap": resolve_cmap(cmap) if cmap is not None else "viridis", "color": color, "width": width, + "extend": extend, "opacity": 0.0 if transparent_fill else (1.0 if alpha is None else float(alpha)), # Matplotlib dashes negative-level lines for a single-color # contour; a colormapped contour keeps every level solid. - "dash_negative": color is not None, + "dash_negative": ( + monochrome + and linestyles is None + and rcParams["contour.negative_linestyle"] == "dashed" + ), + "corner_mask": bool(corner_mask), }, "source_z": za, + "corner_mask": bool(corner_mask), "domain": (float(public_levels[0]), float(public_levels[-1])), "hatches": list(hatches) if hatches is not None else None, "extend": extend, @@ -2566,8 +3086,9 @@ def contour(self, *args: Any, data: TableLike = None, **kwargs: Any) -> ContourS Call as ``contour(Z)``, ``contour(X, Y, Z)``, or with a trailing level count/sequence. Supported keywords: ``levels``, ``cmap``, ``colors``, ``linewidths``, ``alpha``, ``extent``, ``norm``, - ``extend``, ``hatches``, and ``locator``; ``origin``, - ``linestyles``, and unknown keywords raise loudly. + ``extend``, ``hatches``, ``locator``, and image-oriented ``origin``. + ``linestyles`` accepts the solid forms ``"-"`` and ``"solid"``; + other line styles and unknown keywords raise loudly. """ return self._contour(False, tuple(_from_data(value, data) for value in args), kwargs) @@ -2735,22 +3256,24 @@ def bxp( dtype=np.float64, ) - def style(props: Any, fallback: Any = None) -> dict[str, Any]: + def style( + props: Any, fallback: Any = None + ) -> tuple[dict[str, Any], Optional[tuple[tuple[float, float], ...]]]: source = dict(props or {}) color = source.pop("color", source.pop("edgecolor", fallback)) width = source.pop("linewidth", source.pop("lw", 1.2)) alpha = source.pop("alpha", 1.0) linestyle = source.pop("linestyle", source.pop("ls", None)) - if linestyle not in (None, "-", "solid"): - raise not_implemented( - "bxp component linestyle", "solid component lines with color/width/alpha" - ) + dash_pattern = _dash_segment_pattern("bxp component", linestyle) check_unsupported(source, "bxp component properties") - return { - "color": resolve_color(color) if color is not None else fallback, - "width": float(width), - "opacity": float(alpha), - } + return ( + { + "color": resolve_color(color) if color is not None else fallback, + "width": float(width), + "opacity": float(alpha), + }, + dash_pattern, + ) default_color = self._next_color() @@ -2758,12 +3281,21 @@ def emit(coords: list[tuple[float, float, float, float]], props: Any) -> list[Ar if not coords: return [] values = np.asarray(coords, dtype=np.float64) + rendered_style, dash_pattern = style(props, default_color) + x0, y0, x1, y1 = ( + values[:, 0], + values[:, 1], + values[:, 2], + values[:, 3], + ) + if dash_pattern is not None: + x0, y0, x1, y1 = _dashed_segments(x0, y0, x1, y1, dash_pattern) entry = self._add( "@mark", { "factory": "segments", - "args": (values[:, 0], values[:, 1], values[:, 2], values[:, 3]), - "kwargs": style(props, default_color), + "args": (x0, y0, x1, y1), + "kwargs": rendered_style, }, ) return [Artist(self, entry)] @@ -2773,6 +3305,8 @@ def emit(coords: list[tuple[float, float, float, float]], props: Any) -> list[Ar whisker_segments: list[tuple[float, float, float, float]] = [] cap_segments: list[tuple[float, float, float, float]] = [] mean_segments: list[tuple[float, float, float, float]] = [] + mean_x: list[float] = [] + mean_y: list[float] = [] flier_x: list[float] = [] flier_y: list[float] = [] for index, item in enumerate(stats): @@ -2825,11 +3359,11 @@ def emit(coords: list[tuple[float, float, float, float]], props: Any) -> list[Ar flier_y.extend(float(value) for value in item.get("fliers", ())) if showmeans and "mean" in item: mean = float(item["mean"]) - mean_segments.append( - (center - half, mean, center + half, mean) - if meanline - else (center, mean, center, mean) - ) + if meanline: + mean_segments.append((center - half, mean, center + half, mean)) + else: + mean_x.append(center) + mean_y.append(mean) else: if shownotches: cilo = float(item.get("cilo", med)) @@ -2870,45 +3404,83 @@ def emit(coords: list[tuple[float, float, float, float]], props: Any) -> list[Ar flier_y.extend([center] * len(item.get("fliers", ()))) if showmeans and "mean" in item: mean = float(item["mean"]) - mean_segments.append( - (mean, center - half, mean, center + half) - if meanline - else (mean, center, mean, center) - ) + if meanline: + mean_segments.append((mean, center - half, mean, center + half)) + else: + mean_x.append(mean) + mean_y.append(center) + + def emit_points( + x_values: list[float], + y_values: list[float], + props: Any, + *, + default_marker: str, + default_face: Any, + default_size: float, + default_edge: Any = None, + ) -> list[Artist]: + if not x_values: + return [] + source = dict(props or {}) + color = source.pop("color", default_face) + marker = source.pop("marker", default_marker) + size = source.pop("markersize", source.pop("ms", default_size)) + facecolor = source.pop("markerfacecolor", source.pop("mfc", color)) + edgecolor = source.pop( + "markeredgecolor", + source.pop("mec", color if default_edge is None else default_edge), + ) + edgewidth = source.pop("markeredgewidth", source.pop("mew", 1.0)) + alpha = source.pop("alpha", 1.0) + source.pop("linestyle", source.pop("ls", None)) + check_unsupported(source, "bxp point properties") + entry = self._add( + "scatter", + { + "x": x_values, + "y": y_values, + "kwargs": { + "color": resolve_color(facecolor), + "stroke": resolve_color(edgecolor), + "stroke_width": float(edgewidth), + "size": float(size), + "symbol": MARKER_TO_SYMBOL.get(marker or default_marker, "circle"), + "opacity": float(alpha), + }, + }, + ) + return [Artist(self, entry)] + result = { "boxes": emit(box_segments, boxprops) if showbox else [], "medians": emit(median_segments, medianprops), "whiskers": emit(whisker_segments, whiskerprops), "caps": emit(cap_segments, capprops) if showcaps else [], - "means": emit(mean_segments, meanprops), + "means": ( + emit(mean_segments, meanprops) + if meanline + else emit_points( + mean_x, + mean_y, + meanprops, + default_marker="^", + default_face="C2", + default_size=6.0, + ) + ), "fliers": [], } if showfliers and flier_x: - source = dict(flierprops or {}) - color = source.pop("color", default_color) - marker = source.pop("marker", "o") - size = source.pop("markersize", source.pop("ms", 5.0)) - # single-color flier dots: face color wins, else the edge color - facecolor = source.pop("markerfacecolor", source.pop("mfc", None)) - edgecolor = source.pop("markeredgecolor", source.pop("mec", None)) - if facecolor is not None: - color = facecolor - elif edgecolor is not None: - color = edgecolor - check_unsupported(source, "bxp(flierprops=)") - entry = self._add( - "scatter", - { - "x": flier_x, - "y": flier_y, - "kwargs": { - "color": resolve_color(color), - "size": float(size), - "symbol": MARKER_TO_SYMBOL.get(marker or "o", "circle"), - }, - }, + result["fliers"] = emit_points( + flier_x, + flier_y, + flierprops, + default_marker="o", + default_face="transparent", + default_size=5.0, + default_edge=default_color, ) - result["fliers"] = [Artist(self, entry)] if label is not None and result["medians"]: result["medians"][0].set_label(str(label)) if zorder is not None: @@ -3381,9 +3953,47 @@ def pcolormesh(self, *args: Any, **kwargs: Any) -> PolyCollection: vmax = norm_vmax domain = (float(vmin), float(vmax)) if vmin is not None and vmax is not None else None regular = None if x is None else _uniform_mesh_axes(x, y, z.shape) + if shading == "gouraud": + gouraud_axes = ( + (np.arange(z.shape[1], dtype=float), np.arange(z.shape[0], dtype=float)) + if x is None + else _gouraud_rect_axes(x, y, z.shape) + ) + no_edges = edgecolors is None or ( + isinstance(edgecolors, str) and edgecolors.lower() == "none" + ) + if gouraud_axes is not None and no_edges: + width = max(2, min(512, max(256, z.shape[1] * 32))) + height = max(2, min(512, max(256, z.shape[0] * 32))) + smooth = _bilinear_grid(z, width, height) + gx, gy = gouraud_axes + mark_kwargs: dict[str, Any] = { + "x": np.linspace(float(gx[0]), float(gx[-1]), width), + "y": np.linspace(float(gy[0]), float(gy[-1]), height), + "colormap": colormap, + "opacity": opacity, + } + if domain is not None: + mark_kwargs["domain"] = domain + entry = self._add( + "@mark", + { + "factory": "heatmap", + "args": (smooth,), + "kwargs": mark_kwargs, + "source_z": z, + }, + ) + return PolyCollection(self, entry) if x is None or (regular is not None and shading != "gouraud"): if regular is not None: x, y = regular + elif x is None: + # Matplotlib's implicit pcolormesh coordinates are cell + # *edges* 0..N and 0..M. Heatmaps consume centers, so use + # half-integer centers to preserve that exact geometry. + x = np.arange(z.shape[1], dtype=np.float64) + 0.5 + y = np.arange(z.shape[0], dtype=np.float64) + 0.5 mark_kwargs: dict[str, Any] = { "x": x, "y": y, @@ -3408,6 +4018,24 @@ def pcolormesh(self, *args: Any, **kwargs: Any) -> PolyCollection: if y is None: raise ValueError("pcolormesh requires Y when X is provided") x0, y0, x1, y1, x2, y2, scalar = kernels.quad_mesh_triangles(x, y, z) + mesh_x = np.concatenate((x0, x1, x2)) + mesh_y = np.concatenate((y0, y1, y2)) + finite_x = mesh_x[np.isfinite(mesh_x)] + finite_y = mesh_y[np.isfinite(mesh_y)] + # The native expansion elides triangles whose scalar is masked. An + # entirely masked QuadMesh still contributes its coordinate grid to + # Matplotlib's data limits, so recover that extent from X/Y when no + # triangle survives. + if not finite_x.size: + source_x = np.asarray(x, dtype=np.float64).reshape(-1) + finite_x = source_x[np.isfinite(source_x)] + if not finite_y.size: + source_y = np.asarray(y, dtype=np.float64).reshape(-1) + finite_y = source_y[np.isfinite(source_y)] + mesh_extent = { + "x": (float(finite_x.min()), float(finite_x.max())), + "y": (float(finite_y.min()), float(finite_y.max())), + } finite_triangles = np.isfinite(scalar) if not np.all(finite_triangles): x0, y0, x1, y1, x2, y2, scalar = ( @@ -3434,6 +4062,8 @@ def pcolormesh(self, *args: Any, **kwargs: Any) -> PolyCollection: "kwargs": mark_kwargs, "source_z": scalar, "domain": domain, + "_mpl_extent": mesh_extent, + "_mpl_sticky_edges": mesh_extent, }, ) return PolyCollection(self, entry) @@ -3551,7 +4181,8 @@ def pie( _reject_non_default("pie", "rotatelabels", rotatelabels, False) if hatch is not None: raise not_implemented("pie(hatch=...)") - values = np.asarray(_from_data(x, data), dtype=np.float64) + source_values = np.asarray(_from_data(x, data)) + values = np.asarray(source_values, dtype=np.float64) if values.ndim != 1 or len(values) == 0: raise ValueError("pie x must be a non-empty 1-D array") offsets = np.zeros(len(values), dtype=np.float64) @@ -3602,14 +4233,21 @@ def pie( wedges: list[Wedge] = [] for index in range(len(values)): selected = sectors == float(index) + face = resolve_color(color_values[index]) mark_kwargs: dict[str, Any] = { - "color": resolve_color(color_values[index]), + "color": face, "name": None if label_values[index] is None else str(label_values[index]), "opacity": 1.0 if alpha is None else float(alpha), } if edgecolor is not None: mark_kwargs["stroke"] = resolve_color(edgecolor) mark_kwargs["stroke_width"] = 1.0 if linewidth is None else float(linewidth) + else: + # A sector is a fan of adjacent triangles. Stroke each fan + # triangle with its own face color so anti-aliasing cannot + # expose the figure background as radial hairline spokes. + mark_kwargs["stroke"] = face + mark_kwargs["stroke_width"] = 0.75 entry = self._add( "@mark", { @@ -3674,7 +4312,11 @@ def add_text(distance: float, mid: float, value: str, offset: float) -> Text: extent = float(radius) * (1.25 + float(np.max(offsets))) self.set_xlim(float(center[0]) - extent, float(center[0]) + extent) self.set_ylim(float(center[1]) - extent, float(center[1]) + extent) - return PieContainer(wedges, values, bool(normalize), texts, autotexts) + self.set_aspect("equal", adjustable="box") + if not frame: + self.set_axis_off() + self._hidden_spines.update(("left", "bottom", "top", "right")) + return PieContainer(wedges, source_values, bool(normalize), texts, autotexts) def pie_label( self, @@ -3691,11 +4333,13 @@ def pie_label( ``labels`` may be a sequence or a ``{}``-format string receiving ``absval`` and ``frac`` per wedge; ``distance`` places labels as a fraction of the radius and ``textprops`` styles them. - ``rotate=True`` raises loudly. + ``rotate=True`` orients each label away from its wedge center. """ - _reject_non_default("pie_label", "rotate", rotate, False) if alignment not in ("auto", "center", "outer"): raise ValueError("pie_label alignment must be 'auto', 'center', or 'outer'") + resolved_alignment = "outer" if alignment == "auto" and distance > 1 else alignment + if resolved_alignment == "auto": + resolved_alignment = "center" if isinstance(labels, str): formatted = [ labels.format(absval=value, frac=frac) @@ -3714,15 +4358,25 @@ def pie_label( radius = float(entry_data["pie_radius"]) explode = float(entry_data["pie_explode"]) radial = (float(distance) + explode) * radius + x = center_x + radial * np.cos(mid) + y = center_y + radial * np.sin(mid) + base_style: dict[str, Any] = {"vertical_align": "center"} + anchor = "middle" + if resolved_alignment == "outer": + anchor = "start" if x > 0 else "end" + if rotate: + if resolved_alignment == "outer": + base_style["vertical_align"] = "bottom" if y > 0 else "top" + base_style["rotation"] = float(np.rad2deg(mid) + (0.0 if x > 0 else 180.0)) + kwargs = {"anchor": anchor, "style": base_style} + kwargs.update({key: value for key, value in text_kwargs.items() if key != "style"}) + if text_kwargs.get("style"): + kwargs["style"] = {**base_style, **text_kwargs["style"]} entry = self._add( "@text", { - "args": ( - center_x + radial * np.cos(mid), - center_y + radial * np.sin(mid), - str(label), - ), - "kwargs": dict(text_kwargs), + "args": (x, y, str(label)), + "kwargs": kwargs, }, ) result.append(Text(self, entry)) @@ -4225,12 +4879,12 @@ def _vector_field( raise TypeError(f"{name}() expects U, V or X, Y, U, V[, C]") color = kwargs.pop("color", c) alpha = kwargs.pop("alpha", None) - width = kwargs.pop("width", kwargs.pop("linewidth", 1.2)) + width = kwargs.pop("width", kwargs.pop("linewidth", None)) scale = kwargs.pop("scale", None) pivot = kwargs.pop("pivot", "tail") angles = kwargs.pop("angles", "uv") scale_units = kwargs.pop("scale_units", None) - _reject_non_default(name, "units", kwargs.pop("units", None), "width") + units = kwargs.pop("units", "width") _reject_non_default(name, "headwidth", kwargs.pop("headwidth", None), 3.0) _reject_non_default(name, "headlength", kwargs.pop("headlength", None), 5.0) _reject_non_default(name, "headaxislength", kwargs.pop("headaxislength", None), 4.5) @@ -4254,6 +4908,8 @@ def _vector_field( raise ValueError(f"invalid {name} angles {angles!r}") if scale_units not in (None, "width", "height", "dots", "inches", "x", "y", "xy"): raise ValueError(f"invalid {name} scale_units {scale_units!r}") + if units not in ("width", "height", "dots", "inches", "x", "y", "xy"): + raise ValueError(f"invalid {name} units {units!r}") from xy import kernels magnitudes = np.hypot(u, v) @@ -4266,7 +4922,7 @@ def _vector_field( spacing = min(spacings) if spacings else 1.0 finite_magnitudes = magnitudes[np.isfinite(magnitudes) & (magnitudes > 0)] typical = float(np.median(finite_magnitudes)) if len(finite_magnitudes) else 1.0 - vector_scale = typical / max(0.75 * spacing, np.finfo(float).eps) + vector_scale = typical / max(0.55 * spacing, np.finfo(float).eps) else: vector_scale = float(scale) color_repeats: Optional[np.ndarray] = None @@ -4323,6 +4979,25 @@ def _vector_field( ) else: segment_color = resolve_color(color) if color is not None else self._next_color() + if width is None: + rendered_width = 1.2 + else: + # Matplotlib's ``units`` controls arrow *width*, while + # ``scale_units`` controls length. Segment widths are pixels in + # xy, so convert with a stable nominal 500x370 px Axes viewport; + # resizing preserves the important data-unit distinction. + x_span = max(float(np.ptp(x[np.isfinite(x)])), np.finfo(float).eps) + y_span = max(float(np.ptp(y[np.isfinite(y)])), np.finfo(float).eps) + dots_per_unit = { + "width": 500.0, + "height": 370.0, + "dots": 1.0, + "inches": 100.0, + "x": 500.0 / x_span, + "y": 370.0 / y_span, + "xy": float(np.hypot(500.0, 370.0) / np.hypot(x_span, y_span)), + }[units] + rendered_width = max(0.5, float(width) * dots_per_unit) entry = self._add( "@mark", { @@ -4331,7 +5006,7 @@ def _vector_field( "kwargs": { "color": segment_color, "colormap": resolve_cmap(cmap) if cmap is not None else "viridis", - "width": max(1.0, float(width) * 200.0) if float(width) < 0.1 else float(width), + "width": rendered_width, "opacity": 1.0 if alpha is None else float(alpha), }, "vector_scale": vector_scale, @@ -4339,14 +5014,359 @@ def _vector_field( ) return PolyCollection(self, entry) + def _barb_field( + self, + args: tuple[Any, ...], + kwargs: dict[str, Any], + *, + length: float, + fill_empty: bool, + rounding: bool, + flip_barb: Any, + sizes: Mapping[str, float], + barbcolor: Any, + flagcolor: Any, + barb_increments: Mapping[str, float], + ) -> PolyCollection: + """Render Matplotlib-compatible fixed-length wind-barb geometry.""" + if len(args) == 2: + raw_u, raw_v = args + u_grid, v_grid = _masked_float(raw_u), _masked_float(raw_v) + if u_grid.shape != v_grid.shape: + raise ValueError("barbs U and V must have matching shapes") + if u_grid.ndim == 1: + x, y = np.arange(u_grid.size, dtype=np.float64), np.zeros(u_grid.size) + elif u_grid.ndim == 2: + rows, cols = u_grid.shape + x, y = ( + values.reshape(-1) for values in np.meshgrid(np.arange(cols), np.arange(rows)) + ) + else: + raise ValueError("barbs U and V must be 1-D or 2-D") + u, v, c = u_grid.reshape(-1), v_grid.reshape(-1), None + elif len(args) in (4, 5): + raw_x, raw_y, raw_u, raw_v = args[:4] + c = args[4] if len(args) == 5 else None + u_grid, v_grid = _masked_float(raw_u), _masked_float(raw_v) + x_grid, y_grid = _masked_float(raw_x), _masked_float(raw_y) + if x_grid.ndim == y_grid.ndim == 1 and u_grid.ndim == 2: + x_grid, y_grid = np.meshgrid(x_grid, y_grid) + if ( + u_grid.shape != v_grid.shape + or x_grid.shape != u_grid.shape + or y_grid.shape != u_grid.shape + ): + raise ValueError("barbs X, Y, U, and V must resolve to matching shapes") + x, y = x_grid.reshape(-1), y_grid.reshape(-1) + u, v = u_grid.reshape(-1), v_grid.reshape(-1) + else: + raise TypeError("barbs() expects U, V or X, Y, U, V[, C]") + + pivot = kwargs.pop("pivot", "tip") + linewidth = float(kwargs.pop("linewidth", kwargs.pop("lw", 1.0))) + alpha = float(kwargs.pop("alpha", 1.0)) + color = kwargs.pop("color", None) + cmap = kwargs.pop("cmap", None) + if kwargs.pop("norm", None) is not None: + raise not_implemented("barbs(norm=...)") + check_unsupported(kwargs, "barbs()") + if length <= 0: + raise ValueError("barbs length must be positive") + if isinstance(pivot, str) and pivot.lower() not in ("tip", "middle", "mid"): + raise ValueError("barbs pivot must be 'tip', 'middle', or a number") + + allowed_sizes = {"spacing", "height", "width", "emptybarb"} + unknown_sizes = set(sizes) - allowed_sizes + if unknown_sizes: + raise ValueError(f"unsupported barbs sizes: {sorted(unknown_sizes)}") + increments = {"half": 5.0, "full": 10.0, "flag": 50.0} + unknown_increments = set(barb_increments) - set(increments) + if unknown_increments: + raise ValueError(f"unsupported barb_increments: {sorted(unknown_increments)}") + increments.update({key: float(value) for key, value in barb_increments.items()}) + if any(value <= 0 for value in increments.values()): + raise ValueError("barb increments must be positive") + + valid = np.isfinite(x) & np.isfinite(y) & np.isfinite(u) & np.isfinite(v) + x, y, u, v = x[valid], y[valid], u[valid], v[valid] + if c is not None: + c_values = np.ma.asarray(c).filled(np.nan).reshape(-1) + if len(c_values) != len(valid): + raise ValueError("barbs color values must match U and V") + c = c_values[valid] + flip_values = np.asarray(flip_barb, dtype=bool).reshape(-1) + if len(flip_values) == 1: + flip_values = np.broadcast_to(flip_values, len(x)) + elif len(flip_values) == len(valid): + flip_values = flip_values[valid] + elif len(flip_values) != len(x): + raise ValueError("barbs flip_barb must be scalar or match U and V") + + magnitudes = np.hypot(u, v) + rounded = ( + increments["half"] * np.around(magnitudes / increments["half"]) + if rounding + else magnitudes.copy() + ) + nflags = np.floor_divide(rounded, increments["flag"]).astype(int) + remainder = np.mod(rounded, increments["flag"]) + nbarbs = np.floor_divide(remainder, increments["full"]).astype(int) + remainder = np.mod(remainder, increments["full"]) + halves = remainder >= increments["half"] + empty = ~(halves | (nflags > 0) | (nbarbs > 0)) + + def visible_span(values: np.ndarray) -> float: + span = float(np.ptp(values)) + if span > np.finfo(float).eps: + return span + # Matplotlib's nonsingular locator expands a constant zero-valued + # offset range to roughly (-.05, .05). + return max(0.1, 0.1 * float(np.max(np.abs(values), initial=0.0))) + + x_span = visible_span(x) + y_span = visible_span(y) + figure_width, figure_height = rc_figsize_px(self.figure._figsize, self.figure._dpi) + rects = self.figure._effective_rects() + if rects is None: + plot_width = figure_width * 0.775 + plot_height = figure_height * 0.77 + else: + axes_index = self.figure._axes.index(self) + rect = rects[axes_index] + plot_width = figure_width * rect[2] + plot_height = figure_height * rect[3] + # Barbs are a point-sized PolyCollection in Matplotlib. Its path is + # scaled by sqrt(length**2 / 4) * dpi / 72 before the data-position + # offset is applied. Convert that screen-space path scale separately + # on x/y so a single-panel and a dense subplot grid retain the same + # visual glyph size and circular calm-wind markers remain circular. + dpi = float(self.figure._dpi if self.figure._dpi is not None else rcParams["figure.dpi"]) + path_pixel_scale = length * 0.5 * dpi / 72.0 + data_per_path_x = path_pixel_scale * x_span / max(plot_width, 1.0) + data_per_path_y = path_pixel_scale * y_span / max(plot_height, 1.0) + spacing = length * float(sizes.get("spacing", 0.125)) + full_height = length * float(sizes.get("height", 0.4)) + full_width = length * float(sizes.get("width", 0.25)) + empty_radius = length * float(sizes.get("emptybarb", 0.15)) + + sx0: list[float] = [] + sy0: list[float] = [] + sx1: list[float] = [] + sy1: list[float] = [] + segment_sources: list[int] = [] + tx0: list[float] = [] + ty0: list[float] = [] + tx1: list[float] = [] + ty1: list[float] = [] + tx2: list[float] = [] + ty2: list[float] = [] + triangle_sources: list[int] = [] + + def add_segment(ax: float, ay: float, bx: float, by: float, source: int) -> None: + sx0.append(ax) + sy0.append(ay) + sx1.append(bx) + sy1.append(by) + segment_sources.append(source) + + def add_triangle( + ax: float, + ay: float, + bx: float, + by: float, + cx: float, + cy: float, + source: int, + ) -> None: + tx0.append(ax) + ty0.append(ay) + tx1.append(bx) + ty1.append(by) + tx2.append(cx) + ty2.append(cy) + triangle_sources.append(source) + + for index, (px, py, du, dv, magnitude) in enumerate( + zip(x, y, u, v, magnitudes, strict=True) + ): + if empty[index] or magnitude <= np.finfo(float).eps: + theta = np.linspace(0.0, 2.0 * np.pi, 13) + circle_x = px + empty_radius * data_per_path_x * np.cos(theta) + circle_y = py + empty_radius * data_per_path_y * np.sin(theta) + for point_index in range(12): + add_segment( + float(circle_x[point_index]), + float(circle_y[point_index]), + float(circle_x[point_index + 1]), + float(circle_y[point_index + 1]), + index, + ) + if fill_empty: + add_triangle( + float(px), + float(py), + float(circle_x[point_index]), + float(circle_y[point_index]), + float(circle_x[point_index + 1]), + float(circle_y[point_index + 1]), + index, + ) + continue + + ux, uy = du / magnitude, dv / magnitude + shaft_x, shaft_y = -ux, -uy + side_sign = -1.0 if flip_values[index] else 1.0 + side_x, side_y = side_sign * -uy, side_sign * ux + + def transform_point( + staff: float, + side: float = 0.0, + *, + origin_x: float = float(px), + origin_y: float = float(py), + staff_x: float = float(shaft_x), + staff_y: float = float(shaft_y), + feature_x: float = float(side_x), + feature_y: float = float(side_y), + ) -> tuple[float, float]: + return ( + origin_x + (staff_x * staff + feature_x * side) * data_per_path_x, + origin_y + (staff_y * staff + feature_y * side) * data_per_path_y, + ) + + if isinstance(pivot, str): + pivot_offset = -length / 2.0 if pivot.lower() in ("middle", "mid") else 0.0 + else: + pivot_offset = float(pivot) + root_x, root_y = transform_point(pivot_offset) + outer_x, outer_y = transform_point(pivot_offset + length) + add_segment(root_x, root_y, outer_x, outer_y, index) + offset = length + + for _ in range(nflags[index]): + if offset != length: + offset += spacing / 2.0 + a_x, a_y = transform_point(pivot_offset + offset) + b_x, b_y = transform_point( + pivot_offset + offset - full_width / 2.0, + full_height, + ) + c_x, c_y = transform_point(pivot_offset + offset - full_width) + add_triangle(a_x, a_y, b_x, b_y, c_x, c_y, index) + add_segment(a_x, a_y, b_x, b_y, index) + add_segment(b_x, b_y, c_x, c_y, index) + offset -= full_width + spacing + + for _ in range(nbarbs[index]): + a_x, a_y = transform_point(pivot_offset + offset) + b_x, b_y = transform_point( + pivot_offset + offset + full_width / 2.0, + full_height, + ) + add_segment(a_x, a_y, b_x, b_y, index) + offset -= spacing + + if halves[index]: + if offset == length: + offset -= 1.5 * spacing + a_x, a_y = transform_point(pivot_offset + offset) + b_x, b_y = transform_point( + pivot_offset + offset + full_width / 4.0, + full_height / 2.0, + ) + add_segment(a_x, a_y, b_x, b_y, index) + + edge_spec = c if c is not None else (barbcolor if barbcolor is not None else color or "k") + face_spec = c if c is not None else (flagcolor if flagcolor is not None else edge_spec) + colormap = resolve_cmap(cmap) if cmap is not None else "viridis" + entries: list[dict[str, Any]] = [] + + def emit( + factory: str, + coordinates: tuple[list[float], ...], + sources: list[int], + color_spec: Any, + extra: dict[str, Any], + ) -> None: + arrays = tuple(np.asarray(values, dtype=np.float64) for values in coordinates) + source_array = np.asarray(sources, dtype=np.int64) + if isinstance(color_spec, str): + groups = [(np.ones(len(source_array), dtype=bool), resolve_color(color_spec))] + else: + colors = np.asarray(color_spec) + if colors.ndim == 0: + groups = [ + (np.ones(len(source_array), dtype=bool), resolve_color(colors.item())) + ] + elif colors.dtype.kind in "OUS": + cycled = np.asarray( + [resolve_color(colors.reshape(-1)[i % colors.size]) for i in range(len(x))] + ) + groups = [ + (cycled[source_array] == chosen, chosen) + for chosen in dict.fromkeys(cycled.tolist()) + ] + else: + if colors.size != len(x): + raise ValueError("barbs color values must match U and V") + groups = [ + (np.ones(len(source_array), dtype=bool), colors.reshape(-1)[source_array]) + ] + for keep, chosen_color in groups: + if not np.any(keep): + continue + entries.append( + self._add( + "@mark", + { + "factory": factory, + "args": tuple(values[keep] for values in arrays), + "kwargs": { + "color": chosen_color, + "colormap": colormap, + "opacity": alpha, + **extra, + }, + }, + ) + ) + + emit( + "segments", + (sx0, sy0, sx1, sy1), + segment_sources, + edge_spec, + {"width": linewidth}, + ) + if triangle_sources: + emit( + "triangle_mesh", + (tx0, ty0, tx1, ty1, tx2, ty2), + triangle_sources, + face_spec, + {}, + ) + if not entries: + entries.append( + self._add( + "@mark", + { + "factory": "segments", + "args": ([], [], [], []), + "kwargs": {"color": "#000000", "opacity": 0.0}, + }, + ) + ) + return PolyCollection(self, entries[0]) + def quiver(self, *args: Any, data: TableLike = None, **kwargs: Any) -> PolyCollection: """A field of arrows: ``quiver(U, V)`` or ``quiver(X, Y, U, V[, C])``. Supported keywords: ``color``, ``alpha``, ``width``/``linewidth``, - ``scale``, ``pivot``, ``angles``, ``scale_units``, ``cmap``, and - ``data``. Non-default ``units``/``headwidth``/``headlength``/ - ``headaxislength``/``minshaft``/``minlength``, any - ``norm``/``clim``/``zorder``, and unknown keywords raise loudly. + ``scale``, ``pivot``, ``angles``, ``units``, ``scale_units``, + ``cmap``, and ``data``. Non-default ``headwidth``/``headlength``/ + ``headaxislength``/``minshaft``/``minlength``, any ``norm``/``clim``/ + ``zorder``, and unknown keywords raise loudly. """ return self._vector_field( tuple(_from_data(value, data) for value in args), kwargs, "quiver" @@ -4355,21 +5375,23 @@ def quiver(self, *args: Any, data: TableLike = None, **kwargs: Any) -> PolyColle def barbs(self, *args: Any, data: TableLike = None, **kwargs: Any) -> PolyCollection: """A field of wind barbs: ``barbs(U, V)`` or ``barbs(X, Y, U, V[, C])``. - Accepts the ``quiver`` field keywords (``color``, ``alpha``, - ``width``/``linewidth``, ``scale``, ``pivot``, ...). Rendered at - matplotlib's default barb geometry: non-default - ``length``/``fill_empty``/``rounding``/``flip_barb`` raise loudly, - as do ``sizes``/``barbcolor``/``flagcolor``/``barb_increments``. + Supports Matplotlib's fixed-length staff, flag/full/half-barb + decomposition, pivot, colors, empty-barb fill, feature sizes, + increment controls, rounding, and per-vector flipping. """ args = tuple(_from_data(value, data) for value in args) - _reject_non_default("barbs", "length", kwargs.pop("length", None), 7.0) - _reject_non_default("barbs", "fill_empty", kwargs.pop("fill_empty", None), False) - _reject_non_default("barbs", "rounding", kwargs.pop("rounding", None), True) - _reject_non_default("barbs", "flip_barb", kwargs.pop("flip_barb", None), False) - for option in ("sizes", "barbcolor", "flagcolor", "barb_increments"): - if kwargs.pop(option, None) is not None: - raise not_implemented(f"barbs({option}=...)") - return self._vector_field(args, kwargs, "barbs") + return self._barb_field( + args, + kwargs, + length=float(kwargs.pop("length", 7.0)), + fill_empty=bool(kwargs.pop("fill_empty", False)), + rounding=bool(kwargs.pop("rounding", True)), + flip_barb=kwargs.pop("flip_barb", False), + sizes=dict(kwargs.pop("sizes", None) or {}), + barbcolor=kwargs.pop("barbcolor", None), + flagcolor=kwargs.pop("flagcolor", None), + barb_increments=dict(kwargs.pop("barb_increments", None) or {}), + ) def quiverkey( self, @@ -4400,13 +5422,23 @@ def quiverkey( check_unsupported(kwargs, "quiverkey()") from xy import kernels - if coordinates == "axes": + if coordinates in ("axes", "figure"): qx = np.concatenate((np.asarray(Q._entry["args"][0]), np.asarray(Q._entry["args"][2]))) qy = np.concatenate((np.asarray(Q._entry["args"][1]), np.asarray(Q._entry["args"][3]))) - px = float(np.nanmin(qx) + float(X) * (np.nanmax(qx) - np.nanmin(qx))) - py = float(np.nanmin(qy) + float(Y) * (np.nanmax(qy) - np.nanmin(qy))) - else: + x_fraction, y_fraction = float(X), float(Y) + if coordinates == "figure": + # Default Matplotlib subplot bounds: left/right=.125/.9 and + # bottom/top=.11/.88. Convert figure fractions into the + # equivalent axes fractions so keys at (.9, .9) sit on the + # outer top-right edge, as in the gallery. + x_fraction = (x_fraction - 0.125) / 0.775 + y_fraction = (y_fraction - 0.11) / 0.77 + px = float(np.nanmin(qx) + x_fraction * (np.nanmax(qx) - np.nanmin(qx))) + py = float(np.nanmin(qy) + y_fraction * (np.nanmax(qy) - np.nanmin(qy))) + elif coordinates == "data": px, py = float(X), float(Y) + else: + raise ValueError("quiverkey coordinates must be 'axes', 'figure', or 'data'") x0, x1, y0, y1 = kernels.vector_segments( np.asarray([px], dtype=np.float64), np.asarray([py], dtype=np.float64), @@ -4437,10 +5469,13 @@ def quiverkey( if labelpos not in offsets: raise ValueError("quiverkey labelpos must be N, S, E, or W") dx, dy = offsets[labelpos] + # Math mode discards ordinary whitespace, but the plain-text fraction + # fallback needs a visible word gap before units (`1 m/s`). + key_label = str(label).replace(r" \frac", r"\ \frac") self._add( "@text", { - "args": (px + dx, py + dy, str(label)), + "args": (px + dx, py + dy, mathtext_to_unicode(key_label)), "kwargs": {"color": resolve_color(labelcolor)} if labelcolor is not None else {}, }, ) @@ -4476,10 +5511,10 @@ def streamplot( ``density`` controls line spacing, ``start_points`` seeds specific trajectories, and ``color``/``linewidth`` may be arrays evaluated - along the field (``cmap``/``norm`` map array colors). Non-default - ``arrowstyle``, ``minlength``, ``broken_streamlines``, and - integration scale options raise loudly, as do ``transform`` and - ``zorder``. + along the field (``cmap``/``norm`` map array colors). Unbroken + streamlines and the integration step/error scale controls use the + adaptive Python integrator. Non-default ``arrowstyle`` and + ``minlength`` raise loudly, as do ``transform`` and ``zorder``. """ if transform is not None: raise not_implemented("streamplot(transform=...)") @@ -4487,13 +5522,10 @@ def streamplot( raise not_implemented("streamplot(zorder=...)") _reject_non_default("streamplot", "arrowstyle", arrowstyle, "-|>") _reject_non_default("streamplot", "minlength", minlength, 0.1) - _reject_non_default("streamplot", "broken_streamlines", broken_streamlines, True) - _reject_non_default( - "streamplot", "integration_max_step_scale", integration_max_step_scale, 1.0 - ) - _reject_non_default( - "streamplot", "integration_max_error_scale", integration_max_error_scale, 1.0 - ) + if integration_max_step_scale <= 0.0: + raise ValueError("streamplot integration_max_step_scale must be positive") + if integration_max_error_scale <= 0.0: + raise ValueError("streamplot integration_max_error_scale must be positive") if norm is not None and type(norm).__name__ != "Normalize": # Only the linear Normalize maps onto the engine's domain contract. raise not_implemented( @@ -4517,57 +5549,47 @@ def streamplot( x_values, y_values = _regular_mesh_axes(x_values, y_values, u_values.shape) if x_values.ndim != 1 or y_values.ndim != 1: raise ValueError("streamplot X and Y must define a regular grid") - density_value = float(np.max(np.asarray(density, dtype=np.float64))) + try: + density_xy = np.broadcast_to(np.asarray(density, dtype=np.float64), 2) + except ValueError as exc: + raise ValueError("streamplot density must be a scalar or have length 2") from exc + if np.any(density_xy <= 0): + raise ValueError("streamplot density must be positive") max_steps = max(1, min(100_000, int(float(maxlength) * max(u_values.shape) * 8))) - # One dependency-free integrator regardless of environment: the native - # kernel covers default grid seeding; explicit seeds and one-sided - # integration run the same fixed-step scheme in Python. - if start_points is None and integration_direction == "both": - from xy import kernels - - kx0, kx1, ky0, ky1 = kernels.streamlines( - x_values, - y_values, - u_values, - v_values, - density=density_value, - max_steps=max_steps, + if start_points is not None: + seeds = np.asarray(start_points, dtype=np.float64) + if seeds.ndim != 2 or seeds.shape[1] != 2: + raise ValueError("streamplot start_points must have shape (n, 2)") + inside = ( + (seeds[:, 0] >= x_values[0]) + & (seeds[:, 0] <= x_values[-1]) + & (seeds[:, 1] >= y_values[0]) + & (seeds[:, 1] <= y_values[-1]) ) - source_segments = [ - np.asarray([[sx, sy], [ex, ey]], dtype=np.float64) - for sx, ex, sy, ey in zip(kx0, kx1, ky0, ky1, strict=True) - ] - arrow_budget = max(1, min(len(source_segments), int(30 * density_value))) + if not np.all(inside): + raise ValueError("streamplot start_points must lie inside the x/y grid") else: - if start_points is not None: - seeds = np.asarray(start_points, dtype=np.float64) - if seeds.ndim != 2 or seeds.shape[1] != 2: - raise ValueError("streamplot start_points must have shape (n, 2)") - inside = ( - (seeds[:, 0] >= x_values[0]) - & (seeds[:, 0] <= x_values[-1]) - & (seeds[:, 1] >= y_values[0]) - & (seeds[:, 1] <= y_values[-1]) - ) - if not np.all(inside): - raise ValueError("streamplot start_points must lie inside the x/y grid") - else: - rows, cols = u_values.shape - stride = max(1, int(min(rows, cols) / (12.0 * density_value))) - seed_x, seed_y = np.meshgrid(x_values[::stride], y_values[::stride]) - seeds = np.column_stack((seed_x.reshape(-1), seed_y.reshape(-1))) - source_segments = _integrate_streamlines( - x_values, - y_values, - u_values, - v_values, - seeds, - integration_direction, - max_steps, + seed_x, seed_y = np.meshgrid( + np.linspace(x_values[0], x_values[-1], max(2, int(18 * density_xy[0]))), + np.linspace(y_values[0], y_values[-1], max(2, int(18 * density_xy[1]))), ) - arrow_budget = max(1, len(source_segments)) - arrow_count = num_arrows * arrow_budget - + seeds = np.column_stack((seed_x.reshape(-1), seed_y.reshape(-1))) + source_segments = _integrate_streamlines( + x_values, + y_values, + u_values, + v_values, + seeds, + integration_direction, + max_steps, + float(maxlength), + float(minlength), + broken_streamlines=broken_streamlines, + density=(float(density_xy[0]), float(density_xy[1])), + step_scale=integration_max_step_scale, + error_scale=integration_max_error_scale, + skip_occupied_seeds=start_points is None, + ) x0_values: list[float] = [] y0_values: list[float] = [] x1_values: list[float] = [] @@ -4667,10 +5689,24 @@ def streamplot( ) collection = PolyCollection(self, entries[0]) arrow_collection = collection - if arrow_count > 0 and len(x0): - arrow_indices = np.unique( - np.linspace(0, len(x0) - 1, min(arrow_count, len(x0))).astype(int) - ) + if num_arrows > 0 and len(x0): + arrow_indices_list: list[int] = [] + segment_offset = 0 + for streamline in source_segments: + deltas = np.diff(streamline, axis=0) + lengths = np.hypot( + deltas[:, 0] / max(float(np.ptp(x_values)), np.finfo(float).eps), + deltas[:, 1] / max(float(np.ptp(y_values)), np.finfo(float).eps), + ) + cumulative = np.cumsum(lengths) + if cumulative.size and cumulative[-1] > 0.0: + targets = cumulative[-1] * ( + np.arange(1, num_arrows + 1, dtype=np.float64) / (num_arrows + 1) + ) + local = np.clip(np.searchsorted(cumulative, targets), 0, len(lengths) - 1) + arrow_indices_list.extend((segment_offset + local).tolist()) + segment_offset += len(lengths) + arrow_indices = np.unique(np.asarray(arrow_indices_list, dtype=np.int64)) dx = x1[arrow_indices] - x0[arrow_indices] dy = y1[arrow_indices] - y0[arrow_indices] lengths = np.hypot(dx, dy) diff --git a/python/xy/pyplot/_rc.py b/python/xy/pyplot/_rc.py index 19537e39..60922f19 100644 --- a/python/xy/pyplot/_rc.py +++ b/python/xy/pyplot/_rc.py @@ -4,6 +4,7 @@ from __future__ import annotations import contextlib +import math import warnings from collections.abc import Iterator from typing import Any @@ -32,6 +33,7 @@ def by_key(self) -> dict[str, list[str]]: "lines.linewidth": 1.5, "lines.markersize": 6.0, "lines.markeredgewidth": 1.0, + "errorbar.capsize": 0.0, "patch.linewidth": 1.0, "patch.edgecolor": "black", "patch.force_edgecolor": False, @@ -44,9 +46,12 @@ def by_key(self) -> dict[str, list[str]]: "axes.edgecolor": "black", "axes.labelcolor": "black", "axes.labelsize": "medium", + "axes.labelweight": "normal", "axes.titlesize": "large", "axes.titlecolor": "auto", + "axes.titleweight": "normal", "axes.linewidth": 0.8, + "axes.autolimit_mode": "data", "axes.xmargin": 0.05, "axes.ymargin": 0.05, "axes.spines.left": True, @@ -61,16 +66,28 @@ def by_key(self) -> dict[str, list[str]]: "ytick.labelsize": "medium", "xtick.major.size": 3.5, "ytick.major.size": 3.5, + "xtick.major.pad": 3.5, + "ytick.major.pad": 3.5, "xtick.major.width": 0.8, "ytick.major.width": 0.8, "legend.loc": "best", "legend.fontsize": "medium", "legend.facecolor": "inherit", "legend.edgecolor": "#cccccc", + "legend.framealpha": 0.8, "legend.frameon": True, + "legend.borderpad": 0.4, + "legend.labelspacing": 0.5, + "legend.borderaxespad": 0.5, "text.usetex": False, "image.cmap": "viridis", + # Matplotlib's "antialiased" default resolves to nearest-neighbor when a + # small image is enlarged by more than 3x; pre-rendering has no final plot + # size yet, so nearest is the faithful and compact default here. + "image.interpolation": "nearest", "image.origin": "upper", + "contour.corner_mask": True, + "contour.negative_linestyle": "dashed", "axes.prop_cycle": _PropCycle(), } @@ -123,10 +140,20 @@ def __setitem__(self, key: str, value: Any) -> None: colors = by_key().get("color") if by_key is not None else None if not colors: raise ValueError("axes.prop_cycle must provide a non-empty color cycle") + if key == "axes.autolimit_mode" and value not in {"data", "round_numbers"}: + raise ValueError("axes.autolimit_mode must be 'data' or 'round_numbers'") + if key == "contour.negative_linestyle" and value not in {"solid", "dashed"}: + raise ValueError("contour.negative_linestyle must be 'solid' or 'dashed'") + if key == "contour.corner_mask" and not isinstance(value, bool): + raise ValueError("contour.corner_mask must be boolean") if key in {"font.size"}: value = float(value) if value <= 0: raise ValueError(f"{key} must be positive") + if key in {"xtick.major.pad", "ytick.major.pad"}: + value = float(value) + if not math.isfinite(value): + raise ValueError(f"{key} must be finite") if key in { "axes.xmargin", "axes.ymargin", @@ -137,6 +164,8 @@ def __setitem__(self, key: str, value: Any) -> None: "ytick.major.size", "xtick.major.width", "ytick.major.width", + "xtick.major.pad", + "ytick.major.pad", }: value = float(value) if value < 0: diff --git a/python/xy/pyplot/_ticker.py b/python/xy/pyplot/_ticker.py index 1c1f7b71..a461c9f8 100644 --- a/python/xy/pyplot/_ticker.py +++ b/python/xy/pyplot/_ticker.py @@ -135,7 +135,7 @@ def __init__(self, nbins: Any = 10, **kwargs: Any) -> None: ] ) - def tick_values(self, vmin: float, vmax: float) -> np.ndarray: + def _raw_ticks(self, vmin: float, vmax: float, *, round_numbers: bool = False) -> np.ndarray: vmin, vmax = sorted((float(vmin), float(vmax))) if not (np.isfinite(vmin) and np.isfinite(vmax)) or vmin == vmax: return np.asarray([vmin], dtype=float) @@ -152,7 +152,14 @@ def tick_values(self, vmin: float, vmax: float) -> np.ndarray: # For steps > 1, keep only integer values. steps = steps[(steps < 1) | (np.abs(steps - np.round(steps)) < 0.001)] raw_step = (_vmax - _vmin) / nbins - large = np.nonzero(steps >= raw_step)[0] + large_steps = steps >= raw_step + if round_numbers: + # Match Matplotlib's MaxNLocator round-number mode: reject a step + # that cannot span the entire padded view in ``nbins`` intervals. + floored_vmins = (_vmin // steps) * steps + floored_vmaxs = floored_vmins + steps * nbins + large_steps &= floored_vmaxs >= _vmax + large = np.nonzero(large_steps)[0] istep = int(large[0]) if len(large) else len(steps) - 1 # Start at the smallest step >= the raw step; walk down only if it # leaves fewer than min_n_ticks ticks inside the view. @@ -170,6 +177,20 @@ def tick_values(self, vmin: float, vmax: float) -> np.ndarray: break return ticks + offset + def tick_values(self, vmin: float, vmax: float) -> np.ndarray: + return self._raw_ticks(vmin, vmax) + + def view_limits(self, vmin: float, vmax: float) -> tuple[float, float]: + """Return data limits, or edge ticks in Matplotlib round-number mode.""" + from ._rc import rcParams + + if rcParams["axes.autolimit_mode"] != "round_numbers": + return float(vmin), float(vmax) + ticks = self._raw_ticks(vmin, vmax, round_numbers=True) + if len(ticks) < 2: + return float(vmin), float(vmax) + return float(ticks[0]), float(ticks[-1]) + class AutoLocator(MaxNLocator): """The default: matplotlib's AutoLocator — MaxNLocator with axes-size diff --git a/python/xy/pyplot/_translate.py b/python/xy/pyplot/_translate.py index 9e526aa4..299d6220 100644 --- a/python/xy/pyplot/_translate.py +++ b/python/xy/pyplot/_translate.py @@ -103,7 +103,10 @@ def line_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: out["dash"] = list(dashes) gapcolor = kwargs.pop("gapcolor", None) if gapcolor is not None: - raise not_implemented("Line2D gapcolor") + # Kept private to the pyplot entry. Materialization draws a solid + # underlay before the dashed foreground, reproducing Matplotlib's + # alternating gap paint without expanding the public mark protocol. + out["_gapcolor"] = resolve_color(gapcolor) path_effects = kwargs.pop("path_effects", None) if path_effects: raise not_implemented("Line2D path_effects") diff --git a/python/xy/styles.py b/python/xy/styles.py index c24a1515..41140573 100644 --- a/python/xy/styles.py +++ b/python/xy/styles.py @@ -40,8 +40,18 @@ _AXIS_COLOR_PROPERTIES = frozenset( {"grid_color", "axis_color", "tick_color", "tick_label_color", "label_color"} ) -_AXIS_LENGTH_PROPERTIES = frozenset({"grid_width", "axis_width", "tick_length", "tick_width"}) +_AXIS_LENGTH_PROPERTIES = frozenset( + { + "grid_width", + "axis_width", + "tick_length", + "tick_label_pad", + "tick_padding", + "tick_width", + } +) _AXIS_SIZE_PROPERTIES = frozenset({"tick_size", "tick_label_size", "label_size"}) +_AXIS_FONT_PROPERTIES = frozenset({"label_font_family", "label_font_style", "label_font_weight"}) _AXIS_COMPAT_PROPERTIES = frozenset({"grid_dash", "grid_opacity"}) _AXIS_DASH_STYLES = frozenset({"solid", "dashed", "dotted", "dashdot"}) _AXIS_DIRECTIONS = frozenset({"in", "out", "inout"}) @@ -147,6 +157,21 @@ def _px(value: StyleValue, label: str, *, positive: bool = False) -> float: return number +def _signed_px(value: StyleValue, label: str) -> float: + if isinstance(value, (int, float)) and not isinstance(value, bool): + number = float(value) + elif isinstance(value, str): + match = _PX_RE.match(value) + if match is None: + raise ValueError(f"{label} must be a finite CSS px length") + number = float(match.group(1)) + else: # pragma: no cover - normalize_css_style rejects this first + raise ValueError(f"{label} must be a finite CSS px length") + if not np.isfinite(number): + raise ValueError(f"{label} must be a finite CSS px length") + return number + + def _opacity(value: StyleValue, label: str) -> float: try: number = float(value) @@ -329,6 +354,7 @@ def _compile_axis_style( _AXIS_COLOR_PROPERTIES | _AXIS_LENGTH_PROPERTIES | _AXIS_SIZE_PROPERTIES + | _AXIS_FONT_PROPERTIES | _AXIS_COMPAT_PROPERTIES | {"tick_direction", "tick_label_anchor"} ) @@ -341,10 +367,20 @@ def _compile_axis_style( raise ValueError(f"{label} has unsupported property {css_prop!r}; supports: {expected}") if prop in _AXIS_COLOR_PROPERTIES: parsed: StyleValue = _paint(raw, f"{label}[{css_prop!r}]") + elif prop in {"tick_label_pad", "tick_padding"}: + parsed = _signed_px(raw, f"{label}[{css_prop!r}]") elif prop in _AXIS_LENGTH_PROPERTIES: parsed = _px(raw, f"{label}[{css_prop!r}]") elif prop in _AXIS_SIZE_PROPERTIES: parsed = _px(raw, f"{label}[{css_prop!r}]", positive=True) + elif prop == "label_font_style": + if not isinstance(raw, str) or raw not in {"normal", "italic", "oblique"}: + raise ValueError(f"{label}[{css_prop!r}] must be 'normal', 'italic', or 'oblique'") + parsed = raw + elif prop in {"label_font_family", "label_font_weight"}: + if not isinstance(raw, (str, int, float)) or isinstance(raw, bool): + raise ValueError(f"{label}[{css_prop!r}] must be a CSS font value") + parsed = raw elif prop == "grid_opacity": parsed = _opacity(raw, f"{label}[{css_prop!r}]") elif prop == "grid_dash": @@ -359,7 +395,8 @@ def _compile_axis_style( if not isinstance(raw, str) or raw not in _AXIS_DIRECTIONS: raise ValueError(f"{label}[{css_prop!r}] must be one of {sorted(_AXIS_DIRECTIONS)}") parsed = raw - _set(out, prop, parsed, css_prop, sources) + canonical = "tick_padding" if prop == "tick_label_pad" else prop + _set(out, canonical, parsed, css_prop, sources) return out diff --git a/scripts/gen_font.py b/scripts/gen_font.py index 9c29a2c6..8b16e524 100644 --- a/scripts/gen_font.py +++ b/scripts/gen_font.py @@ -22,9 +22,11 @@ # Printable ASCII. Axis labels/titles/legends mostly stay within this set. FIRST, LAST = 0x20, 0x7E # Extra codepoints for the pyplot shim's TeX-subset → unicode conversion -# (greek, super/subscripts, math operators) plus typography mpl emits (−, µ). +# (greek, super/subscripts, math operators), typography mpl emits (−, µ), and +# the precomposed umlauts used by Matplotlib's canonical text_commands example. EXTRA = sorted( set( + "öü" "αβγδεζηθικλμνξοπρστυφχψω" "ΓΔΘΛΞΠΣΥΦΨΩ" "⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ⁿⁱ" @@ -33,8 +35,17 @@ ) ) PX = 16 # render size; runtime scales this coverage bitmap to the requested size. +# Keep the two historical atlas advances stable across Matplotlib's bundled +# DejaVu Sans revisions; changing them would move unrelated existing labels. +STABLE_ADVANCES = {"?": 8, "K": 10} ROOT = Path(__file__).resolve().parents[1] OUT = ROOT / "src" / "font.rs" +# The advance/cell metrics alone, for Python-side static layout: `_svg.layout()` +# has to know how wide a tick label or axis title will actually be *before* it +# can reserve a gutter for it, and the rasterizer that draws it is the Rust +# core. Emitting the same numbers from the same generator keeps the reservation +# and the ink from drifting apart (there is no font library in either process). +OUT_PY = ROOT / "python" / "xy" / "_fontmetrics.py" def _load_face() -> ImageFont.FreeTypeFont: @@ -54,7 +65,7 @@ def main() -> None: for code in codepoints: ch = chr(code) # Advance width (horizontal pen movement). - advance = round(face.getlength(ch)) + advance = STABLE_ADVANCES.get(ch, round(face.getlength(ch))) box = face.getbbox(ch) # (left, top, right, bottom) in the ascent-origin frame if box is None or box[2] <= box[0] or box[3] <= box[1]: glyphs.append((advance, 0, 0, 0, 0, b"")) @@ -80,6 +91,8 @@ def main() -> None: _emit(cell_h, ascent, blob, records) print(f"wrote {OUT} — {len(records)} glyphs, {len(blob)} coverage bytes, cell_h={cell_h}") + _emit_python(cell_h, ascent, records) + print(f"wrote {OUT_PY} — {len(records)} advances") def _emit(cell_h: int, ascent: int, blob: bytearray, records: list) -> None: @@ -120,5 +133,65 @@ def _emit(cell_h: int, ascent: int, blob: bytearray, records: list) -> None: OUT.write_text("\n".join(lines) + "\n", encoding="utf-8") +def _emit_python(cell_h: int, ascent: int, records: list) -> None: + """Advance/cell metrics for the Python static-layout path (`_svg.layout`).""" + n_ascii = LAST - FIRST + 1 + ascii_adv = [record[0] for record in records[:n_ascii]] + extra_adv = {ord(ch): records[n_ascii + i][0] for i, ch in enumerate(EXTRA)} + lines = [ + '"""Advance widths of the core\'s embedded DejaVu Sans face.', + "", + "@generated by scripts/gen_font.py — do not edit by hand.", + "", + "`src/font.rs` bakes the same numbers for the Rust rasterizer that draws the", + "text; this module is how `_svg.layout()` can size an axis gutter from the ink", + "it is about to reserve for. DejaVu Sans is also Matplotlib's default face, so", + "an advance measured here is the advance Matplotlib would lay out.", + '"""', + "", + "from __future__ import annotations", + "", + f"BASE_PX = {PX}", + f"CELL_H = {cell_h}", + f"ASCENT = {ascent}", + f"DESCENT = {cell_h - ascent}", + f"FIRST = {FIRST}", + f"LAST = {LAST}", + "", + "# fmt: off", + "# Advances at BASE_PX for printable ASCII, `FIRST` first.", + "ASCII_ADVANCES: tuple[int, ...] = (", + ] + for i in range(0, len(ascii_adv), 20): + lines.append(" " + " ".join(f"{v}," for v in ascii_adv[i : i + 20])) + lines.append(")") + lines.append("") + lines.append("# Advances at BASE_PX for the non-ASCII glyphs, keyed by codepoint.") + lines.append("EXTRA_ADVANCES: dict[int, int] = {") + items = sorted(extra_adv.items()) + for i in range(0, len(items), 8): + chunk = " ".join(f"{cp}: {adv}," for cp, adv in items[i : i + 8]) + lines.append(f" {chunk}") + lines.append("}") + lines.append("# fmt: on") + lines.append("") + lines.append("# Fallback advance for a codepoint the atlas has no glyph for: the") + lines.append("# rasterizer skips it entirely, so it contributes no ink and no advance.") + lines.append("_MISSING = 0") + lines.append("") + lines.append("") + lines.append("def advance(text: str, font_size: float) -> float:") + lines.append(' """Advance width in px of `text` rendered at `font_size`."""') + lines.append(" units = 0") + lines.append(" for char in text:") + lines.append(" code = ord(char)") + lines.append(" if FIRST <= code <= LAST:") + lines.append(" units += ASCII_ADVANCES[code - FIRST]") + lines.append(" else:") + lines.append(" units += EXTRA_ADVANCES.get(code, _MISSING)") + lines.append(" return font_size * units / BASE_PX") + OUT_PY.write_text("\n".join(lines) + "\n", encoding="utf-8") + + if __name__ == "__main__": main() diff --git a/spec/api/styling.md b/spec/api/styling.md index 9549b330..a9dd01c6 100644 --- a/spec/api/styling.md +++ b/spec/api/styling.md @@ -126,7 +126,9 @@ or a CSS `px` value such as `"3px"`. | `grid_dash` | `"solid"`, `"dashed"`, `"dotted"`, or `"dashdot"` | | `grid_opacity` | Number from `0` to `1` | | `tick_length` | Non-negative pixel length | +| `tick_padding` | Signed pixel length (negative allowed) — extra distance between an axis tick and its tick label, on top of the tick's outward length. Defaults to `0`. Honored by static SVG/PNG exports. | | `tick_size` / `tick_label_size`, `label_size` | Positive pixel font size | +| `label_font_weight`, `label_font_family`, `label_font_style` | Axis-label font overrides, passed through to the browser, SVG, and native PNG paths. `label_font_weight` defaults to `400` — see [Chrome text weight](#chrome-text-weight). | | `tick_direction` | `"in"`, `"out"`, or `"inout"` | | `tick_label_anchor` | `"start"`, `"center"`, or `"end"` (mpl `ha` aliases `"left"`/`"right"`/`"middle"` normalize) — which label edge pins to the tick; rotated labels pivot about the pinned edge. Also a first-class `x_axis`/`y_axis` option. X defaults to `"center"`; y defaults to the tick-side edge (`"end"` left of the plot, `"start"` right of it). Honored by static SVG/PNG exports. | @@ -148,6 +150,114 @@ xy.x_axis( ) ``` +Tick-label placement has two regimes, and which one applies is decided by +whether the axis authored any tick geometry — `tick_length` or +`tick_padding`: + +- **Authored.** The label's anchor sits `tick_padding` past the outward end of + the tick mark, plus the room the glyph box itself needs on that side. This is + matplotlib's rule, and it is how the pyplot shim reproduces mpl spacing: it + always supplies `{x,y}tick.major.size` and `{x,y}tick.major.pad` from + `rcParams` (`_rc_axis_style`), so pyplot charts are always in this regime. +- **Unauthored.** The chart keeps a fixed per-side gap. Core's default + `tick_length` is `0` and there is no default `tick_padding`, so deriving the + gap from tick geometry would silently pull the labels of every chart that + styles no ticks toward the spine. The per-side gaps are a layout contract: + charts that author no tick styling render identically before and after + `tick_padding` existed, in the browser client, SVG export, and native + raster alike. `_axis_tick_label_offset` in `python/xy/_svg.py` (shared with + `_raster.py`) and `tickLabelOffset` in `js/src/50_chartview.ts` are the two + implementations, and each renderer passes its own historical per-side value. + +Grid visibility is **per axis**. Every renderer — WebGL canvas, SVG, and native +PNG — paints an axis's grid lines from that axis's own `grid_color` and +`grid_width`, so `grid_color: "transparent"` hides exactly that axis's grid and +leaves the other axis untouched. Enabling one axis's grid never turns the +opposite axis's grid off; x and y are independent switches, and the matplotlib +shim's `Axes.grid(axis="x")`/`Axes.grid(axis="y")` and `Axis.grid()` resolve +onto the same rule. + +### Plot rectangle and chrome reservations + +`xy.chart(..., padding=[top, right, bottom, left])` sets the gutters around the +plot rectangle in pixels. When omitted, the renderers pick label-aware defaults +that leave room for ordinary tick and axis labels; those defaults are +implementation-owned and may evolve with the text measurement and layout +engines. `padding=[0, 0, 0, 0]` plus hidden axes gives an edge-to-edge +sparkline. + +Some chrome is reserved **outside** `padding` rather than inside it, so +supplying padding does not have to anticipate it: + +| Reservation | Where it is allocated | +| --- | --- | +| Chart title band | above the plot | +| A top-side x axis | above the plot | +| Right-side y axis gutter (secondary/named `y`) | to the right of the plot | +| Vertical colorbar and its label | to the right of the plot | +| Horizontal colorbar and its label | below the plot | + +`xy._svg.layout()` is the single resolver for this in the Python exporters, and +the browser client's `ChartView._layout()` mirrors it exactly — the two must +stay in step, because a caller that pins a plot rectangle (as `xy.pyplot` does +to honor Matplotlib's `figure.subplot.*` frame) computes its padding by +subtracting these reservations. + +#### Measured left gutter and the rotated y-axis title + +The **left** gutter is additionally floored at what the left y axis's own text +measures, rather than trusting the flat `46/62 px`: + +``` +left ≥ 10 px inset + half the title's line box + + 0.4 em title-to-tick gap + + tick_padding (+ the outward part of tick_length) + + the widest tick label's advance +``` + +with the title terms dropped when the axis has no title (or places it +`inside_*`), and the tick terms dropped when its tick labels are hidden. Widths +come from the advance table in `python/xy/_fontmetrics.py`, generated by +`scripts/gen_font.py` from the same DejaVu Sans face `src/font.rs` bakes for the +Rust rasterizer — the reservation is measured in the metrics of the font that +will draw the ink, which is also Matplotlib's default face. A rotated tick label +(`tick_label_angle`) contributes `advance·cos θ + line box·sin θ`. + +This is a floor, never an override: `padding` and the `46/62` default both stand +whenever they already fit, so a chart whose text fits the default is laid out +byte-identically. It rises above them only when the alternative is ink drawn off +the canvas or on top of the tick labels, which a static export cannot recover +from the way the DOM can (the browser ellipsizes an overlong categorical tick +label; an SVG has no such fallback). + +The **outside** y-axis title is a quarter-turned line box centered on a fixed +inset — `10 px` from the canvas edge on the left, `plot-right + 40 px` on the +right — matching ChartView's `left:` values. Static exporters emit a *baseline* +rather than a CSS box, so they shift it by half the ascent/descent asymmetry +(`(ascent − descent) / 2`, away from the plot) to land the same ink; this is the +y-axis counterpart of the `font_size × 0.82` correction the x-axis title makes. +A title whose line box is taller than twice the inset is clamped to keep 1 px of +leading ink on the canvas. Titles at an angle other than ±90° keep the raw inset. +`label_offset` moves the title within the reserved gutter and is included in the +reservation. + +Two asymmetries are deliberate, not oversights: + +- **Right-side y axes keep the flat `42/54 px`.** Their title is pinned + plot-relative (`plot-right + 40`) rather than to a canvas inset, so widening + only the static exporters' right gutter would move their title away from the + browser's. Unusually wide right-side tick labels can therefore still meet + their axis title, in every renderer alike. +- **Only a spec-authored `padding` reaches the browser.** `layout()` is a Python + function; a chart rendered live with `padding=None` gets ChartView's own + `46/62` default, not the measured floor. The pyplot shim closes that gap on the + path where it matters — `_mplfig._to_notebook_html` pins a padding to match + Matplotlib's inline `bbox_inches="tight"` canvas, so it asks `layout()` for the + measured gutter first and ships that number, widening the canvas by the + shortfall so the plot box keeps Matplotlib's `0.775` width fraction. Browser, + SVG, and PNG then share one reservation by construction rather than by two + implementations agreeing. + ### Axis ticks and label formatting Tick placement is computed in f64 on the CPU (§16), never through f32, and is @@ -192,6 +302,117 @@ but they fail differently, and only the numeric grammar falls back. `format` is absent or not a string. - **Category axes** ignore `format=` and render the category label. +### Colorbar placement and ticks + +The built-in colorbar's geometry rides the first-paint spec's `colorbar` object +(`spec["colorbar"]`, written by `python/xy/_payload.py` from +`Figure.colorbar_options`) and is honored identically by the browser client +(`js/src/50_chartview.ts`), SVG (`python/xy/_svg.py`), and native PNG +(`python/xy/_raster.py`). + +| Colorbar option | Value | Default | +| --- | --- | --- | +| `orientation` | `"vertical"` (right of the plot) or `"horizontal"` (below it) | `"vertical"` | +| `shrink` | Fraction of the plot's length the bar spans along its long axis, in `(0, 1]` | `1` — full plot length | +| `anchor` | `[x, y]` placement of a shrunken bar within the leftover room | `[0.5, 0.5]` — centered | +| `minor_ticks` | Draw unlabeled minor ticks between the major ticks | absent — off | + +- **`shrink`** scales only the long axis: a horizontal bar's width becomes + `plot.w * shrink`, a vertical bar's height `plot.h * shrink`. Bar thickness + and the chrome room the layout reserves are unchanged, so shrinking a colorbar + never reflows the plot. The browser client additionally clamps the value into + `[0.01, 1]` (absent, zero, or non-finite reads as `1`) and floors a vertical + bar at 24 px; the static renderers use the authored value as given, because + the authoring surface below validates it. +- **`anchor`** is a fraction of the *leftover* room, not of the plot, and only + the component along the bar's long axis is read: a vertical bar uses + `anchor[1]`, a horizontal bar `anchor[0]`. `anchor[0]` runs left → right + (`0` flush left, `1` flush right). `anchor[1]` runs **bottom → top** (`0` + flush with the plot's bottom edge, `1` with its top) — Matplotlib's bottom-up + axes-fraction convention, not the renderers' top-down pixel space. At + `shrink = 1` there is no leftover room, so `anchor` has no effect. The + cross-axis position stays layout-owned: a vertical bar always clears + right-side y-axis chrome, a horizontal one always sits below the bottom axis. +- **`minor_ticks`** splits each interval between consecutive *rendered* major + ticks into fifths and draws four unlabeled 3 px ticks per interval on the + bar's tick side (right of a vertical bar, below a horizontal one). The + subdivision follows whichever major positions the colorbar actually drew — + explicit `ticks` included — and needs at least two of them, so a colorbar + showing a single major tick draws no minor ticks. Minor ticks carry + `data-xy-colorbar-minor="true"` in both the DOM and the SVG and deliberately + carry **no slot**: they are not `class_names`/`styles` targets and inherit the + surrounding text color (`currentColor` in the browser). + +`plt.colorbar()` / `fig.colorbar()` is the only authoring surface for `shrink`, +`anchor`, and `minor_ticks` today; the declarative `xy.colorbar()` component +still exposes `title`, `orientation`, and `ticks` only. The shim also accepts +Matplotlib's `location=` as a synonym for the side — `"right"` selects +`orientation: "vertical"`, `"bottom"` selects `"horizontal"` — and `location` +never reaches the spec as a field of its own. Invalid values raise instead of +being silently reinterpreted: `location="left"`/`"top"` is a +`NotImplementedError` (unsupported placement), a `location`/`orientation` pair +naming different sides is a `ValueError`, and so are a `shrink` outside +`(0, 1]` and an `anchor` that is not a finite `(x, y)` pair. +`Colorbar.minorticks_on()` / `minorticks_off()` toggle `minor_ticks` on the live +handle. `shrink` and `anchor` are omitted from the spec entirely when they hold +their defaults, so the wire shape of a default colorbar is unchanged. + +An **inferred** colorbar domain — the one the shim derives when no explicit +`domain` was authored — is computed over **unmasked, finite** samples only: +`np.ma`-masked entries are compressed out before the min/max, so a masked +image's colorbar spans the values it actually paints rather than the fill values +hidden underneath the mask. When masking (or non-finiteness) leaves no sample at +all, the domain falls through to the existing autoscale path and resolves from +the compiled figure's color domain at render time instead of a `0..1` +placeholder. + +### Legend placement — `loc` and `anchor` + +`xy.legend(loc=...)` places the legend against the plot rectangle by name +(`"upper right"`, `"lower left"`, `"center"`, …). The box is inset 6 px from the +named edge and kept inside the plot rectangle — static export clamps it there +explicitly — so `loc` alone can never paint a legend outside the axes. + +`xy.legend(anchor=...)` replaces that bounded, name-only placement with explicit +geometry, mirroring Matplotlib's `bbox_to_anchor`; the `pyplot` shim maps +`legend(bbox_to_anchor=...)` — a sequence, or any object exposing `.bounds` — +onto this same option. It accepts a sequence of **2 or 4 finite numbers**. +Anything else — a wrong length, a string, a non-finite value — raises +`ValueError` when the component is created, before the chart or an export +renders. The values reach the wire as `spec["legend"]["anchor"]`. + +Coordinates are **normalized plot-rectangle fractions with y pointing up**, the +Matplotlib axes-fraction convention: `x = 0` is the plot's left edge and `x = 1` +its right edge, `y = 0` the **bottom** edge and `y = 1` the **top**. Values +outside `0…1` are legal and are the point of the option — they are how a legend +is placed beside or above the axes. + +| Form | Meaning | +| --- | --- | +| `(x, y)` | A single anchor point. | +| `(x, y, w, h)` | An anchor *box* whose lower-left corner is `(x, y)`, spanning `w` × `h`. | + +`loc` keeps a job under `anchor`: it selects **which point of the legend box** is +pinned to the anchor, and for the 4-value form which point of the anchor box +supplies it. Horizontally `"left"` → 0, `"right"` → 1, otherwise 0.5; +vertically `"lower"` → 0, `"upper"` → 1, otherwise 0.5. So +`legend(loc="lower left", anchor=(0, 1))` pins the legend's lower-left corner to +the plot's upper-left corner, seating the legend entirely above the axes. + +An anchored legend is **not** clamped into the plot rectangle: the 6 px inset and +the containment clamp are both skipped and the coordinates are honored literally. +Reserving room for a legend placed outside the axes is therefore the caller's +job. The composition API performs no automatic padding reservation — only the +`pyplot` shim widens its own chart padding when `bbox_to_anchor` pushes the +legend past an edge. + +In the browser the legend is a DOM overlay above the marks canvas, positioned +through the private `--xy-legend-left` / `--xy-legend-top` custom properties and +a matching `translate()`, with `--xy-legend-right` / `--xy-legend-bottom` set to +`auto` under `anchor`. Static SVG and PNG export compute the same geometry; see +*Static export* below for the clipping consequence, which is a contract change, +not just a new placement. + ## Slot reference Every element below is rendered with `data-xy-slot=""`, so @@ -212,7 +433,7 @@ raises before it reaches the client. | `colorbar` | Colorbar container | | `colorbar_bar` | Colorbar gradient/bands | | `colorbar_tick` | Colorbar tick label | -| `colorbar_title` | Colorbar title | +| `colorbar_title` | Colorbar label (rotated beside a vertical bar) | | `tooltip` | Hover tooltip | | `modebar` | Mode/tool bar container | | `modebar_button` | One mode/tool button (`.xy-active` when engaged) | @@ -237,6 +458,157 @@ raises before it reaches the client.
``` +### Legend geometry + +Legend metrics are **font-relative**, never fixed pixels. Every length below is +a multiple of the legend font size — 11 px unless a `font-size` in `px` is set +on the `legend` slot (pyplot: `legend(fontsize=)`) — so a legend keeps its +proportions instead of cramping as its type grows. The factors are Matplotlib's +`legend` defaults, which is why a pyplot legend measures like a Matplotlib one +without a shim-only code path. + +| Metric | Factor | At 11 px | Notes | +| --- | --- | --- | --- | +| Border pad, per side | `0.4` | 4.4 px | mpl `borderpad`; an `em` `padding` on the slot overrides it | +| Handle length | `2` | 22 px | mpl `handlelength` — the line sample, marker cell, or patch width | +| Handle-to-label pad | `0.8` | 8.8 px | mpl `handletextpad` | +| Column spacing | `2` | 22 px | mpl `columnspacing`, between `ncols` columns | +| Row spacing | `0.5` | 5.5 px | mpl `labelspacing`; an `em` `rowGap` on the slot overrides it | +| Label row height | `1.03` | 11.33 px | one row advances `1.03 + labelspacing` = 16.83 px | +| Glyph advance | `0.564` | 6.2 px | conservative width estimate for column sizing and ellipsis | + +This governs **every static legend**, not only pyplot's: the SVG exporter and +the native rasterizer share one `_legend_layout` (`python/xy/_svg.py`), so a +composed `scatter_chart`/`line_chart` legend and a pyplot one are laid out by +the same code with the same defaults. The browser carries the three spacing +factors as CSS (`padding` in `em`, `column-gap: 2em`, `row-gap: .5em`) and +leaves handle and label metrics to the cascade, because a DOM legend measures +itself and can scroll where a static file cannot. + +Columns size to their own labels rather than inheriting the widest label in the +legend, and each retains at least a handle plus four glyphs; a plot too narrow +for the requested `ncols` loses columns first and only then ellipsizes labels. +A **legend title participates in both measurements**: it widens the box when +its glyph advance plus both border pads exceeds the entry columns, and it is +ellipsized against that same full inner width, so a title that fits is never +shortened. It also consumes one extra `1.03 + labelspacing` row of height, +which can push the last entry out of a short plot; a plot with room for no +entry at all renders neither frame nor title. + +### Default colorbar label orientation + +The `colorbar_title` slot carries the colorbar's label (`title=` on the +composition API, `Colorbar.set_label(...)` under `xy.pyplot`). By default its +orientation follows the bar, matching Matplotlib: + +| Orientation | Placement | Rotation | +| --- | --- | --- | +| vertical | centered beside the bar, outboard of the tick labels | 90° counter-clockwise (reads bottom-to-top) | +| horizontal | centered below the bar, under the tick labels | upright | + +All three renderers agree on this default vertical label: the browser client +uses `writing-mode: vertical-rl` plus a half turn, the SVG exporter uses +`rotate(-90 …)`, and the native PNG exporter uses the rasterizer's quarter-turn +glyph path (`_TEXT_ROT_CCW`). The two static exporters use the same baseline +(`bar_x + bar_width + 38`), and `layout()` reserves enough right-margin room +for the label's cross-axis glyph extent. + +Quarter turns are exact in every renderer, including native PNG; only +*arbitrary* text angles degrade there (glyphs stay upright). The pyplot shim +does not yet model Matplotlib's `Colorbar.set_label(loc=..., labelpad=..., +rotation=..., **text_properties)` customizations; those keyword arguments are +currently accepted and ignored. + +### Chrome text weight + +**Every chrome text element defaults to `font-weight: 400`** — chart title, axis +titles, tick labels, legend entries, legend titles, colorbar titles, and text/ +label/callout annotations alike. This is Matplotlib's default and it is +deliberate: `axes.titleweight`, `axes.labelweight`, and `font.weight` are all +`normal` in Matplotlib 3.11, and its legend titles and colorbar labels are +normal too, so a chart exported from `xy.pyplot` carries the same text weight as +the same script run under Matplotlib. + +The default is a **cross-renderer contract**, not a per-renderer choice. All +three renderers must agree: + +| Renderer | Where the default lives | +| --- | --- | +| Browser render client | `font-weight:400` on the text slot rules in `js/src/20_theme.ts`, plus the inline axis-label/legend-title weights in `js/src/50_chartview.ts` (inline styles beat the slot stylesheet, so both have to say 400) | +| SVG export | `python/xy/_svg.py` — the `font-weight` attribute on the title, axis-title, and legend-title `` elements | +| Native PNG export | `python/xy/_raster.py` — `_native_font_emphasis` maps a weight `>= 600` onto the baked atlas's bold face, so 400 emits a plain, unemphasized text record | + +A renderer that drifts heavier is a bug; `tests/test_text_weight_defaults.py` +asserts the emitted weight per element in the SVG output and in the native +raster command stream, and holds a source-level guard on the TypeScript +defaults (the client bundles are a generated, git-ignored artifact, so a +bundle-reading test could not run from a fresh checkout). + +Heavier text is always opt-in, never a default: + +```python +xy.chart(..., styles={"title": {"font_weight": 600}}) # per-slot +xy.x_axis(label="time", style={"label_font_weight": "bold"}) # per-axis +``` + +Under the pyplot shim, Matplotlib's own knobs work too — +`rcParams["axes.titleweight"]`, `rcParams["axes.labelweight"]`, and the explicit +`ax.set_title(..., fontweight=)` / `ax.set_xlabel(..., fontweight=)` arguments. +Because `normal` is already every renderer's default, the shim only puts a +weight on the wire when it differs from `normal`. + +The native PNG exporter's font atlas is bounded and carries one regular and one +bold face, so it approximates: any weight `>= 600` (or a name in +`bold`/`semibold`/`demibold`/`heavy`/`black`) renders with the bold face, and +everything lighter renders regular. Intermediate weights are therefore not +distinguishable in native PNG output, while the browser and SVG paths pass the +requested weight through verbatim. + +### Legend placement + +The pyplot shim accepts Matplotlib's ten anchored names — `upper right`, +`upper left`, `lower left`, `lower right`, `right`, `center left`, +`center right`, `lower center`, `upper center`, `center` — plus `"best"`. +Validation stays in pyplot: core `xy.legend()` has its own existing vocabulary, +including the documented `"top left"` spelling, and a Matplotlib compatibility +change must not narrow that API. + +`"best"` is resolved to an anchored name during figure build, before the wire. +The scorer follows Matplotlib's `Legend._find_best_position`: + +- candidates are scored in Matplotlib's location-code order (1..10, with code 5 + `right` folded onto its identical code-7 anchor), the first empty one wins, + and ties go to the earlier candidate — this order *is* the tie-break contract; +- each candidate is the **measured** legend box from `_legend_layout` above, as + a fraction of the plot box, not an estimate from row count and label length; +- the box is anchored inside the plot box inset by `borderaxespad` on all four + sides, as Matplotlib's `offsetbox._get_anchored_bbox` pads its container; +- badness is a raw count of line/path vertices strictly inside the box plus one + per intersecting path, collection offsets, and overlapping bar rectangles, + scored against the **displayed** view (an autoranged view is padded by the + engine, so the corner a mark reaches on screen is not the corner it reaches + in data space); +- candidate fractions use the plot rectangle returned by the shared exporter + layout after the figure is built. They are not inferred from a second copy of + default margins. + +Known departures from Matplotlib's badness, in descending impact: + +- **Frame dependency.** A measured box can only match Matplotlib as a fraction + when the displayed axes frame also matches. The frame-geometry work tracked + separately from legend scoring is therefore a required compatibility + dependency, not a reason to score against an imaginary rectangle. +- **Text extents.** Matplotlib 3.11 counts rendered `Text` bounding-box + overlaps. The shim does not yet include text boxes in badness. +- **Non-bar patch detail.** Polygon vertices and crossings are included, and + bars use rectangle overlaps, but marker extents are omitted just as they are + in Matplotlib 3.11. +- **Decimation** (§28). Occupancy is scored from at most 4096 strided vertices + per series, weighted back up to the true length so relative badness survives. + A lone excursion into an otherwise empty box can be missed on a series far + longer than that; Matplotlib counts every vertex and warns that `loc="best"` + is slow for exactly this reason. + ## Why your styles always win The client injects one stylesheet of *visual* defaults (background, color, @@ -480,6 +852,21 @@ antialiased SDF in the point shader, so shapes stay crisp at any size and the border is a true ring (a stroke width with no color borders in the mark color). Symbols compose with the color/size channels. +Glyph geometry follows Matplotlib's marker paths, size convention included. +`diamond` is the `square` glyph rotated 45°, so its half-diagonal is √2× the +glyph radius — the rotated square keeps `square`'s side length at the same +`size` rather than shrinking to fit the unrotated footprint, and `thin_diamond` +is that same diamond squashed to 0.6 width. `triangle_left` and +`triangle_right` rotate the shared triangle path so the apex points along the +named direction and the wide base sits opposite it. Each backend reaches that +geometry by its own route and lands on the same size convention: the WebGL +client scales the point sprite by √2 and leaves the unit-space SDF untouched, +the native rasterizer scales both the SDF threshold and the bounding-box extent +it paints into, and SVG emits the widened outline directly — so one `size` +value is one on-screen glyph across WebGL, PNG, and SVG. Charts that already +used these four symbols render at a corrected size or orientation for an +unchanged `size`; the set of available symbols does not change. + Interaction state belongs to the host framework. In Reflex, use Reflex state, event handlers, conditions, and ordinary CSS classes/styles; XY only emits the events and renders the resulting props. The component API deliberately does not @@ -550,6 +937,34 @@ them through the annotation's own `color` / `stroke_color` / `stroke_width` / `opacity` arguments. Only annotation **labels** are DOM (`annotation_label`) and thus fully CSS-styleable. +### Annotation label boxes + +A text/label/callout annotation may carry a boxed background through four +style keys. The render client applies them as ordinary CSS on the label +element (`border_radius` → `border-radius`, numbers gaining `px`); the SVG and +native-PNG exporters reimplement the same four keys so an export matches the +live label. + +| Key | Browser | SVG export | Native PNG export | +| --- | --- | --- | --- | +| `background` | CSS `background` | `` | `FILL` polygon | +| `border` | CSS `border` (`"1px solid "`) | `` + `stroke-width` | `STROKE` polyline | +| `padding` | CSS `padding` | grows the rect | grows the polygon | +| `border_radius` | CSS `border-radius` | `` | polygon corners arc-flattened, 4 segments per quarter turn | + +Each renderer clamps `border_radius` to half the shorter box side, as CSS +does, so an oversized radius degrades to a stadium rather than an inverted +polygon. The exporters size the box from a dependency-free, glyph-shaped +sans-serif width estimate, so a box tracks its text approximately, not exactly. + +**Label color** resolves as `label_color` → `color` → the renderer's own +default, and the three defaults are *not* the same value: the browser uses +`--chart-annotation-text` (falling back to `--chart-text`), the SVG exporter +`#667085`, and the native rasterizer `rgba(32,32,32,.85)` (which composites to +`rgb(65,65,65)` on white). A caller that needs one colour across all three must +say so; `xy.pyplot` does, pinning `label_color` from +`rcParams["text.color"]` on every text/annotate label. + ## Static export `fig.to_image(format="png", *, width=, height=, scale=2.0, background=, @@ -593,8 +1008,8 @@ so small labels are slightly less refined than a browser's. **Native text coverage.** The atlas is a generated grayscale DejaVu Sans sheet (`src/font.rs`, regenerated by `scripts/gen_font.py`) baked at a 16 px base cell and blitted and scaled at runtime, so glyph coverage is a fixed set: ASCII -32–126 plus 110 enumerated extras (Greek, common math operators, arrows, -super/subscripts, typographic quotes and dashes). A codepoint outside that set +32–126 plus 112 enumerated extras (Greek, common math operators, arrows, +super/subscripts, typographic quotes and dashes, and `ö`/`ü`). A codepoint outside that set — CJK, Cyrillic, Arabic, emoji, most accented Latin — has no glyph and is **silently skipped**, with no tofu box and no advance reserved, so a title, tick label, legend entry, or annotation containing one renders shortened rather @@ -624,3 +1039,50 @@ PNG. Complete paint references such as `var(--accent)` resolve against custom properties in the chart's own `style`, including nested token aliases and `var()` fallbacks. SVG renders smooth curves as exact cubic Béziers; the native raster flattens them to a fine polyline. + +**Legend clipping, and the `anchor` exemption.** The browser hands an oversized +legend a scrollbar. A static file cannot scroll, so SVG and PNG export instead +ellipsize the labels and clip the legend to the plot rectangle. A legend with +`anchor` set (see *Legend placement* above) is **exempt** from that clip. This is +a deliberate narrowing of an older guarantee: static export used to promise that +a legend never painted outside the plot rectangle, and an anchored legend gives +that promise up so it can sit beside or above the axes. Nothing else bounds it — +an anchored legend that overruns the canvas is cut off by the image edge, so +reserve padding for it. + +The exemption is scoped **per legend** in both static backends: each legend box +keeps or drops the clip on its own `anchor`, so an anchored extra legend does not +un-clip the main one (or a non-anchored sibling extra). SVG gives each legend +group its own `clip-path`; the native rasterizer's clip is a stateful command, so +it switches the clip rectangle around each legend and only emits a command on a +transition — an all-anchored or all-bounded figure produces the same command +stream it always did. The browser needs no equivalent rule: every legend box is +its own scroll container sized by `--xy-legend-max-width`/`-height`, so the +constraint is already per element there. + +**The frame is sized to measured glyph advances.** A static legend column is as +wide as its widest label actually sets, not as wide as its character count +suggests. The advances are the bundled DejaVu Sans ones the native rasterizer +already blits, mirrored Python-side into `python/xy/_fontmetrics.py` and +generated beside `src/font.rs` by `scripts/gen_font.py`, so the two cannot +drift. A flat per-character average cannot bound a proportional face — `m` is +over three times the width of `l`, so `"gamma"` sets 42.6 px at the 11 px legend +font against a 31.0 px estimate — and sizing a frame from the estimate drew the +border *inside* its own labels. Labels and the title are both ellipsized against +the same measured budget, so whatever survives truncation also fits. This is +what the browser does natively: each legend column is `max-content`. A codepoint +the atlas lacks reserves the nominal average advance rather than the +rasterizer's zero, because SVG resolves it against the viewer's fonts and does +paint it; over-reserving only widens the frame, which can never spill a label. + +Border pad aside, the guarantee is one-directional: the frame contains its +entries. It is a bound, not a matplotlib-identical measurement — the faces +differ, so expect small numeric differences against matplotlib's own +`borderpad` inset, not a different sign. + +**The frame is a closed rectangle.** All four sides paint, matching +matplotlib's legend frame (a `FancyBboxPatch`). SVG emits a `` and the +browser a CSS `border`, both inherently four-sided; the native rasterizer +strokes the four corner points as a *closed* polyline, since stroking them open +paints top/right/bottom and silently drops the left edge. Fill and stroke both +carry `framealpha`, and `frameon=False` drops the box entirely. diff --git a/spec/design/pan-and-zoom-configuration.md b/spec/design/pan-and-zoom-configuration.md index 18629afe..c43cb660 100644 --- a/spec/design/pan-and-zoom-configuration.md +++ b/spec/design/pan-and-zoom-configuration.md @@ -457,12 +457,34 @@ single coordinated keymap design. xy.x_axis( domain=(20, 80), # initial/home view bounds=(0, 100), # hard navigation envelope + margin=0.05, # padding around an *automatic* domain ) ``` Domain is never a hard limit. `bounds="data"` resolves the canonical data range in Python independently of an explicit domain. +`margin` is a non-negative fraction of the data span padded onto both ends of an +**automatic** domain (matplotlib's `Axes.margins`; the pyplot shim routes +`margins()`/`rcParams["axes.{x,y}margin"]` through it). An explicit `domain` +short-circuits autoscaling entirely, so `margin` and `domain` never combine — +the axis takes `domain` verbatim. Unset, the axis keeps the historical 3% pad, so +`margin` is additive public API and changes no existing chart. Details that are +part of the contract, not incidental: + +| Case | Behavior | +| --- | --- | +| `margin` unset | 3% of the data span on each end. A log axis additionally floors the low edge at `max(lo / 10, nextafter(0, 1))`. | +| `margin=0` | The domain is exactly the data range — no pad, on any scale kind. | +| Log axis with an explicit `margin` | The pad is applied in log10 space (`10 ** (log10(lo) - span * margin)`), so it is multiplicative and symmetric on screen. The `lo / 10` floor does not apply: an authored margin is the authority on the low edge. | +| Singleton data range (`lo == hi`) with an explicit `margin` | The extent becomes `[lo, lo + 1]` and the margin pads that unit interval — matching mpl's singleton handling. Without a margin the legacy fallback still applies: `±5%` of `abs(lo)`, or `±0.5` at zero. | +| Zero-baseline marks (bars, areas) | Unchanged: the padded edge still snaps back to `0` when the data range touches it, so a bar chart's baseline does not float off the spine. | +| Both ends sticky (mesh, image, ECDF cumulative axis) | The axis takes the data range verbatim, as matplotlib's sticky edges do for `imshow`/`pcolormesh`/`hist2d`/`specgram` and for an ECDF's 0/1 axis. The engine has no sticky concept beyond the zero-baseline anchor above, so the pyplot shim resolves this case itself and ships a materialized `domain` in place of `margin` (`Axes._fully_sticky_domain`) — the two never combine. A *one-sided* sticky edge is the zero baseline and stays with `margin`, anchored by the engine. | + +`margin` is resolved in Python, in f64, by `Figure._range` — only the resulting +domain crosses the wire, so it is not a renderer-side concept and needs no +client, SVG, or raster support. + `bounds` and `zoom_limits` are complementary: - `bounds` constrains where a range may be positioned and therefore affects pan, diff --git a/spec/design/rust-engine.md b/spec/design/rust-engine.md index db452d0c..881fc0a1 100644 --- a/spec/design/rust-engine.md +++ b/spec/design/rust-engine.md @@ -82,12 +82,12 @@ src/ # 15,423 lines shipped, 8 modules # byte-identical to the serial path) and the fused # raster→PNG encode via `png`/fdeflate. # No unsafe; owns the crate's one third-party dep. - font.rs (1039) # generated by scripts/gen_font.py — do not hand-edit. + font.rs (1051) # generated by scripts/gen_font.py — do not hand-edit. # Baked DejaVu Sans grayscale coverage atlas for - # raster.rs: 205 glyph records (advance, w, h, left, + # raster.rs: 207 glyph records (advance, w, h, left, # top, coverage offset/len) at BASE_PX=16 plus the # row-major coverage bytes, and EXTRA_CODEPOINTS, the - # sorted table of the 110 non-ASCII codepoints. Data + # sorted table of the 112 non-ASCII codepoints. Data # only — no shaping, no FreeType, no unsafe. Coverage # limits are a product constraint, not a detail: §2.1. css.rs (788) # tiered CSS value/color validation behind `xy_css_check`. @@ -127,13 +127,14 @@ argminmax, tsdownsample-class speed) with the lean build as default. ### 2.1 Native text is a bounded subset, and misses are silent Declining FreeType bought the single-cdylib property (§3.1) and paid for it in -Unicode coverage. `font.rs` bakes exactly 205 glyphs: ASCII 32–126 (95) plus -the 110 codepoints enumerated in `font::EXTRA_CODEPOINTS` — lowercase Greek +Unicode coverage. `font.rs` bakes exactly 207 glyphs: ASCII 32–126 (95) plus +the 112 codepoints enumerated in `font::EXTRA_CODEPOINTS` — lowercase Greek (α–ω) and the eleven uppercase Greek letters that differ from Latin forms (Γ Δ Θ Λ Ξ Π Σ Υ Φ Ψ Ω), math operators (`∂ ∇ ∈ − ∓ √ ∝ ∞ ∫ ≈ ≠ ≤ ≥`), the left and right arrows only, super/subscript digits and a handful of subscript -letters, typographic quotes, en/em dashes, and a few symbols (`° ± × · µ ²³¹ …`). -Nothing else exists: no accented Latin at all, no Cyrillic, no CJK, no Arabic, +letters, typographic quotes, en/em dashes, the `ö`/`ü` glyphs used by +Matplotlib's canonical text example, and a few symbols (`° ± × · µ ²³¹ …`). +Nothing else exists: no other accented Latin, no Cyrillic, no CJK, no Arabic, no emoji. The failure mode is worse than the coverage gap. `glyph_index` @@ -141,8 +142,8 @@ The failure mode is worse than the coverage gap. `glyph_index` loop's `let … else { continue; }` (`src/raster.rs:1236-1238`) drops that character **before** the advance is applied — so the glyph is deleted, not substituted, and the following glyphs close up over the hole. There is no tofu -box, no fallback glyph, no warning, and no error. `"Müller"` rasterizes as -`"Mller"`; a fully non-Latin label rasterizes as nothing. The anchoring pass +box, no fallback glyph, no warning, and no error. `"café"` rasterizes as +`"caf"`; a fully non-Latin label rasterizes as nothing. The anchoring pass sums advances through the same `glyph_index` filter (`src/raster.rs:1200-1204`), so a centered or right-anchored label is positioned on its *shortened* width — the loss is self-consistent and therefore invisible in the output. diff --git a/spec/matplotlib/compat-changelog.md b/spec/matplotlib/compat-changelog.md index 0a58aa0f..1778169b 100644 --- a/spec/matplotlib/compat-changelog.md +++ b/spec/matplotlib/compat-changelog.md @@ -4,6 +4,18 @@ This changelog records changes to the upstream compatibility target and to the meaning of xy's compatibility levels. It complements the project changelog, which covers user-visible releases across the whole package. +## Vector-field gallery corrections — 2026-07-24 + +- `quiver(units=...)` now converts Matplotlib's width-unit vocabulary without + changing arrow length semantics; figure-coordinate quiver keys also convert + their basic MathText labels. +- `barbs` now renders fixed-length WMO-style flag/full/half geometry and honors + length, pivot, increments, rounding, empty fill, size, color, and flip + controls. +- `streamplot` now uses an occupancy-aware adaptive Heun integrator for default + and explicit seeds. `broken_streamlines=False` and both Matplotlib 3.11 + integration scale controls affect the generated trajectories. + ## Matplotlib 3.11 development snapshot — 2026-07-13 - Pinned upstream revision `bde111fb4e` @@ -266,5 +278,56 @@ colorbar domains) fully cleared. `subplots(..., toolbar=...)`, which forwards it to `figure` — overrides rcParams for one figure. +### Default colorbar label orientation — 2026-07-24 (Matplotlib 3.11.1 reference) + +- `Colorbar.set_label(...)` / `colorbar(label=...)` now render Matplotlib's + default label geometry in native PNG: rotated 90° counter-clockwise and + centered beside a vertical bar, outboard of its tick labels. The native exporter had + instead drawn the label horizontally above the bar at `plot.y - 5`, where the + glyph ascent overflowed the canvas top edge and the text was clipped — the + placement was chosen on the since-outdated assumption that the native text + primitive could not rotate. It rotates in quarter turns + (`TEXT_ROTATED`/`TEXT_ROTATED_CW`, already used for rotated axis titles), so + 90° is exact here; only arbitrary text angles still fall back to upright + glyphs. The two static exporters now use the same baseline. Browser and SVG + output are unchanged — both already had the correct default orientation. + This clears the three loud-free but visually wrong PDSH ch. 04.05 cells + (`hist2d`, `hexbin`, and `imshow` colorbars with labels). +- Non-pyplot (composition API) colorbars built with `xy.colorbar(title=...)` + share the same renderer, so their vertical labels change in PNG export the + same way. Horizontal colorbar labels are untouched in every renderer. +- Matplotlib's `Colorbar.set_label` customization keywords (`loc`, `labelpad`, + rotation, and other text properties) remain outside this change and are + currently accepted and ignored by the shim. + +### Mesh and distribution autoscale — 2026-07-24 (Matplotlib 3.11.1 reference) + +- The shim's pre-build autoscale scan (`Axes._iter_entry_arrays`) now + recognizes the `@mark`/`heatmap`, `step`, and `box` entry shapes, which keep + their coordinates inside `kwargs` or compact factory arguments rather than + as top-level `x`/`y`. Those + axes previously scanned as *dataless* and were pinned to the empty `(0, 1)` + view, clipping the geometry: a 30×30 `hist2d` showed roughly 3×1 of its bins. + Affects `hist2d` (uniform bins), `pcolormesh` on a uniform grid, `specgram`, + `ecdf`, `step`, and the compact `boxplot` path. Non-uniform + `hist2d`/`pcolormesh` meshes now carry their coordinate-grid extent through + the triangle expansion too, including when every scalar is masked. + `hexbin`, `contour`/`contourf`, `imshow`, `tripcolor`, `violinplot`, and + `errorbar` already scanned correctly and are unchanged. +- Sticky edges are now derived for mesh, image, and ECDF entries, so + `hist2d`/`pcolormesh`/`specgram`/`imshow` view limits are exactly the outer + cell edges and an ECDF's cumulative axis is exactly `0..1` — matching + Matplotlib, which gives these artists sticky edges and therefore no margin. + An axis with sticky edges on *both* ends ships a materialized `domain` + instead of a `margin`; one-sided rectangle baselines are unchanged and stay + anchored by the engine. +- `pcolormesh(C)` uses Matplotlib's implicit integer edges `0..N` and `0..M`; + `specgram` reconstructs its image centers so the frequency view lands on the + FFT endpoints instead of adding half a frequency bin beyond them. +- `boxplot` autoscales its value axis over the Tukey whiskers plus the flier + points when `showfliers` is on. Its default category positions are + Matplotlib's 1-based ordinals, and `manage_ticks=True` reserves a half unit + around the outer positions regardless of the drawn box width. + Future entries must identify the Matplotlib release/revision, inventory additions or removals, and any compatibility-level changes. diff --git a/spec/matplotlib/compat.md b/spec/matplotlib/compat.md index c11fb4fd..ef5009be 100644 --- a/spec/matplotlib/compat.md +++ b/spec/matplotlib/compat.md @@ -54,28 +54,29 @@ dependency-free `triangles=` shorthand into Matplotlib's equivalent | `scatter(x, y, s=, c=, cmap=, vmin=, vmax=, alpha=, marker=, edgecolors=, plotnonfinite=)` | `s` (pt², area) maps to pixel diameter; numeric 1-D `c` remains a colormap encoding, while `N×3`/`N×4` face and edge colors, alpha arrays, sizes, and linewidth arrays stay in one collection. Explicit alpha replaces intrinsic RGBA alpha, matching Matplotlib; custom norms/marker paths fail loudly | | `bar`, `barh`, `grouped_bar`, `bar_label` | string categories, stacking bases, per-bar face/edge color-alpha pairs and linewidths, plus iterable/indexable `BarContainer.patches` views whose setters mutate the parent batched trace | | `hist(bins=, range=, density=, cumulative=, weights=, orientation=, stacked=)` | Returns computed counts/edges; bar, step, and stepfilled families render in both vertical and horizontal orientations | -| `hist2d`, `hexbin`, `ecdf` | 2D uniform binning uses the native Rust kernel; hexbin uses Matplotlib's two-offset-grid nearest-center assignment and six-triangle data-space cells, supports `C`, arbitrary scalar reducers, and `mincnt`, and retains only the bounded lattice rather than source points | -| `boxplot`, `violinplot`, `bxp`, `violin`, `errorbar` | Boxplots support notches, bootstrap/user confidence intervals, median overrides (drawn median only; notch CIs stay data-derived like Matplotlib), percentile/custom whiskers, cap widths, `sym`, and component colors/widths/alpha — dashed component linestyles fail loudly. Violins support Scott/Silverman/scalar/callable Gaussian-KDE bandwidths, quantiles, and low/high sides; the default (bw_method omitted) uses the native histogram violin mark, whose shape differs from the explicit KDE path | +| `hist2d`, `hexbin`, `ecdf` | 2D uniform binning uses the native Rust kernel; hexbin uses Matplotlib's two-offset-grid nearest-center assignment and six-triangle data-space cells, supports `C`, arbitrary scalar reducers, and `mincnt`, and retains only the bounded lattice rather than source points. `hist2d` view limits are the outer bin edges with no margin, matching Matplotlib's sticky mesh edges; non-uniform bins delegate to `pcolormesh` and autoscale through the quad-mesh path instead. `ecdf` carries the ordinary margin on the sample axis and is sticky at 0 and 1 on the cumulative axis | +| `boxplot`, `violinplot`, `bxp`, `violin`, `errorbar` | Boxplots support notches, bootstrap/user confidence intervals, median overrides (drawn median only; notch CIs stay data-derived like Matplotlib), percentile/custom whiskers, cap widths, `sym`, and component colors/widths/alpha — dashed component linestyles fail loudly. Violins support Scott/Silverman/scalar/callable Gaussian-KDE bandwidths, quantiles, and low/high sides; the default (bw_method omitted) uses the native histogram violin mark, whose shape differs from the explicit KDE path. `boxplot` autoscales its value axis over the Tukey whiskers plus, when `showfliers` is on, the flier points. Its default category positions are 1-based and `manage_ticks=True` reserves half a unit around the outer positions, matching Matplotlib | | `fill_between(x, y1, y2, where=, step=)` / `fill_betweenx` | Masks are split into finite contiguous polygons; step geometry is expanded exactly | | `stackplot` | All four baselines are computed by the native stacked-bounds kernel | -| `imshow` / `pcolormesh` (`cmap=`, `vmin=`/`vmax=`, `origin=`) | `imshow` defaults to `rcParams['image.origin']`; nearest stays cell-exact and Matplotlib's smoothing mode names all collapse to the shim's single bounded gradient upsampling (a visual approximation, not per-mode kernels) and apply to scalar data only — RGB(A) truecolor arrays render unresampled — while unsupported stages/transforms fail loudly. Uniform meshes retain the texture fast path; nonuniform and curvilinear grids use native quad-to-triangle expansion | +| `imshow` / `pcolormesh` (`cmap=`, `vmin=`/`vmax=`, `origin=`) | `imshow` defaults to `rcParams['image.origin']`; nearest stays cell-exact and Matplotlib's smoothing mode names all collapse to the shim's single bounded gradient upsampling (a visual approximation, not per-mode kernels) and apply to scalar data only — RGB(A) truecolor arrays render unresampled — while unsupported stages/transforms fail loudly. Uniform meshes retain the texture fast path; nonuniform and curvilinear grids use native quad-to-triangle expansion. Both hug their outer cell edge with no margin, as Matplotlib's sticky image/mesh edges do | | `step`, `stairs`, `stem`, `eventplot` | Compact step/stem/segment marks; no Python-side vertex expansion | | `contour` / `contourf` / `clabel` | Native marching squares over rectilinear grids; warped grids route through native Delaunay/marching-triangle kernels; automatic labels repeat at bounded, separated positions along each level (line knockout for `inline=True` remains a visual approximation) | -| `quiver`, `barbs`, `streamplot` | Native vector endpoint/arrowhead and bounded streamline kernels feeding one instanced segment mark. Barbs are a visual approximation: magnitude maps to a bounded tick count, not WMO 50/10/5 increments. Streamplot always uses the shim's own bounded fixed-step integrator (identical output with or without Matplotlib installed, but paths approximate Matplotlib's adaptive ones); `start_points`, `integration_direction`, array widths/colors and `num_arrows` are honored, and remaining non-default integration options fail loudly | +| `quiver`, `barbs`, `streamplot` | Quiver supports Matplotlib's width-unit vocabulary independently from length scaling. Barbs use fixed-length staffs and Matplotlib's flag/full/half decomposition, including increments, rounding, empty glyphs, colors, sizes, flipping, and pivots. Streamplot uses a dependency-free adaptive Heun integrator with occupancy-aware seeding; `start_points`, `integration_direction`, `broken_streamlines`, integration step/error scales, array widths/colors, and `num_arrows` are honored | | `tripcolor`, `triplot`, `tricontour`, `tricontourf` | Explicit topology or native dependency-free Delaunay triangulation; indexed geometry and isolines stay in Rust | -| `pie` / `pie_label` | Native pie/donut tessellation and the Matplotlib 3.11 `PieContainer` (`values`, `fracs`, grouped text labels) | -| `axhline` / `axvline` / `axhspan` / `axvspan`, `text`, `annotate`, `table` | Fractional span bounds plus data/axes/figure text coordinates are supported. `annotate(arrowprops=)` draws real arrows in every output: offset-point text becomes an engine callout (arrow pinned from label to point across zoom), data-coordinate text an arrow annotation; date-string coordinates convert on datetime axes. Arrowstyles map to head/tail shapes (`->` open V, `-\|>` filled, `\|-\|`/brackets bar caps, `fancy`/`simple`/`wedge` filled tapered shafts sized by the text's mutation scale) and `connectionstyle` arc3/angle3/angle become quadratic curves (corner rounding approximated); `alpha` dims the arrow only. `bbox=` becomes label box styles (fill/edge/round corners/`pad`) on the HTML label; static exporters keep the plain label. Text is unclipped like Matplotlib (`clip_on=False`), and axes-fraction text right of the axes box (x > 1, e.g. seaborn-style row titles) reserves right margin in every exporter. `rotation=90/270` renders vertical text in browser, PNG, and SVG with Matplotlib's rotate-then-align box semantics; other angles rotate in browser and SVG output only (native PNG draws them horizontally) | +| `pie` / `pie_label` | Native pie/donut tessellation and the Matplotlib 3.11 `PieContainer` (`values`, `fracs`, grouped text labels), including dtype-preserving value formats, radial label rotation/alignment, and common text properties | +| `axhline` / `axvline` / `axhspan` / `axvspan`, `text`, `annotate`, `table` | Fractional span bounds plus data/axes/figure text coordinates are supported. `annotate(arrowprops=)` draws real arrows in every output: offset-point text becomes an engine callout (arrow pinned from label to point across zoom), data-coordinate text an arrow annotation; date-string coordinates convert on datetime axes. Arrowstyles map to head/tail shapes (`->` open V, `-\|>` filled, `\|-\|`/brackets bar caps, `fancy`/`simple`/`wedge` filled tapered shafts sized by the text's mutation scale) and `connectionstyle` arc3/angle3/angle become quadratic curves (corner rounding approximated); `alpha` dims the arrow only. `bbox=` becomes label box styles (fill/edge/round corners/`pad`) in browser and static exports; its `alpha` is the *patch* alpha and dims face and edge together, as Matplotlib's element `opacity` does, and `boxstyle="round"`/`round4` corners are rounded in SVG (`rx`) and native PNG as well as in the browser. An arrow-less `text`/`annotate` label is painted with `rcParams["text.color"]` in all three renderers rather than each renderer's own annotation-label default. Text is unclipped like Matplotlib (`clip_on=False`), and axes-fraction text right of the axes box (x > 1, e.g. seaborn-style row titles) reserves right margin in every exporter. `rotation=90/270` renders vertical text in browser, PNG, and SVG with Matplotlib's rotate-then-align box semantics; other angles rotate in browser and SVG output only (native PNG draws them horizontally) | | `from xy.pyplot import FacetGrid` (seaborn-shaped) | Row/column small multiples with seaborn's `map` contract (subset → activate panel → call the pyplot function), shared domains, edge-only axis labels, top-row column titles, and `margin_titles=True` rotated row titles. `hue=`/`palette=`, `col_wrap=`, `map_dataframe`, and `add_legend` fail loudly | -| `xlabel` / `ylabel` / `title` / `suptitle` | Suptitles are retained in HTML and multi-panel PNG/SVG | -| `legend()` | `loc`, columns, title/font size/colors, frame styling, `borderpad`, `labelspacing`, `fancybox`, `framealpha`, and `shadow` are retained across browser and static output. `loc='best'` chooses the least occupied corner from bounded samples of the current data | +| `xlabel` / `ylabel` / `title` / `suptitle` | Suptitles are retained in HTML and multi-panel PNG/SVG. `ylabel` sits clear of the y tick labels in every renderer: the left gutter is reserved from the measured advances of the tick labels and the rotated title rather than from a fixed constant, leaving Matplotlib's `0.4 em` (5.6 px at the 10 pt/100 dpi default) title-to-tick gap — see *Chrome gutters and the rotated y-axis title* in `spec/api/styling.md` for the formula and its two documented asymmetries | +| `legend()` | `loc`, columns, title/font size/colors, frame styling, `borderpad`, `labelspacing`, `borderaxespad`, `fancybox`, `framealpha`, and `shadow` are retained across browser and static output. `loc='best'` scores the measured displayed legend box in Matplotlib location-code order using path vertices/crossings, collection offsets, and bar-rectangle overlaps. It resolves before the wire; pyplot rejects misspelled Matplotlib locations without narrowing core `xy.legend()`'s independent location vocabulary. Text-box scoring and bounded long-path sampling are documented in `spec/api/styling.md` § Legend placement | | `grid(True/False)` | toggles the grid via the theme | -| `xlim` / `ylim`, axis scales, `invert_xaxis/yaxis` | linear/log are native; symlog/logit/asinh use dependency-free monotone data transforms with inverse limit/tick semantics. Automatic linear ticks include Matplotlib's 2.5 step and use uniform decimal padding across a tick set; locations refresh as data arrives. Artist `get_data()` reflects the transformed space; logit masks values at/outside (0, 1) | +| `xlim` / `ylim`, `set_xmargin` / `set_ymargin`, axis scales, `invert_xaxis/yaxis` | linear/log are native; symlog/logit/asinh use dependency-free monotone data transforms with inverse limit/tick semantics. Automatic linear ticks include Matplotlib's 2.5 step and use uniform decimal padding across a tick set; locations refresh as data arrives. `axes.autolimit_mode="round_numbers"` expands automatic linear limits to the first and last AutoLocator ticks after applying the configured margins. Artist `get_data()` reflects the transformed space; logit masks values at/outside (0, 1) | | `set_major_locator` / `set_major_formatter`, `plt.NullLocator/FixedLocator/MultipleLocator/MaxNLocator/LinearLocator/LogLocator`, `plt.NullFormatter/FixedFormatter/FuncFormatter/FormatStrFormatter/StrMethodFormatter/ScalarFormatter` | xy-owned re-implementations resolved at build time against live data limits (Null/Fixed/Multiple/Linear are position-exact; MaxN/Auto port Matplotlib's `MaxNLocator._raw_ticks` — same step tables, edge extension, and offset handling — with `nbins="auto"` budgeted from the estimated plot rect like `Axis.get_tick_space()`; Log remains approximate). Third-party locator objects work if they implement `tick_values(vmin, vmax)`; minor locators/formatters are retained for round-tripping but minor ticks do not render, except that a labeled minor pair under a blanked major formatter (the centered date-label idiom) is promoted to the drawn tick set | | `plt.dates.MonthLocator/YearLocator/DayLocator/DateFormatter` | xy-owned equivalents of the `matplotlib.dates` classes gallery scripts use; they locate and format in the engine's canonical ms-since-epoch axis unit (not Matplotlib's day floats), and `interval` approximates rrule by epoch-anchored occurrence counting | | datetime, timedelta, and string coordinates | datetime inputs use the engine's automatic date ticks, timedeltas are bounded to elapsed seconds, and common strings use categorical ticks; the general Matplotlib units registry is intentionally out of scope. pandas datetime plotting (`series.plot(ax=ax)`) works against that contract: `get_{x,y}data(orig=False)` returns ms-since-epoch floats, and pandas' period-ordinal tickers (`TimeSeries_Date*`) are accepted as no-ops so the native date ticks keep rendering | | `xticks(positions, labels, rotation=)` / `tick_params(labelrotation=)` | Exact positions and strings render in browser, PNG, and SVG | | `twinx()`, `secondary_xaxis()`, `secondary_yaxis()` | second data axes and linked tick-only secondary axes with callable forward/inverse conversions. Secondary-axis ticks are evenly spaced conversions of the primary domain (not Matplotlib's secondary-unit locators) and currently reach the interactive HTML client only — PNG/SVG export does not draw them yet | | `fig, ax = plt.subplots()`; `plt.subplots(n, m, figsize=, dpi=, squeeze=, sharex=, sharey=)` | Grid renders as CSS-grid HTML and stitched PNG/SVG; shared axes use common domains and live linked pan/zoom. `Figure.subplots_adjust(left=, right=, top=, bottom=, wspace=, hspace=)` moves the SubplotParams frame: the grid resolves to explicit figure rectangles and every exporter (HTML, PNG, SVG) positions panels at those rectangles | +| `Axes.get_position(original=False)` and the rendered axes frame | Supported subplot and free-form axes report their live figure rectangle and render on it. `original=True` returns the allocated rectangle before an adjustable-box aspect correction; the default applies the correction and its anchor, matching Matplotlib. Grid cells resolve under the live SubplotParams (`wspace`/`hspace`, width/height ratios), while explicit `add_axes`/`set_position` rectangles take precedence until a later layout adjustment. Titles, top-side x axes (`matshow`), and secondary-y gutters grow the surrounding allocation instead of moving the frame. **Known exception:** an axes carrying a colorbar keeps label-aware margins because xy and Matplotlib currently reserve the colorbar strip through different layout paths | | `fig.add_subplot(2, 2, 1)` / `add_subplot(221)` | | | `plt.subplot_mosaic([['A','B'],['C','C']])` / `Figure.subplot_mosaic` | Row sequences (a list of equal-length label strings, or nested label lists) resolve to a uniform grid; each distinct label, in first-appearance order, binds to the next cell, returning `(fig, {label: Axes})` with `figsize=`/`dpi=` sizing the figure. Repeated labels do not span and `'.'` does not blank a cell — the grid keeps one axes per cell — and Matplotlib's single-string forms (`'AB;CC'`, newline-separated blocks) are not parsed into rows | | `gca` / `gcf` / `sca` / `figure(num)` / `close(...)` | matplotlib's implicit-state semantics | @@ -83,10 +84,12 @@ dependency-free `triangles=` shorthand into Matplotlib's equivalent | `plt.show()` | notebooks: inline HTML display; scripts: opens the default browser | | Artists: `set_data` / `set_ydata` / `set_color` / `set_label` / `set_linewidth` / `remove` | mutating a handle rebuilds the chart on next render. Scatter collections additionally vectorize facecolors, edgecolors, alpha, linewidths, and sizes; `alpha=None` restores intrinsic paint alpha | | Colors | single letters, `C0`–`C9`, `tab:*`, gray `'0.5'`, RGB(A) tuples, `(color, alpha)` pairs, per-item RGB(A) arrays, and any CSS color | -| `plt.cm.*` / `plt.colormaps[...]` / `cmap=` names | viridis, plasma, inferno, magma, cividis, gray, turbo, coolwarm, Blues, Purples, PuBu, RdBu, RdYlGn, RdGy, PiYG, PRGn, jet, rainbow, Spectral, binary, aliases, and true `*_r` reversal (RdGy/jet render from 11-stop anchor tables sampled from Matplotlib 3.11, linearly interpolated) | +| `plt.cm.*` / `plt.colormaps[...]` / `cmap=` names | viridis, plasma, inferno, magma, cividis, gray, bone, autumn, winter, turbo, coolwarm, Blues, Purples, Reds, PuBu, BuPu, RdBu, RdYlGn, RdGy, PiYG, PRGn, jet, rainbow, Spectral, binary, aliases, and true `*_r` reversal resolved generically for every listed name, including `plt.cm._r` attribute access (RdGy/jet/Reds/bone/autumn/winter/BuPu render from 11-stop anchor tables sampled from Matplotlib 3.11, linearly interpolated) | | `LinearSegmentedColormap.from_list` / `ListedColormap` | Python-side callables (`cmap(np.arange(cmap.N))` → RGBA) for scripts that colormap values themselves; they cannot be passed as `cmap=` to plotting calls (no engine table), which fails loudly | | `plt.colorbar()` / `fig.colorbar()` / `plt.clim()` / `plt.gci()` | Returns a live handle (`set_label`, `set_ticks`); with no mappable it uses the current image the way pyplot does. `ticks=`/`extend=` render in PNG and SVG (the HTML colorbar stays a minimal gradient without tick text); `clim` retargets the mappable's color window and any colorbar derived from it | -| `rcParams` | Figure size/DPI, line width/marker size, image cmap/origin, axes color cycle, and all four `axes.spines.*` switches affect every exporter. Pyplot axes default to Matplotlib's four-sided box and each spine can be hidden independently. The chrome keys (axes face/edge/label/title styles, font family/size, tick colors/sizes, legend defaults, figure facecolor) reach the HTML renderer and multi-panel PNG stitching; single-chart PNG and SVG export currently render their own fixed chrome and ignore them. Unknown keys warn once | +| `Colorbar.set_label(...)` / `colorbar(label=...)` | Matplotlib's default label geometry in all three renderers: beside a vertical bar rotated 90° counter-clockwise and centered on it, or upright and centered below a horizontal bar. The vertical label is a quarter turn, which the native PNG rasterizer renders exactly (only arbitrary text angles fall back to upright glyphs there), and the reserved right-margin room contains its cross-axis glyph extent. `set_label` ignores Matplotlib's customization kwargs (`loc=`, `labelpad=`, `rotation=`, font properties) rather than failing — the default orientation is derived from the bar | +| `rcParams` | Figure size/DPI, line width/marker size, image cmap/origin, axes color cycle, and all four `axes.spines.*` switches affect every exporter. Pyplot axes default to Matplotlib's four-sided box and each spine can be hidden independently. The chrome keys (axes face/edge/label/title styles, font family/size, tick colors/sizes, legend defaults, figure facecolor) reach the HTML renderer and multi-panel PNG stitching; single-chart PNG and SVG export currently render their own fixed chrome and ignore most of them. `axes.titleweight` and `axes.labelweight` are supported and verified to reach all three renderers (browser, single-chart SVG, single-chart native PNG); both default to `normal`, matching Matplotlib. Unknown keys warn once | +| Text weight | Title, axis-label, tick-label, legend, legend-title, colorbar-title, and annotation text all default to normal (400) weight in every renderer, matching Matplotlib's `axes.titleweight`/`axes.labelweight`/`font.weight` defaults. Heavier text needs an explicit `fontweight=`, `label_font_weight`, `styles[slot]`, or rcParam. Native PNG approximates: the bounded font atlas holds one regular and one bold face, so weights `>= 600` render bold and everything lighter renders regular — intermediate weights are not distinguishable in native PNG, while browser and SVG output pass the requested weight through verbatim. See [styling § Chrome text weight](../api/styling.md#chrome-text-weight) | | `plt.style.use(...)` / `plt.style.context(...)` | `"default"`, `"xy"`, bounded rcParam dictionaries, ordered lists, and the stock sheets fivethirtyeight, ggplot, bmh, dark_background, grayscale, seaborn-v0_8-white(grid), seaborn-v0_8-darkgrid, and seaborn-v0_8-deep — reduced to the supported rcParams subset (colors, grid, cycle, line width, font size; per-sheet keys outside that subset are not carried). The darkgrid sheet mirrors seaborn's `axes_style` (including `patch.edgecolor: white` + `patch.force_edgecolor`, which give hist/bar patches their white separators); `-deep` installs seaborn's classic color cycle. `context()` snapshots and restores. Unknown sheet names fail precisely | | `plt.GridSpec(r, c, wspace=, hspace=, width_ratios=)` + slice specs | Spans (`grid[0, 1:]`, `grid[:-1, 0]`) and custom spacing resolve to explicit figure rectangles using Matplotlib's SubplotParams frame; default-geometry single cells keep the uniform grid. Spanning layouts position exactly in HTML, PNG, and SVG: free-form panels (including `add_axes` rects and insets) render absolutely at their figure rectangles in every exporter, with later axes stacked above earlier ones | | `add_subplot(spec, sharex=, sharey=, xticklabels=[], ...)` | per-axes sharing aliases the axis-property store (static domains, as `twiny` does), not Matplotlib's live Grouper; `get_shared_x_axes()` reflects it | @@ -102,12 +105,15 @@ supported. Unknown keyword arguments on supported calls raise `TypeError` naming the offending keyword. Known material options that the native marks cannot honor raise `NotImplementedError`, with these documented exceptions that are accepted -as visual approximations rather than rejected: the barbs glyph and imshow -smoothing collapse above, `annotate(arrowprops=...)` connection curves and +as visual approximations rather than rejected: imshow smoothing collapse above, +`annotate(arrowprops=...)` connection curves and fancy/wedge outlines drawn as quadratic-curve tapered fills rather than -Matplotlib's exact patch paths, `bbox=` boxes drawn only by the HTML label, -and errorbar limit flags rendered as one-sided bars without Matplotlib's caret -arrows. +Matplotlib's exact patch paths, `bbox=` boxes sized from an estimated text +width with a fixed corner radius per box style (5 px for `round`, 8 px for +`round4`) rather than Matplotlib's `pad × fontsize` box path — measured +against Matplotlib 3.11.1 at 10 pt, `round` is 4.17 px there against 5 px +here — and errorbar limit flags rendered as one-sided bars without +Matplotlib's caret arrows. ## Sharp edges diff --git a/spec/matplotlib/shim-todo.md b/spec/matplotlib/shim-todo.md index dcdf2c03..4a7bccdc 100644 --- a/spec/matplotlib/shim-todo.md +++ b/spec/matplotlib/shim-todo.md @@ -171,10 +171,19 @@ The shim can be called complete for ordinary 2-D scripts when: `tests/pyplot/test_layout_noops.py::test_autofmt_xdate_rotates_x_tick_labels_on_all_axes` verifies rotation and horizontal alignment state on every axes. - [x] Implement `Axes.margins()` and make it affect automatic domains. Evidence: - automatic x/y domains expand by configured margins while explicit limits remain fixed. + automatic x/y domains expand by configured margins while explicit limits remain fixed; + `tests/pyplot/test_gallery_auto_ticks_compat.py` covers the axis-specific + setters and Matplotlib's `axes.autolimit_mode="round_numbers"` gallery. - [x] Implement `Axes.set_position()` and preserve the requested figure rect. Evidence: `set_position([left, bottom, width, height])` updates `get_position().bounds` and `_figure_rect`. +- [x] Make `Axes.get_position()` grid-aware and render the axes frame on the + rectangle it reports. Evidence: `tests/pyplot/test_frame_geometry.py` + pins reported-vs-rendered agreement for single axes and for every panel of + 2x2/1x3/5x5/8x8 grids (including `subplots_adjust` frames and width + ratios), distinguishes original and active aspect-adjusted positions, + preserves cell identity after an axes is removed, and checks a dense grid + composites all 64 panels instead of only its last column. - [x] Implement `Axes.set_anchor()` or reject unsupported anchor modes. Evidence: Matplotlib compass anchors are stored and unsupported modes raise `ValueError`. - [x] Finish `axis("equal")`, `axis("scaled")`, `axis("tight")`, and related @@ -253,7 +262,7 @@ appear frequently in ordinary scripts and notebooks. ### Limits, autoscaling, ticks and axes helpers - [x] `plt.autoscale()`, `Axes.autoscale()`, `autoscale_view()`, and `relim()`. Evidence: `tests/pyplot/test_axes_helpers.py::test_autoscale_bounds_and_relim_helpers` verifies explicit bounds, relim, autoscale, and tight autoscale behavior. -- [x] `get/set_xbound`, `get/set_ybound`, x/y margins, and sticky-edge behavior. Evidence: `tests/pyplot/test_axes_helpers.py::test_autoscale_bounds_and_relim_helpers` verifies bound setters/getters and margin-aware automatic domains; sticky edges are intentionally out of scope because xy artists do not expose sticky-edge metadata. +- [x] `get/set_xbound`, `get/set_ybound`, x/y margins, and sticky-edge behavior. Evidence: `tests/pyplot/test_axes_helpers.py::test_autoscale_bounds_and_relim_helpers` verifies bound setters/getters and margin-aware automatic domains. Sticky edges are derived from the entry list rather than from artist metadata (`Axes._entry_sticky_edges`): rectangle baselines for bar/histogram/contour, the outer cell edge for mesh and image entries (`imshow`/`pcolormesh`/`hist2d`/`specgram`), and 0/1 for `ecdf`. An axis whose sticky edges pin *both* ends ships a materialized `domain` instead of a `margin` (`Axes._fully_sticky_domain`), which is how a mesh stays flush with its outer cell edge; one-sided baselines still ship a `margin` and are anchored by the engine. Evidence: `tests/pyplot/test_mesh_autoscale_regressions.py`. - [x] `ticklabel_format()`. Evidence: `tests/pyplot/test_axes_helpers.py::test_ticklabel_minor_label_axis_and_legend_helpers` verifies stored style, scientific limits, and offset policy. - [x] `minorticks_on()` and `minorticks_off()` with an explicit minor-tick model. Evidence: `tests/pyplot/test_axes_helpers.py::test_ticklabel_minor_label_axis_and_legend_helpers` verifies explicit minor tick state toggles. - [x] `get_xlabel`, `get_ylabel`, `get_title`, `get_xaxis`, and `get_yaxis`. Evidence: `tests/pyplot/test_axes_helpers.py::test_ticklabel_minor_label_axis_and_legend_helpers` verifies label/title getters and axis proxy identity. @@ -350,17 +359,15 @@ method accepts the call. - [x] `quiver`: units, head geometry, pivots, angles, scaling, norm, z-order and scalar-mappable behavior. - [x] `barbs`: non-default increments, flags, rounding, empty-barb, flip, - color and size options now fail loudly instead of being discarded. The - rendered glyph remains a documented visual approximation (bounded tick - count, not WMO barb geometry) — see `spec/matplotlib/compat.md`. + color, size, length, and pivot options render through fixed-staff + WMO-style geometry. - [x] `quiverkey`: coordinates, label positions, fonts and sizing. -- [x] `streamplot`: always integrates with the shim's own bounded fixed-step - kernel, so output no longer depends on whether Matplotlib is installed; +- [x] `streamplot`: always integrates with the shim's own occupancy-aware + adaptive Heun kernel, so output no longer depends on whether Matplotlib is installed; `start_points`, `integration_direction`, array `linewidth`/`color`, - `num_arrows`, `arrowsize`, and plain `Normalize` are implemented, while - `transform`, `zorder`, `broken_streamlines=False`, and non-default - minlength/arrowstyle/step-scale options fail loudly. Streamline paths - are a visual approximation of Matplotlib's adaptive integrator. + `num_arrows`, `arrowsize`, `broken_streamlines`, both integration scale + controls, and plain `Normalize` are implemented, while `transform`, + `zorder`, and non-default minlength/arrowstyle options fail loudly. ### Scales, units and dates @@ -661,7 +668,10 @@ streamplot ### Known-inconsistent, still open - Exporter chrome beyond backgrounds (fonts, tick/legend styling) stays fixed - in single-chart PNG/SVG regardless of rcParams. + in single-chart PNG/SVG regardless of rcParams — except `axes.titleweight` + and `axes.labelweight`, which reach the browser, single-chart SVG, and + single-chart native PNG paths and are covered by + `tests/pyplot/test_rc_chrome_contracts.py`. - `ax.set_facecolor()` mutates the per-Axes plot background after creation, but `set_facecolor(None)` is a silent no-op rather than a reset to the rc default; restoring it requires passing `rcParams["axes.facecolor"]` back diff --git a/src/font.rs b/src/font.rs index 18d05564..c3868d9f 100644 --- a/src/font.rs +++ b/src/font.rs @@ -10,15 +10,15 @@ pub const CELL_H: i32 = 19; pub const ASCENT: i32 = 15; /// Codepoints of the non-ASCII glyphs, sorted; GLYPHS row = 95 + index. -pub static EXTRA_CODEPOINTS: [u32; 110] = [ - 176, 177, 178, 179, 181, 183, 185, 215, 915, 916, 920, 923, 926, 928, 931, 933, 934, 936, 937, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 963, 964, 965, 966, 967, 968, 969, 7522, 7523, 7524, 7525, 8211, 8212, 8216, 8217, 8220, 8221, 8230, 8304, 8305, 8308, 8309, 8310, 8311, 8312, 8313, 8314, 8315, 8316, 8317, 8318, 8319, 8320, 8321, 8322, 8323, 8324, 8325, 8326, 8327, 8328, 8329, 8330, 8331, 8332, 8333, 8334, 8336, 8337, 8338, 8339, 8341, 8342, 8343, 8344, 8345, 8346, 8347, 8348, 8592, 8594, 8706, 8711, 8712, 8722, 8723, 8730, 8733, 8734, 8747, 8776, 8800, 8804, 8805, +pub static EXTRA_CODEPOINTS: [u32; 112] = [ + 176, 177, 178, 179, 181, 183, 185, 215, 246, 252, 915, 916, 920, 923, 926, 928, 931, 933, 934, 936, 937, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 963, 964, 965, 966, 967, 968, 969, 7522, 7523, 7524, 7525, 8211, 8212, 8216, 8217, 8220, 8221, 8230, 8304, 8305, 8308, 8309, 8310, 8311, 8312, 8313, 8314, 8315, 8316, 8317, 8318, 8319, 8320, 8321, 8322, 8323, 8324, 8325, 8326, 8327, 8328, 8329, 8330, 8331, 8332, 8333, 8334, 8336, 8337, 8338, 8339, 8341, 8342, 8343, 8344, 8345, 8346, 8347, 8348, 8592, 8594, 8706, 8711, 8712, 8722, 8723, 8730, 8733, 8734, 8747, 8776, 8800, 8804, 8805, ]; /// Per-glyph metrics at BASE_PX: (advance, w, h, left, top, cov_off, cov_len). /// `top` is the pixel offset of the glyph's top edge below the baseline /// (negative = above). Coverage bytes live in `COVERAGE[cov_off..][..cov_len]`, /// row-major w*h, 0..=255. -pub static GLYPHS: [(i32, i32, i32, i32, i32, u32, u32); 205] = [ +pub static GLYPHS: [(i32, i32, i32, i32, i32, u32, u32); 207] = [ (5, 0, 0, 0, 0, 0, 0), (6, 6, 12, 0, -12, 0, 72), (7, 7, 12, 0, -12, 72, 84), @@ -122,111 +122,113 @@ pub static GLYPHS: [(i32, i32, i32, i32, i32, u32, u32); 205] = [ (5, 5, 7, 0, -7, 10666, 35), (6, 6, 12, 0, -12, 10701, 72), (13, 13, 10, 0, -10, 10773, 130), - (9, 9, 12, 0, -12, 10903, 108), - (11, 11, 12, 0, -12, 11011, 132), - (13, 13, 12, 0, -12, 11143, 156), - (11, 11, 12, 0, -12, 11299, 132), - (10, 10, 12, 0, -12, 11431, 120), - (12, 12, 12, 0, -12, 11551, 144), - (10, 10, 12, 0, -12, 11695, 120), - (10, 11, 12, -1, -12, 11815, 132), - (13, 13, 12, 0, -12, 11947, 156), - (13, 13, 12, 0, -12, 12103, 156), - (12, 12, 12, 0, -12, 12259, 144), - (11, 11, 9, 0, -9, 12403, 99), - (10, 10, 16, 0, -13, 12502, 160), - (9, 9, 12, 0, -9, 12662, 108), - (10, 10, 12, 0, -12, 12770, 120), - (9, 9, 9, 0, -9, 12890, 81), - (9, 9, 15, 0, -12, 12971, 135), - (10, 10, 12, 0, -9, 13106, 120), - (10, 10, 12, 0, -12, 13226, 120), - (5, 5, 9, 0, -9, 13346, 45), - (9, 10, 9, 0, -9, 13391, 90), - (9, 9, 12, 0, -12, 13481, 108), - (10, 10, 12, 0, -9, 13589, 120), - (9, 9, 9, 0, -9, 13709, 81), - (9, 9, 15, 0, -12, 13790, 135), - (10, 10, 9, 0, -9, 13925, 90), - (10, 10, 9, 0, -9, 14015, 90), - (10, 10, 12, 0, -9, 14105, 120), - (10, 10, 9, 0, -9, 14225, 90), - (10, 10, 9, 0, -9, 14315, 90), - (9, 9, 9, 0, -9, 14405, 81), - (11, 11, 12, 0, -9, 14486, 132), - (9, 9, 12, 0, -9, 14618, 108), + (10, 10, 12, 0, -12, 10903, 120), + (10, 10, 12, 0, -12, 11023, 120), + (9, 9, 12, 0, -12, 11143, 108), + (11, 11, 12, 0, -12, 11251, 132), + (13, 13, 12, 0, -12, 11383, 156), + (11, 11, 12, 0, -12, 11539, 132), + (10, 10, 12, 0, -12, 11671, 120), + (12, 12, 12, 0, -12, 11791, 144), + (10, 10, 12, 0, -12, 11935, 120), + (10, 11, 12, -1, -12, 12055, 132), + (13, 13, 12, 0, -12, 12187, 156), + (13, 13, 12, 0, -12, 12343, 156), + (12, 12, 12, 0, -12, 12499, 144), + (11, 11, 9, 0, -9, 12643, 99), + (10, 10, 16, 0, -13, 12742, 160), + (9, 9, 12, 0, -9, 12902, 108), + (10, 10, 12, 0, -12, 13010, 120), + (9, 9, 9, 0, -9, 13130, 81), + (9, 9, 15, 0, -12, 13211, 135), + (10, 10, 12, 0, -9, 13346, 120), + (10, 10, 12, 0, -12, 13466, 120), + (5, 5, 9, 0, -9, 13586, 45), + (9, 10, 9, 0, -9, 13631, 90), + (9, 9, 12, 0, -12, 13721, 108), + (10, 10, 12, 0, -9, 13829, 120), + (9, 9, 9, 0, -9, 13949, 81), + (9, 9, 15, 0, -12, 14030, 135), + (10, 10, 9, 0, -9, 14165, 90), + (10, 10, 9, 0, -9, 14255, 90), + (10, 10, 12, 0, -9, 14345, 120), + (10, 10, 9, 0, -9, 14465, 90), + (10, 10, 9, 0, -9, 14555, 90), + (9, 9, 9, 0, -9, 14645, 81), (11, 11, 12, 0, -9, 14726, 132), - (13, 13, 9, 0, -9, 14858, 117), - (3, 3, 7, 0, -7, 14975, 21), - (4, 5, 6, 0, -6, 14996, 30), - (6, 6, 6, 0, -6, 15026, 36), - (7, 7, 6, 0, -6, 15062, 42), - (8, 8, 5, 0, -5, 15104, 40), - (16, 16, 5, 0, -5, 15144, 80), - (5, 5, 12, 0, -12, 15224, 60), - (5, 5, 12, 0, -12, 15284, 60), - (8, 8, 12, 0, -12, 15344, 96), - (8, 8, 12, 0, -12, 15440, 96), - (16, 16, 2, 0, -2, 15536, 32), - (6, 6, 12, 0, -12, 15568, 72), - (3, 3, 12, 0, -12, 15640, 36), - (6, 6, 12, 0, -12, 15676, 72), - (6, 6, 12, 0, -12, 15748, 72), - (6, 6, 12, 0, -12, 15820, 72), - (6, 6, 12, 0, -12, 15892, 72), - (6, 6, 12, 0, -12, 15964, 72), - (6, 6, 12, 0, -12, 16036, 72), - (8, 8, 11, 0, -11, 16108, 88), - (8, 8, 9, 0, -9, 16196, 72), - (8, 8, 10, 0, -10, 16268, 80), - (4, 4, 13, 0, -13, 16348, 52), - (4, 4, 13, 0, -13, 16400, 52), - (6, 6, 10, 0, -10, 16452, 60), - (6, 6, 7, 0, -7, 16512, 42), - (6, 6, 7, 0, -7, 16554, 42), - (6, 6, 7, 0, -7, 16596, 42), - (6, 6, 7, 0, -7, 16638, 42), - (6, 6, 7, 0, -7, 16680, 42), - (6, 6, 7, 0, -7, 16722, 42), - (6, 6, 7, 0, -7, 16764, 42), - (6, 6, 7, 0, -7, 16806, 42), - (6, 6, 7, 0, -7, 16848, 42), - (6, 6, 7, 0, -7, 16890, 42), - (8, 8, 6, 0, -6, 16932, 48), - (8, 8, 4, 0, -4, 16980, 32), - (8, 8, 5, 0, -5, 17012, 40), - (4, 4, 9, 0, -8, 17052, 36), - (4, 4, 9, 0, -8, 17088, 36), - (6, 6, 6, 0, -6, 17124, 36), - (7, 7, 6, 0, -6, 17160, 42), - (7, 7, 5, 0, -5, 17202, 35), - (7, 7, 6, 0, -6, 17237, 42), - (6, 6, 7, 0, -7, 17279, 42), - (7, 7, 8, 0, -8, 17321, 56), - (3, 3, 7, 0, -7, 17377, 21), - (10, 10, 5, 0, -5, 17398, 50), - (6, 6, 5, 0, -5, 17448, 30), - (7, 7, 8, 0, -6, 17478, 56), - (6, 6, 6, 0, -6, 17534, 36), - (5, 5, 7, 0, -7, 17570, 35), - (13, 13, 8, 0, -8, 17605, 104), - (13, 13, 8, 0, -8, 17709, 104), - (8, 8, 12, 0, -11, 17813, 96), - (11, 12, 12, -1, -12, 17909, 144), - (14, 14, 13, 0, -12, 18053, 182), - (13, 13, 5, 0, -5, 18235, 65), - (13, 13, 11, 0, -11, 18300, 143), - (10, 11, 13, 0, -13, 18443, 143), - (11, 11, 8, 0, -8, 18586, 88), - (13, 13, 8, 0, -8, 18674, 104), - (8, 8, 17, 0, -13, 18778, 136), - (13, 13, 9, 0, -9, 18914, 117), - (13, 13, 9, 0, -9, 19031, 117), - (13, 13, 9, 0, -9, 19148, 117), - (13, 13, 9, 0, -9, 19265, 117), + (9, 9, 12, 0, -9, 14858, 108), + (11, 11, 12, 0, -9, 14966, 132), + (13, 13, 9, 0, -9, 15098, 117), + (3, 3, 7, 0, -7, 15215, 21), + (4, 5, 6, 0, -6, 15236, 30), + (6, 6, 6, 0, -6, 15266, 36), + (7, 7, 6, 0, -6, 15302, 42), + (8, 8, 5, 0, -5, 15344, 40), + (16, 16, 5, 0, -5, 15384, 80), + (5, 5, 12, 0, -12, 15464, 60), + (5, 5, 12, 0, -12, 15524, 60), + (8, 8, 12, 0, -12, 15584, 96), + (8, 8, 12, 0, -12, 15680, 96), + (16, 16, 2, 0, -2, 15776, 32), + (6, 6, 12, 0, -12, 15808, 72), + (3, 3, 12, 0, -12, 15880, 36), + (6, 6, 12, 0, -12, 15916, 72), + (6, 6, 12, 0, -12, 15988, 72), + (6, 6, 12, 0, -12, 16060, 72), + (6, 6, 12, 0, -12, 16132, 72), + (6, 6, 12, 0, -12, 16204, 72), + (6, 6, 12, 0, -12, 16276, 72), + (8, 8, 11, 0, -11, 16348, 88), + (8, 8, 9, 0, -9, 16436, 72), + (8, 8, 10, 0, -10, 16508, 80), + (4, 4, 13, 0, -13, 16588, 52), + (4, 4, 13, 0, -13, 16640, 52), + (6, 6, 10, 0, -10, 16692, 60), + (6, 6, 7, 0, -7, 16752, 42), + (6, 6, 7, 0, -7, 16794, 42), + (6, 6, 7, 0, -7, 16836, 42), + (6, 6, 7, 0, -7, 16878, 42), + (6, 6, 7, 0, -7, 16920, 42), + (6, 6, 7, 0, -7, 16962, 42), + (6, 6, 7, 0, -7, 17004, 42), + (6, 6, 7, 0, -7, 17046, 42), + (6, 6, 7, 0, -7, 17088, 42), + (6, 6, 7, 0, -7, 17130, 42), + (8, 8, 6, 0, -6, 17172, 48), + (8, 8, 4, 0, -4, 17220, 32), + (8, 8, 5, 0, -5, 17252, 40), + (4, 4, 9, 0, -8, 17292, 36), + (4, 4, 9, 0, -8, 17328, 36), + (6, 6, 6, 0, -6, 17364, 36), + (7, 7, 6, 0, -6, 17400, 42), + (7, 7, 5, 0, -5, 17442, 35), + (7, 7, 6, 0, -6, 17477, 42), + (6, 6, 7, 0, -7, 17519, 42), + (7, 7, 8, 0, -8, 17561, 56), + (3, 3, 7, 0, -7, 17617, 21), + (10, 10, 5, 0, -5, 17638, 50), + (6, 6, 5, 0, -5, 17688, 30), + (7, 7, 8, 0, -6, 17718, 56), + (6, 6, 6, 0, -6, 17774, 36), + (5, 5, 7, 0, -7, 17810, 35), + (13, 13, 8, 0, -8, 17845, 104), + (13, 13, 8, 0, -8, 17949, 104), + (8, 8, 12, 0, -11, 18053, 96), + (11, 12, 12, -1, -12, 18149, 144), + (14, 14, 13, 0, -12, 18293, 182), + (13, 13, 5, 0, -5, 18475, 65), + (13, 13, 11, 0, -11, 18540, 143), + (10, 11, 13, 0, -13, 18683, 143), + (11, 11, 8, 0, -8, 18826, 88), + (13, 13, 8, 0, -8, 18914, 104), + (8, 8, 17, 0, -13, 19018, 136), + (13, 13, 9, 0, -9, 19154, 117), + (13, 13, 9, 0, -9, 19271, 117), + (13, 13, 9, 0, -9, 19388, 117), + (13, 13, 9, 0, -9, 19505, 117), ]; -pub static COVERAGE: [u8; 19382] = [ +pub static COVERAGE: [u8; 19622] = [ 0, 0, 148, 255, 0, 0, 0, 0, 148, 255, 0, 0, 0, 0, 148, 255, 0, 0, 0, 0, 148, 255, 0, 0, 0, 0, 148, 255, 0, 0, 0, 0, 143, 251, 0, 0, 0, 0, 130, 237, 0, 0, 0, 0, 115, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 255, 0, 0, 0, 0, 148, 255, 0, 0, @@ -681,7 +683,17 @@ pub static COVERAGE: [u8; 19382] = [ 0, 0, 0, 0, 0, 0, 124, 255, 225, 6, 0, 0, 0, 0, 0, 0, 0, 0, 69, 246, 183, 246, 164, 2, 0, 0, 0, 0, 0, 0, 69, 246, 160, 2, 67, 246, 164, 2, 0, 0, 0, 0, 69, 246, 159, 2, 0, 0, 66, 245, 164, 2, 0, 0, 0, 95, 156, 2, 0, 0, 0, 0, 64, 180, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 108, 255, 255, 255, 255, 255, 255, 212, 0, 108, 255, 40, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 255, 44, 92, 255, 60, 0, 0, 0, 0, 104, 255, 44, 92, 255, + 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 196, 246, 241, 178, 40, 0, 0, 0, + 67, 252, 145, 24, 36, 187, 237, 30, 0, 0, 199, 209, 0, 0, 0, 19, 245, 148, 0, 8, 253, 133, 0, 0, + 0, 0, 186, 212, 0, 24, 255, 111, 0, 0, 0, 0, 163, 231, 0, 8, 253, 132, 0, 0, 0, 0, 185, 212, + 0, 0, 199, 207, 0, 0, 0, 18, 244, 149, 0, 0, 69, 252, 143, 23, 34, 185, 239, 31, 0, 0, 0, 69, + 197, 247, 242, 179, 42, 0, 0, 0, 0, 88, 255, 60, 76, 255, 76, 0, 0, 0, 0, 88, 255, 60, 76, 255, + 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 204, 0, 0, 0, 0, 192, 176, 0, 0, + 164, 204, 0, 0, 0, 0, 192, 176, 0, 0, 164, 204, 0, 0, 0, 0, 192, 176, 0, 0, 164, 204, 0, 0, + 0, 0, 192, 176, 0, 0, 164, 204, 0, 0, 0, 0, 193, 176, 0, 0, 150, 216, 0, 0, 0, 0, 218, 176, + 0, 0, 117, 246, 11, 0, 0, 36, 252, 176, 0, 0, 28, 250, 146, 16, 45, 172, 204, 176, 0, 0, 0, 83, + 219, 248, 194, 39, 192, 176, 0, 0, 108, 255, 255, 255, 255, 255, 255, 212, 0, 108, 255, 40, 0, 0, 0, 0, 0, 0, 108, 255, 40, 0, 0, 0, 0, 0, 0, 108, 255, 40, 0, 0, 0, 0, 0, 0, 108, 255, 40, 0, 0, 0, 0, 0, 0, 108, 255, 40, 0, 0, 0, 0, 0, 0, 108, 255, 40, 0, 0, 0, 0, 0, 0, 108, 255, 40, 0, 0, 0, 0, 0, 0, 108, 255, 40, 0, 0, 0, 0, 0, 0, 108, 255, 40, 0, 0, 0, 0, diff --git a/src/kernels.rs b/src/kernels.rs index d5991b19..38134487 100644 --- a/src/kernels.rs +++ b/src/kernels.rs @@ -2698,6 +2698,7 @@ fn marching_squares_scan( x_coords: &[f64], y_coords: &[f64], levels: &[f64], + corner_mask: bool, mut emit: F, ) -> usize where @@ -2714,18 +2715,73 @@ where let v10 = z[row * cols + col + 1]; let v11 = z[(row + 1) * cols + col + 1]; let v01 = z[(row + 1) * cols + col]; - if !(v00.is_finite() && v10.is_finite() && v11.is_finite() && v01.is_finite()) { + let finite = [ + v00.is_finite(), + v10.is_finite(), + v11.is_finite(), + v01.is_finite(), + ]; + let finite_count = finite.iter().filter(|&&value| value).count(); + if finite_count < 4 && (!corner_mask || finite_count != 3) { continue; } - let local_min = v00.min(v10).min(v11).min(v01); - let local_max = v00.max(v10).max(v11).max(v01); + let values = [v00, v10, v11, v01]; + let local_min = values + .iter() + .copied() + .filter(|value| value.is_finite()) + .fold(f64::INFINITY, f64::min); + let local_max = values + .iter() + .copied() + .filter(|value| value.is_finite()) + .fold(f64::NEG_INFINITY, f64::max); let corners = [ (x_coords[col], y_coords[row], v00), (x_coords[col + 1], y_coords[row], v10), (x_coords[col + 1], y_coords[row + 1], v11), (x_coords[col], y_coords[row + 1], v01), ]; + let triangle_edges: Option<&[(usize, usize); 3]> = if finite_count == 3 { + Some(match finite.iter().position(|value| !value).unwrap() { + 0 => &[(1, 2), (2, 3), (3, 1)], + 1 => &[(0, 2), (2, 3), (3, 0)], + 2 => &[(0, 1), (1, 3), (3, 0)], + 3 => &[(0, 1), (1, 2), (2, 0)], + _ => unreachable!(), + }) + } else { + None + }; let mut process_level = |level: f64| { + if let Some(edges) = triangle_edges { + let mut intersections = [(0.0, 0.0); 2]; + let mut n_intersections = 0usize; + for &(a, b) in edges { + let (xa, ya, va) = corners[a]; + let (xb, yb, vb) = corners[b]; + if (va >= level) == (vb >= level) { + continue; + } + let fraction = ((level - va) / (vb - va)).clamp(0.0, 1.0); + if n_intersections < intersections.len() { + intersections[n_intersections] = + (xa + (xb - xa) * fraction, ya + (yb - ya) * fraction); + } + n_intersections += 1; + } + if n_intersections == 2 { + emit( + intersections[0].0, + intersections[1].0, + intersections[0].1, + intersections[1].1, + level, + ); + count += 1; + } + return; + } let mask = u8::from(v00 >= level) | (u8::from(v10 >= level) << 1) | (u8::from(v11 >= level) << 2) @@ -2787,6 +2843,7 @@ pub fn marching_squares_into( x_coords: &[f64], y_coords: &[f64], levels: &[f64], + corner_mask: bool, x0_out: &mut [f64], x1_out: &mut [f64], y0_out: &mut [f64], @@ -2806,6 +2863,7 @@ pub fn marching_squares_into( x_coords, y_coords, levels, + corner_mask, |x0, x1, y0, y1, level| { if written < capacity { x0_out[written] = x0; @@ -5811,6 +5869,7 @@ mod tests { &x, &y, &levels, + false, &mut x0, &mut x1, &mut y0, @@ -5844,6 +5903,7 @@ mod tests { &x, &y, &levels, + false, &mut x0, &mut x1, &mut y0, @@ -5885,6 +5945,7 @@ mod tests { &[0.0, 1.0], &[0.0, 1.0], &[0.5], + false, &mut x0, &mut x1, &mut y0, @@ -5894,6 +5955,36 @@ mod tests { assert_eq!(written, 0); } + #[test] + fn marching_squares_corner_mask_retains_the_opposite_triangle() { + let z = [f64::NAN, 1.0, 0.0, 0.0]; + let mut x0 = [0.0; 1]; + let mut x1 = [0.0; 1]; + let mut y0 = [0.0; 1]; + let mut y1 = [0.0; 1]; + let mut emitted_levels = [0.0; 1]; + let written = marching_squares_into( + &z, + 2, + 2, + &[0.0, 1.0], + &[0.0, 1.0], + &[0.5], + true, + &mut x0, + &mut x1, + &mut y0, + &mut y1, + &mut emitted_levels, + ); + assert_eq!(written, 1); + assert_eq!(x0[0].min(x1[0]), 0.5); + assert_eq!(x0[0].max(x1[0]), 1.0); + assert_eq!(y0, [0.5]); + assert_eq!(y1, [0.5]); + assert_eq!(emitted_levels, [0.5]); + } + #[test] fn bin_2d_indices_matches_separate_kernels() { // Random data with NaN and exact-boundary values: the fused kernel's diff --git a/src/lib.rs b/src/lib.rs index 0d893374..513fbc00 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1511,6 +1511,7 @@ pub unsafe extern "C" fn xy_marching_squares( y_coords: *const f64, levels: *const f64, n_levels: usize, + corner_mask: u8, out_x0: *mut f64, out_x1: *mut f64, out_y0: *mut f64, @@ -1572,6 +1573,7 @@ pub unsafe extern "C" fn xy_marching_squares( x_coords, y_coords, levels, + corner_mask != 0, empty_x0, empty_x1, empty_y0, @@ -1585,7 +1587,17 @@ pub unsafe extern "C" fn xy_marching_squares( let y1_out = std::slice::from_raw_parts_mut(out_y1, capacity); let level_out = std::slice::from_raw_parts_mut(out_levels, capacity); kernels::marching_squares_into( - z, rows, cols, x_coords, y_coords, levels, x0_out, x1_out, y0_out, y1_out, + z, + rows, + cols, + x_coords, + y_coords, + levels, + corner_mask != 0, + x0_out, + x1_out, + y0_out, + y1_out, level_out, ) } diff --git a/src/raster.rs b/src/raster.rs index 5da85840..12aadfa3 100644 --- a/src/raster.rs +++ b/src/raster.rs @@ -32,6 +32,7 @@ const OP_HEATMAP_IMAGE: u8 = 13; const OP_AFFINE_POINTS: u8 = 14; const OP_AFFINE_CHANNEL_POINTS: u8 = 15; const OP_STROKED_TRIANGLES: u8 = 16; +const OP_STYLED_TEXT: u8 = 17; const SS: usize = 4; // vertical supersamples per scanline for polygon AA @@ -749,14 +750,14 @@ fn pentagon_sdf(p: (f32, f32), r: f32) -> f32 { fn symbol_sdf(px: f32, py: f32, r: f32, sym: u8) -> f32 { match sym { 1 => px.abs().max(py.abs()) - r, // square - 2 => (px.abs() + py.abs()) - r, // diamond + 2 => (px.abs() + py.abs()) - r * std::f32::consts::SQRT_2, // diamond 3 | 8 | 9 | 10 => { // Matplotlib's normalized triangle: apex at one edge and a // full-width base at the opposite edge. let d = match sym { 8 => (-px, -py), // down - 9 => (py, -px), // left - 10 => (-py, px), // right + 9 => (-py, px), // left + 10 => (py, -px), // right _ => (px, py), }; triangle_sdf(d, (0.0, -r), (-r, r), (r, r)) @@ -774,7 +775,7 @@ fn symbol_sdf(px: f32, py: f32, r: f32, sym: u8) -> f32 { (ax - 0.34 * r).max(ay - r).min((ax - r).max(ay - 0.34 * r)) } 13 => px.abs().max(py.abs()) - r, // snapped pixel - 14 => (px.abs() / 0.6 + py.abs()) - r, // thin diamond + 14 => (px.abs() / 0.6 + py.abs()) - r * std::f32::consts::SQRT_2, // thin diamond 15 => { // Unfilled plus: its width comes from markeredgewidth below. let (ax, ay) = (px.abs(), py.abs()); @@ -820,6 +821,15 @@ fn symbol_sdf(px: f32, py: f32, r: f32, sym: u8) -> f32 { } } +#[inline] +fn symbol_extent(r: f32, sym: u8) -> f32 { + if matches!(sym, 2 | 14) { + r * std::f32::consts::SQRT_2 + } else { + r + } +} + #[allow(clippy::too_many_arguments)] fn point( cv: &mut Canvas, @@ -865,7 +875,7 @@ fn point_u8_at( let stroke_rgb = [stroke[0], stroke[1], stroke[2]]; let fill_alpha = fill[3] as f32 / 255.0; let stroke_alpha = stroke[3] as f32 / 255.0; - let ext = r + 1.0; + let ext = symbol_extent(r, sym) + 1.0; let (bx0, by0, bx1, by1) = cv.bbox(cx - ext, cy - ext, cx + ext, cy + ext); if sw <= 0.0 && sym == 0 { // Stroke-free circle — the default mark and the overwhelming batch @@ -1188,6 +1198,8 @@ fn glyph_index(ch: char) -> Option { pub const TEXT_ROTATED: u8 = 0x80; /// 0x40 requests 90°-CW text (top-down right-margin titles, mpl rotation=270). pub const TEXT_ROTATED_CW: u8 = 0x40; +const TEXT_ITALIC: u8 = 0x01; +const TEXT_BOLD: u8 = 0x02; fn text(cv: &mut Canvas, x: f32, y: f32, anchor: u8, size: f32, rgba: [f32; 4], s: &[u8]) { let rotated = anchor & TEXT_ROTATED != 0; @@ -1310,6 +1322,131 @@ fn text(cv: &mut Canvas, x: f32, y: f32, anchor: u8, size: f32, rgba: [f32; 4], } } +#[allow(clippy::too_many_arguments)] +fn styled_text( + cv: &mut Canvas, + x: f32, + y: f32, + anchor: u8, + size: f32, + angle_degrees: f32, + flags: u8, + italic_ranges: &[(u32, u32)], + rgba: [f32; 4], + s: &[u8], +) { + let scale = size / font::BASE_PX as f32; + let text = String::from_utf8_lossy(s); + let advance = text + .chars() + .filter_map(glyph_index) + .map(|index| font::GLYPHS[index].0 as f32) + .sum::() + * scale; + let mut pen = match anchor { + 1 => -advance * 0.5, + 2 => -advance, + _ => 0.0, + }; + let theta = angle_degrees.to_radians(); + let (sin_theta, cos_theta) = theta.sin_cos(); + let bold_shift = if flags & TEXT_BOLD != 0 { + (size * 0.055).clamp(0.55, 1.2) + } else { + 0.0 + }; + + for (char_index, ch) in text.chars().enumerate() { + let Some(index) = glyph_index(ch) else { + continue; + }; + let italic = flags & TEXT_ITALIC != 0 + || italic_ranges + .iter() + .any(|&(start, end)| { + start <= char_index as u32 && (char_index as u32) < end + }); + let italic_shear = if italic { 0.22 } else { 0.0 }; + let (glyph_advance, gw, gh, left, top, offset, len) = font::GLYPHS[index]; + if gw > 0 && gh > 0 { + let coverage = &font::COVERAGE[offset as usize..(offset + len) as usize]; + let sample = + |sx: usize, sy: usize| coverage[sy * gw as usize + sx] as f32 / 255.0; + let bilinear = |u: f32, v: f32| { + if u < -0.5 || v < -0.5 || u > gw as f32 - 0.5 || v > gh as f32 - 0.5 { + return 0.0; + } + let u = u.clamp(0.0, gw as f32 - 1.0); + let v = v.clamp(0.0, gh as f32 - 1.0); + let (x0, y0) = (u.floor() as usize, v.floor() as usize); + let (x1, y1) = ((x0 + 1).min(gw as usize - 1), (y0 + 1).min(gh as usize - 1)); + let (fx, fy) = (u - x0 as f32, v - y0 as f32); + sample(x0, y0) * (1.0 - fx) * (1.0 - fy) + + sample(x1, y0) * fx * (1.0 - fy) + + sample(x0, y1) * (1.0 - fx) * fy + + sample(x1, y1) * fx * fy + }; + + let u0 = pen + left as f32 * scale; + let v0 = top as f32 * scale; + let u1 = u0 + gw as f32 * scale + bold_shift; + let v1 = v0 + gh as f32 * scale; + let transform = |u: f32, v: f32| { + let sheared_u = u - italic_shear * v; + ( + x + sheared_u * cos_theta - v * sin_theta, + y + sheared_u * sin_theta + v * cos_theta, + ) + }; + let corners = [ + transform(u0, v0), + transform(u1, v0), + transform(u1, v1), + transform(u0, v1), + ]; + let min_x = corners + .iter() + .map(|point| point.0) + .fold(f32::INFINITY, f32::min); + let max_x = corners + .iter() + .map(|point| point.0) + .fold(f32::NEG_INFINITY, f32::max); + let min_y = corners + .iter() + .map(|point| point.1) + .fold(f32::INFINITY, f32::min); + let max_y = corners + .iter() + .map(|point| point.1) + .fold(f32::NEG_INFINITY, f32::max); + let (bx0, by0, bx1, by1) = cv.bbox(min_x, min_y, max_x, max_y); + for py in by0..by1 { + for px in bx0..bx1 { + let dx = px as f32 + 0.5 - x; + let dy = py as f32 + 0.5 - y; + let sheared_u = dx * cos_theta + dy * sin_theta; + let local_v = -dx * sin_theta + dy * cos_theta; + let local_u = sheared_u + italic_shear * local_v; + let atlas_u = (local_u - u0) / scale - 0.5; + let atlas_v = (local_v - v0) / scale - 0.5; + let mut alpha = bilinear(atlas_u, atlas_v); + if bold_shift > 0.0 { + alpha = alpha.max(bilinear( + (local_u - bold_shift - u0) / scale - 0.5, + atlas_v, + )); + } + if alpha > 0.0 { + cv.blend(px, py, rgba, alpha); + } + } + } + } + pen += glyph_advance as f32 * scale; + } +} + // ---- command-buffer reader -------------------------------------------------- struct Reader<'a> { @@ -1709,7 +1846,7 @@ fn paint_affine_points(cv: &mut Canvas, batch: &AffinePointsBatch, threads: usiz xs.push(batch.x.project(i)); ys.push(batch.y.project(i)); } - let ext = batch.radius + batch.sw + 1.0; + let ext = symbol_extent(batch.radius, batch.sym) + batch.sw + 1.0; paint_banded( cv, threads, @@ -1783,7 +1920,7 @@ fn paint_styled_points(cv: &mut Canvas, batch: &StyledPointsBatch, threads: usiz threads, batch.n, |i| { - let ext = batch.rs[i] + batch.sw + 1.0; + let ext = symbol_extent(batch.rs[i], batch.sym) + batch.sw + 1.0; Some((batch.ys[i] - ext, batch.ys[i] + ext)) }, |surface, indices| { @@ -2030,6 +2167,33 @@ fn rasterize_with_spans( let s = r.bytes(nb)?; text(&mut cv, x, y, anchor, size, c, s); } + OP_STYLED_TEXT => { + let (x, y) = (r.f32()?, r.f32()?); + let anchor = r.u8()?; + let size = r.f32()?; + let angle = r.f32()?; + let flags = r.u8()?; + let range_count = r.u32()? as usize; + let mut italic_ranges = Vec::with_capacity(range_count); + for _ in 0..range_count { + italic_ranges.push((r.u32()?, r.u32()?)); + } + let c = r.rgba()?; + let nb = r.u32()? as usize; + let s = r.bytes(nb)?; + styled_text( + &mut cv, + x, + y, + anchor, + size, + angle, + flags, + &italic_ranges, + c, + s, + ); + } OP_POINTS => { // Batched marks, struct-of-arrays: one header (symbol + // shared stroke) then cx/cy/r f32 arrays and per-point @@ -2119,7 +2283,7 @@ fn rasterize_with_spans( output_scale, }, }; - let side = 2.0 * (radius + sw + 1.0); + let side = 2.0 * (symbol_extent(radius, sym) + sw + 1.0); let est_px = side * side * n as f32; paint_affine_points( &mut cv, @@ -2260,7 +2424,7 @@ fn rasterize_with_spans( }; fills.push(fill); if radius.is_finite() { - let side = 2.0 * (radius + sw + 1.0); + let side = 2.0 * (symbol_extent(radius, sym) + sw + 1.0); est_px += side * side; } } @@ -2500,6 +2664,43 @@ fn grad_color(stops: &[(f32, [f32; 4])], t: f32) -> [f32; 4] { mod tests { use super::*; + #[test] + fn horizontal_triangle_symbols_point_in_the_named_direction() { + let moment = |symbol| { + let mut total = 0.0; + for y in -20..=20 { + for x in -20..=20 { + let px = x as f32 / 10.0; + let py = y as f32 / 10.0; + if symbol_sdf(px, py, 2.0, symbol) <= 0.0 { + total += px; + } + } + } + total + }; + + assert!( + moment(9) > 0.0, + "triangle_left must put its wide base right of the leftward apex" + ); + assert!( + moment(10) < 0.0, + "triangle_right must put its wide base left of the rightward apex" + ); + } + + #[test] + fn diamond_symbols_match_matplotlib_marker_extents() { + let radius = 3.0; + let extent = radius * std::f32::consts::SQRT_2; + + assert_eq!(symbol_extent(radius, 2), extent); + assert_eq!(symbol_extent(radius, 14), extent); + assert!(symbol_sdf(0.0, extent, radius, 2).abs() < 1e-6); + assert!(symbol_sdf(0.6 * extent, 0.0, radius, 14).abs() < 1e-6); + } + fn px(out: &[u8], w: usize, x: usize, y: usize) -> [u8; 4] { let o = (y * w + x) * 4; [out[o], out[o + 1], out[o + 2], out[o + 3]] @@ -2639,6 +2840,25 @@ mod tests { assert!(ink > 5, "glyph produced no ink: {ink}"); } + #[test] + fn matplotlib_text_commands_umlauts_have_native_glyphs() { + assert!(glyph_index('ö').is_some()); + assert!(glyph_index('ü').is_some()); + let mut cmd = vec![OP_TEXT]; + cmd.extend(f32le(1.0)); + cmd.extend(f32le(30.0)); + cmd.push(0); // anchor start + cmd.extend(f32le(20.0)); // size + cmd.extend([0, 0, 0, 255]); + let s = "öü".as_bytes(); + cmd.extend(u32le(s.len() as u32)); + cmd.extend_from_slice(s); + let mut out = vec![0u8; 40 * 40 * 4]; + assert!(rasterize_into(&cmd, 40, 40, &mut out)); + let ink: u32 = out.chunks(4).map(|p| (p[3] > 32) as u32).sum(); + assert!(ink > 10, "umlaut glyphs produced no ink: {ink}"); + } + #[test] fn rotated_cw_text_walks_downward() { // "II" rotated CW from (20, 5): ink extends down the column below the diff --git a/tests/pyplot/test_advanced_compatibility.py b/tests/pyplot/test_advanced_compatibility.py index 731744f9..cae40594 100644 --- a/tests/pyplot/test_advanced_compatibility.py +++ b/tests/pyplot/test_advanced_compatibility.py @@ -69,11 +69,11 @@ def test_nonlinear_scales_secondary_axes_and_affine_transforms() -> None: np.testing.assert_allclose( line.get_xdata(), [-(adjusted + 1), -adjusted, 0, adjusted, adjusted + 1] ) - assert ax.get_xlim() == (-10, 10) + np.testing.assert_allclose(ax.get_xlim(), (-16.259646938814825, 16.259646938814825)) secondary = ax.secondary_xaxis("top", functions=(lambda x: x * 100, lambda x: x / 100)) secondary.set_xlabel("percent") axis = ax._build_chart(640, 480).figure().axis_options["xs1"] - assert axis["side"] == "top" and axis["tick_labels"][-1] == "1000" + assert axis["side"] == "top" and axis["tick_labels"][-1] == "1625.96" _, transformed = plt.subplots() line = transformed.plot([0, 1], [0, 1], transform=Affine2D().translate(2, 3))[0] diff --git a/tests/pyplot/test_annotation_box_text_fidelity.py b/tests/pyplot/test_annotation_box_text_fidelity.py new file mode 100644 index 00000000..e51201aa --- /dev/null +++ b/tests/pyplot/test_annotation_box_text_fidelity.py @@ -0,0 +1,355 @@ +"""Annotation bbox/text fidelity against Matplotlib, on real emitted output. + +Measured against matplotlib 3.11.1 rendering cell 23 of +``examples/pdsh/pdsh_04_09_text_and_annotation.ipynb`` with the real +``examples/pdsh/data/births.csv``. The reference values quoted in the +assertions come from that figure's own SVG/PNG, not from taste: + +- ``bbox=dict(boxstyle="round", alpha=0.1)`` → Matplotlib emits + ``style="fill: #1f77b4; opacity: 0.1; stroke: #000000"``. ``opacity`` is + *element* opacity, so face and edge are dimmed together. +- an arrow-less ``annotate`` ("Labor Day Weekend") → Matplotlib paints it + with ``rcParams["text.color"]``, i.e. pure black; its PNG's darkest + glyph pixel is ``(0, 0, 0)``. +- ``boxstyle="round"`` at 10 pt → a 3.00 pt (4.17 px at 96 dpi) corner + radius in Matplotlib's own path; ``round4`` curves rather than arcs. +""" + +from __future__ import annotations + +import struct +from typing import Any +from xml.etree import ElementTree + +import pytest + +import xy.pyplot as plt +from xy import _raster + + +@pytest.fixture(autouse=True) +def _clean(): + plt.close("all") + yield + plt.close("all") + + +def _annotation_rects(fig, ax) -> list[dict[str, str]]: + """Every stroked ```` in the emitted SVG, as raw attributes.""" + svg = ax._build_chart(*fig._panel_px()).figure().to_svg() + root = ElementTree.fromstring(svg) + return [e.attrib for e in root.iter() if e.tag.endswith("rect") and "stroke" in e.attrib] + + +def _annotation_texts(fig, ax) -> dict[str, dict[str, str]]: + """Emitted SVG ```` attributes, keyed by the rendered string.""" + svg = ax._build_chart(*fig._panel_px()).figure().to_svg() + root = ElementTree.fromstring(svg) + out: dict[str, dict[str, str]] = {} + for e in root.iter(): + if not e.tag.endswith("text"): + continue + text = "".join(e.itertext()).strip() + if text: + out[text] = e.attrib + return out + + +def _first_fill(cmd: _raster._Cmd) -> tuple[int, list[tuple[float, float]], tuple[int, ...]]: + """Decode the first FILL command out of a raw native display list. + + Layout (little-endian, must match ``src/raster.rs``): opcode byte, + u32 vertex count, 2 f32 per vertex, then 4 bytes of RGBA. + """ + buf = bytes(cmd.buf) + assert buf[0] == _raster._FILL, f"expected a FILL opcode, got {buf[0]}" + (count,) = struct.unpack_from(" tuple[int, ...]: + """RGBA of the first STROKE command in a raw native display list.""" + buf = bytes(cmd.buf) + offset = 0 + while offset < len(buf): + if buf[offset] == _raster._STROKE: + (count,) = struct.unpack_from(" None: + """Matplotlib's patch ``alpha`` dims face *and* edge (element opacity).""" + fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [0.0, 1.0]) + ax.annotate( + "Christmas", + xy=(0.9, 0.1), + xytext=(-30, 0), + textcoords="offset points", + ha="right", + va="center", + bbox=dict(boxstyle="round", alpha=0.1), + arrowprops=dict(arrowstyle="wedge,tail_width=0.5", alpha=0.1), + ) + + (rect,) = _annotation_rects(fig, ax) + # Face keeps the alpha it always had; the edge now carries it too, so the + # default black edge is as invisible as Matplotlib's. + assert rect["fill"] == "rgba(31,119,180,0.1)" + assert rect["stroke"] == "rgba(0,0,0,0.1)" + + +def test_bbox_without_alpha_keeps_an_opaque_edge() -> None: + """No ``alpha`` means no compositing — Matplotlib draws a solid edge.""" + fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [0.0, 1.0]) + ax.annotate( + "Thanksgiving", + xy=(0.5, 0.5), + xytext=(-40, -30), + textcoords="offset points", + bbox=dict(boxstyle="round4,pad=.5", fc="0.9"), + arrowprops=dict(arrowstyle="->"), + ) + + (rect,) = _annotation_rects(fig, ax) + assert rect["fill"] == "rgb(230,230,230)" # fc="0.9" + assert rect["stroke"] == "black" + + +def test_bbox_alpha_dims_an_explicit_edge_colour() -> None: + """``alpha`` applies to whatever ``ec`` resolves to, not just to black.""" + fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [0.0, 1.0]) + # "0.4" is Matplotlib's grey shorthand, the form the pdsh corpus uses. + ax.text(0.5, 0.5, "boxed", bbox=dict(boxstyle="round", fc="none", ec="0.4", alpha=0.5)) + + (rect,) = _annotation_rects(fig, ax) + assert rect["fill"] == "none" + assert rect["stroke"] == "rgba(102,102,102,0.5)" + + +def test_css_named_edge_colour_receives_the_patch_alpha() -> None: + """CSS/Matplotlib colour names use the same patch alpha as hex colours.""" + fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [0.0, 1.0]) + ax.text(0.5, 0.5, "boxed", bbox=dict(boxstyle="round", fc="none", ec="gray", alpha=0.5)) + + (rect,) = _annotation_rects(fig, ax) + assert rect["stroke"] == "rgba(128,128,128,0.5)" + + +def test_bbox_alpha_overrides_embedded_face_and_edge_alpha() -> None: + """Matplotlib's patch alpha replaces, rather than multiplies, colour alpha.""" + fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [0.0, 1.0]) + ax.text( + 0.5, + 0.5, + "boxed", + bbox=dict( + boxstyle="round", + fc=(1.0, 0.0, 0.0, 0.25), + ec=(0.0, 0.0, 1.0, 0.75), + alpha=0.4, + ), + ) + + (rect,) = _annotation_rects(fig, ax) + assert rect["fill"] == "rgba(255,0,0,0.4)" + assert rect["stroke"] == "rgba(0,0,255,0.4)" + + +def test_bbox_alpha_reaches_the_native_raster_stroke_colour() -> None: + """The native display list carries the same composited edge alpha.""" + style: dict[str, Any] = { + "background": "rgba(31,119,180,0.1)", + "border": "1px solid rgba(0,0,0,0.1)", + "padding": "4px", + } + cmd = _raster._Cmd(1.0) + _raster._emit_text_box(cmd, style, ["Christmas"], 100.0, 100.0, 13.2, 11.0, 0) + + # 0.1 alpha -> round(0.1 * 255) == 26 in the RGBA byte quad. + assert _first_stroke_rgba(cmd) == (0, 0, 0, 26) + + +# --- D2: an arrow-less annotation is Matplotlib-black, not a design token ---- + + +def test_arrowless_annotation_text_is_matplotlib_black_in_svg() -> None: + """Matplotlib paints Text with rcParams["text.color"] (black).""" + fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [0.0, 1.0]) + ax.annotate( + "Labor Day Weekend", + xy=(0.5, 0.9), + xycoords="data", + ha="center", + xytext=(0, -20), + textcoords="offset points", + ) + + texts = _annotation_texts(fig, ax) + # Previously "#667085", the SVG exporter's own annotation-label token. + assert texts["Labor Day Weekend"]["fill"] == "black" + + +def test_arrowless_annotation_text_is_black_in_the_native_stream(monkeypatch) -> None: + """The native text command must carry opaque black, not a design token. + + Before, this label reached the rasterizer as ``rgba(32,32,32,.85)`` — + the ``_TEXT`` token — which composites to (65, 65, 65) on white, while + Matplotlib's own PNG bottoms out at (0, 0, 0). + """ + fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [0.0, 1.0]) + ax.annotate( + "Labor Day Weekend", + xy=(0.5, 0.9), + xycoords="data", + ha="center", + xytext=(0, -20), + textcoords="offset points", + ) + + seen: list[tuple[str, tuple[int, ...]]] = [] + original = _raster._Cmd.text + + def spy(self, x, y, anchor, size, color, text, *args, **kwargs): + seen.append((str(text), tuple(color))) + return original(self, x, y, anchor, size, color, text, *args, **kwargs) + + monkeypatch.setattr(_raster._Cmd, "text", spy) + fig._to_png() + + labels = [color for text, color in seen if text == "Labor Day Weekend"] + assert labels, f"annotation label never reached the rasterizer; saw {seen}" + assert labels[0] == (0, 0, 0, 255) + + +def test_explicit_text_colour_still_wins_over_the_matplotlib_default() -> None: + """``color=`` must not be overridden by the pinned default (pdsh cell 13).""" + fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [0.0, 1.0]) + ax.text(0.5, 0.5, "Christmas ", ha="right", size=10, color="gray") + + texts = _annotation_texts(fig, ax) + assert texts["Christmas"]["fill"] == "gray" + + +# --- D3: an exported boxstyle="round" box has rounded corners ---------------- + + +def test_round_boxstyle_exports_a_non_zero_corner_radius_in_svg() -> None: + """``rx`` must be present and non-zero, as CSS border-radius already was.""" + fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [0.0, 1.0]) + ax.annotate( + "Independence Day", + xy=(0.5, 0.5), + bbox=dict(boxstyle="round", fc="none", ec="gray"), + xytext=(10, -40), + textcoords="offset points", + ha="center", + arrowprops=dict(arrowstyle="->"), + ) + + (rect,) = _annotation_rects(fig, ax) + assert float(rect["rx"]) > 0.0 + # Matplotlib's own path radius for boxstyle="round" at 10 pt is 3.00 pt + # (4.17 px at 96 dpi); the shim's CSS approximation is 5 px. + assert float(rect["rx"]) == pytest.approx(5.0) + + +def test_exported_round_box_is_wide_enough_for_a_mixed_width_label() -> None: + """The static width heuristic must not let ``Thanksgiving`` escape its box.""" + fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [0.0, 1.0]) + ax.annotate( + "Thanksgiving", + xy=(0.5, 0.5), + bbox=dict(boxstyle="round4,pad=.5", fc="0.9"), + ) + + (rect,) = _annotation_rects(fig, ax) + # 11 px font with 5.5 px padding per side. The old flat 0.48em estimate + # produced 74.36 px and visibly clipped the final glyphs. + assert float(rect["width"]) > 80.0 + + +def test_square_boxstyle_keeps_square_corners_in_svg() -> None: + """Only the rounded box styles round — ``square`` must emit no ``rx``.""" + fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [0.0, 1.0]) + ax.text(0.5, 0.5, "plain", bbox=dict(boxstyle="square", fc="0.9")) + + (rect,) = _annotation_rects(fig, ax) + assert "rx" not in rect + + +def test_round_boxstyle_exports_rounded_corners_in_the_native_stream() -> None: + """The FILL polygon gains arc vertices instead of four square corners.""" + style: dict[str, Any] = { + "background": "rgb(230,230,230)", + "border": "1px solid black", + "padding": "4px", + "border_radius": 8.0, + } + cmd = _raster._Cmd(1.0) + _raster._emit_text_box(cmd, style, ["Thanksgiving"], 100.0, 100.0, 13.2, 11.0, 0) + count, pts, _rgba = _first_fill(cmd) + + # 4 corners x (4 arc steps + 1) vertices, versus 4 for a square rect. + assert count == 20 + xs = [x for x, _ in pts] + ys = [y for _, y in pts] + # A rounded corner means no vertex sits at the rect's own corner. + assert (min(xs), min(ys)) not in pts + + +def test_square_box_keeps_a_four_vertex_native_polygon() -> None: + """Without ``border_radius`` the native box is the plain rect it was.""" + style: dict[str, Any] = { + "background": "rgb(230,230,230)", + "border": "1px solid black", + "padding": "4px", + } + cmd = _raster._Cmd(1.0) + _raster._emit_text_box(cmd, style, ["Thanksgiving"], 100.0, 100.0, 13.2, 11.0, 0) + + count, _pts, _rgba = _first_fill(cmd) + assert count == 4 + + +def test_corner_radius_is_clamped_to_the_box_like_css() -> None: + """An absurd radius must not invert the polygon or escape the box.""" + style: dict[str, Any] = { + "background": "rgb(230,230,230)", + "padding": "2px", + "border_radius": 500.0, + } + cmd = _raster._Cmd(1.0) + _raster._emit_text_box(cmd, style, ["x"], 100.0, 100.0, 13.2, 11.0, 0) + _count, pts, _rgba = _first_fill(cmd) + + xs = [x for x, _ in pts] + ys = [y for _, y in pts] + width = max(xs) - min(xs) + height = max(ys) - min(ys) + assert width > 0 and height > 0 + # Clamped to half the shorter side, so the polygon still spans the box. + assert height == pytest.approx(11.0 + 4.0, abs=1e-3) diff --git a/tests/pyplot/test_autoscale_margin_bar_regressions.py b/tests/pyplot/test_autoscale_margin_bar_regressions.py new file mode 100644 index 00000000..d1188a01 --- /dev/null +++ b/tests/pyplot/test_autoscale_margin_bar_regressions.py @@ -0,0 +1,187 @@ +from __future__ import annotations + +import numpy as np +import pytest + +import xy.pyplot as plt + + +@pytest.fixture(autouse=True) +def _clean(): + plt.close("all") + plt.rcdefaults() + yield + plt.close("all") + plt.rcdefaults() + + +def _axis_domain(ax, which: str) -> tuple[float, float]: + chart = ax._build_chart(640, 480) + figure = chart.figure() + return figure.x_range() if which == "x" else figure.y_range() + + +def test_default_rc_margins_apply_to_public_and_rendered_line_limits() -> None: + _fig, ax = plt.subplots() + ax.plot([0.0, 1.0, 2.0], [1.0, 3.0, 2.0]) + + assert ax.get_xlim() == pytest.approx((-0.1, 2.1)) + assert ax.get_ylim() == pytest.approx((0.9, 3.1)) + assert _axis_domain(ax, "x") == pytest.approx((-0.1, 2.1)) + assert _axis_domain(ax, "y") == pytest.approx((0.9, 3.1)) + + +def test_default_margin_render_delegates_to_figure_autorange(monkeypatch) -> None: + _fig, ax = plt.subplots() + ax.plot(np.arange(10_000.0), np.arange(10_000.0)) + + def unexpected_scan(_axis: str) -> tuple[float, float]: + raise AssertionError("ordinary rendering must not rescan pyplot arrays") + + monkeypatch.setattr(ax, "_auto_domain", unexpected_scan) + chart = ax._build_chart(640, 480) + axes = { + child.which: child + for child in chart.children + if getattr(child, "which", None) in {"x", "y"} + } + + assert axes["x"].domain is None + assert axes["y"].domain is None + assert axes["x"].margin == pytest.approx(0.05) + assert axes["y"].margin == pytest.approx(0.05) + assert chart.figure().x_range() == pytest.approx((-499.95, 10_498.95)) + + +def test_singleton_margin_matches_public_and_rendered_limits() -> None: + _fig, ax = plt.subplots() + ax.plot([5.0], [1.0]) + + assert ax.get_xlim() == pytest.approx((4.95, 6.05)) + assert ax.get_ylim() == pytest.approx((0.95, 2.05)) + assert _axis_domain(ax, "x") == pytest.approx(ax.get_xlim()) + assert _axis_domain(ax, "y") == pytest.approx(ax.get_ylim()) + + +def test_twin_y_margin_matches_public_and_rendered_limits() -> None: + _fig, ax = plt.subplots() + ax.plot([0.0, 1.0], [1.0, 2.0]) + twin = ax.twinx() + twin.plot([0.0, 1.0], [10.0, 20.0]) + twin.margins(y=0.1) + + rendered = ax._build_chart(640, 480).figure()._range("y2") + + assert ax.get_ylim() == pytest.approx((0.95, 2.05)) + assert twin.get_ylim() == pytest.approx((9.0, 21.0)) + assert rendered == pytest.approx(twin.get_ylim()) + + +def test_axes_snapshot_rc_margins_at_creation() -> None: + with plt.rc_context({"axes.xmargin": 0.1, "axes.ymargin": 0.2}): + _fig, ax = plt.subplots() + ax.plot([0.0, 10.0], [-1.0, 1.0]) + + assert ax.get_xlim() == pytest.approx((-1.0, 11.0)) + assert ax.get_ylim() == pytest.approx((-1.4, 1.4)) + + +def test_default_margin_is_applied_in_log_coordinate_space() -> None: + _fig, ax = plt.subplots() + ax.plot([1.0, 10.0, 100.0], [1.0, 2.0, 3.0]) + ax.set_xscale("log") + + expected = (10.0**-0.1, 10.0**2.1) + assert ax.get_xlim() == pytest.approx(expected) + assert _axis_domain(ax, "x") == pytest.approx(expected) + + +@pytest.mark.parametrize( + ("values", "expected"), + [ + ([1.2, 1.8, 1.4], (0.0, 1.89)), + ([-1.2, -1.8, -1.4], (-1.89, 0.0)), + ([-2.0, 3.0, 1.0], (-2.25, 3.25)), + ], +) +def test_vertical_bar_limits_include_sticky_baseline_and_margin(values, expected) -> None: + _fig, ax = plt.subplots() + ax.bar([0.0, 1.0, 2.0], values) + + assert ax.get_ylim() == pytest.approx(expected) + assert _axis_domain(ax, "y") == pytest.approx(expected) + + +def test_stacked_bar_limits_include_bases_and_cumulative_tops() -> None: + _fig, ax = plt.subplots() + ax.bar([0.0, 1.0, 2.0], [1.0, 1.5, 0.8]) + ax.bar( + [0.0, 1.0, 2.0], + [2.0, 1.0, 2.5], + bottom=[1.0, 1.5, 0.8], + ) + + assert ax.get_xlim() == pytest.approx((-0.54, 2.54)) + assert ax.get_ylim() == pytest.approx((0.0, 3.465)) + assert _axis_domain(ax, "x") == pytest.approx((-0.54, 2.54)) + assert _axis_domain(ax, "y") == pytest.approx((0.0, 3.465)) + + +def test_horizontal_bar_limits_include_value_baseline_and_category_width() -> None: + _fig, ax = plt.subplots() + ax.barh(["A", "B", "C"], [1.2, 1.8, 1.4]) + + assert ax.get_xlim() == pytest.approx((0.0, 1.89)) + assert ax.get_ylim() == pytest.approx((-0.54, 2.54)) + assert _axis_domain(ax, "x") == pytest.approx((0.0, 1.89)) + assert _axis_domain(ax, "y") == pytest.approx((-0.54, 2.54)) + + +def test_categorical_bar_domain_covers_every_category() -> None: + _fig, ax = plt.subplots() + ax.bar( + ["first category", "second category", "third category", "fourth category"], + [1.0, 3.0, 2.0, 4.0], + ) + + assert ax.get_xlim() == pytest.approx((-0.59, 3.59)) + assert ax.get_ylim() == pytest.approx((0.0, 4.2)) + assert _axis_domain(ax, "x") == pytest.approx((-0.59, 3.59)) + + +def test_default_bar_margin_reserves_visible_headroom_for_edge_labels() -> None: + _fig, ax = plt.subplots() + bars = ax.bar([0.0, 1.0, 2.0], [1.2, 1.8, 1.4], width=0.55) + labels = ax.bar_label(bars, fmt="%.1f", padding=3) + + assert [label.get_text() for label in labels] == ["1.2", "1.8", "1.4"] + assert ax.get_ylim() == pytest.approx((0.0, 1.935)) + assert _axis_domain(ax, "y") == pytest.approx((0.0, 1.935)) + assert max(np.asarray(bars.tops, dtype=float)) < ax.get_ylim()[1] + + +def test_explicit_margin_overrides_bar_label_headroom_default() -> None: + _fig, ax = plt.subplots() + bars = ax.bar([0.0, 1.0], [1.0, 2.0]) + ax.margins(y=0.02) + ax.bar_label(bars, padding=3) + + assert ax.get_ylim() == pytest.approx((0.0, 2.04)) + assert _axis_domain(ax, "y") == pytest.approx((0.0, 2.04)) + + +def test_horizontal_edge_labels_reserve_value_axis_headroom() -> None: + _fig, ax = plt.subplots() + bars = ax.barh(["A", "B", "C"], [1.2, 1.8, 1.4]) + ax.bar_label(bars, padding=3) + + assert ax.get_xlim() == pytest.approx((0.0, 1.935)) + assert _axis_domain(ax, "x") == pytest.approx((0.0, 1.935)) + + +def test_centered_bar_labels_do_not_expand_autoscale_margin() -> None: + _fig, ax = plt.subplots() + bars = ax.bar([0.0, 1.0], [1.0, 2.0]) + ax.bar_label(bars, label_type="center") + + assert ax.get_ylim() == pytest.approx((0.0, 2.1)) diff --git a/tests/pyplot/test_axes_charts.py b/tests/pyplot/test_axes_charts.py index 1471b722..918c75e6 100644 --- a/tests/pyplot/test_axes_charts.py +++ b/tests/pyplot/test_axes_charts.py @@ -374,13 +374,13 @@ def test_imshow_accepts_descending_extent_with_upper_origin() -> None: assert trace.kind == "heatmap" -def test_fill_arrow_and_axline_compile_to_native_mesh_and_segments() -> None: +def test_fill_arrow_and_axline_compile_to_native_mesh_segments_and_line() -> None: _fig, ax = plt.subplots() patches = ax.fill([0, 2, 2, 1, 0], [0, 0, 2, 1, 2], "tab:blue", alpha=0.5) arrow = ax.arrow(0, 0, 2, 1, head_width=0.4) line = ax.axline((0, 1), slope=0.5, color="red") assert len(patches) == 1 and arrow is not None and line is not None - assert [trace.kind for trace in _traces(ax)] == ["triangle_mesh", "segments", "segments"] + assert [trace.kind for trace in _traces(ax)] == ["triangle_mesh", "segments", "line"] def test_spectral_family_dispatches_fft_welch_and_correlation_to_rust() -> None: @@ -405,14 +405,15 @@ def test_spectral_family_dispatches_fft_welch_and_correlation_to_rust() -> None: assert "heatmap" in kinds and "segments" in kinds -def test_quiver_and_barbs_use_native_vector_segments() -> None: +def test_quiver_and_barbs_translate_to_vector_segments() -> None: _fig, ax = plt.subplots() q = ax.quiver([0, 1], [0, 1], [1, 0], [0, 1], angles="xy", scale_units="xy", scale=1) b = ax.barbs([0, 1], [1, 2], [0.5, 1.0], [1.0, 0.5]) assert q is not None and b is not None traces = _traces(ax) assert [trace.kind for trace in traces] == ["segments", "segments"] - assert all(len(trace.x0.values) == 6 for trace in traces) + assert len(traces[0].x0.values) == 6 + assert len(traces[1].x0.values) > 2 def test_streamplot_translates_lines_and_arrowheads_to_xy_marks() -> None: @@ -549,11 +550,12 @@ def test_clabel_table_and_quiverkey_complete_annotation_families() -> None: cellColours=[["#fee2e2", "#dcfce7"], ["#dbeafe", "#fef3c7"]], ) quiver = ax.quiver([0, 1], [0, 1], [1, 1], [1, 0], [0.2, 0.8], cmap="plasma") - key = ax.quiverkey(quiver, 0.5, 0.5, 1.0, "1 m/s") + key = ax.quiverkey(quiver, 0.9, 0.9, 1.0, r"$1 \frac{m}{s}$", coordinates="figure") assert {label.get_text() for label in contour_labels} == {"L=4", "L=8"} assert len(contour_labels) > 2 assert len(table.get_celld()) == 9 assert key is not None + assert ax._entries[-1]["args"][2] == "1 m/s" assert {trace.kind for trace in _traces(ax)} >= {"contour", "triangle_mesh", "segments"} diff --git a/tests/pyplot/test_axes_layout.py b/tests/pyplot/test_axes_layout.py index 3e19c127..2774389f 100644 --- a/tests/pyplot/test_axes_layout.py +++ b/tests/pyplot/test_axes_layout.py @@ -1,10 +1,12 @@ from __future__ import annotations import builtins +import re import pytest import xy.pyplot as plt +from xy._svg import layout @pytest.fixture(autouse=True) @@ -31,8 +33,12 @@ def no_matplotlib(name, *args, **kwargs): monkeypatch.setattr(builtins, "__import__", no_matplotlib) default = ax.get_position() - assert default.bounds == (0.125, 0.11, 0.775, 0.77) - assert (default.x0, default.y0, default.x1, default.y1) == (0.125, 0.11, 0.9, 0.88) + # Resolved through the gridspec now that get_position() is grid-aware, so + # the bottom edge carries matplotlib's own 0.88 - 0.77 rounding. + assert default.bounds == pytest.approx((0.125, 0.11, 0.775, 0.77)) + assert (default.x0, default.y0, default.x1, default.y1) == pytest.approx( + (0.125, 0.11, 0.9, 0.88) + ) ax.set_position([0.2, 0.3, 0.4, 0.5]) @@ -49,8 +55,9 @@ def test_margins_expand_only_automatic_domains() -> None: assert ax.get_xlim() == (9.0, 21.0) assert ax.get_ylim() == (90.0, 150.0) - assert _axis_child(ax, "x").domain == (9.0, 21.0) - assert _axis_child(ax, "y").domain == (90.0, 150.0) + figure = ax._build_chart(640, 480).figure() + assert figure.x_range() == (9.0, 21.0) + assert figure.y_range() == (90.0, 150.0) ax.set_xlim(0.0, 1.0) ax.margins(x=0.5) @@ -73,7 +80,10 @@ def test_axis_tight_sets_data_domains_and_equal_expands_to_panel_ratio() -> None assert x_axis.domain == pytest.approx((-0.1, 2.1)) # axis("equal") uses adjustable='datalim': preserve the ordinary panel # rectangle and expand y until x/y data units have the same pixel scale. - assert y_axis.domain == pytest.approx((-0.3347517730, 1.3347517730)) + # The expansion now solves over the *matplotlib* axes rectangle + # (0.775 x 0.77 of 640x480), so these are Matplotlib 3.11's own limits for + # this figure rather than the ones implied by the old label-aware margins. + assert y_axis.domain == pytest.approx((-0.31967741935483873, 1.3196774193548388)) assert ax.get_position().bounds == pytest.approx((0.125, 0.11, 0.775, 0.77)) @@ -164,6 +174,7 @@ def test_tick_params_records_supported_style_and_rejects_unknown() -> None: labelrotation=45, colors="tab:red", length=7, + pad=6, width=2, direction="in", labelbottom=False, @@ -177,6 +188,7 @@ def test_tick_params_records_supported_style_and_rejects_unknown() -> None: "tick_color": "#d62728", "tick_label_color": "#d62728", "tick_length": pytest.approx(7.0 * 100.0 / 72.0), + "tick_padding": pytest.approx(6.0 * 100.0 / 72.0), "tick_width": pytest.approx(2.0 * 100.0 / 72.0), "tick_direction": "in", # Always explicit (10 pt font.size at dpi 100): the render client and @@ -189,6 +201,59 @@ def test_tick_params_records_supported_style_and_rejects_unknown() -> None: ax.tick_params(which="minor") +def _tick_label_positions(chart) -> dict[str, tuple[float, float]]: + return { + match.group(3): (float(match.group(1)), float(match.group(2))) + for match in re.finditer( + r']*>([^<]*)', chart.to_svg() + ) + } + + +def test_rc_tick_padding_places_labels_by_the_matplotlib_rule() -> None: + """The shim always supplies `{x,y}tick.major.size` and `.pad` from rcParams, + so its tick labels follow matplotlib's geometry rule — padding measured from + the outward end of the tick mark — instead of core's flat per-side gaps for + charts that author no tick styling. The two regimes must stay + distinguishable; `tests/test_svg_export.py` pins the core side of the seam. + """ + _fig, ax = plt.subplots() + ax.plot([0.0, 1.0, 2.0], [0.0, 1.0, 0.5]) + ax.set_xticks([0.0, 1.0, 2.0]) + ax.set_yticks([0.0, 0.5, 1.0]) + + chart = ax._build_chart(400, 300) + plot = layout(chart.figure().build_payload()[0])[3] + labels = _tick_label_positions(chart) + + scale = 100.0 / 72.0 # figure.dpi 100: points -> px + # 3.5 pt outward tick + 3.5 pt pad, then 0.8 * the 10 pt label font. + x_gap = (3.5 + 3.5 + 0.8 * 10.0) * scale + assert x_gap == pytest.approx(20.83, abs=0.01) + assert labels["1"][1] == pytest.approx(plot["y"] + plot["h"] + x_gap, abs=0.01) + assert x_gap > 16.0 # an unstyled core chart's flat bottom gap + + y_gap = (3.5 + 3.5) * scale + assert y_gap == pytest.approx(9.72, abs=0.01) + assert labels["0.5"][0] == pytest.approx(plot["x"] - y_gap, abs=0.01) + assert y_gap > 8.0 # an unstyled core chart's flat y gap + + +def test_tick_params_pad_moves_the_labels_further_from_the_spine() -> None: + """`tick_params(pad=)` overrides the rc pad in the same geometry.""" + _fig, ax = plt.subplots() + ax.plot([0.0, 1.0, 2.0], [0.0, 1.0, 0.5]) + ax.set_yticks([0.0, 0.5, 1.0]) + ax.tick_params(axis="y", pad=12) + + chart = ax._build_chart(400, 300) + plot = layout(chart.figure().build_payload()[0])[3] + labels = _tick_label_positions(chart) + + scale = 100.0 / 72.0 + assert labels["0.5"][0] == pytest.approx(plot["x"] - (3.5 + 12.0) * scale, abs=0.01) + + def test_axes_set_rejects_unknown_properties_after_applying_known_setters() -> None: _fig, ax = plt.subplots() diff --git a/tests/pyplot/test_axis_tick_gallery_compat.py b/tests/pyplot/test_axis_tick_gallery_compat.py new file mode 100644 index 00000000..b68bfa83 --- /dev/null +++ b/tests/pyplot/test_axis_tick_gallery_compat.py @@ -0,0 +1,88 @@ +"""Matplotlib 3.11 axis/tick APIs exercised by the upstream gallery.""" + +from __future__ import annotations + +import pytest + +import xy.pyplot as plt + + +def test_set_ticklabels_matches_fixed_locator_and_empty_label_semantics() -> None: + _fig, ax = plt.subplots() + ax.set_xticks([0, 1, 2]) + + labels = ax.set_xticklabels(["zero", "one", "two"], color="tab:red", fontsize=12, rotation=30) + + assert [label.get_text() for label in labels] == ["zero", "one", "two"] + assert ax._axis_props("x")["tick_labels"] == ["zero", "one", "two"] + assert ax._axis_props("x")["tick_label_angle"] == 30.0 + assert ax._axis_props("x")["style"]["tick_label_color"] == "#d62728" + assert ax._axis_props("x")["style"]["tick_label_size"] == pytest.approx(12 * 100 / 72) + + with pytest.raises(ValueError, match="FixedLocator locations"): + ax.set_xticklabels(["too", "short"]) + + tick_positions = list(ax._axis_props("x")["tick_values"]) + hidden = ax.set_xticklabels([]) + assert [label.get_text() for label in hidden] == ["", "", ""] + assert ax._axis_props("x")["tick_values"] == tick_positions + assert ax._axis_props("x")["tick_label_strategy"] == "off" + + +def test_set_yticklabels_without_fixed_ticks_uses_current_static_tick_set() -> None: + _fig, ax = plt.subplots() + ax.plot([0, 1], [0, 4]) + current = ax.get_yticks() + + labels = ax.set_yticklabels(["low", "high"]) + + assert len(labels) == len(current) + assert [label.get_text() for label in labels[:2]] == ["low", "high"] + assert all(label.get_text() == "" for label in labels[2:]) + assert ax.get_yticks() == pytest.approx(current) + + +def test_axis_proxy_grid_targets_only_its_dimension_and_minor_is_accepted() -> None: + _fig, ax = plt.subplots() + + ax.xaxis.grid(True, color="tab:red", linewidth=2) + assert ax._axis_props("x")["style"]["grid_color"] == "#d62728" + assert ax._axis_props("x")["style"]["grid_width"] == 2.0 + assert ax._axis_props("y")["style"]["grid_color"] == "transparent" + + ax.yaxis.grid(True, color="tab:blue") + assert ax._axis_props("x")["style"]["grid_color"] == "#d62728" + assert ax._axis_props("y")["style"]["grid_color"] == "#1f77b4" + + ax.xaxis.grid(False) + assert ax._axis_props("x")["style"]["grid_color"] == "transparent" + assert ax._axis_props("y")["style"]["grid_color"] == "#1f77b4" + + # Minor ticks are not rendered natively, but Matplotlib's accepted call is + # a compatibility no-op rather than a gallery-stopping ValueError. + ax.xaxis.grid(which="minor", color="0.9") + assert ax._axis_props("y")["style"]["grid_color"] == "#1f77b4" + + +def test_tick_params_side_flags_and_xtick_rotation_mode() -> None: + _fig, ax = plt.subplots() + default_x_length = ax._axis_props("x")["style"]["tick_length"] + default_y_length = ax._axis_props("y")["style"]["tick_length"] + + ax.tick_params(left=False, bottom=False, labelbottom=False) + + assert ax._axis_props("x")["style"]["tick_length"] == 0.0 + assert ax._axis_props("y")["style"]["tick_length"] == 0.0 + assert ax._axis_props("x")["tick_label_strategy"] == "off" + assert ax._axis_props("y").get("tick_label_strategy") is None + + ax.tick_params(axis="x", bottom=True, rotation=45, rotation_mode="xtick") + assert ax._axis_props("x")["style"]["tick_length"] == default_x_length + assert ax._axis_props("y")["style"]["tick_length"] == 0.0 + assert default_y_length > 0 + assert ax._axis_props("x")["tick_label_angle"] == 45.0 + assert ax._axis_props("x")["tick_label_anchor"] == "end" + assert ax.get_xticklabels()[0].get_rotation_mode() == "xtick" + + with pytest.raises(ValueError, match="rotation_mode"): + ax.tick_params(axis="x", rotation_mode="sideways") diff --git a/tests/pyplot/test_best_legend_placement.py b/tests/pyplot/test_best_legend_placement.py new file mode 100644 index 00000000..c71cbe20 --- /dev/null +++ b/tests/pyplot/test_best_legend_placement.py @@ -0,0 +1,438 @@ +"""``legend(loc="best")`` must choose the corner Matplotlib chooses. + +Every ``matplotlib`` location in this file is a *measured* value, not a guess: +each was read out of ``matplotlib.legend.Legend._find_best_position`` under +matplotlib 3.11.1 for the same figure, together with its per-candidate badness. +The comments quote those badness numbers so a future change to the scoring model +can be judged against Matplotlib rather than against this file. + +Assertions are on the resolved ``loc`` that reaches the wire, never on pixels. +""" + +from __future__ import annotations + +import numpy as np +import pytest + +import xy +import xy.pyplot as plt +from xy._svg import _legend_layout + + +def resolved_loc(ax) -> str: + """The legend loc the built figure actually ships, at the figure's own size.""" + spec, _ = ax.figure._charts()[0].figure().build_payload() + return spec["legend"]["loc"] + + +# -------------------------------------------------------------------------- +# Parity table. `matplotlib` is what matplotlib 3.11.1 picks; `expected` is what +# the shim picks. They are equal except where `note` records a measured reason. +# -------------------------------------------------------------------------- + + +def _births_seasonal_curve(): + """The reported defect, reduced to its geometry. + + `examples/pdsh/pdsh_04_09_text_and_annotation.ipynb` cell 23: one wide, + 366-point series labelled `births`, a late-summer peak reaching ~0.87 of the + view, and a low winter tail that leaves the top-right corner clear. + Matplotlib picks upper right at badness 0. + + The old linear estimate sized this legend at 0.30 x 0.17 of the axes + (`0.12 + 0.03 * len("births")` by `0.10 + 0.07 * 1`) against a real + 0.097 x 0.083. The inflated upper-right candidate reached back to x=0.70 and + down to y=0.83, swallowing the summer peak, while the inflated upper-left + candidate stopped at x=0.30 and stayed empty -- so upper left won. + """ + t = np.linspace(0.0, 1.0, 366) + y = 3900 + 1300 * np.exp(-(((t - 0.68) / 0.16) ** 2)) + y += 40 * np.sin(2 * np.pi * t * 7) + _, ax = plt.subplots(figsize=(12, 4)) + ax.plot(t, y, label="births") + ax.set_ylim(3600, 5400) + ax.legend(loc="best") + return ax + + +def _data_in_upper_right(): + """A rising diagonal fills the upper right. Matplotlib: upper left (0); + upper right scores 11.""" + _, ax = plt.subplots() + x = np.linspace(0, 10, 200) + ax.plot(x, x, label="rising") + ax.legend(loc="best") + return ax + + +def _data_in_upper_left(): + """A falling diagonal fills the upper left. Matplotlib: upper right (0).""" + _, ax = plt.subplots() + x = np.linspace(0, 10, 200) + ax.plot(x, 10 - x, label="falling") + ax.legend(loc="best") + return ax + + +def _few_entries_short_labels(): + """One entry, one-character label -> the smallest possible box. + Matplotlib: upper right, badness 0.""" + _, ax = plt.subplots() + x = np.linspace(0, 10, 100) + ax.plot(x, np.sin(x), label="a") + ax.legend(loc="best") + return ax + + +def _full_amplitude_oscillation(): + """A sine filling the view vertically. Matplotlib: lower left (0), after + scoring upper right 2 and upper left 45 -- the two vertices near the last + peak are what disqualify upper right.""" + _, ax = plt.subplots() + x = np.linspace(0, 20, 1000) + ax.plot(x, np.sin(x), label="sin") + ax.legend(loc="best") + return ax + + +def _center_band_oscillation(): + """Four phase-shifted sines: every corner busy, the center band sparse. + Matplotlib: center left 20, against center right 36.""" + _, ax = plt.subplots() + x = np.linspace(0, 10, 500) + ax.plot(x, np.sin(x[:, None] + np.pi * np.arange(0, 2, 0.5))) + ax.legend(["a", "b"]) + return ax + + +def _diagonal_band_long_labels(): + """Two near-identical diagonals with a long label -> a wide two-row box. + Matplotlib: upper left (0); upper right scores 57.""" + _, ax = plt.subplots() + x = np.linspace(0, 10, 300) + ax.plot(x, x, label="identity") + ax.plot(x, x + 0.5, label="identity shifted up by a half") + ax.legend(loc="best") + return ax + + +def _data_fills_axes(): + """A uniform cloud over the whole view: no candidate is empty. + + Matplotlib ties upper left and lower right at 2 contained vertices out of + 400 and breaks the tie by location code, giving upper left. The shim's box + is ~12% narrower and ~14% shorter *as a fraction of its plot rect* (the box + is pixel-accurate; xy's plot rect is larger than Matplotlib's axes rect), + which separates the tie and leaves lower right strictly emptier. + """ + _, ax = plt.subplots() + rng = np.random.default_rng(0) + ax.plot(rng.uniform(0, 1, 400), rng.uniform(0, 1, 400), "o", label="cloud") + ax.legend(loc="best") + return ax + + +def _scatter_cluster_upper_right(): + """A tight cluster near the upper-right corner. + + Matplotlib scores upper right 1 -- a single one of 200 offsets sits in the + corner box -- and so falls through to upper left. That lone offset lies + between the shim's box edge and Matplotlib's, for the same plot-rect reason + as `_data_fills_axes`, so the shim sees upper right as empty. + """ + _, ax = plt.subplots() + rng = np.random.default_rng(3) + ax.scatter(rng.normal(8, 0.4, 200), rng.normal(8, 0.4, 200), label="cluster") + ax.set_xlim(0, 10) + ax.set_ylim(0, 10) + ax.legend(loc="best") + return ax + + +def _many_entries_long_labels(): + """Six long labels -> a box covering ~71% x ~31% of the plot. + + No candidate is close to empty. Matplotlib ties lower left and lower center + at 147 and takes lower left; the shim's smaller box makes the dead-center + box the emptiest instead. Same plot-rect gap, amplified by a box this large. + """ + _, ax = plt.subplots() + x = np.linspace(0, 10, 100) + for index in range(6): + ax.plot( + x, + 0.4 * np.sin(x) + index * 0.05, + label=f"a very long descriptive series label number {index}", + ) + ax.legend(loc="best") + return ax + + +PARITY_CASES = [ + # (id, builder, matplotlib 3.11.1 loc, shim loc) + ("births_seasonal_curve", _births_seasonal_curve, "upper right", "upper right"), + ("data_in_upper_right", _data_in_upper_right, "upper left", "upper left"), + ("data_in_upper_left", _data_in_upper_left, "upper right", "upper right"), + ("few_entries_short_labels", _few_entries_short_labels, "upper right", "upper right"), + ("full_amplitude_oscillation", _full_amplitude_oscillation, "lower left", "lower left"), + ("center_band_oscillation", _center_band_oscillation, "center left", "center left"), + ("diagonal_band_long_labels", _diagonal_band_long_labels, "upper left", "upper left"), + ("data_fills_axes", _data_fills_axes, "upper left", "upper left"), + ("scatter_cluster_upper_right", _scatter_cluster_upper_right, "upper left", "upper left"), + ("many_entries_long_labels", _many_entries_long_labels, "lower left", "lower left"), +] + + +@pytest.mark.parametrize( + ("builder", "matplotlib_loc", "expected"), + [case[1:] for case in PARITY_CASES], + ids=[case[0] for case in PARITY_CASES], +) +def test_best_loc_matches_matplotlib_per_data_shape(builder, matplotlib_loc, expected): + assert resolved_loc(builder()) == expected + + +def test_measured_parity_against_matplotlib(): + """Pin the combined measured parity rate against Matplotlib 3.11.""" + parity = {case[0]: resolved_loc(case[1]()) == case[2] for case in PARITY_CASES} + assert sum(parity.values()) == 10 + + +def test_residual_divergence_is_attributable_to_the_plot_rect(monkeypatch): + """The legacy Matplotlib plot-rect probe also remains 10/10.""" + monkeypatch.setattr( + type(plt.subplots()[1]), + "_displayed_plot_size", + staticmethod( + lambda figure: ( + figure.width * 0.775, + figure.height * 0.77, + ) + ), + ) + parity = {case[0]: resolved_loc(case[1]()) == case[2] for case in PARITY_CASES} + assert sum(parity.values()) == 10 + + +# -------------------------------------------------------------------------- +# The footprint is measured, not estimated +# -------------------------------------------------------------------------- + + +def test_best_scores_the_measured_legend_box_not_a_linear_estimate(): + """The scored footprint is the box the exporters actually lay out.""" + _, ax = plt.subplots() + x = np.linspace(0, 10, 366) + ax.plot(x, 0.05 * np.sin(x), label="average daily births") + ax.set_ylim(-1, 1) + ax.legend(loc="best") + + chart = ax._build_chart(1200, 400) + spec, _ = chart.figure().build_payload() + from xy._svg import layout + + _, _, _, plot = layout(spec) + box = _legend_layout( + [trace for trace in spec["traces"] if trace.get("name")], plot, spec["legend"] + ) + # One row of one label: nowhere near the 0.12 + 0.03 * len(label) width and + # 0.10 + 0.07 * rows height the old estimate produced (0.30 x 0.17). + assert box["box_w"] / plot["w"] < 0.21 + assert box["box_h"] / plot["h"] < 0.12 + assert spec["legend"]["loc"] == "upper right" + + +def test_longer_labels_grow_the_scored_footprint(): + """A wider legend guards a wider region, so it can change the choice.""" + + def build(label): + _, ax = plt.subplots() + x = np.linspace(0, 10, 200) + # Data hugging the top-left leaves the right side clear, but only for a + # box narrow enough to fit beside it. + ax.plot(x, 10 - 3 * x, label=label) + ax.set_xlim(0, 10) + ax.set_ylim(0, 10) + ax.legend(loc="best") + return ax + + narrow = _legend_footprint_width(build("a")) + wide = _legend_footprint_width(build("an extremely long series label indeed")) + assert wide > narrow * 2 + + +def _legend_footprint_width(ax) -> float: + spec, _ = ax._build_chart(640, 480).figure().build_payload() + from xy._svg import layout + + _, _, _, plot = layout(spec) + box = _legend_layout( + [trace for trace in spec["traces"] if trace.get("name")], plot, spec["legend"] + ) + return box["box_w"] / plot["w"] + + +def test_best_scores_the_displayed_view_not_the_raw_data_extent(): + """Autorange padding moves the corners; `best` must see the padded view. + + Data spanning exactly the data extent reaches y=1.0, but the rendered view + is padded past it, so the top band is clear on screen. Scoring the raw + extent instead reports the top band as occupied. + """ + _, ax = plt.subplots() + x = np.linspace(0, 10, 200) + ax.plot(x, np.full_like(x, 1.0), label="flat top") + ax.plot(x, np.linspace(0.0, 0.2, 200), label="rising floor") + ax.legend(loc="best") + figure = ax._build_chart(640, 480).figure() + lo, hi = figure.y_range() + assert hi > 1.0 and lo < 0.0 # the engine padded past the data + # The flat line at y=1.0 sits *below* the padded top edge, so the upper + # corners are still occupied by it and matplotlib's first empty candidate + # is a lower one. + assert resolved_loc(ax) in {"lower left", "lower right", "lower center"} + + +def test_borderaxespad_insets_every_candidate_box(): + """Matplotlib pads the container before anchoring, so the pad must reach + scoring -- otherwise every candidate sits flush against the plot edge.""" + + def pads(borderaxespad): + _, ax = plt.subplots() + x = np.linspace(0, 10, 400) + ax.plot(x, x, label="rising") + ax.legend(loc="best", borderaxespad=borderaxespad) + *_, pad_x, pad_y = ax._legend_footprint(ax._legend_options, None, (564.0, 428.0)) + return pad_x, pad_y + + assert pads(0.0) == (0.0, 0.0) + half_x, half_y = pads(0.5) + assert half_x > 0.0 and half_y > 0.0 + # Linear in borderaxespad, and larger vertically because the plot box is + # shorter than it is wide. + quad_x, quad_y = pads(2.0) + assert quad_x == pytest.approx(half_x * 4.0) + assert quad_y == pytest.approx(half_y * 4.0) + assert half_y > half_x + # The pixel pad itself is Matplotlib's: borderaxespad * legend font px. + assert half_x * 564.0 == pytest.approx(0.5 * 10.0 * 100.0 / 72.0) + + +def test_segment_crossing_disqualifies_a_box_without_contained_vertices(): + """Matplotlib adds one badness point when a path crosses a candidate. + + Both vertices sit outside the upper-right legend, but their segment crosses + it. A vertex-only scorer incorrectly calls that corner empty. + """ + _, ax = plt.subplots() + ax.plot([0.7, 1.1], [0.7, 1.1], label="x") + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + ax.legend(loc="best") + assert resolved_loc(ax) == "upper left" + + +def test_bar_rectangle_overlap_is_not_reduced_to_its_anchor(): + """A legend entirely inside a wide bar overlaps its Rectangle bbox.""" + _, ax = plt.subplots() + ax.bar([0.9], [1.0], width=0.4, label="bar") + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + ax.legend(loc="best") + assert resolved_loc(ax) == "upper left" + + +def test_datetime_paths_participate_in_best_placement(): + """Datetime vertices use the same converted millisecond space as drawing.""" + _, ax = plt.subplots() + dates = np.asarray(["2026-01-01", "2026-01-02"], dtype="datetime64[D]") + ax.plot(dates, [0.0, 1.0], label="dated") + ax.legend(loc="best") + assert resolved_loc(ax) == "upper left" + + +def test_best_is_resolved_before_the_wire(): + """`"best"` is a shim concept; the wire only ever carries a real location.""" + _, ax = plt.subplots() + ax.plot([0, 1], [0, 1], label="a") + ax.legend(loc="best") + spec, _ = ax._build_chart(640, 480).figure().build_payload() + assert spec["legend"]["loc"] != "best" + assert spec["legend"]["loc"] in xy.pyplot._axes._LEGEND_LOC_ANCHORS + + +def test_unlabeled_entries_do_not_crash_measurement(): + """A legend with no labelled entry still measures as one empty row.""" + _, ax = plt.subplots() + ax.plot([0, 1], [0, 1]) + ax.legend(loc="best") + assert resolved_loc(ax) in xy.pyplot._axes._LEGEND_LOC_ANCHORS + + +# -------------------------------------------------------------------------- +# The substring-match guard +# -------------------------------------------------------------------------- + + +def test_pyplot_legend_loc_rejects_misspelled_locations(): + """Matplotlib's location vocabulary belongs to the pyplot shim. + + Core ``xy.legend`` intentionally has its own vocabulary (including the + documented ``"top left"`` spelling), so validating this in the shared + component is a core API regression rather than a pyplot compatibility fix. + """ + _, ax = plt.subplots() + for bogus in ("uppper right", "top left", "", "middle"): + with pytest.raises(ValueError, match="legend loc must be one of"): + ax.legend(loc=bogus) + assert xy.legend(loc="top left").loc == "top left" + + +def test_every_matplotlib_loc_places_the_box_at_its_anchor(): + items = [{"name": "abc"}] + plot = {"x": 40.0, "y": 20.0, "w": 400.0, "h": 300.0} + inset = 6.0 + for loc, (hx, vy) in xy.pyplot._axes._LEGEND_LOC_ANCHORS.items(): + box = _legend_layout(items, plot, {"loc": loc}) + want_x = plot["x"] + inset + hx * (plot["w"] - 2 * inset - box["box_w"]) + want_y = plot["y"] + inset + (1.0 - vy) * (plot["h"] - 2 * inset - box["box_h"]) + assert box["x"] == pytest.approx(want_x), loc + assert box["y"] == pytest.approx(want_y), loc + + +def test_right_and_center_right_are_the_same_anchor(): + """Matplotlib resolves codes 5 and 7 to the same offsetbox corner.""" + locations = xy.pyplot._axes._LEGEND_LOC_ANCHORS + assert locations["right"] == locations["center right"] + items = [{"name": "abc"}] + plot = {"x": 0.0, "y": 0.0, "w": 400.0, "h": 300.0} + a = _legend_layout(items, plot, {"loc": "right"}) + b = _legend_layout(items, plot, {"loc": "center right"}) + assert (a["x"], a["y"]) == (b["x"], b["y"]) + + +def test_best_candidate_order_is_matplotlib_code_order(): + """The tie-break contract: Matplotlib prefers the lower location code.""" + from xy.pyplot._axes import _BEST_LOC_ORDER + + # Codes 1..10 with code 7 folded onto its identical code-5 "right" anchor. + assert _BEST_LOC_ORDER == ( + "upper right", + "upper left", + "lower left", + "lower right", + "right", + "center left", + "lower center", + "upper center", + "center", + ) + assert set(_BEST_LOC_ORDER) <= set(xy.pyplot._axes._LEGEND_LOC_ANCHORS) + + +def test_ties_keep_the_earliest_candidate(): + """An empty plot leaves every candidate at zero -> code 1 wins.""" + _, ax = plt.subplots() + ax.plot([], [], label="nothing") + ax.legend(loc="best") + assert resolved_loc(ax) == "upper right" diff --git a/tests/pyplot/test_categorical_gallery_regressions.py b/tests/pyplot/test_categorical_gallery_regressions.py new file mode 100644 index 00000000..1aab7931 --- /dev/null +++ b/tests/pyplot/test_categorical_gallery_regressions.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +import numpy as np +import pytest + +import xy.pyplot as plt + + +def _axis_domain(ax, which: str) -> tuple[float, float]: + figure = ax._build_chart(640, 480).figure() + return figure.x_range() if which == "x" else figure.y_range() + + +def test_categorical_variables_trajectories_keep_every_first_seen_category() -> None: + activity = ["combing", "drinking", "feeding", "napping", "playing", "washing"] + dog = ["happy", "happy", "happy", "happy", "bored", "bored"] + cat = ["bored", "happy", "bored", "bored", "happy", "bored"] + + _fig, ax = plt.subplots() + ax.plot(activity, dog, label="dog") + ax.plot(activity, cat, label="cat") + + assert ax.get_xlim() == pytest.approx((-0.25, 5.25)) + assert ax.get_ylim() == pytest.approx((-0.05, 1.05)) + assert _axis_domain(ax, "x") == pytest.approx(ax.get_xlim()) + assert _axis_domain(ax, "y") == pytest.approx(ax.get_ylim()) + + traces = ax._build_chart(640, 480).figure().traces + np.testing.assert_allclose(traces[0].x.values, np.arange(6)) + np.testing.assert_allclose(traces[1].x.values, np.arange(6)) + np.testing.assert_allclose(traces[0].y.values, [0, 0, 0, 0, 1, 1]) + np.testing.assert_allclose(traces[1].y.values, [1, 0, 1, 1, 0, 1]) + + +def test_categorical_scatter_and_line_autoscale_to_the_shared_category_union() -> None: + names = ["apple", "orange", "lemon", "lime"] + values = [10, 15, 5, 20] + + _fig, ax = plt.subplots() + ax.scatter(names, values) + ax.plot(list(reversed(names)), list(reversed(values))) + + assert ax.get_xlim() == pytest.approx((-0.15, 3.15)) + assert _axis_domain(ax, "x") == pytest.approx((-0.15, 3.15)) + assert ax._build_chart(640, 480).figure()._axis_categories["x"] == names + + +def test_bar_patch_labels_make_individual_colored_legend_entries() -> None: + _fig, ax = plt.subplots() + bars = ax.bar( + ["apple", "blueberry", "cherry", "orange"], + [40, 100, 30, 55], + label=["red", "blue", "_red", "orange"], + color=["tab:red", "tab:blue", "tab:red", "tab:orange"], + ) + ax.legend(title="Fruit color") + + handles, labels = ax.get_legend_handles_labels() + assert labels == ["red", "blue", "orange"] + assert handles == [bars[0], bars[1], bars[3]] + + spec, _blob = ax._build_chart(640, 480).figure().build_payload() + assert spec["traces"][0]["n_marks"] == 4 + assert [ + (trace["name"], trace["style"]["color"], trace["n_marks"]) for trace in spec["traces"][1:] + ] == [ + ("red", "rgba(214,39,40,1)", 0), + ("blue", "rgba(31,119,180,1)", 0), + ("orange", "rgba(255,127,14,1)", 0), + ] + + +def test_bar_patch_labels_validate_against_the_bar_count() -> None: + _fig, ax = plt.subplots() + + with pytest.raises(ValueError, match=r"number of labels \(1\).*number of bars \(2\)"): + ax.bar(["apple", "orange"], [1, 2], label=["only one"]) + + +def test_barh_gallery_width_vector_remains_bar_value_geometry() -> None: + people = ("Tom", "Dick", "Harry", "Slim", "Jim") + performance = [5, 7, 6, 4, 9] + + _fig, ax = plt.subplots() + ax.barh(people, performance, xerr=[0.2, 0.4, 0.3, 0.6, 0.2], align="center") + + bar_trace = ax._build_chart(640, 480).figure().traces[0] + np.testing.assert_allclose(bar_trace.x1.values - bar_trace.x0.values, performance) + assert ax.get_xlim() == pytest.approx((0.0, 9.45)) diff --git a/tests/pyplot/test_color_pipeline_fixes.py b/tests/pyplot/test_color_pipeline_fixes.py index 7dce20d3..b30ae12b 100644 --- a/tests/pyplot/test_color_pipeline_fixes.py +++ b/tests/pyplot/test_color_pipeline_fixes.py @@ -113,10 +113,16 @@ def test_default_colorbar_ticks_are_dense_for_small_decimal_domains(): plt.colorbar(image) svg = _svg() assert all(f">{value:.2f}<" in svg for value in (0.02, 0.04, 0.06, 0.08, 0.12, 0.14)) - # The client-side colorbar mirrors the 8-tick target; the embedded bundle - # is minified, so assert against the client source instead of the HTML. + # A normal-height colorbar retains the dense eight-tick ceiling. Shorter + # bars reduce their budget so labels do not collide. + from xy._svg import _colorbar_tick_target + + assert _colorbar_tick_target(360) == 8 + assert _colorbar_tick_target(140) == 3 + # The client-side colorbar uses the same 48 px spacing budget; the embedded + # bundle is minified, so assert against the client source instead of HTML. client = ROOT / "js" / "src" / "50_chartview.ts" - assert "linearTicks(lo, hi, 8)" in client.read_text(encoding="utf-8") + assert "barLength) / 48" in client.read_text(encoding="utf-8") def test_explicit_colorbar_ticks_still_honored(): diff --git a/tests/pyplot/test_contour_gallery_colors.py b/tests/pyplot/test_contour_gallery_colors.py new file mode 100644 index 00000000..862e2899 --- /dev/null +++ b/tests/pyplot/test_contour_gallery_colors.py @@ -0,0 +1,107 @@ +from __future__ import annotations + +import re + +import numpy as np + +import xy.pyplot as plt + + +def _gallery_field() -> tuple[np.ndarray, np.ndarray, np.ndarray]: + """The scalar field shared by Matplotlib's contour gallery examples.""" + delta = 0.025 + x = np.arange(-3.0, 3.0, delta) + y = np.arange(-2.0, 2.0, delta) + X, Y = np.meshgrid(x, y) + z1 = np.exp(-(X**2) - Y**2) + z2 = np.exp(-((X - 1) ** 2) - (Y - 1) ** 2) + return X, Y, (z1 - z2) * 2 + + +def test_contour_demo_cycles_listed_colors_per_level_through_renderers() -> None: + X, Y, Z = _gallery_field() + levels = np.arange(-1.2, 1.4, 0.4) + colors = ("r", "green", "blue", (1, 1, 0), "#afeeee", "0.5") + + _fig, ax = plt.subplots() + contour = ax.contour( + X, + Y, + Z, + levels, + linewidths=np.arange(0.5, 4, 0.5), + colors=colors, + ) + + expected = np.asarray( + [ + [1.0, 0.0, 0.0, 1.0], + [0.0, 128 / 255, 0.0, 1.0], + [0.0, 0.0, 1.0, 1.0], + [1.0, 1.0, 0.0, 1.0], + [175 / 255, 238 / 255, 238 / 255, 1.0], + [128 / 255, 128 / 255, 128 / 255, 1.0], + [1.0, 0.0, 0.0, 1.0], + ] + ) + np.testing.assert_allclose(contour._entry["kwargs"]["color"], expected) + + figure = ax._build_chart(640, 480).figure() + trace = next(trace for trace in figure.traces if trace.kind == "contour") + assert trace.color_ch is not None and trace.color_ch.mode == "direct_rgba" + assert trace.color_ch.rgba is not None + for rgba in expected: + assert np.any(np.all(np.isclose(trace.color_ch.rgba, rgba), axis=1)) + + svg = figure.to_svg() + strokes = set(re.findall(r'stroke="([^"]+)', svg)) + assert {"rgb(255,0,0)", "rgb(0,128,0)", "rgb(0,0,255)"} <= strokes + + spec, blob = figure.build_payload() + paint = next(item["color"] for item in spec["traces"] if item["kind"] == "contour") + assert paint["mode"] == "direct_rgba" + column = spec["columns"][paint["buf"]] + packed = np.frombuffer( + blob, + dtype=np.uint8, + count=column["len"], + offset=column["byte_offset"], + ).reshape(-1, 4) + for rgba in np.rint(expected * 255).astype(np.uint8): + assert np.any(np.all(packed == rgba, axis=1)) + + +def test_contourf_demo_cycles_bands_and_updates_extended_colors() -> None: + X, Y, Z = _gallery_field() + levels = [-1.5, -1, -0.5, 0, 0.5, 1] + + _fig, ax = plt.subplots() + contour = ax.contourf(X, Y, Z, levels, colors=("r", "g", "b"), extend="both") + contour.cmap.set_under("yellow") + contour.cmap.set_over("cyan") + + expected = np.asarray( + [ + [1.0, 1.0, 0.0, 1.0], + [1.0, 0.0, 0.0, 1.0], + [0.0, 128 / 255, 0.0, 1.0], + [0.0, 0.0, 1.0, 1.0], + [1.0, 0.0, 0.0, 1.0], + [0.0, 128 / 255, 0.0, 1.0], + [0.0, 1.0, 1.0, 1.0], + ] + ) + np.testing.assert_allclose(contour._entry["kwargs"]["color"], expected) + + figure = ax._build_chart(640, 480).figure() + heatmap = next(trace for trace in figure.traces if trace.kind == "heatmap") + assert heatmap.style["truecolor"] is True + assert heatmap.style["opacity"] == 1.0 + assert heatmap.rgba_grid is not None + rendered = np.column_stack([column.values for column in heatmap.rgba_grid]) + for rgba in expected: + assert np.any(np.all(np.isclose(rendered, rgba), axis=1)) + + spec, _blob = figure.build_payload() + shipped = next(item["heatmap"] for item in spec["traces"] if item["kind"] == "heatmap") + assert len(shipped["rgba_bufs"]) == 4 diff --git a/tests/pyplot/test_frame_geometry.py b/tests/pyplot/test_frame_geometry.py new file mode 100644 index 00000000..a08124f2 --- /dev/null +++ b/tests/pyplot/test_frame_geometry.py @@ -0,0 +1,275 @@ +"""The rendered axes frame must land on the rectangle `get_position()` reports. + +Every assertion here reads real emitted geometry: `_svg.layout()` is the single +plot-rect resolver both static exporters use (and the browser client mirrors it), +and the dense-grid check probes the composed PNG buffer itself. Reference values +are Matplotlib 3.11's own — figure.subplot.* frame, gridspec cell arithmetic, and +`Axes.get_window_extent()` — so a drift shows up as a compatibility failure +rather than a snapshot churn. +""" + +from __future__ import annotations + +import io + +import numpy as np +import pytest + +import xy.pyplot as plt +from xy import _svg + + +def teardown_function(): + plt.close("all") + + +def _plot_rects(fig) -> list[tuple[float, float, float, float]]: + """Absolute (x0, y0_from_top, w, h) px of every panel's plot rect.""" + from xy.pyplot._rc import rc_figsize_px + + canvas = rc_figsize_px(fig._figsize, fig._dpi) + charts = fig._charts() + rects = fig._effective_rects() + if rects is None: + offsets = [(0.0, 0.0)] + else: + offsets = [ + (round(p[0] * canvas[0]), round((1.0 - p[1] - p[3]) * canvas[1])) + for p in fig._panel_positions(rects, canvas) + ] + out = [] + for (ox, oy), chart in zip(offsets, charts, strict=True): + spec, _blob = chart.figure().build_payload() + _w, _h, _compact, plot = _svg.layout(spec) + out.append((ox + plot["x"], oy + plot["y"], plot["w"], plot["h"])) + return out + + +def _reported_rects(fig) -> list[tuple[float, float, float, float]]: + """The same rectangles as scripts read them, converted to top-origin px.""" + from xy.pyplot._rc import rc_figsize_px + + width, height = rc_figsize_px(fig._figsize, fig._dpi) + out = [] + for ax in fig.axes: + x0, y0, w, h = ax.get_position().bounds + out.append((x0 * width, (1.0 - y0 - h) * height, w * width, h * height)) + return out + + +def test_default_axes_renders_on_the_matplotlib_subplot_frame(): + fig, ax = plt.subplots(figsize=(6.4, 4.8), dpi=100) + ax.plot([0, 1, 2], [1, 3, 2]) + + # rcParams figure.subplot.*: left .125, bottom .11, right .9, top .88. + assert ax.get_position().bounds == pytest.approx((0.125, 0.11, 0.775, 0.77)) + (rendered,) = _plot_rects(fig) + assert rendered == pytest.approx((80.0, 57.6, 496.0, 369.6), abs=0.5) + + +def test_axes_title_does_not_move_the_rendered_frame(): + """matplotlib draws the title above the axes without changing its position.""" + fig, ax = plt.subplots(figsize=(6.4, 4.8), dpi=100) + ax.plot([0, 1], [0, 1]) + (plain,) = _plot_rects(fig) + + plt.close("all") + fig, ax = plt.subplots(figsize=(6.4, 4.8), dpi=100) + ax.plot([0, 1], [0, 1]) + ax.set_title("titled") + ax.set_xlabel("x") + ax.set_ylabel("y") + (titled,) = _plot_rects(fig) + + assert titled == pytest.approx(plain, abs=0.5) + + +@pytest.mark.parametrize( + "figsize", + [(6.4, 4.8), (3.2, 2.4), (12.0, 3.0), (5.0, 5.0)], +) +def test_reported_and_rendered_frames_agree_for_a_single_axes(figsize): + fig, ax = plt.subplots(figsize=figsize, dpi=100) + ax.plot([0, 1], [0, 1]) + + (reported,) = _reported_rects(fig) + (rendered,) = _plot_rects(fig) + assert rendered == pytest.approx(reported, abs=0.5) + + +@pytest.mark.parametrize( + ("nrows", "ncols", "figsize", "adjust"), + [ + (2, 2, (6.4, 4.8), {}), + (1, 3, (9.0, 3.0), {"left": 0.05, "right": 0.98, "wspace": 0.35}), + (5, 5, (5.0, 5.0), {"hspace": 0.0, "wspace": 0.0}), + (8, 8, (6.0, 6.0), {}), + ], +) +def test_reported_and_rendered_frames_agree_for_every_grid_panel(nrows, ncols, figsize, adjust): + fig, axes = plt.subplots(nrows, ncols, figsize=figsize, dpi=100) + if adjust: + fig.subplots_adjust(**adjust) + for ax in np.asarray(axes).ravel(): + ax.plot([0, 1], [0, 1]) + + reported = _reported_rects(fig) + rendered = _plot_rects(fig) + assert len(rendered) == nrows * ncols + for want, got in zip(reported, rendered, strict=True): + assert got == pytest.approx(want, abs=1.0) + + +def test_grid_panel_reservations_keep_the_plot_rect_on_its_cell(): + """A top-side x axis (matshow) and a secondary y axis both take room the + renderers reserve outside the padding; the panel must grow, not shift.""" + fig, axes = plt.subplots(2, 2, figsize=(6.4, 4.8), dpi=100) + flat = list(np.asarray(axes).ravel()) + flat[0].matshow(np.arange(9.0).reshape(3, 3)) + flat[1].plot([0, 1], [0, 1]) + flat[1].twinx().plot([0, 1], [3, 4]) + flat[2].plot([0, 1], [0, 1]) + flat[2].set_title("titled") + flat[3].plot([0, 1], [0, 1]) + + for index, (want, got) in enumerate(zip(_reported_rects(fig), _plot_rects(fig), strict=True)): + # matshow is aspect-equal, so only its cell *origin* and height are + # pinned — adjustable='box' centers a square axes inside the cell. + if index == 0: + assert got[1] == pytest.approx(want[1], abs=1.0) + assert got[3] == pytest.approx(want[3], abs=1.0) + else: + assert got == pytest.approx(want, abs=1.0) + + +def test_get_position_reports_one_distinct_box_per_grid_panel(): + fig, axes = plt.subplots(8, 8, figsize=(6.0, 6.0), dpi=100) + boxes = [tuple(np.round(ax.get_position().bounds, 6)) for ax in np.asarray(axes).ravel()] + + assert len(boxes) == 64 + assert len(set(boxes)) == 64 + # Matplotlib's gridspec arithmetic: 0.775 wide / 0.77 tall frame, cells + # separated by wspace/hspace = 0.2 of the average cell. + assert boxes[0][0] == pytest.approx(0.125) + assert boxes[-1][0] + boxes[-1][2] == pytest.approx(0.9) + assert boxes[-1][1] == pytest.approx(0.11) + assert boxes[0][1] + boxes[0][3] == pytest.approx(0.88) + del fig + + +def test_get_position_keeps_subplot_cells_stable_after_an_axes_is_removed(): + fig, axes = plt.subplots(2, 2, figsize=(6.4, 4.8), dpi=100) + flat = list(np.asarray(axes).ravel()) + expected = [ax.get_position().bounds for ax in flat] + + fig.delaxes(flat[0]) + + assert [ax.get_position().bounds for ax in fig.axes] == pytest.approx(expected[1:]) + for want, got in zip(_reported_rects(fig), _plot_rects(fig), strict=True): + assert got == pytest.approx(want, abs=1.0) + + +def test_get_position_distinguishes_active_and_original_aspect_boxes(): + fig, ax = plt.subplots(figsize=(6.4, 4.8), dpi=100) + ax.imshow(np.arange(4.0).reshape(2, 2)) + + assert ax.get_position(original=True).bounds == pytest.approx((0.125, 0.11, 0.775, 0.77)) + assert ax.get_position().bounds == pytest.approx((0.22375, 0.11, 0.5775, 0.77)) + assert _plot_rects(fig)[0] == pytest.approx(_reported_rects(fig)[0], abs=1.0) + + ax.set_anchor("W") + assert ax.get_position().bounds == pytest.approx((0.125, 0.11, 0.5775, 0.77)) + assert _plot_rects(fig)[0] == pytest.approx(_reported_rects(fig)[0], abs=1.0) + + +def test_subplots_adjust_restores_a_set_position_axes_to_its_grid_cell(): + fig, axes = plt.subplots(1, 2, figsize=(6.4, 4.8), dpi=100) + left, right = list(np.asarray(axes).ravel()) + left.set_position((0.01, 0.02, 0.03, 0.04)) + assert left.get_position(original=True).bounds == pytest.approx((0.01, 0.02, 0.03, 0.04)) + + fig.subplots_adjust(left=0.2, right=0.8, wspace=0.0) + + assert left.get_position(original=True).bounds == pytest.approx((0.2, 0.11, 0.3, 0.77)) + assert right.get_position(original=True).bounds == pytest.approx((0.5, 0.11, 0.3, 0.77)) + + +def test_rgba_composition_preserves_straight_alpha_on_transparent_figures(): + from xy.pyplot._grid import _composite_rgba + + destination = np.asarray([[[0, 0, 255, 128]]], dtype=np.uint8) + source = np.asarray([[[255, 0, 0, 128]]], dtype=np.uint8) + + _composite_rgba(destination, source) + + # Source-over in straight alpha: A=0.75, RGB=(2/3 red, 1/3 blue). + assert destination[0, 0] == pytest.approx((170, 0, 85, 192), abs=1) + + +def test_get_position_follows_subplots_adjust_and_ratios(): + fig, axes = plt.subplots(2, 2, figsize=(6.4, 4.8), width_ratios=[1, 3]) + fig.subplots_adjust(left=0.2, right=0.95, wspace=0.0) + flat = list(np.asarray(axes).ravel()) + + left, right = flat[0].get_position(), flat[1].get_position() + assert left.x0 == pytest.approx(0.2) + assert right.x0 + right.width == pytest.approx(0.95) + # wspace=0 makes the columns adjacent, split 1:3 across the frame. + assert left.x0 + left.width == pytest.approx(right.x0) + assert right.width == pytest.approx(3.0 * left.width) + + +def test_explicit_rects_and_set_position_still_win(): + fig = plt.figure(figsize=(6.4, 4.8), dpi=100) + ax = fig.add_axes((0.2, 0.25, 0.6, 0.5)) + ax.plot([0, 1], [0, 1]) + + assert ax.get_position().bounds == pytest.approx((0.2, 0.25, 0.6, 0.5)) + (rendered,) = _plot_rects(fig) + assert rendered == pytest.approx((128.0, 120.0, 384.0, 240.0), abs=0.5) + + ax.set_position([0.1, 0.1, 0.5, 0.5]) + assert ax.get_position().bounds == pytest.approx((0.1, 0.1, 0.5, 0.5)) + + +def test_dense_grid_composite_draws_every_panel(monkeypatch): + """Panels are wider than their gridspec cell, so the compositor must + alpha-blend them; an opaque paste left only the last column visible.""" + from xy import _png + + captured: list[np.ndarray] = [] + real_encode = _png.encode + + def capture(canvas, *args, **kwargs): + captured.append(np.array(canvas)) + return real_encode(canvas, *args, **kwargs) + + monkeypatch.setattr(_png, "encode", capture) + + nrows = ncols = 8 + rng = np.random.default_rng(0) + fig, axes = plt.subplots(nrows, ncols, figsize=(6.0, 6.0), dpi=100) + for ax in np.asarray(axes).ravel(): + ax.imshow(rng.random((8, 8)), cmap="binary") + ax.set(xticks=[], yticks=[]) + rects = _plot_rects(fig) + + fig.savefig(io.BytesIO(), format="png", dpi=100) + assert captured, "savefig did not compose a figure canvas" + canvas = captured[-1] + assert canvas.shape[:2] == (600, 600) + + # Probe the middle of each panel's own plot rect on the composed buffer. + covered = [] + for x0, y0, w, h in rects: + patch = canvas[ + int(y0 + 0.25 * h) : int(y0 + 0.75 * h), + int(x0 + 0.25 * w) : int(x0 + 0.75 * w), + :3, + ].astype(int) + covered.append(float(np.mean(np.any(np.abs(patch - 255) > 12, axis=2)))) + + assert len(covered) == nrows * ncols + assert min(covered) > 0.5, f"blank panels: {[i for i, c in enumerate(covered) if c <= 0.5]}" + # The composed figure canvas stays opaque for the default white facecolor. + assert int(canvas[..., 3].min()) == 255 diff --git a/tests/pyplot/test_gallery_auto_ticks_compat.py b/tests/pyplot/test_gallery_auto_ticks_compat.py new file mode 100644 index 00000000..34a44b72 --- /dev/null +++ b/tests/pyplot/test_gallery_auto_ticks_compat.py @@ -0,0 +1,92 @@ +from __future__ import annotations + +import warnings + +import numpy as np +import pytest + +import xy.pyplot as plt +from xy.pyplot._ticker import AutoLocator + + +def _auto_ticks_data() -> tuple[np.ndarray, np.ndarray]: + dots = np.linspace(0.3, 1.2, 10) + x, y = np.meshgrid(dots, dots) + return x.ravel(), y.ravel() + + +def _axis_domains(ax) -> tuple[tuple[float, float], tuple[float, float]]: + spec, _blob = ax._build_chart(640, 480).figure().build_payload() + return tuple(spec["x_axis"]["domain"]), tuple(spec["y_axis"]["domain"]) + + +def test_auto_ticks_round_numbers_matches_exact_gallery_domains() -> None: + x, y = _auto_ticks_data() + with warnings.catch_warnings(): + warnings.simplefilter("error") + plt.rcParams["axes.autolimit_mode"] = "round_numbers" + + _fig, ax = plt.subplots() + ax.scatter(x, y, c=x + y) + x_domain, y_domain = _axis_domains(ax) + assert x_domain == pytest.approx((0.2, 1.4)) + assert y_domain == pytest.approx((0.2, 1.4)) + + _fig, ax = plt.subplots() + ax.scatter(x, y, c=x + y) + ax.set_xmargin(0.8) + assert ax.get_xmargin() == 0.8 + assert ax.get_ymargin() == 0.05 + x_domain, y_domain = _axis_domains(ax) + assert x_domain == pytest.approx((-0.5, 2.0)) + assert y_domain == pytest.approx((0.2, 1.4)) + + +def test_round_numbers_is_read_at_render_time_and_respects_explicit_limits() -> None: + x, y = _auto_ticks_data() + _fig, ax = plt.subplots() + ax.scatter(x, y) + ax.set_xlim(0.0, 2.0) + + with plt.rc_context({"axes.autolimit_mode": "round_numbers"}): + x_domain, y_domain = _axis_domains(ax) + + assert x_domain == (0.0, 2.0) + assert y_domain == pytest.approx((0.2, 1.4)) + + ax.clear() + ax.scatter(x, y) + with plt.rc_context({"axes.autolimit_mode": "round_numbers"}): + x_domain, y_domain = _axis_domains(ax) + assert x_domain == pytest.approx((0.2, 1.4)) + assert y_domain == pytest.approx((0.2, 1.4)) + + +def test_axis_margin_setters_match_matplotlib_validation_and_clipping() -> None: + _fig, ax = plt.subplots() + assert ax.get_xmargin() == 0.05 + assert ax.get_ymargin() == 0.05 + + ax.plot([0.0, 10.0], [0.0, 20.0]) + ax.set_xmargin(-0.1) + ax.set_ymargin(0.25) + assert ax.get_xlim() == pytest.approx((1.0, 9.0)) + assert ax.get_ylim() == pytest.approx((-5.0, 25.0)) + + for value in (-0.5, -1.0, np.inf, np.nan): + with pytest.raises(ValueError, match=r"greater than -0\.5"): + ax.set_xmargin(value) + + +def test_auto_locator_round_view_limits_use_edge_ticks() -> None: + locator = AutoLocator() + locator._nbins_hint = 9 + assert locator.view_limits(0.255, 1.245) == pytest.approx((0.255, 1.245)) + with plt.rc_context({"axes.autolimit_mode": "round_numbers"}): + assert locator.view_limits(0.255, 1.245) == pytest.approx((0.2, 1.4)) + assert locator.view_limits(-0.42, 1.92) == pytest.approx((-0.5, 2.0)) + + +def test_autolimit_mode_rejects_unknown_values() -> None: + with pytest.raises(ValueError, match=r"data.*round_numbers"): + plt.rcParams["axes.autolimit_mode"] = "rounded" diff --git a/tests/pyplot/test_gallery_canvas_gutters.py b/tests/pyplot/test_gallery_canvas_gutters.py new file mode 100644 index 00000000..8e394d50 --- /dev/null +++ b/tests/pyplot/test_gallery_canvas_gutters.py @@ -0,0 +1,155 @@ +"""Matplotlib's y-axis title sits clear of its tick labels; so must the shim's. + +Measured against Matplotlib 3.11.1 on `examples/pdsh/data/births.csv` +(`examples/pdsh/pdsh_04_09_text_and_annotation.ipynb`, cell 23): the reference +puts the y title's ink at x 10.0..24.3 and the tick ink at 29.9..65.9 — a 5.6 px +gap. The shim used to draw the title at -3.0..13.5 over ticks reaching x -3.4, +because pyplot's rcParam fonts (13.89 px at 100 dpi) overrun the renderer's flat +62 px gutter and the notebook path pins a 41 px one. + +The gutter is now measured in `_svg.layout()` from the ink it has to hold, so +these assertions read the emitted SVG geometry rather than a padding constant. +""" + +from __future__ import annotations + +import math +import re +from io import BytesIO +from xml.etree import ElementTree + +import pytest + +import xy.pyplot as plt +from xy import _fontmetrics, _svg + +_ASCENT = _fontmetrics.ASCENT / _fontmetrics.BASE_PX +_DESCENT = _fontmetrics.DESCENT / _fontmetrics.BASE_PX +# `_mplfig._to_notebook_html` pins these to match Matplotlib's inline +# `bbox_inches="tight", pad_inches=.1` footprint at 100 dpi. +NOTEBOOK_PADDING = [15.0, 20.0, 34.0, 41.0] + + +def teardown_function() -> None: + plt.close("all") + + +def _title_and_tick_boxes(svg: str, plot: dict[str, float], title: str): + root = ElementTree.fromstring(svg) + title_box = None + ticks: list[tuple[float, float]] = [] + for element in root.iter(): + if not element.tag.endswith("text"): + continue + text = "".join(element.itertext()) + size = float(element.attrib.get("font-size", 12)) + x = float(element.attrib.get("x", 0)) + rotation = re.match(r"rotate\((-?[\d.]+)", element.attrib.get("transform", "")) + angle = float(rotation.group(1)) if rotation else 0.0 + if text == title and abs(abs(angle) - 90) < 0.5: + title_box = (x - _ASCENT * size, x + _DESCENT * size) + elif not rotation and element.attrib.get("text-anchor") == "end" and x <= plot["x"]: + ticks.append((x - _fontmetrics.advance(text, size), x)) + assert title_box is not None, f"no rotated {title!r} axis title in the SVG" + assert ticks, "no y tick labels in the SVG" + pin = max(box[1] for box in ticks) + ticks = [box for box in ticks if math.isclose(box[1], pin, abs_tol=0.01)] + return title_box, (min(box[0] for box in ticks), max(box[1] for box in ticks)) + + +def _assert_clear(svg: str, plot: dict[str, float], title: str) -> tuple[float, float]: + title_box, tick_span = _title_and_tick_boxes(svg, plot, title) + overlap = min(title_box[1], tick_span[1]) - max(title_box[0], tick_span[0]) + assert overlap < 0, ( + f"{title!r} at {title_box} overlaps tick labels {tick_span} by {overlap:.1f}px" + ) + assert title_box[0] > 0, f"{title!r} ink starts at x={title_box[0]:.1f} — clipped" + assert tick_span[0] > 0, f"tick ink starts at x={tick_span[0]:.1f} — clipped" + return title_box[1], tick_span[0] + + +def _svg_geometry(ax, width, height, padding=None): + if padding is not None: + ax._padding = list(padding) + spec, blob = ax._build_chart(width, height).figure().build_payload() + _w, _h, _compact, plot = _svg.layout(spec) + return spec, _svg.render_svg(spec, blob), plot + + +def test_numeric_y_ticks_keep_the_axis_title_clear() -> None: + """The pdsh cell-23 shape: four-digit ticks under a long rotated title.""" + _fig, ax = plt.subplots(figsize=(12, 4)) + ax.plot([0, 1], [3600, 5400]) + ax.set_ylim(3600, 5400) + ax.set_ylabel("average daily births") + + _spec, svg, plot = _svg_geometry(ax, 1200, 400) + title_right, tick_left = _assert_clear(svg, plot, "average daily births") + # Matplotlib 3.11.1 leaves 5.6 px here, and the shim's title font is the + # same 13.89 px, so the 0.4 em rule reproduces the reference gap. + assert abs((tick_left - title_right) - 5.6) < 0.1 + assert plot["x"] > 62.0, "the flat default gutter cannot hold this axis's ink" + + +def test_notebook_padding_still_reserves_the_measured_gutter() -> None: + """The reported defect: `padding[3] = 41` is 27 px short of the ink. + + An authored padding is a floor. The notebook path pins one to match + Matplotlib's inline canvas, and before this change that pin was also the + effective gutter — so the title landed on top of the 5400/5200/5000 labels. + """ + _fig, ax = plt.subplots(figsize=(12, 4)) + ax.plot([0, 1], [3600, 5400]) + ax.set_ylim(3600, 5400) + ax.set_ylabel("average daily births") + + spec, svg, plot = _svg_geometry(ax, 992, 356, padding=NOTEBOOK_PADDING) + assert spec["padding"] == NOTEBOOK_PADDING, "the authored padding still ships as authored" + assert plot["x"] > NOTEBOOK_PADDING[3], "the measured gutter has to win over the pin" + _assert_clear(svg, plot, "average daily births") + + +def test_long_category_ticks_keep_the_axis_title_clear() -> None: + fig, ax = plt.subplots(figsize=(6.4, 4.8)) + labels = [f"Question {index}" for index in range(1, 7)] + ax.barh(labels, [10, 20, 30, 40, 50, 60]) + ax.set_ylabel("survey question") + + spec, svg, plot = _svg_geometry(ax, 640, 480) + assert spec["axes"]["y"]["categories"] == labels + _assert_clear(svg, plot, "survey question") + assert plot["x"] > 100.0 + + # The same reservation reaches savefig, not just the in-process layout. + output = BytesIO() + fig.savefig(output, format="svg") + root = ElementTree.fromstring(output.getvalue()) + question = next( + element + for element in root.iter() + if element.tag.endswith("text") and "".join(element.itertext()) == "Question 1" + ) + ink_left = float(question.attrib["x"]) - _fontmetrics.advance( + "Question 1", float(question.attrib["font-size"]) + ) + assert ink_left > 0 + + +def test_long_category_ticks_under_notebook_padding_keep_the_title_clear() -> None: + _fig, ax = plt.subplots(figsize=(6.4, 4.8)) + labels = [f"Question {index}" for index in range(1, 7)] + ax.barh(labels, [10, 20, 30, 40, 50, 60]) + ax.set_ylabel("survey question") + + _spec, svg, plot = _svg_geometry(ax, 536, 404, padding=NOTEBOOK_PADDING) + _assert_clear(svg, plot, "survey question") + + +def test_short_category_ticks_keep_the_core_default_gutter() -> None: + """Short ticks do not widen Matplotlib's default axes rectangle.""" + _fig, ax = plt.subplots() + ax.barh(["A", "B"], [1, 2]) + + spec, _svg_text, plot = _svg_geometry(ax, 640, 480) + assert spec["padding"] == pytest.approx([57.6, 64.0, 52.8, 80.0]) + assert plot["x"] == 80.0 diff --git a/tests/pyplot/test_gallery_colorbar_options.py b/tests/pyplot/test_gallery_colorbar_options.py new file mode 100644 index 00000000..e7e0df10 --- /dev/null +++ b/tests/pyplot/test_gallery_colorbar_options.py @@ -0,0 +1,104 @@ +"""Regressions reduced from Matplotlib's colorbar gallery.""" + +from __future__ import annotations + +import re +from io import BytesIO + +import numpy as np +import pytest + +import xy.pyplot as plt + + +@pytest.fixture(autouse=True) +def _clean() -> None: + plt.close("all") + yield + plt.close("all") + + +def test_colorbar_location_anchor_shrink_and_minor_ticks_reach_exports() -> None: + fig, ax = plt.subplots() + image = ax.imshow(np.arange(16).reshape(4, 4), cmap="Blues") + + colorbar = fig.colorbar( + image, + ax=ax, + location="right", + anchor=(0.0, 0.3), + shrink=0.7, + ) + colorbar.minorticks_on() + + assert ax._colorbar["orientation"] == "vertical" + assert ax._colorbar["anchor"] == [0.0, 0.3] + assert ax._colorbar["shrink"] == pytest.approx(0.7) + assert ax._colorbar["minor_ticks"] is True + + svg = BytesIO() + fig.savefig(svg, format="svg") + assert b'data-xy-colorbar-minor="true"' in svg.getvalue() + + png = BytesIO() + fig.savefig(png, format="png") + assert png.getvalue().startswith(b"\x89PNG\r\n\x1a\n") + + colorbar.minorticks_off() + assert ax._colorbar["minor_ticks"] is False + + +def test_bottom_location_selects_horizontal_orientation() -> None: + fig, ax = plt.subplots() + image = ax.imshow(np.eye(3)) + + fig.colorbar(image, ax=ax, location="bottom", shrink=0.5) + + assert ax._colorbar["orientation"] == "horizontal" + assert ax._colorbar["shrink"] == pytest.approx(0.5) + + +def test_colorbar_domain_excludes_masked_image_values() -> None: + fig, ax = plt.subplots() + values = np.ma.masked_greater(np.asarray([[-2.0, -1.0], [1.0, 2.0]]), 0.0) + image = ax.imshow(values, cmap="Blues") + + fig.colorbar(image, ax=ax) + + assert ax._colorbar["domain"] == [-2.0, -1.0] + + +def test_short_gallery_colorbar_renders_only_three_major_tick_labels() -> None: + """The shrunken negative panel stays readable like the gallery reference.""" + size = 37 + x, y = np.mgrid[:size, :size] + values = np.cos(x * 0.2) + np.sin(y * 0.3) + negative = np.ma.masked_greater(values, 0.0) + fig, ax = plt.subplots(figsize=(13 / 3, 3)) + image = ax.imshow(negative, cmap="Blues", interpolation="none") + fig.colorbar(image, ax=ax, location="right", anchor=(0.0, 0.3), shrink=0.7) + + svg = BytesIO() + fig.savefig(svg, format="svg") + negative_labels = re.findall(rb"]*>(-[^<]+)", svg.getvalue()) + + assert negative_labels == [b"-1.5", b"-1", b"-0.5"] + + +@pytest.mark.parametrize( + ("kwargs", "message"), + [ + ({"location": "left"}, "right or bottom"), + ({"shrink": 0.0}, "shrink"), + ({"anchor": (0.5,)}, "anchor"), + ({"location": "right", "orientation": "horizontal"}, "incompatible"), + ], +) +def test_colorbar_gallery_options_reject_invalid_values( + kwargs: dict[str, object], message: str +) -> None: + fig, ax = plt.subplots() + image = ax.imshow(np.eye(3)) + + with pytest.raises((ValueError, NotImplementedError), match=message): + fig.colorbar(image, ax=ax, **kwargs) diff --git a/tests/pyplot/test_gallery_hist_errorbar_compat.py b/tests/pyplot/test_gallery_hist_errorbar_compat.py new file mode 100644 index 00000000..866399db --- /dev/null +++ b/tests/pyplot/test_gallery_hist_errorbar_compat.py @@ -0,0 +1,181 @@ +from __future__ import annotations + +import numpy as np +import pytest + +import xy.pyplot as plt + + +def test_hist_patch_styles_apply_per_dataset() -> None: + _fig, ax = plt.subplots() + values = np.arange(18.0).reshape(6, 3) + + _counts, _edges, containers = ax.hist( + values, + bins=3, + facecolor=["red", "green", "blue"], + edgecolor=["black", "gray", "white"], + linewidth=[1, 2, 3], + ) + + assert len(containers) == 3 + assert [entry["kwargs"]["stroke_width"] for entry in ax._entries] == [1.0, 2.0, 3.0] + assert [entry["kwargs"]["color"] for entry in ax._entries] == [ + "red", + "green", + "blue", + ] + + +def test_hist_fill_false_is_unfilled_and_scalar_input_is_one_dataset() -> None: + _fig, ax = plt.subplots() + + counts, _edges, container = ax.hist( + 2.0, bins=2, fill=False, facecolor="red", edgecolor="blue", linewidth=3 + ) + + assert counts.shape == (2,) + assert len(container) == 2 + entry = ax._entries[-1] + assert entry["kwargs"]["color"] == "transparent" + assert entry["kwargs"]["stroke"] == "blue" + assert entry["kwargs"]["stroke_width"] == 3.0 + + +def test_hist_step_fill_and_linewidth_override_histtype_defaults() -> None: + _fig, ax = plt.subplots() + ax.hist([0, 1, 2], bins=2, histtype="step", fill=True, facecolor="green", linewidth=4) + ax.hist([0, 1, 2], bins=2, histtype="stepfilled", fill=False, linewidth=5) + + filled, unfilled = ax._entries + assert filled["factory"] == "area" + assert filled["kwargs"]["color"] == "green" + assert filled["kwargs"]["line_color"] == "#1f77b4" + assert unfilled["factory"] == "stairs" + assert unfilled["kwargs"]["color"] == "black" + assert unfilled["kwargs"]["width"] == 5.0 + + +def test_hist_dataset_style_lengths_must_match_dataset_count() -> None: + _fig, ax = plt.subplots() + with pytest.raises(ValueError, match="sequence must have length 2"): + ax.hist([[0, 1], [2, 3]], bins=2, linewidth=[1, 2, 3]) + + +@pytest.mark.parametrize("histtype", ["step", "stepfilled"]) +def test_hist_step_geometry_contributes_to_autoscale(histtype: str) -> None: + _fig, ax = plt.subplots() + + counts, edges, _container = ax.hist( + [-3.0, -1.0, -0.5, 0.0, 0.5, 1.0, 3.0], + bins=np.arange(-4.0, 4.1, 0.5), + histtype=histtype, + weights=np.full(7, 1 / 7), + ) + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + assert ax._entry_extent("x") == pytest.approx((edges[0], edges[-1])) + assert ax._entry_extent("y") == pytest.approx((0.0, counts.max())) + + core = ax._build_chart(350, 300).figure() + # Matplotlib's default axes.xmargin is 5% of the eight-unit data span. + assert core.x_range() == pytest.approx((-4.4, 4.4)) + assert core.y_range()[1] > counts.max() + + +def test_hist_density_and_probability_weights_match_numpy() -> None: + values = np.array([-2.2, -1.8, -0.4, -0.1, 0.2, 0.7, 1.1, 2.4]) + edges = np.array([-3.0, -1.0, 0.0, 0.5, 1.5, 3.0]) + _fig, (density_ax, weights_ax) = plt.subplots(1, 2) + + density, returned_edges, _ = density_ax.hist(values, bins=edges, density=True, histtype="step") + weighted, _, _ = weights_ax.hist( + values, + bins=edges, + weights=np.full(len(values), 1 / len(values)), + histtype="step", + ) + + expected_density, expected_edges = np.histogram(values, bins=edges, density=True) + expected_weighted, _ = np.histogram( + values, bins=edges, weights=np.full(len(values), 1 / len(values)) + ) + np.testing.assert_allclose(density, expected_density) + np.testing.assert_array_equal(returned_edges, expected_edges) + np.testing.assert_allclose(weighted, expected_weighted) + assert np.sum(density * np.diff(edges)) == pytest.approx(1.0) + assert weighted.sum() == pytest.approx(1.0) + + +def test_errorbar_forwards_marker_size_and_linestyle_to_data_line_only() -> None: + _fig, ax = plt.subplots() + container = ax.errorbar( + [0, 1], + [1, 2], + yerr=0.1, + marker="o", + markersize=8, + linestyle="dotted", + ) + + assert container.lines[0] is not None + assert [entry["kind"] for entry in ax._entries] == ["@mark", "line", "scatter"] + line, markers = ax._entries[1:] + assert line["kwargs"]["dash"] + assert markers["kwargs"]["symbol"] == "circle" + assert markers["kwargs"]["size"] > 8 + + +def test_errorbar_fmt_none_accepts_marker_keywords_without_data_line() -> None: + _fig, ax = plt.subplots() + container = ax.errorbar([0, 1], [1, 2], yerr=0.1, fmt="none", marker="o", markersize=8) + + assert container.lines[0] is None + assert len(ax._entries) == 1 + + +def test_errorbar_uses_matplotlib_default_caps_width_and_limit_marker_size() -> None: + _fig, ax = plt.subplots() + ax.errorbar([1], [3], yerr=[0.5], lolims=True, fmt="none") + + errorbar, marker = ax._entries + assert errorbar["kwargs"]["cap_size"] == plt.rcParams["errorbar.capsize"] == 0.0 + assert errorbar["kwargs"]["width"] == plt.rcParams["lines.linewidth"] == 1.5 + assert marker["kwargs"]["size"] == pytest.approx( + plt.rcParams["lines.markersize"] * plt.rcParams["figure.dpi"] / 72.0 + ) + + +def test_errorbar_limit_flags_render_directional_endpoint_markers() -> None: + _fig, ax = plt.subplots() + ax.errorbar( + [1, 2], + [3, 4], + xerr=[0.2, 0.4], + yerr=[0.5, 0.6], + lolims=[True, False], + uplims=[False, True], + xlolims=[False, True], + xuplims=[True, False], + fmt="none", + ) + + marker_entries = [entry for entry in ax._entries if entry["kind"] == "scatter"] + assert {entry["kwargs"]["symbol"] for entry in marker_entries} == { + "triangle", + "triangle_down", + "triangle_left", + "triangle_right", + } + points = { + entry["kwargs"]["symbol"]: ( + np.asarray(entry["x"]).tolist(), + np.asarray(entry["y"]).tolist(), + ) + for entry in marker_entries + } + assert points["triangle"] == ([1], [3.5]) + assert points["triangle_down"] == ([2], [3.4]) + assert points["triangle_right"] == ([2.4], [4]) + assert points["triangle_left"] == ([0.8], [3]) diff --git a/tests/pyplot/test_gallery_layout_api_regressions.py b/tests/pyplot/test_gallery_layout_api_regressions.py new file mode 100644 index 00000000..d5fb3446 --- /dev/null +++ b/tests/pyplot/test_gallery_layout_api_regressions.py @@ -0,0 +1,116 @@ +"""Regressions reduced from Matplotlib's layout gallery examples.""" + +from __future__ import annotations + +from io import BytesIO + +import numpy as np + +import xy.pyplot as plt +from xy.pyplot._grid import _composite_rgba + + +def test_set_aspect_accepts_positional_adjustable() -> None: + _fig, ax = plt.subplots() + ax.plot([-3.0, 3.0], [-3.0, 3.0]) + + ax.set_aspect("equal", "box") + + assert ax._aspect_equal is True + assert ax._aspect_adjustable == "box" + + +def test_uniform_subplot_axes_expose_one_shared_gridspec() -> None: + fig, axes = plt.subplots(nrows=3, ncols=3) + + gridspec = axes[1, 2].get_gridspec() + + assert gridspec is axes[0, 0].get_gridspec() + assert gridspec is axes[2, 2].get_gridspec() + assert gridspec.nrows == 3 + assert gridspec.ncols == 3 + assert axes[1, 2].get_subplotspec().rows == (1, 2) + assert axes[1, 2].get_subplotspec().cols == (2, 3) + + for ax in axes[1:, -1]: + ax.remove() + spanning = fig.add_subplot(gridspec[1:, -1]) + + assert spanning.get_gridspec() is gridspec + assert spanning.get_subplotspec().rows == (1, 3) + assert spanning.get_subplotspec().cols == (2, 3) + assert (fig._nrows, fig._ncols) == (3, 3) + + +def test_absolute_subplot_composition_preserves_neighboring_spines() -> None: + fig, _axes = plt.subplots(nrows=1, ncols=2, figsize=(6.4, 4.8)) + output = BytesIO() + + fig.savefig(output, dpi=100, format="png") + output.seek(0) + + pixels = np.asarray(plt.imread(output)) + left_rect = fig._effective_rects()[0] + scale = pixels.shape[1] / 640 + right = round((left_rect[0] + left_rect[2]) * 640 * scale) + top = round((1.0 - left_rect[1] - left_rect[3]) * 480 * scale) + bottom = round((1.0 - left_rect[1]) * 480 * scale) + spine_strip = pixels[top:bottom, right - 2 : right + 3, :3] + dark_threshold = 128 if np.issubdtype(spine_strip.dtype, np.integer) else 0.5 + dark_by_column = np.all(spine_strip < dark_threshold, axis=2).sum(axis=0) + + assert dark_by_column.max() > 0.9 * (bottom - top) + + +def test_tight_layout_reserves_subplot_tick_chrome() -> None: + fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(6.4, 4.8)) + axes[1, 2].get_gridspec() + + fig.tight_layout() + + first = axes[0, 0]._figure_rect + second = axes[0, 1]._figure_rect + below = axes[1, 0]._figure_rect + assert first is not None and second is not None and below is not None + horizontal_gap = (second[0] - first[0] - first[2]) * 640 + vertical_gap = (first[1] - below[1] - below[3]) * 480 + assert horizontal_gap >= 57 + assert vertical_gap >= 43 + + +def test_subplots_constrained_layout_reserves_subplot_tick_chrome() -> None: + plt.close("all") + fig, _axes = plt.subplots(nrows=1, ncols=3, figsize=(8, 4), layout="constrained") + + first, second, _third = fig._effective_rects() + assert fig._layout_options["engine"] == "tight" + assert (second[0] - first[0] - first[2]) * 800 >= 57 + + +def test_subplot_mosaic_constrained_layout_reserves_subplot_tick_chrome() -> None: + plt.close("all") + fig, _axes = plt.subplot_mosaic( + [["no_norm", "density", "weight"]], + figsize=(8, 4), + layout="constrained", + ) + + first, second, _third = fig._effective_rects() + assert fig._layout_options["engine"] == "tight" + assert (second[0] - first[0] - first[2]) * 800 >= 57 + + +def test_rgba_compositor_preserves_transparent_chrome() -> None: + destination = np.array( + [[[255, 255, 255, 255], [0, 0, 255, 255]]], + dtype=np.uint8, + ) + source = np.array( + [[[0, 0, 0, 0], [255, 0, 0, 128]]], + dtype=np.uint8, + ) + + _composite_rgba(destination, source) + + np.testing.assert_array_equal(destination[0, 0], [255, 255, 255, 255]) + np.testing.assert_array_equal(destination[0, 1], [128, 0, 127, 255]) diff --git a/tests/pyplot/test_gallery_statistics_semantics.py b/tests/pyplot/test_gallery_statistics_semantics.py new file mode 100644 index 00000000..997a7126 --- /dev/null +++ b/tests/pyplot/test_gallery_statistics_semantics.py @@ -0,0 +1,101 @@ +from __future__ import annotations + +import numpy as np + +import xy.pyplot as plt +from xy._figure import Figure + + +def teardown_function() -> None: + plt.close("all") + + +def test_core_bar_accepts_per_item_widths_and_ships_exact_rectangles() -> None: + spec, _ = Figure().bar([0.0, 2.0], [1.0, 3.0], width=[0.5, 1.5]).build_payload() + + trace = spec["traces"][0] + assert "bar" not in trace + assert {"x0", "x1", "y0", "y1"} <= trace.keys() + + +def test_barh_accepts_one_height_per_bar() -> None: + _fig, ax = plt.subplots() + bars = ax.barh([1.0, 3.0], [2.0, 4.0], height=[0.4, 1.2]) + + np.testing.assert_allclose(bars._entry["kwargs"]["width"], [0.4, 1.2]) + + +def test_hist_rwidth_scales_each_nonuniform_bin() -> None: + _fig, ax = plt.subplots() + _counts, edges, bars = ax.hist( + [0.2, 1.5, 3.0], + bins=[0.0, 1.0, 2.0, 4.0], + histtype="barstacked", + rwidth=0.8, + ) + + np.testing.assert_allclose(edges, [0.0, 1.0, 2.0, 4.0]) + np.testing.assert_allclose(bars._entry["kwargs"]["width"], [0.8, 0.8, 1.6]) + np.testing.assert_allclose(bars._entry["x"], [0.5, 1.5, 3.0]) + + +def test_hist_hatch_families_emit_visible_overlay_geometry() -> None: + _fig, ax = plt.subplots() + ax.hist( + [[0.1, 0.2], [0.3, 0.4]], + bins=[0.0, 0.5, 1.0], + histtype="barstacked", + hatch=["/", "O"], + ) + + factories = [entry.get("factory", entry.get("kind")) for entry in ax._entries] + assert "segments" in factories + assert "scatter" in factories + + +def test_hist_per_dataset_linestyles_emit_distinct_outlines() -> None: + _fig, ax = plt.subplots() + ax.hist( + [[0.1, 0.2], [0.3, 0.4]], + bins=[0.0, 0.5, 1.0], + fill=False, + linestyle=["-", ":"], + edgecolor=["green", "red"], + ) + + outlined = [ + entry + for entry in ax._entries + if entry.get("factory") == "segments" and entry["kwargs"].get("dash") + ] + assert len(outlined) == 1 + assert outlined[0]["kwargs"]["color"] == "red" + + +def test_hist_negative_cumulative_runs_from_right_to_left() -> None: + _fig, ax = plt.subplots() + + counts, edges, _bars = ax.hist([0.2, 0.4, 1.2, 2.2], bins=[0.0, 1.0, 2.0, 3.0], cumulative=-1) + + np.testing.assert_allclose(edges, [0.0, 1.0, 2.0, 3.0]) + np.testing.assert_allclose(counts, [4.0, 2.0, 1.0]) + + +def test_boxplot_component_dashes_and_point_means_are_rendered() -> None: + _fig, ax = plt.subplots() + result = ax.boxplot( + [[1.0, 2.0, 3.0, 9.0]], + showmeans=True, + boxprops={"linestyle": "--", "linewidth": 3.0, "color": "goldenrod"}, + meanprops={ + "marker": "D", + "markerfacecolor": "firebrick", + "markeredgecolor": "black", + }, + ) + + box_entry = result["boxes"][0]._entry + assert box_entry["factory"] == "segments" + assert len(box_entry["args"][0]) > 4 + assert result["means"][0]._entry["kind"] == "scatter" + assert result["means"][0]._entry["kwargs"]["symbol"] == "diamond" diff --git a/tests/pyplot/test_gallery_stem_regressions.py b/tests/pyplot/test_gallery_stem_regressions.py new file mode 100644 index 00000000..9f218e7c --- /dev/null +++ b/tests/pyplot/test_gallery_stem_regressions.py @@ -0,0 +1,74 @@ +"""Regressions reduced from Matplotlib's ``stem_plot`` gallery example.""" + +from __future__ import annotations + +import numpy as np + +import xy.pyplot as plt +from xy._figure import Figure + + +def test_stem_contributes_tip_and_baseline_to_autoscale() -> None: + x = np.linspace(0.1, 2 * np.pi, 41) + y = np.exp(np.sin(x)) + _fig, ax = plt.subplots() + + ax.stem(x, y, bottom=0.0) + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + np.testing.assert_allclose(ax._entry_extent("x"), (x.min(), x.max())) + np.testing.assert_allclose(ax._entry_extent("y"), (0.0, y.max())) + # Stems are segment marks, not sticky-edge rectangles. The core's normal + # autorange padding must leave the baseline visible inside the frame. + ylo, yhi = ax._build_chart(640, 480).figure().y_range() + assert ylo < 0.0 + assert yhi > y.max() + + +def test_stem_padding_does_not_unstick_rectangle_baselines() -> None: + assert Figure().bar(["a", "b"], [1.0, 2.0]).y_range()[0] == 0.0 + assert Figure().hist([1.0, 2.0, 3.0]).y_range()[0] == 0.0 + + +def test_stem_nonzero_bottom_is_part_of_the_value_extent() -> None: + _fig, ax = plt.subplots() + + markerline, stemlines, baseline = ax.stem([1.0, 2.0], [1.5, 1.8], bottom=1.1) + + np.testing.assert_allclose(ax._entry_extent("x"), (1.0, 2.0)) + np.testing.assert_allclose(ax._entry_extent("y"), (1.1, 1.8)) + assert markerline is not stemlines + assert baseline is not stemlines + np.testing.assert_allclose(baseline.get_xdata(), (1.0, 2.0)) + np.testing.assert_allclose(baseline.get_ydata(), (1.1, 1.1)) + assert baseline.get_color() == "#d62728" + + +def test_stem_marker_face_mutation_does_not_recolor_stems() -> None: + _fig, ax = plt.subplots() + markerline, stemlines, _baseline = ax.stem( + [1.0, 2.0], + [1.5, 1.8], + linefmt="grey", + markerfmt="D", + ) + + markerline.set_markerfacecolor("none") + + assert markerline._entry["kwargs"]["color"] == "transparent" + assert markerline._entry["kwargs"]["opacity"] == 1.0 + assert markerline._entry["kwargs"]["stroke"] == "grey" + assert stemlines._entry["kwargs"]["color"] == "grey" + + +def test_stem_basefmt_controls_the_independent_baseline() -> None: + _fig, ax = plt.subplots() + + _markerline, _stemlines, baseline = ax.stem( + [1.0, 2.0], + [1.5, 1.8], + basefmt="k-", + ) + + assert baseline.get_color() == "#000000" diff --git a/tests/pyplot/test_gallery_text_pie_compat.py b/tests/pyplot/test_gallery_text_pie_compat.py new file mode 100644 index 00000000..a9d03c68 --- /dev/null +++ b/tests/pyplot/test_gallery_text_pie_compat.py @@ -0,0 +1,293 @@ +from __future__ import annotations + +from io import BytesIO + +import numpy as np +import pytest + +import xy.pyplot as plt + + +@pytest.fixture(autouse=True) +def _clean(): + plt.close("all") + yield + plt.close("all") + + +def test_pie_label_preserves_integer_values_for_integer_format_codes() -> None: + _fig, ax = plt.subplots() + pie = ax.pie([36, 24, 8, 12]) + + labels = ax.pie_label(pie, "{absval:03d}\n{frac:.1%}") + + assert pie.values.dtype.kind in "iu" + assert not pie.values.flags.writeable + assert [label.get_text() for label in labels] == [ + "036\n45.0%", + "024\n30.0%", + "008\n10.0%", + "012\n15.0%", + ] + + +def test_pie_label_does_not_integer_cast_float_input() -> None: + _fig, ax = plt.subplots() + pie = ax.pie([1.0, 2.0]) + + with pytest.raises(ValueError, match="format code 'd'"): + ax.pie_label(pie, "{absval:d}") + + +def test_positioned_png_keeps_figure_suptitle() -> None: + fig, ax = plt.subplots() + ax.plot([0, 1], [0, 1]) + fig.suptitle("visible figure title") + fig.subplots_adjust(top=0.85) + + pixels = np.asarray(plt.imread(BytesIO(fig._to_png()))) + + assert np.any(pixels[:48, :, :3] < 200) + + +@pytest.mark.parametrize( + ("distance", "rotate", "expected"), + [ + ( + 0.6, + False, + [ + ("middle", "center", None), + ("middle", "center", None), + ("middle", "center", None), + ("middle", "center", None), + ], + ), + ( + 1.1, + False, + [ + ("start", "center", None), + ("end", "center", None), + ("end", "center", None), + ("start", "center", None), + ], + ), + ( + 0.6, + True, + [ + ("middle", "center", 45.0), + ("middle", "center", 315.0), + ("middle", "center", 405.0), + ("middle", "center", 315.0), + ], + ), + ( + 1.1, + True, + [ + ("start", "bottom", 45.0), + ("end", "bottom", 315.0), + ("end", "top", 405.0), + ("start", "top", 315.0), + ], + ), + ], +) +def test_pie_label_matches_matplotlib_radial_alignment( + distance: float, + rotate: bool, + expected: list[tuple[str, str, float | None]], +) -> None: + _fig, ax = plt.subplots() + pie = ax.pie([1, 1, 1, 1]) + + labels = ax.pie_label(pie, ["a", "b", "c", "d"], distance=distance, rotate=rotate) + + actual = [ + ( + label._entry["kwargs"]["anchor"], + label._entry["kwargs"]["style"]["vertical_align"], + label._entry["kwargs"]["style"].get("rotation"), + ) + for label in labels + ] + for result, reference in zip(actual, expected, strict=True): + assert result[:2] == reference[:2] + if reference[2] is None: + assert result[2] is None + else: + assert result[2] == pytest.approx(reference[2]) + + +def test_pie_label_textprops_override_geometry_and_accept_gallery_font_styles() -> None: + _fig, ax = plt.subplots() + pie = ax.pie([1, 2]) + + labels = ax.pie_label( + pie, + ["one", "two"], + distance=1.1, + rotate=True, + textprops={ + "ha": "center", + "va": "center", + "rotation": 12, + "fontsize": "large", + "weight": "bold", + "style": "italic", + "family": "serif", + }, + ) + + for label in labels: + kwargs = label._entry["kwargs"] + assert kwargs["anchor"] == "middle" + assert kwargs["style"] == { + "vertical_align": "center", + "rotation": 12.0, + "font_size": 12.0, + "font_weight": "bold", + "font_family": "serif", + "font_style": "italic", + } + + +def test_pie_label_rotation_reaches_static_svg() -> None: + _fig, ax = plt.subplots() + pie = ax.pie([1, 1, 1, 1]) + ax.pie_label(pie, ["a", "b", "c", "d"], rotate=True) + + svg = ax._build_chart(640, 480).figure().to_svg() + + assert svg.count('transform="rotate(-45 ') == 2 + assert 'transform="rotate(-315 ' in svg + + +def test_text_accepts_matplotlib_style_alias_and_bbox_properties() -> None: + fig, ax = plt.subplots(figsize=(6.4, 4.8), dpi=100) + ax.set_xlim(0, 10) + ax.set_ylim(0, 10) + + label = ax.text( + 3, + 8, + "boxed italics text in data coords", + style="italic", + bbox={"facecolor": "red", "alpha": 0.5, "pad": 10}, + ) + + assert label._entry["kwargs"] == { + "bbox": {"facecolor": "red", "alpha": 0.5, "pad": 10}, + "style": {"font_style": "italic"}, + } + chart = ax._build_chart(*fig._panel_px()) + annotation = next(child for child in chart.children if getattr(child, "kind", None) == "text") + assert annotation.style["font_style"] == "italic" + assert annotation.style["background"] == "rgba(255,0,0,0.5)" + assert annotation.style["padding"] == "13.9px" + svg = chart.figure().to_svg() + assert 'fill="rgba(255,0,0,0.5)"' in svg + assert 'stroke="black"' in svg + assert 'font-style="italic"' in svg + target = BytesIO() + fig.savefig(target, format="png") + rgba = np.asarray(plt.imread(BytesIO(target.getvalue()))) + assert np.any((rgba[..., 0] > 200) & (rgba[..., 1] < 180) & (rgba[..., 2] < 180)) + + +def test_text_preserves_mathtext_italic_span_across_all_exporters() -> None: + fig, ax = plt.subplots() + + label = ax.text(2, 6, r"an equation: $E=mc^2$", fontsize=15) + + assert label.get_text() == "an equation: E=mc²" + assert label._entry["kwargs"]["style"]["math_italic_ranges"] == "13:14,15:17" + svg = ax._build_chart(*fig._panel_px()).figure().to_svg() + assert 'E=' in svg + assert 'mc²' in svg + target = BytesIO() + fig.savefig(target, format="png") + rgba = np.asarray(plt.imread(BytesIO(target.getvalue()))) + assert np.any(rgba[..., :3] < 0.5) + + +def test_text_fontdict_styles_title_labels_and_named_math_functions() -> None: + fig, ax = plt.subplots(figsize=(6.4, 4.8), dpi=100) + font = {"family": "serif", "color": "darkred", "weight": "normal", "size": 16} + + ax.set_title("Damped exponential decay", fontdict=font) + equation = ax.text(2, 0.65, r"$\cos(2 \pi t) \exp(-t)$", fontdict=font) + ax.set_xlabel("time (s)", fontdict=font) + ax.set_ylabel("voltage (mV)", fontdict=font) + + assert equation.get_text() == "cos(2πt)exp(\N{MINUS SIGN}t)" + assert equation._entry["kwargs"]["style"]["math_italic_ranges"] == "5:7,13:14" + spec, _ = ax._build_chart(*fig._panel_px()).figure().build_payload() + assert spec["dom"]["styles"]["title"] == { + "font-size": "22.2222px", + "color": "darkred", + "font-weight": "normal", + "font-family": "serif", + } + for axis in ("x_axis", "y_axis"): + style = spec[axis]["style"] + assert style["label_size"] == pytest.approx(22.2222, rel=1e-4) + assert style["label_color"] == "darkred" + assert style["label_font_weight"] == "normal" + assert style["label_font_family"] == "serif" + svg = ax._build_chart(*fig._panel_px()).figure().to_svg() + assert 'font-family="serif"' in svg + assert 'font-weight="normal"' in svg + assert 'fill="darkred"' in svg + assert ">cos(" in svg + assert "\\cos" not in svg and "\\exp" not in svg + + +def test_text_commands_umlauts_render_in_native_png_and_survive_svg() -> None: + phrase = "Unicode: Institut für Festkörperphysik" + deleted = "Unicode: Institut fr Festkrperphysik" + + def render(text: str) -> np.ndarray: + fig, ax = plt.subplots() + ax.set_xlim(0, 10) + ax.set_ylim(0, 10) + ax.text(3, 2, text) + return np.asarray(plt.imread(BytesIO(fig._to_png()))) + + with_umlauts = render(phrase) + plt.close("all") + without_umlauts = render(deleted) + assert not np.array_equal(with_umlauts, without_umlauts) + + fig, ax = plt.subplots() + ax.text(3, 2, phrase) + assert phrase in ax._build_chart(*fig._panel_px()).figure().to_svg() + + +def test_pie_container_values_are_defensive_and_fracs_stay_numeric() -> None: + _fig, ax = plt.subplots() + pie = ax.pie(np.array([2, 3, 5], dtype=np.int16)) + + values = pie.values + assert values.dtype == np.dtype(np.int16) + assert not values.flags.writeable + np.testing.assert_allclose(pie.fracs, [0.2, 0.3, 0.5]) + + +def test_pie_uses_equal_aspect_hidden_axes_and_seam_covering_face_strokes() -> None: + _fig, ax = plt.subplots() + + pie = ax.pie([2, 3, 5], startangle=90) + spec, _ = ax._build_chart(640, 480).figure().build_payload() + + assert ax._aspect_equal is True + assert spec["frame_sides"] == [] + assert spec["x_axis"]["tick_label_strategy"] == "none" + assert spec["y_axis"]["tick_label_strategy"] == "none" + assert all(wedge._entry["kwargs"]["stroke_width"] == 0.75 for wedge in pie.wedges) + assert all( + wedge._entry["kwargs"]["stroke"] == wedge._entry["kwargs"]["color"] for wedge in pie.wedges + ) + assert pie.wedges[0]._entry["pie_mid"] == pytest.approx(np.deg2rad(126)) diff --git a/tests/pyplot/test_grid_legend_contracts.py b/tests/pyplot/test_grid_legend_contracts.py index ab4c330e..be2ef8b4 100644 --- a/tests/pyplot/test_grid_legend_contracts.py +++ b/tests/pyplot/test_grid_legend_contracts.py @@ -49,12 +49,17 @@ def test_legend_maps_supported_style_and_rejects_unknown_options(): assert ax._legend_options["loc"] == "upper right" assert ax._legend_options["ncols"] == 2 assert ax._legend_options["title"] == "Legend" + assert ax._legend_options["border_pad"] == pytest.approx(0.5 * 13 * 100 / 72) assert ax._legend_options["style"] == { "fontSize": "18.0556px", "color": "green", "background": "white", "borderColor": "black", "borderStyle": "solid", + "borderWidth": "1px", + "--xy-legend-frame-alpha": 0.8, + "padding": "0.4em", + "rowGap": "0.5em", } ax.legend(shadow=True, fancybox=True, framealpha=0.8, borderpad=1, labelspacing=0.7) @@ -64,6 +69,11 @@ def test_legend_maps_supported_style_and_rejects_unknown_options(): assert style["padding"] == "1em" assert style["rowGap"] == "0.7em" + ax.legend(fontsize=13, borderaxespad=0.75) + assert ax._legend_options["border_pad"] == pytest.approx(0.75 * 13 * 100 / 72) + with pytest.raises(ValueError, match="borderaxespad"): + ax.legend(borderaxespad=-0.1) + def test_legend_frameoff_maps_to_transparent_style(): _, ax = plt.subplots() @@ -95,6 +105,7 @@ def test_second_legend_via_add_artist_renders_own_box_with_dash_handles(): spec, _ = ax._build_chart(573, 400).figure().build_payload() assert spec["legend"]["loc"] == "upper right" + assert [item["name"] for item in spec["legend"]["items"]] == ["line A", "line B"] extras = spec.get("extra_legends") assert extras and len(extras) == 1 assert extras[0]["loc"] == "lower right" @@ -104,9 +115,9 @@ def test_second_legend_via_add_artist_renders_own_box_with_dash_handles(): dashes = [it["style"].get("dash") for it in extras[0]["items"]] assert dashes[0] and len(dashes[0]) == 4 # "-." → [on, off, on, off] assert dashes[1] and len(dashes[1]) == 2 # ":" → [on, off] - # The primary legend must not have acquired the second legend's labels. + # Neither explicit legend mutates trace names. named_traces = [t.get("name") for t in spec["traces"] if t.get("name")] - assert "line C" not in named_traces and "line D" not in named_traces + assert not named_traces def test_standalone_extra_legend_survives_primary_legend_suppression(): @@ -133,7 +144,11 @@ def test_standalone_legend_unwraps_errorbar_container(): { "name": "uncertainty", "kind": "line", - "style": {"color": "red", "width": pytest.approx(1.6666666667), "opacity": 1.0}, + "style": { + "color": "red", + "width": pytest.approx(plt.rcParams["lines.linewidth"] * 100.0 / 72.0), + "opacity": 1.0, + }, } ] @@ -150,14 +165,19 @@ def test_standalone_legend_preserves_rule_annotation_dash(): assert item["style"]["dash"] == [10.2778, 4.4444] -def test_center_right_legend_loc_reaches_spec(): +def test_center_band_legend_loc_reaches_spec(): import numpy as np _, ax = plt.subplots() x = np.linspace(0, 10, 500) # A full-amplitude oscillation leaves every corner busy; matplotlib's "best" - # parks the legend on the sparse vertical-center band. + # parks the legend on the sparse vertical-center band. Matplotlib 3.11.1 + # scores this exact figure center left 20 against center right 36 — a + # decisive win for the left band, not a tie. This asserted "center right" + # while the shim compared *mean fractional* occupancy under a 0.02 tie band, + # which flattened the 20-vs-36 gap into a tie and handed it to the + # earlier-ordered candidate. ax.plot(x, np.sin(x[:, None] + np.pi * np.arange(0, 2, 0.5))) ax.legend(["a", "b"]) spec, _ = ax._build_chart(573, 400).figure().build_payload() - assert spec["legend"]["loc"] == "center right" + assert spec["legend"]["loc"] == "center left" diff --git a/tests/pyplot/test_launch_compat.py b/tests/pyplot/test_launch_compat.py index be28152b..fa40598e 100644 --- a/tests/pyplot/test_launch_compat.py +++ b/tests/pyplot/test_launch_compat.py @@ -48,7 +48,8 @@ def test_bar_labels_are_centered_over_vertical_bars() -> None: assert label._entry["args"][0] == center assert label._entry["kwargs"]["anchor"] == "middle" assert label._entry["kwargs"]["dx"] == 0.0 - assert label._entry["kwargs"]["dy"] == -8.0 + assert label._entry["kwargs"]["dy"] == pytest.approx(-3.0 * 100.0 / 72.0) + assert label._entry["kwargs"]["style"]["vertical_align"] == "bottom" def test_pyplot_legend_location_and_columns_reach_render_spec() -> None: @@ -81,7 +82,8 @@ def test_filled_stairs_use_seamless_bins_and_hatches_are_not_dropped() -> None: assert any(entry["kind"] == "bar" for entry in ax._entries) assert not any(entry.get("factory") == "triangle_mesh" for entry in ax._entries) hatch = [entry for entry in ax._entries if entry.get("factory") == "segments"][-1] - assert len(hatch["args"][0]) == 14 + assert len(hatch["args"][0]) >= 14 + assert len({len(values) for values in hatch["args"]}) == 1 def test_adding_external_step_patch_does_not_advance_color_cycle() -> None: diff --git a/tests/pyplot/test_layout_text_parity_fixes.py b/tests/pyplot/test_layout_text_parity_fixes.py index 6233583d..50f7687d 100644 --- a/tests/pyplot/test_layout_text_parity_fixes.py +++ b/tests/pyplot/test_layout_text_parity_fixes.py @@ -92,7 +92,7 @@ def test_subplots_adjust_positions_grid_panels_in_every_exporter() -> None: ax.text(0.5, 0.5, str((2, 3, i)), fontsize=18, ha="center") html = fig._to_html() assert len(re.findall(r'style="position:absolute;left:', html)) == 6 - assert _png_pixels(fig).shape[:2] == (960, 1280) # the full 640x480 canvas at 2x + assert _png_pixels(fig).shape[:2] == (480, 640) # the requested 640x480 canvas assert _svg(fig).count(" None: ax.plot([0, 1], [0, 1]) ax.set_ylabel("amplitude of the signal") pixels = _png_pixels(fig) + plain_fig, plain_ax = plt.subplots() + plain_ax.plot([0, 1], [0, 1]) + plain = _png_pixels(plain_fig) height, width = pixels.shape[:2] # Ink confined to a tall, narrow left-margin band — rotated text; the old - # horizontal top-left placement would put ink in the top band instead. - left_band = pixels[height // 4 : 3 * height // 4, : width // 24, :3] - assert (left_band < 200).any() - top_band = pixels[: height // 40, : width // 24, :3] - assert not (top_band < 200).any() + # horizontal top-left placement would change the top band instead. Compare + # against the same axes without a title so tick-label ink cannot satisfy + # the assertion by accident. + left_band = np.s_[height // 4 : 3 * height // 4, : width // 12, :3] + assert (pixels[left_band] != plain[left_band]).any() + top_band = np.s_[: height // 40, : width // 12, :3] + assert not (pixels[top_band] != plain[top_band]).any() def test_errorbar_color_and_ecolor_resolve_independently() -> None: diff --git a/tests/pyplot/test_line_gallery_semantics.py b/tests/pyplot/test_line_gallery_semantics.py new file mode 100644 index 00000000..253bb6cd --- /dev/null +++ b/tests/pyplot/test_line_gallery_semantics.py @@ -0,0 +1,71 @@ +from __future__ import annotations + +import numpy as np +import pytest + +import xy.pyplot as plt + + +def teardown_function() -> None: + plt.close("all") + + +def test_axline_is_clipped_to_the_final_view_and_keeps_dash_style() -> None: + _fig, ax = plt.subplots() + ax.axline((0, 0.5), slope=0.25, color="black", linestyle=(0, (5, 5))) + ax.set(xlim=(-10, 10), ylim=(-0.05, 1.05)) + + trace = ax._build_chart(640, 480).figure().traces[0] + + np.testing.assert_allclose(trace.x.values, [-2.2, 2.2]) + np.testing.assert_allclose(trace.y.values, [-0.05, 1.05]) + assert trace.style["dash"] == [10.4167, 10.4167] + assert trace.style["width"] == pytest.approx(1.5 * 100 / 72) + + +def test_axline_axes_transform_is_deferred_but_slope_stays_in_data_space() -> None: + _fig, ax = plt.subplots() + ax.axline((-1 / 3, 0), slope=0.5, color="black", transform=ax.transAxes) + + # A transformed defining point does not alter the dataless view. + assert ax.get_xlim() == (0.0, 1.0) + assert ax.get_ylim() == (0.0, 1.0) + + ax.set(xlim=(0, 1), ylim=(0, 1)) + trace = ax._build_chart(640, 480).figure().traces[0] + np.testing.assert_allclose(trace.x.values, [0.0, 1.0]) + np.testing.assert_allclose(trace.y.values, [1 / 6, 2 / 3]) + + +def test_axline_reclips_after_limits_change_and_handles_vertical_lines() -> None: + _fig, ax = plt.subplots() + ax.axline((0.25, 0.5), slope=np.inf) + ax.set(xlim=(0, 1), ylim=(-2, 2)) + first = ax._build_chart(640, 480).figure().traces[0] + np.testing.assert_allclose(first.x.values, [0.25, 0.25]) + np.testing.assert_allclose(first.y.values, [-2, 2]) + + ax.set_ylim(-4, 4) + second = ax._build_chart(640, 480).figure().traces[0] + np.testing.assert_allclose(second.y.values, [-4, 4]) + + +def test_axline_slope_rejects_nonlinear_scales_like_matplotlib() -> None: + _fig, ax = plt.subplots() + ax.set_xscale("log") + + with pytest.raises(TypeError, match=r"slope.*non-linear"): + ax.axline((1, 1), slope=1) + + +def test_line_set_dashes_updates_the_rendered_dash_pattern() -> None: + _fig, ax = plt.subplots() + (line,) = ax.plot([0, 1], [0, 1], linewidth=2) + + line.set_dashes([2, 2, 10, 2]) + + trace = ax._build_chart(640, 480).figure().traces[0] + assert trace.style["dash"] == pytest.approx( + [value * 2 * 100 / 72 for value in (2, 2, 10, 2)], + abs=1e-4, + ) diff --git a/tests/pyplot/test_line_legend_gallery_compat.py b/tests/pyplot/test_line_legend_gallery_compat.py new file mode 100644 index 00000000..cdd5a241 --- /dev/null +++ b/tests/pyplot/test_line_legend_gallery_compat.py @@ -0,0 +1,397 @@ +from __future__ import annotations + +from io import BytesIO +from xml.etree import ElementTree + +import numpy as np +import pytest + +import xy.pyplot as plt +from xy import _raster +from xy._svg import _LEGEND_CHAR_WIDTH, _legend_layout, _legend_text_width, layout +from xy.pyplot import Legend + + +def teardown_function(): + plt.close("all") + + +def _legend_frame_and_labels(svg_root, names): + """The emitted legend frame rect and label texts, from real SVG geometry. + + The legend frame is the only rect carrying both a fill and a stroke opacity + in a line chart, so it is identified without consulting the layout that is + under test. + """ + frames = [ + element + for element in svg_root.iter() + if element.tag.endswith("rect") + and "fill-opacity" in element.attrib + and "stroke-opacity" in element.attrib + ] + assert len(frames) == 1, [frame.attrib for frame in frames] + labels = [ + element + for element in svg_root.iter() + if element.tag.endswith("text") and (element.text or "") in names + ] + return frames[0], labels + + +def test_plot_drawstyle_steps_aliases_steps_pre(): + _, ax = plt.subplots() + line = ax.plot([0, 1, 2], [2, 1, 3], drawstyle="steps")[0] + + assert line._entry["factory"] == "step" + assert line._entry["kwargs"]["where"] == "pre" + spec, _ = ax._build_chart(640, 480).figure().build_payload() + assert spec["traces"][0]["kind"] == "line" + assert spec["traces"][0]["style"]["step"] == "pre" + + +def test_legend_bbox_to_anchor_reaches_payload_and_static_layout(): + _, ax = plt.subplots() + ax.plot([0, 1], [0, 1], label="line") + ax.legend(loc="lower left", bbox_to_anchor=(0, 1)) + + spec, _ = ax._build_chart(640, 480).figure().build_payload() + assert spec["legend"]["anchor"] == [0.0, 1.0] + assert spec["legend"]["style"]["--xy-legend-frame-alpha"] == 0.8 + assert spec["legend"]["style"]["borderColor"] == "#cccccc" + assert spec["legend"]["style"]["borderWidth"] == "1px" + + plot = {"x": 10.0, "y": 20.0, "w": 100.0, "h": 80.0} + layout = _legend_layout( + [{"name": "line"}], + plot, + {"loc": "lower left", "anchor": (0.0, 1.0)}, + ) + assert layout["x"] == 10.0 + assert layout["y"] + layout["box_h"] == 20.0 + + +def test_multicolumn_legend_sizes_each_column_to_its_own_labels(): + named = [ + {"name": "Strongly disagree"}, + {"name": "Disagree"}, + {"name": "Neither agree nor disagree"}, + {"name": "Agree"}, + {"name": "Strongly agree"}, + ] + plot = {"x": 0.0, "y": 0.0, "w": 900.0, "h": 200.0} + + layout = _legend_layout(named, plot, {"ncols": 5, "loc": "upper center"}) + + assert layout["names"] == [entry["name"] for entry in named] + assert len(set(layout["column_widths"])) > 1 + assert layout["column_offsets"][1] == ( + layout["column_offsets"][0] + layout["column_widths"][0] + layout["column_gap"] + ) + equal_width_box = 5 * max(layout["column_widths"]) + 4 * layout["column_gap"] + layout["pad"] + assert layout["box_w"] < equal_width_box + + +def test_outside_top_legend_reserves_its_measured_box_and_axes_gap(): + fig, ax = plt.subplots(figsize=(9.2, 5)) + labels = [ + "Strongly disagree", + "Disagree", + "Neither agree nor disagree", + "Agree", + "Strongly agree", + ] + for index, label in enumerate(labels): + ax.barh(["Question 1", "Question 2"], [index + 1, index + 2], label=label) + ax.legend( + ncols=len(labels), + bbox_to_anchor=(0, 1), + loc="lower left", + fontsize="small", + ) + + spec, _ = ax._build_chart(920, 500).figure().build_payload() + _, _, _, plot = layout(spec) + legend = _legend_layout( + [trace for trace in spec["traces"] if trace.get("name")], + plot, + spec["legend"], + ) + + assert spec["padding"][0] >= legend["box_h"] + spec["legend"]["border_pad"] + 6 + assert legend["y"] >= 6 + assert plot["y"] - (legend["y"] + legend["box_h"]) == pytest.approx( + spec["legend"]["border_pad"] + ) + + +def test_titled_scatter_legend_box_fits_title_and_every_entry(): + _, ax = plt.subplots() + scatter = ax.scatter( + np.arange(4), + np.arange(4), + c=np.array([1, 2, 3, 4]), + s=np.array([10, 40, 90, 160]), + ) + handles, labels = scatter.legend_elements() + legend = ax.legend(handles, labels, loc="lower left", title="Classes") + + spec = legend.spec() + box = _legend_layout( + spec["items"], + {"x": 62.0, "y": 10.0, "w": 564.0, "h": 428.0}, + spec, + ) + + assert box["title"] == "Classes" + assert box["names"] == labels + assert box["visible_count"] == len(labels) + char_width = box["font_size"] * (_LEGEND_CHAR_WIDTH / 11.0) + assert box["box_w"] >= _legend_text_width("Classes", char_width) + box["pad"] + assert box["box_h"] > 100 + + +def test_hidden_axis_keeps_explicit_matplotlib_spines_in_static_exports(): + fig, ax = plt.subplots(figsize=(3, 2)) + ax.xaxis.set_visible(False) + spec, _ = ax._build_chart(300, 200).figure().build_payload() + assert spec["frame_sides"] == ["left", "bottom", "top", "right"] + _, _, _, plot = layout(spec) + + output = BytesIO() + fig.savefig(output, format="svg") + root = ElementTree.fromstring(output.getvalue()) + lines = [element for element in root.iter() if element.tag.endswith("line")] + full_width_rules = { + round(float(line.attrib["y1"]), 6) + for line in lines + if abs(float(line.attrib["x1"]) - plot["x"]) < 1e-6 + and abs(float(line.attrib["x2"]) - (plot["x"] + plot["w"])) < 1e-6 + and abs(float(line.attrib["y1"]) - float(line.attrib["y2"])) < 1e-6 + } + assert round(plot["y"], 6) in full_width_rules + assert round(plot["y"] + plot["h"], 6) in full_width_rules + + output = BytesIO() + fig.savefig(output, format="png", dpi=100) + output.seek(0) + pixels = plt.imread(output) + scale_x = pixels.shape[1] / 300 + scale_y = pixels.shape[0] / 200 + x = round((plot["x"] + plot["w"] / 2) * scale_x) + for edge in (plot["y"], plot["y"] + plot["h"]): + y = round(edge * scale_y) + sample = pixels[max(0, y - 2) : min(pixels.shape[0], y + 3), x, :3] + dark_threshold = 128.0 if np.issubdtype(sample.dtype, np.integer) else 0.5 + assert float(sample.min()) < dark_threshold + + +def test_bar_numpy_rgba_row_is_one_color_for_trace_and_legend(): + _, ax = plt.subplots() + rgba = np.array([0.9, 0.2, 0.1, 1.0]) + ax.barh(["a", "b"], [1, 2], label="answers", color=rgba) + + entry = ax._entries[-1] + assert entry["kwargs"]["color"] == "rgba(230,51,26,1)" + + +def test_scalar_scatter_alpha_survives_native_affine_fast_path(): + fig, ax = plt.subplots(figsize=(2, 2)) + ax.scatter([0.5], [0.5], s=2500, c="red", alpha=0.25, edgecolors="none") + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + + output = BytesIO() + fig.savefig(output, format="png", dpi=100) + output.seek(0) + pixels = plt.imread(output).astype(np.float64) / 255.0 + red_pixels = pixels[(pixels[..., 0] > 0.95) & (pixels[..., 1] < 0.9) & (pixels[..., 2] < 0.9)] + assert red_pixels.size + assert float(red_pixels[..., 1].min()) > 0.6 + + +def test_scatter_legend_elements_return_real_legend_artists_and_two_boxes(): + _, ax = plt.subplots() + scatter = ax.scatter( + np.arange(4), + np.arange(4), + c=np.array([1, 2, 3, 4]), + s=np.array([10, 40, 90, 160]), + ) + + color_handles, color_labels = scatter.legend_elements() + first = ax.legend(color_handles, color_labels, loc="lower left", title="Classes") + assert isinstance(first, Legend) + ax.add_artist(first) + + size_handles, size_labels = scatter.legend_elements( + prop="sizes", + num=3, + alpha=0.6, + fmt="$ {x:.0f}", + func=lambda value: np.sqrt(value), + ) + second = ax.legend(size_handles, size_labels, loc="upper right", title="Sizes") + assert isinstance(second, Legend) + assert ax.get_legend() is second + + spec, _ = ax._build_chart(640, 480).figure().build_payload() + assert spec["show_legend"] is False + assert [legend["title"] for legend in spec["extra_legends"]] == ["Classes", "Sizes"] + assert len(spec["extra_legends"][0]["items"]) == 4 + sizes = [item["style"]["size"] for item in spec["extra_legends"][1]["items"]] + assert sizes == sorted(sizes) + assert all(label.startswith("$ ") for label in size_labels) + assert all(item["name"].startswith("$ ") for item in spec["extra_legends"][1]["items"]) + + +def test_round_dash_capstyle_mutation_matches_fixed_round_renderers(): + _, ax = plt.subplots() + line = ax.plot([0, 1], [0, 1], "--")[0] + + line.set_dash_capstyle("round") + + assert line.get_dash_capstyle() == "round" + assert line._entry["kwargs"]["dash_capstyle"] == "round" + + +def test_legend_frame_is_wide_enough_for_its_measured_labels(): + """The frame must contain its own labels, wide glyphs included. + + Regression: columns were sized as ``len(label) * _LEGEND_CHAR_WIDTH``, a + flat per-character average. "gamma" sets 42.6 px at 11 px against a 31.0 px + estimate, so the 1 px frame landed ~7.6 px inside the label's right edge and + "alpha"/"gamma" visibly crossed the border. Matplotlib insets the widest + label from its frame by ``borderpad``; the sign is what matters here. + """ + names = ("alpha", "beta", "gamma") + fig, ax = plt.subplots(figsize=(6.4, 4.8)) + for name in names: + ax.plot([0, 1], [0, 1], label=name) + ax.legend( + loc="upper left", + bbox_to_anchor=(1.02, 1.0), + frameon=True, + edgecolor="black", + title="series", + ) + + output = BytesIO() + fig.savefig(output, format="svg") + frame, labels = _legend_frame_and_labels(ElementTree.fromstring(output.getvalue()), names) + + assert {label.text for label in labels} == set(names) + frame_right = float(frame.attrib["x"]) + float(frame.attrib["width"]) + for label in labels: + label_right = float(label.attrib["x"]) + _legend_text_width(label.text) + assert label_right <= frame_right, ( + f"{label.text!r} runs to {label_right:.3f}, past the frame's {frame_right:.3f}" + ) + # The label is inset, not merely touching, as matplotlib's borderpad is. + widest = max(float(label.attrib["x"]) + _legend_text_width(label.text) for label in labels) + assert frame_right - widest > 0.0 + + +def test_legend_column_width_measures_glyphs_not_character_count(): + """A flat per-character average cannot bound a proportional face.""" + # "m" is far wider than the average and "l" far narrower, yet a character + # count scores these two identically -- which is exactly the bug. + assert _legend_text_width("mmmmm") > 5 * _LEGEND_CHAR_WIDTH + assert _legend_text_width("lllll") < 5 * _LEGEND_CHAR_WIDTH + assert _legend_text_width("gamma") > _legend_text_width("alpha") + + plot = {"x": 0.0, "y": 0.0, "w": 560.0, "h": 400.0} + result = _legend_layout([{"name": "gamma"}], plot, {"loc": "upper right"}) + # The column is sized to the measured label, so the frame encloses text + # drawn at handle + gap with the border pad still to spare on the right. + text_x = result["column_offsets"][0] + result["handle"] + result["gap"] + assert text_x + _legend_text_width("gamma") <= result["box_w"] + + +def test_ellipsized_legend_label_fits_the_column_it_was_sized_for(): + """Truncation is measured too, so a shortened label cannot overrun either.""" + plot = {"x": 0.0, "y": 0.0, "w": 150.0, "h": 400.0} + names = ["Wmmmmmmmmmmmmmmmmmmmm", "iiiiiiiiiiiiiiiiiiii"] + result = _legend_layout([{"name": name} for name in names], plot, {"loc": "upper right"}) + + assert any(name.endswith("...") for name in result["names"]) + text_x = result["column_offsets"][0] + result["handle"] + result["gap"] + for rendered in result["names"]: + assert text_x + _legend_text_width(rendered) <= result["box_w"] + + +def test_titled_legend_frame_contains_its_title(): + """A title is ellipsized against measured width, so it stays in the frame. + + Regression: the title budget subtracted two border pads from a box that had + only been grown by one, so "Classes" over short entries lost two more + characters than it needed to -- "Cl..." where the merge-base rendered + "Cla...". Measuring the title's real extent more than restores it. + """ + plot = {"x": 0.0, "y": 0.0, "w": 560.0, "h": 400.0} + short = _legend_layout( + [{"name": name} for name in ("1", "2", "3", "4")], + plot, + {"loc": "lower left", "title": "Classes"}, + ) + # Whatever survives truncation fits between the two border pads, since the + # title is drawn at x + pad. + assert _legend_text_width(short["title"]) <= short["box_w"] - short["pad"] + # Strictly longer than the "Cl..." this branch produced before the fix, and + # than the "Cla..." the merge-base produced. + assert short["title"].startswith("Clas") + + # Given entries wide enough to carry it, the title is not truncated at all. + wide = _legend_layout( + [{"name": name} for name in ("alpha", "beta", "gamma")], + plot, + {"loc": "lower left", "title": "Classes"}, + ) + assert wide["title"] == "Classes" + + +def test_raster_legend_frame_strokes_all_four_sides(monkeypatch): + """The frame is a closed rectangle, like matplotlib's FancyBboxPatch. + + Regression: ``_rect_pts`` is four corners, so stroking it as an open + polyline painted top/right/bottom and silently dropped the left edge. + """ + recorded: list[tuple[list[tuple[float, float]], bool]] = [] + original_stroke = _raster._Cmd.stroke + + def record_stroke(self, pts, width, color, closed=False, dash=None): + recorded.append(([tuple(map(float, point)) for point in pts], bool(closed))) + return original_stroke(self, pts, width, color, closed=closed, dash=dash) + + monkeypatch.setattr(_raster._Cmd, "stroke", record_stroke) + + _, ax = plt.subplots(figsize=(4.2, 3.0)) + for name in ("alpha", "beta", "gamma"): + ax.plot([0, 1], [0, 1], label=name) + ax.legend(loc="upper right", frameon=True, edgecolor="black") + spec, blob = ax._build_chart(420, 300).figure().build_payload() + _width, _height, _compact, plot = layout(spec) + legend = _legend_layout( + [{"name": name} for name in ("alpha", "beta", "gamma")], plot, spec["legend"] + ) + _raster.render_raster(spec, blob, scale=1) + + corners = [ + (legend["x"], legend["y"]), + (legend["x"] + legend["box_w"], legend["y"]), + (legend["x"] + legend["box_w"], legend["y"] + legend["box_h"]), + (legend["x"], legend["y"] + legend["box_h"]), + ] + matches = [ + closed + for pts, closed in recorded + if len(pts) == 4 + and all( + abs(pts[index][axis] - corners[index][axis]) < 1e-6 + for index in range(4) + for axis in (0, 1) + ) + ] + assert matches, [pts for pts, _ in recorded if len(pts) == 4] + # Four corners stroked open would leave the closing left edge unpainted. + assert all(matches), "legend frame stroked as an open polyline (left edge missing)" diff --git a/tests/pyplot/test_marker_fidelity.py b/tests/pyplot/test_marker_fidelity.py index 716f87ec..9412818d 100644 --- a/tests/pyplot/test_marker_fidelity.py +++ b/tests/pyplot/test_marker_fidelity.py @@ -1,6 +1,13 @@ +from __future__ import annotations + import io +import re + +import numpy as np +import pytest import xy.pyplot as plt +from xy import _svg def teardown_function(): @@ -40,3 +47,19 @@ def test_matplotlib_marker_family_keeps_distinct_symbols_in_payload(): output = io.BytesIO() fig.savefig(output, format=format) assert output.tell() > 100 + + +@pytest.mark.parametrize( + ("symbol", "expected_width"), + (("diamond", 2**0.5 * 10), ("thin_diamond", 0.6 * 2**0.5 * 10)), +) +def test_svg_diamond_markers_match_matplotlib_path_extents( + symbol: str, expected_width: float +) -> None: + path = _svg._SYMBOL_BUILDERS[symbol](10.0, 20.0, 5.0) + coordinates = np.asarray( + [float(value) for value in re.findall(r"-?\d+(?:\.\d+)?", path)] + ).reshape(-1, 2) + + assert np.ptp(coordinates[:, 0]) == pytest.approx(expected_width, abs=0.01) + assert np.ptp(coordinates[:, 1]) == pytest.approx(2**0.5 * 10, abs=0.01) diff --git a/tests/pyplot/test_matplotlib_mismatch_regressions.py b/tests/pyplot/test_matplotlib_mismatch_regressions.py new file mode 100644 index 00000000..03698561 --- /dev/null +++ b/tests/pyplot/test_matplotlib_mismatch_regressions.py @@ -0,0 +1,110 @@ +from __future__ import annotations + +import numpy as np +import pytest + +import xy.pyplot as plt +from xy._figure import Figure + + +def test_axis_equal_before_fill_keeps_data_autoscaling() -> None: + _fig, ax = plt.subplots() + ax.axis("equal") + ax.fill([-3.0, 4.0, 1.0], [-2.0, 0.0, 5.0]) + + assert "domain" not in ax._axis["x"] + assert "domain" not in ax._axis["y"] + assert ax._entry_extent("x") == (-3.0, 4.0) + assert ax._entry_extent("y") == (-2.0, 5.0) + assert ax._aspect_bounds == pytest.approx((-3.35, 4.35, -2.35, 5.35)) + + +def test_barh_error_components_stay_on_the_requested_axes() -> None: + _fig, ax = plt.subplots() + ax.barh([0.0, 1.0], [3.0, 4.0], xerr=[0.2, 0.3], yerr=[0.4, 0.5]) + + errorbar = next(entry for entry in ax._entries if entry.get("factory") == "errorbar") + np.testing.assert_allclose(errorbar["kwargs"]["xerr"], [0.2, 0.3]) + np.testing.assert_allclose(errorbar["kwargs"]["yerr"], [0.4, 0.5]) + + +def test_direct_bar_and_mesh_strokes_match_each_face_without_extra_color_data() -> None: + rgba = np.array([[1.0, 0.0, 0.0, 0.4], [0.0, 0.0, 1.0, 0.8]]) + bars = Figure().bar([0.0, 1.0], [2.0, 3.0], color=rgba, stroke_width=[1.0, 2.0]) + bar_spec = bars.build_payload()[0]["traces"][0] + assert bar_spec["stroke"] == {"mode": "match_fill"} + bar_svg = bars.to_svg() + assert 'stroke="rgb(255,0,0)"' in bar_svg + assert 'stroke="rgb(0,0,255)"' in bar_svg + + mesh = Figure().triangle_mesh( + [0.0, 2.0], + [0.0, 0.0], + [1.0, 3.0], + [0.0, 0.0], + [0.0, 2.0], + [1.0, 1.0], + color=rgba, + stroke_width=[1.0, 2.0], + ) + mesh_spec = mesh.build_payload()[0]["traces"][0] + assert mesh_spec["stroke"] == {"mode": "match_fill"} + mesh_svg = mesh.to_svg() + assert 'stroke="rgb(255,0,0)"' in mesh_svg + assert 'stroke="rgb(0,0,255)"' in mesh_svg + + +def test_imshow_interpolates_truecolor_and_honors_rgba_stage() -> None: + _fig, ax = plt.subplots() + rgb = np.zeros((2, 2, 3), dtype=float) + rgb[0, 0] = 1.0 + truecolor = ax.imshow(rgb, interpolation="bilinear") + assert np.asarray(truecolor._entry["z"]).shape == (512, 512, 3) + + _fig, (data_ax, rgba_ax) = plt.subplots(1, 2) + values = np.array([[0.0, 1.0], [1.0, 0.0]]) + data_image = data_ax.imshow( + values, cmap="viridis", interpolation="bilinear", interpolation_stage="data" + ) + rgba_image = rgba_ax.imshow( + values, cmap="viridis", interpolation="bilinear", interpolation_stage="rgba" + ) + assert np.asarray(data_image._entry["z"]).shape == (512, 512) + assert np.asarray(rgba_image._entry["z"]).shape == (512, 512, 4) + + +def test_named_imshow_filters_are_not_all_bilinear_aliases() -> None: + values = np.array([[0.0, 0.0, 0.0, 0.0], [0.0, 1.0, 1.0, 0.0]] * 2) + _fig, (linear_ax, lanczos_ax) = plt.subplots(1, 2) + linear = np.asarray(linear_ax.imshow(values, interpolation="bilinear")._entry["z"]) + lanczos = np.asarray(lanczos_ax.imshow(values, interpolation="lanczos")._entry["z"]) + assert not np.allclose(linear, lanczos) + + +def test_imshow_interpolation_does_not_spread_one_nan_over_the_image() -> None: + values = np.arange(9.0).reshape(3, 3) + values[0, 0] = np.nan + _fig, ax = plt.subplots() + interpolated = np.asarray(ax.imshow(values, interpolation="bilinear")._entry["z"]) + assert np.isfinite(interpolated).any() + assert np.isfinite(interpolated[-1, -1]) + + +def test_regular_gouraud_pcolormesh_uses_a_smooth_scalar_surface() -> None: + _fig, ax = plt.subplots() + values = np.arange(15.0).reshape(3, 5) + artist = ax.pcolormesh( + np.arange(5.0), + np.arange(3.0), + values, + shading="gouraud", + vmin=0.0, + vmax=14.0, + ) + assert artist._entry["factory"] == "heatmap" + smooth = np.asarray(artist._entry["args"][0]) + assert smooth.shape == (256, 256) + assert np.unique(smooth).size > values.size + + with pytest.raises(ValueError, match="matching shapes"): + ax.pcolormesh(np.arange(6.0), np.arange(4.0), values, shading="gouraud") diff --git a/tests/pyplot/test_mesh_autoscale_regressions.py b/tests/pyplot/test_mesh_autoscale_regressions.py new file mode 100644 index 00000000..90eaa48b --- /dev/null +++ b/tests/pyplot/test_mesh_autoscale_regressions.py @@ -0,0 +1,267 @@ +"""The pre-build autoscale scan must recognize every factory the shim emits. + +`Axes._iter_entry_arrays` feeds `_axis_is_dataless`, and a populated axes that +scans as dataless gets pinned to the empty ``(0, 1)`` view in `_build_chart` — +clipping the real geometry. Mesh, image, ECDF, and box entries keep their +coordinates inside ``kwargs`` rather than as top-level ``x``/``y``, so each +needs an explicit branch. These lock every one of them in place. +""" + +from __future__ import annotations + +import numpy as np +import pytest + +import xy.pyplot as plt + + +@pytest.fixture(autouse=True) +def _clean(): + plt.close("all") + plt.rcdefaults() + yield + plt.close("all") + plt.rcdefaults() + + +def _rendered(ax, which: str) -> tuple[float, float]: + figure = ax._build_chart(640, 480).figure() + return figure.x_range() if which == "x" else figure.y_range() + + +def _assert_contains(view: tuple[float, float], lo: float, hi: float) -> None: + span = max(abs(lo), abs(hi), 1.0) + tolerance = span * 1e-12 + assert view[0] <= lo + tolerance, f"{view} clips data low edge {lo}" + assert view[1] >= hi - tolerance, f"{view} clips data high edge {hi}" + + +def test_hist2d_view_contains_every_bin() -> None: + """The reported defect: 30x30 bins computed, ~4x3 of them visible.""" + rng = np.random.default_rng(1701) + x, y = rng.multivariate_normal([0, 0], [[1, 1], [1, 2]], 10_000).T + _fig, ax = plt.subplots() + + counts, xedges, yedges, _image = ax.hist2d(x, y, bins=30) + + assert counts.shape == (30, 30) + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + # Matplotlib gives hist2d sticky edges: the view is exactly the bin edges. + assert ax.get_xlim() == pytest.approx((xedges[0], xedges[-1])) + assert ax.get_ylim() == pytest.approx((yedges[0], yedges[-1])) + _assert_contains(_rendered(ax, "x"), xedges[0], xedges[-1]) + _assert_contains(_rendered(ax, "y"), yedges[0], yedges[-1]) + + +def test_hist2d_explicit_range_is_not_pinned_to_the_unit_view() -> None: + rng = np.random.default_rng(0) + _fig, ax = plt.subplots() + + _counts, xedges, yedges, _image = ax.hist2d( + rng.normal(size=500), rng.normal(size=500), bins=10, range=((-3, 3), (-2, 2)) + ) + + assert (xedges[0], xedges[-1]) == pytest.approx((-3.0, 3.0)) + assert ax.get_xlim() == pytest.approx((-3.0, 3.0)) + assert ax.get_ylim() == pytest.approx((-2.0, 2.0)) + _assert_contains(_rendered(ax, "x"), xedges[0], xedges[-1]) + _assert_contains(_rendered(ax, "y"), yedges[0], yedges[-1]) + + +def test_hist2d_irregular_bins_take_the_mesh_path_and_still_autoscale() -> None: + """Non-uniform bins delegate to pcolormesh; both paths must autoscale.""" + rng = np.random.default_rng(0) + xedges = np.array([-4.0, -1.0, 0.0, 1.0, 4.0]) + yedges = np.array([-4.0, 0.0, 1.0, 4.0]) + _fig, ax = plt.subplots() + + ax.hist2d(rng.normal(size=500), rng.normal(size=500), bins=[xedges, yedges]) + + assert not ax._axis_is_dataless("x") + assert ax.get_xlim() == pytest.approx((xedges[0], xedges[-1])) + assert ax.get_ylim() == pytest.approx((yedges[0], yedges[-1])) + assert _rendered(ax, "x") == pytest.approx((xedges[0], xedges[-1])) + assert _rendered(ax, "y") == pytest.approx((yedges[0], yedges[-1])) + + +def test_pcolormesh_uniform_grid_hugs_its_outer_cell_edges() -> None: + z = np.random.default_rng(1).normal(size=(25, 30)) + _fig, ax = plt.subplots() + + ax.pcolormesh(np.linspace(0.0, 5.0, 31), np.linspace(0.0, 5.0, 26), z) + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + assert ax.get_xlim() == pytest.approx((0.0, 5.0)) + assert ax.get_ylim() == pytest.approx((0.0, 5.0)) + # Sticky on both ends, so no margin is added to a mesh. + assert _rendered(ax, "x") == pytest.approx((0.0, 5.0)) + assert _rendered(ax, "y") == pytest.approx((0.0, 5.0)) + + +def test_pcolormesh_two_dimensional_coordinates_autoscale() -> None: + grid_x, grid_y = np.meshgrid(np.linspace(0.0, 5.0, 30), np.linspace(0.0, 5.0, 25)) + _fig, ax = plt.subplots() + + ax.pcolormesh(grid_x, grid_y, np.sin(grid_x)[:-1, :-1]) + + assert not ax._axis_is_dataless("x") + _assert_contains(_rendered(ax, "x"), 0.0, 5.0) + _assert_contains(_rendered(ax, "y"), 0.0, 5.0) + + +def test_pcolormesh_without_coordinates_uses_implicit_integer_edges() -> None: + """Matplotlib's pcolormesh(C) occupies edges 0..N and 0..M.""" + _fig, ax = plt.subplots() + + ax.pcolormesh(np.arange(12.0).reshape(3, 4)) + + assert not ax._axis_is_dataless("x") + assert ax.get_xlim() == pytest.approx((0.0, 4.0)) + assert ax.get_ylim() == pytest.approx((0.0, 3.0)) + + +def test_specgram_axes_are_not_pinned_to_the_unit_view() -> None: + rng = np.random.default_rng(0) + _fig, ax = plt.subplots() + + _power, frequency, time, _image = ax.specgram(rng.normal(size=4096), NFFT=256, Fs=2.0) + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + half_time_bin = float(time[1] - time[0]) * 0.5 + assert ax.get_xlim() == pytest.approx( + (float(time[0]) - half_time_bin, float(time[-1]) + half_time_bin) + ) + assert ax.get_ylim() == pytest.approx((float(frequency[0]), float(frequency[-1]))) + assert _rendered(ax, "x") == pytest.approx(ax.get_xlim()) + assert _rendered(ax, "y") == pytest.approx(ax.get_ylim()) + + +def test_imshow_explicit_extent_stays_flush_with_the_image_edges() -> None: + _fig, ax = plt.subplots() + + ax.imshow(np.arange(12.0).reshape(3, 4), extent=(0.0, 4.0, 0.0, 3.0), aspect="auto") + + assert ax.get_xlim() == pytest.approx((0.0, 4.0)) + assert ax.get_ylim() == pytest.approx((0.0, 3.0)) + assert _rendered(ax, "x") == pytest.approx((0.0, 4.0)) + assert _rendered(ax, "y") == pytest.approx((0.0, 3.0)) + + +def test_ecdf_spans_its_samples_and_sticks_to_zero_and_one() -> None: + _fig, ax = plt.subplots() + + ax.ecdf(np.array([1.0, 2.0, 3.0, 4.0])) + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + # Matplotlib: x carries the ordinary 5% margin, y is sticky at 0 and 1. + assert ax.get_xlim() == pytest.approx((0.85, 4.15)) + assert ax.get_ylim() == pytest.approx((0.0, 1.0)) + _assert_contains(_rendered(ax, "x"), 1.0, 4.0) + assert _rendered(ax, "y") == pytest.approx((0.0, 1.0)) + + +@pytest.mark.parametrize( + ("kwargs", "sample_axis", "cumulative_axis"), + [ + ({"weights": [1.0, 2.0, 3.0, 4.0]}, "x", "y"), + ({"complementary": True}, "x", "y"), + ({"compress": True}, "x", "y"), + ({"orientation": "horizontal"}, "y", "x"), + ], +) +def test_nondefault_ecdf_variants_autoscale_and_keep_cumulative_axis_sticky( + kwargs: dict[str, object], sample_axis: str, cumulative_axis: str +) -> None: + _fig, ax = plt.subplots() + + ax.ecdf(np.array([1.0, 2.0, 3.0, 4.0]), **kwargs) + + assert not ax._axis_is_dataless(sample_axis) + assert not ax._axis_is_dataless(cumulative_axis) + assert (ax.get_xlim() if cumulative_axis == "x" else ax.get_ylim()) == pytest.approx((0.0, 1.0)) + assert _rendered(ax, cumulative_axis) == pytest.approx((0.0, 1.0)) + + +def test_ordinary_step_factory_contributes_both_axes_to_autoscale() -> None: + _fig, ax = plt.subplots() + + ax.step([10.0, 20.0, 30.0], [-4.0, 2.0, 8.0]) + + assert ax.get_xlim() == pytest.approx((9.0, 31.0)) + assert ax.get_ylim() == pytest.approx((-4.6, 8.6)) + + +def test_boxplot_value_axis_covers_whiskers_and_fliers() -> None: + rng = np.random.default_rng(0) + left, right = rng.normal(size=2000), rng.normal(size=2000) + _fig, ax = plt.subplots() + + ax.boxplot([left, right]) + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + assert ax.get_xlim() == pytest.approx((0.5, 2.5)) + # Fliers are drawn, so the value axis reaches the extreme observations. + _assert_contains(_rendered(ax, "y"), float(min(left.min(), right.min())), 0.0) + _assert_contains(_rendered(ax, "y"), 0.0, float(max(left.max(), right.max()))) + + +def test_boxplot_without_fliers_tightens_to_the_whiskers() -> None: + rng = np.random.default_rng(0) + values = rng.normal(size=2000) + _fig, ax = plt.subplots() + + ax.boxplot([values], showfliers=False) + + rendered = _rendered(ax, "y") + assert rendered[0] > values.min() + assert rendered[1] < values.max() + assert not ax._axis_is_dataless("y") + + +def test_horizontal_boxplot_swaps_which_axis_carries_the_values() -> None: + rng = np.random.default_rng(0) + values = rng.normal(size=500) + _fig, ax = plt.subplots() + + ax.boxplot([values], orientation="horizontal") + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + assert ax.get_ylim() == pytest.approx((0.5, 1.5)) + _assert_contains( + _rendered(ax, "x"), float(np.percentile(values, 25)), float(np.percentile(values, 75)) + ) + + +def test_boxplot_custom_positions_reserve_half_unit_category_edges() -> None: + rng = np.random.default_rng(0) + _fig, ax = plt.subplots() + + ax.boxplot([rng.normal(size=100), rng.normal(size=100)], positions=[2.0, 4.0]) + + assert ax.get_xlim() == pytest.approx((1.5, 4.5)) + assert _rendered(ax, "x") == pytest.approx((1.5, 4.5)) + + +def test_mesh_entries_do_not_make_bar_baselines_sticky_on_both_ends() -> None: + """Guard the `_fully_sticky_domain` narrowing: bars keep their margin. + + A one-sided sticky edge is the rectangle baseline, which the core anchors + itself; materializing a domain for it would bypass the engine's autorange. + """ + _fig, ax = plt.subplots() + ax.bar([0.0, 1.0, 2.0], [1.0, 3.0, 2.0]) + + chart = ax._build_chart(640, 480) + axes = { + child.which: child + for child in chart.children + if getattr(child, "which", None) in {"x", "y"} + } + assert axes["y"].domain is None + assert axes["y"].margin == pytest.approx(0.05) diff --git a/tests/pyplot/test_p3_option_contracts.py b/tests/pyplot/test_p3_option_contracts.py index 3b78f346..596e2be3 100644 --- a/tests/pyplot/test_p3_option_contracts.py +++ b/tests/pyplot/test_p3_option_contracts.py @@ -1,6 +1,7 @@ from __future__ import annotations from datetime import datetime, timedelta +from typing import Any import numpy as np import pytest @@ -36,7 +37,6 @@ def test_plot_marker_styles_and_markevery_reach_marker_entry() -> None: (lambda ax: ax.fill_betweenx([0, 1], [0, 1], step="pre"), "step"), (lambda ax: ax.arrow(0, 0, 1, 1, shape="left"), "head shape"), (lambda ax: ax.errorbar([0], [1], yerr=0.2, barsabove=True), "barsabove"), - (lambda ax: ax.imshow([[1]], interpolation_stage="rgba"), "interpolation_stage"), (lambda ax: ax.psd([1, 2, 3], window=np.ones(3)), "window"), ], ) @@ -172,7 +172,6 @@ def _stream_args() -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: (lambda ax: ax.pie([1, 2], rotatelabels=True), "rotatelabels"), (lambda ax: ax.pie([1, 2], hatch="//"), "hatch"), (lambda ax: ax.pie([1, 2], wedgeprops={"hatch": "x"}), "hatch"), - (lambda ax: ax.quiver([0, 1], [0, 1], [1, 0], [0, 1], units="xy"), "units"), (lambda ax: ax.quiver([0, 1], [0, 1], [1, 0], [0, 1], headwidth=6), "headwidth"), (lambda ax: ax.quiver([0, 1], [0, 1], [1, 0], [0, 1], headlength=2), "headlength"), (lambda ax: ax.quiver([0, 1], [0, 1], [1, 0], [0, 1], headaxislength=2), "headaxislength"), @@ -181,44 +180,18 @@ def _stream_args() -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: (lambda ax: ax.quiver([0, 1], [0, 1], [1, 0], [0, 1], norm=Normalize(0, 1)), "norm"), (lambda ax: ax.quiver([0, 1], [0, 1], [1, 0], [0, 1], clim=(0, 1)), "clim"), (lambda ax: ax.quiver([0, 1], [0, 1], [1, 0], [0, 1], zorder=3), "zorder"), - (lambda ax: ax.barbs([0, 1], [0, 1], [1, 0], [0, 1], length=9), "length"), - (lambda ax: ax.barbs([0, 1], [0, 1], [1, 0], [0, 1], fill_empty=True), "fill_empty"), - (lambda ax: ax.barbs([0, 1], [0, 1], [1, 0], [0, 1], rounding=False), "rounding"), - (lambda ax: ax.barbs([0, 1], [0, 1], [1, 0], [0, 1], flip_barb=True), "flip_barb"), - (lambda ax: ax.barbs([0, 1], [0, 1], [1, 0], [0, 1], sizes={"spacing": 0.2}), "sizes"), - (lambda ax: ax.barbs([0, 1], [0, 1], [1, 0], [0, 1], barbcolor="red"), "barbcolor"), - (lambda ax: ax.barbs([0, 1], [0, 1], [1, 0], [0, 1], flagcolor="red"), "flagcolor"), - ( - lambda ax: ax.barbs([0, 1], [0, 1], [1, 0], [0, 1], barb_increments={"half": 3}), - "barb_increments", - ), - (lambda ax: ax.contour(_Z, origin="lower"), "origin"), (lambda ax: ax.contour(_Z, linestyles="dashed"), "linestyles"), - (lambda ax: ax.contourf(_Z, corner_mask=False), "corner_mask"), (lambda ax: ax.contourf(_Z, corner_mask="legacy"), "corner_mask"), (lambda ax: ax.streamplot(*_stream_args(), transform="data"), "transform"), (lambda ax: ax.streamplot(*_stream_args(), zorder=2), "zorder"), (lambda ax: ax.streamplot(*_stream_args(), minlength=0.5), "minlength"), - ( - lambda ax: ax.streamplot(*_stream_args(), broken_streamlines=False), - "broken_streamlines", - ), (lambda ax: ax.streamplot(*_stream_args(), arrowstyle="->"), "arrowstyle"), - ( - lambda ax: ax.streamplot(*_stream_args(), integration_max_step_scale=2.0), - "integration_max_step_scale", - ), - ( - lambda ax: ax.streamplot(*_stream_args(), integration_max_error_scale=0.5), - "integration_max_error_scale", - ), (lambda ax: ax.pcolormesh(_Z, antialiased=False), "antialiased"), (lambda ax: ax.pcolor(_Z, antialiased=False), "antialiased"), (lambda ax: ax.table(cellText=[["a"]], cellLoc="center"), "cellLoc"), (lambda ax: ax.table(cellText=[["a"]], rowLoc="center"), "rowLoc"), (lambda ax: ax.table(cellText=[["a"]], colLoc="left"), "colLoc"), (lambda ax: ax.table(cellText=[["a"]], loc="top"), "loc"), - (lambda ax: ax.stem([0, 1], [1, 2], basefmt="k-"), "basefmt"), ( lambda ax: ax.quiverkey(_quiver(ax), 0.5, 0.5, 1, "k", fontproperties={"size": 9}), "fontproperties", @@ -259,10 +232,6 @@ def _stream_args() -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: lambda ax: ax.tricontour([0, 1, 2], [0, 1, 0], [1.0, 2.0, 3.0], norm=LogNorm()), r"tricontour\(norm=LogNorm\)", ), - ( - lambda ax: ax.pie_label(ax.pie([1.0, 2.0]), "{frac:.0%}", rotate=True), - "rotate", - ), ], ) def test_p3_options_are_rejected_instead_of_silently_discarded(call, match: str) -> None: @@ -304,6 +273,126 @@ def test_matplotlib_default_option_values_pass_through() -> None: assert ax._entries +def test_quiver_units_control_width_without_changing_vector_length() -> None: + _fig, ax = plt.subplots() + width_units = ax.quiver([0, 10], [0, 10], [1, 0], [0, 1], units="width", width=0.02, scale=1) + x_units = ax.quiver([0, 10], [0, 10], [1, 0], [0, 1], units="x", width=0.02, scale=1) + np.testing.assert_allclose(width_units._entry["args"][0], x_units._entry["args"][0]) + np.testing.assert_allclose(width_units._entry["args"][2], x_units._entry["args"][2]) + assert width_units._entry["kwargs"]["width"] > x_units._entry["kwargs"]["width"] + + +def test_barbs_use_fixed_staffs_and_matplotlib_tail_decomposition() -> None: + _fig, ax = plt.subplots() + ax.barbs( + np.arange(5.0), + np.zeros(5), + [0, 5, 10, 50, 65], + np.zeros(5), + length=8, + fill_empty=True, + rounding=False, + ) + segments = ax._entries[0] + triangles = ax._entries[1] + assert segments["factory"] == "segments" + assert triangles["factory"] == "triangle_mesh" + # Empty circle (12), then half/full/flag/flag+full+half geometries. + assert len(segments["args"][0]) == 24 + assert len(triangles["args"][0]) == 14 # 12 circle wedges + two flags + x0, y0, x1, y1 = map(np.asarray, segments["args"]) + staff_indices = [12, 14, 16, 19] + staff_lengths = np.hypot( + x1[staff_indices] - x0[staff_indices], y1[staff_indices] - y0[staff_indices] + ) + np.testing.assert_allclose(staff_lengths, staff_lengths[0]) + + +def test_barbs_support_increment_flip_size_and_color_controls() -> None: + _fig, ax = plt.subplots() + ax.barbs( + [0, 1], + [0, 0], + [120, 40], + [0, 0], + barb_increments={"half": 10, "full": 20, "flag": 100}, + sizes={"spacing": 0.2, "height": 0.3, "emptybarb": 0.25}, + flip_barb=True, + barbcolor=["b", "g"], + flagcolor="r", + ) + segment_entries = [entry for entry in ax._entries if entry["factory"] == "segments"] + triangle_entries = [entry for entry in ax._entries if entry["factory"] == "triangle_mesh"] + assert {entry["kwargs"]["color"] for entry in segment_entries} == {"#0000ff", "#008000"} + assert triangle_entries[0]["kwargs"]["color"] == "#ff0000" + + +def test_barb_staff_length_is_screen_stable_across_subplot_grids() -> None: + def staff_pixels(fig: Any, ax: Any) -> float: + ax.barbs([0.0, 4.0], [0.0, 3.0], [50.0, 50.0], [0.0, 0.0]) + segments = next(entry for entry in ax._entries if entry["factory"] == "segments") + x0, y0, x1, y1 = (np.asarray(values) for values in segments["args"]) + figure_width, figure_height = fig._panel_px() + rects = fig._effective_rects() + if rects is None: + plot_width, plot_height = figure_width * 0.775, figure_height * 0.77 + else: + rect = rects[fig._axes.index(ax)] + total_width = figure_width * fig._ncols + total_height = figure_height * fig._nrows + plot_width, plot_height = total_width * rect[2], total_height * rect[3] + return float( + np.hypot( + (x1[0] - x0[0]) / 4.0 * plot_width, + (y1[0] - y0[0]) / 3.0 * plot_height, + ) + ) + + single_fig, single_ax = plt.subplots() + grid_fig, grid_axes = plt.subplots(2, 2) + np.testing.assert_allclose( + staff_pixels(single_fig, single_ax), + staff_pixels(grid_fig, grid_axes[0, 0]), + rtol=1e-12, + ) + + +def test_streamplot_integration_controls_drive_adaptive_step_size() -> None: + x = np.linspace(-1.0, 1.0, 30) + y = np.linspace(-1.0, 1.0, 30) + xx, yy = np.meshgrid(x, y) + + def segment_lengths(step_scale: float) -> np.ndarray: + _fig, ax = plt.subplots() + ax.streamplot( + x, + y, + -yy, + xx, + start_points=[[0.5, 0.0]], + broken_streamlines=False, + integration_max_step_scale=step_scale, + integration_max_error_scale=step_scale, + ) + entry = next(entry for entry in ax._entries if entry.get("factory") == "segments") + x0, y0, x1, y1 = map(np.asarray, entry["args"]) + return np.hypot(x1 - x0, y1 - y0) + + fine = segment_lengths(0.2) + coarse = segment_lengths(2.0) + assert np.median(fine) < np.median(coarse) + assert len(fine) > len(coarse) + + +def test_streamplot_accepts_gallery_autumn_colormap() -> None: + x = np.linspace(-1.0, 1.0, 8) + y = np.linspace(-1.0, 1.0, 8) + xx, yy = np.meshgrid(x, y) + _fig, ax = plt.subplots() + result = ax.streamplot(x, y, -yy, xx, color=xx, cmap="autumn") + assert result.lines._entry["kwargs"]["colormap"] == "autumn" + + def test_contour_extent_generates_coordinate_grids() -> None: _fig, ax = plt.subplots() ax.contour(np.arange(12.0).reshape(3, 4), extent=(0, 6, 10, 40)) @@ -312,6 +401,117 @@ def test_contour_extent_generates_coordinate_grids() -> None: np.testing.assert_allclose(entry["kwargs"]["y"], [10.0, 25.0, 40.0]) +def test_contour_origin_matches_image_pixel_centers() -> None: + _fig, ax = plt.subplots() + lower = ax.contour(_Z, origin="lower")._entry + upper = ax.contour(_Z, origin="upper", extent=(10, 14, 20, 26))._entry + + np.testing.assert_allclose(lower["kwargs"]["x"], [0.5, 1.5, 2.5, 3.5]) + np.testing.assert_allclose(lower["kwargs"]["y"], [0.5, 1.5, 2.5, 3.5]) + np.testing.assert_allclose(upper["kwargs"]["x"], [10.5, 11.5, 12.5, 13.5]) + # The native kernel requires increasing coordinates, so origin='upper' + # reverses the source rows while preserving Matplotlib's top-first visual. + np.testing.assert_allclose(upper["kwargs"]["y"], [20.75, 22.25, 23.75, 25.25]) + np.testing.assert_allclose(upper["source_z"], _Z[::-1]) + + +def test_contour_corner_mask_controls_missing_corner_geometry_and_is_inherited() -> None: + _fig, ax = plt.subplots() + z = np.array([[np.nan, 1.0], [0.0, 0.0]]) + masked = ax.contour(z, levels=[0.5], corner_mask=True) + assert masked._entry["corner_mask"] is True + + inherited = ax.contour(masked) + assert inherited._entry["corner_mask"] is True + explicit = ax.contour(z, levels=[0.5], corner_mask=False) + assert explicit._entry["corner_mask"] is False + + _fig2, ax2 = plt.subplots() + ax2.contour(z, levels=[0.5], corner_mask=True) + chart = ax2._build_chart(640, 480).figure() + contour_traces = [trace for trace in chart.traces if trace.kind == "contour"] + assert len(contour_traces) == 1 + + +def test_contourf_legend_elements_keep_per_band_hatches_and_handleheight() -> None: + _fig, ax = plt.subplots() + contour = ax.contourf( + _Z, + levels=[0.0, 5.0, 10.0, 15.0], + colors="none", + hatches=[".", "/", "\\"], + ) + handles, labels = contour.legend_elements(str_format="{:2.1f}".format) + assert len(handles) == len(labels) == 3 + assert len({id(handle) for handle in handles}) == 3 + assert [handle._entry["kwargs"]["hatch"] for handle in handles] == [".", "/", "\\"] + + ax.legend(handles, labels, handleheight=2, framealpha=1) + spec, _ = ax._build_chart(640, 480).figure().build_payload() + assert spec["legend"]["handleheight"] == 2.0 + assert [item["style"]["hatch"] for item in spec["legend"]["items"]] == [".", "/", "\\"] + assert all(item["kind"] == "bar" for item in spec["legend"]["items"]) + + +def test_plot_masked_integer_coordinates_use_nan_gaps() -> None: + _fig, ax = plt.subplots() + line = ax.plot( + np.ma.array([0, 1, 2], mask=[False, True, False]), + [3, 4, 5], + "ro", + )[0] + np.testing.assert_allclose(line.get_xdata()[[0, 2]], [0.0, 2.0]) + assert np.isnan(line.get_xdata()[1]) + + +def test_contour_solid_style_and_negative_rc_setting() -> None: + _fig, ax = plt.subplots() + explicit = ax.contour(_Z - 7.5, colors="black", linestyles="-") + assert explicit._entry["kwargs"]["dash_negative"] is False + + with plt.rc_context({"contour.negative_linestyle": "solid"}): + configured = ax.contour(_Z - 7.5, colors="black") + assert configured._entry["kwargs"]["dash_negative"] is False + + default = ax.contour(_Z - 7.5, colors="black") + assert default._entry["kwargs"]["dash_negative"] is True + + listed = ax.contourf(_Z, colors=("r", "g", "b")) + palette = np.asarray( + [ + [1.0, 0.0, 0.0, 1.0], + [0.0, 128 / 255, 0.0, 1.0], + [0.0, 0.0, 1.0, 1.0], + ] + ) + expected = palette[np.arange(len(listed.levels) - 1) % len(palette)] + np.testing.assert_allclose(listed._entry["kwargs"]["color"], expected) + assert listed._entry["kwargs"]["dash_negative"] is False + + +def test_contour_linewidths_cycle_by_level_and_artist_updates_preserve_arrays() -> None: + _fig, ax = plt.subplots() + contour = ax.contour( + np.arange(25.0).reshape(5, 5), + levels=[4, 8, 12, 16, 20], + colors="black", + linewidths=[0.5, 2.0], + ) + np.testing.assert_allclose(contour.get_linewidth(), [2 / 3, 8 / 3]) + contour.set_linewidth([1.0, 3.0, 2.0]) + np.testing.assert_allclose(contour.get_linewidth(), [1.0, 3.0, 2.0]) + + traces = ax._build_chart(640, 480).figure().traces + widths = np.concatenate( + [ + trace.style_channels["width"].values + for trace in traces + if trace.kind == "contour" and "width" in trace.style_channels + ] + ) + assert set(widths) == {1.0, 2.0, 3.0} + + def test_stem_dashed_linefmt_emits_dash_segments_and_markers() -> None: _fig, ax = plt.subplots() ax.stem([0, 1], [4, 8], linefmt="r--") diff --git a/tests/pyplot/test_pdsh_gap_features.py b/tests/pyplot/test_pdsh_gap_features.py index 62071dbe..2865ea96 100644 --- a/tests/pyplot/test_pdsh_gap_features.py +++ b/tests/pyplot/test_pdsh_gap_features.py @@ -223,6 +223,25 @@ def test_rdgy_and_jet_resolve_and_render(): _png() +@pytest.mark.parametrize( + ("name", "canonical"), + [ + ("Reds_r", "reds_r"), + ("bone", "bone"), + ("autumn", "autumn"), + ("winter", "winter"), + ("BuPu", "bupu"), + ], +) +def test_matplotlib_gallery_colormaps_resolve_and_render(name, canonical): + assert plt.get_cmap(name).name == canonical + assert plt.colormaps[name].name == canonical + assert getattr(plt.cm, name) == name + fig, ax = plt.subplots() + ax.imshow(np.arange(16.0).reshape(4, 4), cmap=name) + _png(fig) + + def test_linear_segmented_colormap_from_list_matches_anchors(): table = np.array([[0.0, 0.0, 0.0, 1.0], [1.0, 1.0, 1.0, 1.0]]) cmap = plt.LinearSegmentedColormap.from_list("g", table, 8) @@ -290,6 +309,40 @@ def test_colorbar_returns_handle_and_set_label_lands(): assert ax._colorbar["label"] == "counts in bin" +def test_colorbar_set_label_renders_rotated_beside_the_bar_in_both_exports(): + """PDSH ch. 4.05 (`hist2d`/`hexbin`/`imshow` + `set_label`) expects + Matplotlib's rotated label alongside a vertical colorbar. It used to render + horizontally above the bar, clipped off the top of the native PNG canvas.""" + from xy import _raster + + plt.subplots() + plt.hist2d(*np.random.default_rng(0).normal(size=(2, 200)), bins=10) + plt.colorbar().set_label("counts in bin") + + svg = _svg() + label = re.search(r']*rotate\(-90 [^>]*>counts in bin<', svg) + assert label is not None, "vertical colorbar label must be rotated -90 in SVG" + + recorded: list[tuple[float, float, int, str]] = [] + original_text = _raster._Cmd.text + + def record_text(self, x, y, anchor, size, color, value): + recorded.append((float(x), float(y), int(anchor), str(value))) + return original_text(self, x, y, anchor, size, color, value) + + _raster._Cmd.text = record_text + try: + _png() + finally: + _raster._Cmd.text = original_text + + native_x, native_y, anchor, _text = next( + entry for entry in recorded if entry[3] == "counts in bin" + ) + assert anchor == 1 | _raster._TEXT_ROT_CCW + assert (native_x, native_y) == (float(label.group(1)), float(label.group(2))) + + def test_colorbar_ticks_and_extend_reach_both_exports(): fig, ax = plt.subplots() image = plt.imshow(np.eye(4), cmap="viridis") diff --git a/tests/pyplot/test_rc_chrome_contracts.py b/tests/pyplot/test_rc_chrome_contracts.py index b8dbcf78..580cc25f 100644 --- a/tests/pyplot/test_rc_chrome_contracts.py +++ b/tests/pyplot/test_rc_chrome_contracts.py @@ -71,6 +71,10 @@ def test_legend_rc_defaults_reach_legend_component() -> None: "background": "yellow", "borderColor": "blue", "borderStyle": "solid", + "borderWidth": "1px", + "--xy-legend-frame-alpha": 0.8, + "padding": "0.4em", + "rowGap": "0.5em", } @@ -83,6 +87,7 @@ def test_rc_fonts_and_axis_strokes_scale_with_figure_dpi() -> None: assert built.chrome_styles["tick_label"]["font-size"] == "20px" assert built.axis_options["x"]["style"]["axis_width"] == pytest.approx(1.6) assert built.axis_options["x"]["style"]["tick_length"] == pytest.approx(7.0) + assert built.axis_options["x"]["style"]["tick_padding"] == pytest.approx(7.0) def test_spine_controls_and_invalid_cycle_boundaries() -> None: @@ -96,3 +101,67 @@ def test_spine_controls_and_invalid_cycle_boundaries() -> None: ax.spines[["top", "right"]].set_visible(False) spec, _ = ax._build_chart(640, 480).figure().build_payload() assert spec["frame_sides"] == ["bottom"] + + +def test_title_and_label_weight_rc_defaults_match_matplotlib() -> None: + # Matplotlib 3.11: axes.titleweight and axes.labelweight are both "normal". + assert plt.rcParams["axes.titleweight"] == "normal" + assert plt.rcParams["axes.labelweight"] == "normal" + + _fig, ax = plt.subplots() + ax.set_title("title") + ax.set_xlabel("x") + built = ax._build_chart(640, 480).figure() + + # "normal" is every renderer's own default, so it needs nothing on the + # wire — the browser, SVG, and raster paths all land on 400 unaided. + assert "font-weight" not in built.chrome_styles["title"] + assert "font-weight" not in built.chrome_styles["axis_title"] + assert "label_font_weight" not in built.axis_options["x"]["style"] + + +def test_title_and_label_weight_rc_overrides_reach_every_renderer() -> None: + with plt.rc_context({"axes.titleweight": "bold", "axes.labelweight": 700}): + _fig, ax = plt.subplots() + ax.set_title("title") + ax.set_xlabel("x") + ax.set_ylabel("y") + built = ax._build_chart(640, 480).figure() + svg = built.to_svg() + + # browser: the chrome slot styles the render client applies + assert built.chrome_styles["title"]["font-weight"] == "bold" + assert built.chrome_styles["axis_title"]["font-weight"] == "700" + # SVG + native raster read the weight off the axis style, not the chrome + # slots, so axes.labelweight has to be published in both places. + assert built.axis_options["x"]["style"]["label_font_weight"] == "700" + assert built.axis_options["y"]["style"]["label_font_weight"] == "700" + assert 'font-weight="bold"' in svg + assert 'font-weight="700"' in svg + + +def test_explicit_set_title_weight_still_beats_the_rc_default() -> None: + _fig, ax = plt.subplots() + ax.set_title("title", fontweight="bold") + ax.set_xlabel("x", fontweight="light") + built = ax._build_chart(640, 480).figure() + + assert built.chrome_styles["title"]["font-weight"] == "bold" + assert built.axis_options["x"]["style"]["label_font_weight"] == "light" + + +def test_spine_open_slice_targets_every_side_like_matplotlib() -> None: + _fig, ax = plt.subplots() + + ax.spines[:].set_visible(False) + + assert ax._hidden_spines == {"left", "bottom", "top", "right"} + + +def test_spine_tuple_and_partial_slice_raise_matplotlib_errors() -> None: + _fig, ax = plt.subplots() + + with pytest.raises(ValueError, match="single list"): + ax.spines["left", "right"] + with pytest.raises(ValueError, match=r"fully open slice \[:\]"): + ax.spines[1:] diff --git a/tests/pyplot/test_rc_color_export_contracts.py b/tests/pyplot/test_rc_color_export_contracts.py index 7e493aa7..7d743238 100644 --- a/tests/pyplot/test_rc_color_export_contracts.py +++ b/tests/pyplot/test_rc_color_export_contracts.py @@ -86,6 +86,7 @@ def test_savefig_file_objects_support_common_export_options() -> None: fig.savefig(tight, format="png", bbox_inches="tight", pad_inches=0) regular_size = struct.unpack(">II", regular.getvalue()[16:24]) tight_size = struct.unpack(">II", tight.getvalue()[16:24]) + assert regular_size == (320, 240) # a strict shrink on both axes: equality would mean tight-crop is a no-op assert tight_size[0] < regular_size[0] and tight_size[1] < regular_size[1] @@ -109,6 +110,8 @@ def dimensions(dpi: int) -> tuple[int, int]: low = dimensions(60) high = dimensions(120) + assert low == (240, 180) + assert high == (480, 360) assert high[0] == 2 * low[0] assert high[1] == 2 * low[1] assert fig.get_dpi() == 80 diff --git a/tests/pyplot/test_reference_semantics.py b/tests/pyplot/test_reference_semantics.py index cd4ee005..ad1a5afe 100644 --- a/tests/pyplot/test_reference_semantics.py +++ b/tests/pyplot/test_reference_semantics.py @@ -216,11 +216,11 @@ def _normalize_mask(mask: np.ndarray, size: int = 256) -> np.ndarray: @pytest.mark.parametrize("family", ["line", "bar", "image"]) def test_reference_pngs_have_tolerant_perceptual_and_geometry_agreement(family: str) -> None: - # xy rasterizes its 320x240 logical canvas at 2x. Render the Matplotlib - # reference at the same physical size and effective DPI so point-sized - # strokes, markers, and text remain comparable at 640x480. + # Both backends rasterize the 4x3-inch figure at the requested 80 DPI, so + # point-sized strokes, markers, and text are compared at the same physical + # size rather than hiding a pyplot-only 2x export scale in the reference. xyfig, xyax = xyplt.subplots(figsize=(4, 3), dpi=80) - mplfig, mplax = mplplt.subplots(figsize=(4, 3), dpi=160) + mplfig, mplax = mplplt.subplots(figsize=(4, 3), dpi=80) if family == "line": for ax in (xyax, mplax): ax.plot([0, 1, 2, 3], [0, 2, 1, 3], "o-", color="#2563eb", linewidth=2) @@ -236,9 +236,9 @@ def test_reference_pngs_have_tolerant_perceptual_and_geometry_agreement(family: ax.set_title("image") xybytes = xyfig._to_png() reference = BytesIO() - mplfig.savefig(reference, format="png", dpi=160) + mplfig.savefig(reference, format="png", dpi=80) xypixels, mplpixels = _png_pixels(xybytes), _png_pixels(reference.getvalue()) - assert xypixels.shape == mplpixels.shape == (480, 640, 4) + assert xypixels.shape == mplpixels.shape == (240, 320, 4) xymask, mplmask = _foreground_mask(xypixels), _foreground_mask(mplpixels) normalized_xy = _dilate(_normalize_mask(xymask)) normalized_mpl = _dilate(_normalize_mask(mplmask)) diff --git a/tests/pyplot/test_silent_drop_regressions.py b/tests/pyplot/test_silent_drop_regressions.py index 55e897e3..8ce3b34a 100644 --- a/tests/pyplot/test_silent_drop_regressions.py +++ b/tests/pyplot/test_silent_drop_regressions.py @@ -328,8 +328,8 @@ def test_savefig_svg_and_html_honor_facecolor_and_single_chart_suptitle(): def test_boxplot_component_styles_and_sym_are_honored_or_rejected(): _, ax = plt.subplots() - with pytest.raises(NotImplementedError, match="linestyle"): - ax.boxplot([[1.0, 2.0, 3.0, 4.0]], medianprops={"linestyle": "--"}) + dashed = ax.boxplot([[1.0, 2.0, 3.0, 4.0]], medianprops={"linestyle": "--"}) + assert len(dashed["medians"][0]._entry["args"][0]) > 1 # empty sym suppresses fliers like matplotlib data = [[1.0, 2.0, 3.0, 4.0, 50.0]] result = ax.boxplot(data, sym="") diff --git a/tests/pyplot/test_state_and_figs.py b/tests/pyplot/test_state_and_figs.py index 9039e7c7..2804866d 100644 --- a/tests/pyplot/test_state_and_figs.py +++ b/tests/pyplot/test_state_and_figs.py @@ -1,5 +1,6 @@ from __future__ import annotations +import struct from pathlib import Path import numpy as np @@ -91,12 +92,16 @@ def test_savefig_png_svg_html(tmp_path: Path) -> None: def test_grid_savefig_png_stitches(tmp_path: Path) -> None: - _fig, axes = plt.subplots(1, 2) + fig, axes = plt.subplots(1, 2) axes[0].plot([0, 1], [1, 2]) axes[1].bar(["a", "b"], [2, 1]) target = tmp_path / "grid.png" plt.savefig(target) - assert target.read_bytes().startswith(b"\x89PNG\r\n\x1a\n") + data = target.read_bytes() + assert data.startswith(b"\x89PNG\r\n\x1a\n") + assert struct.unpack(">II", data[16:24]) == tuple( + round(value * fig.get_dpi()) for value in fig.get_size_inches() + ) def test_add_axes_png_uses_native_facecolor_parser() -> None: diff --git a/tests/pyplot/test_visible_style_contracts.py b/tests/pyplot/test_visible_style_contracts.py index c8aa77fb..4d5e2a03 100644 --- a/tests/pyplot/test_visible_style_contracts.py +++ b/tests/pyplot/test_visible_style_contracts.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import pytest import xy.pyplot as plt @@ -7,16 +9,40 @@ def teardown_function(): plt.close("all") -def test_line_cap_and_gapcolor_mutations_fail_loudly(): +def test_line_cap_mutations_fail_loudly_and_gapcolor_round_trips(): _, ax = plt.subplots() - line = ax.plot([0, 1], [0, 1])[0] + line = ax.plot([0, 1], [0, 1], dashes=[4, 4])[0] with pytest.raises(NotImplementedError): - line.set_dash_capstyle("round") + line.set_dash_capstyle("butt") with pytest.raises(NotImplementedError): line.set_solid_capstyle("round") - with pytest.raises(NotImplementedError): - line.set_gapcolor("red") + line.set_gapcolor("red") + assert line.get_gapcolor() == "red" + line.set_gapcolor(None) + assert line.get_gapcolor() is None + + +def test_dashed_gapcolor_materializes_behind_one_named_foreground_trace() -> None: + _, ax = plt.subplots() + line = ax.plot( + [0, 1, 2], + [0, 1, 0], + dashes=[4, 4], + gapcolor="tab:pink", + color="tab:blue", + label="alternating", + )[0] + + assert line.get_gapcolor() == "#e377c2" + spec, _blob = ax._build_chart(640, 480).figure().build_payload() + assert [ + (trace["name"], trace["style"]["color"], trace["style"].get("dash")) + for trace in spec["traces"] + ] == [ + (None, "#e377c2", None), + ("alternating", "#1f77b4", [8.3333, 8.3333]), + ] def test_text_preserves_visible_font_alignment_and_rotation_style(): diff --git a/tests/test_axis_title_gutter.py b/tests/test_axis_title_gutter.py new file mode 100644 index 00000000..a2023556 --- /dev/null +++ b/tests/test_axis_title_gutter.py @@ -0,0 +1,248 @@ +"""The y-axis title must sit clear of the tick labels, on emitted geometry. + +`layout()` used to hand every chart a flat 46/62 px left gutter and +`_axis_label_geometry` used to anchor the rotated y title's *baseline* at a +10 px canvas inset — while ChartView centers its rotated line *box* on that same +inset. The two together drew the title one full ascent further left than the +browser does, off the canvas, on top of the tick labels whenever the gutter was +also short. Both are now measured from the DejaVu advances the rasterizer blits +(`python/xy/_fontmetrics.py`, generated from `src/font.rs`). + +Every assertion below reads the boxes back out of real emitted output — SVG text +coordinates, plus a pixel-ink scan of the native rasterizer's canvas — never out +of the layout helpers that produced them. +""" + +from __future__ import annotations + +import math +import re +from pathlib import Path +from xml.etree import ElementTree + +import numpy as np +import pytest + +import xy +from xy import _fontmetrics, _raster, _svg + +_ASCENT = _fontmetrics.ASCENT / _fontmetrics.BASE_PX +_DESCENT = _fontmetrics.DESCENT / _fontmetrics.BASE_PX + + +def _payload(chart): + return chart.figure().build_payload() + + +def _boxes(svg: str, plot: dict[str, float], title: str): + """(title ink span, [tick ink spans]) in horizontal px, from the SVG itself.""" + root = ElementTree.fromstring(svg) + title_box = None + ticks: list[tuple[str, float, float]] = [] + for element in root.iter(): + if not element.tag.endswith("text"): + continue + text = "".join(element.itertext()) + size = float(element.attrib.get("font-size", 12)) + x = float(element.attrib.get("x", 0)) + rotation = re.match(r"rotate\((-?[\d.]+)", element.attrib.get("transform", "")) + angle = float(rotation.group(1)) if rotation else 0.0 + if text == title and abs(abs(angle) - 90) < 0.5: + # A -90° turn points ascenders toward -x, descenders toward +x. + span = ( + (x - _ASCENT * size, x + _DESCENT * size) + if angle < 0 + else (x - _DESCENT * size, x + _ASCENT * size) + ) + title_box = span + elif not rotation and element.attrib.get("text-anchor") == "end" and x <= plot["x"]: + ticks.append((text, x - _fontmetrics.advance(text, size), x)) + assert title_box is not None, f"no rotated {title!r} title in the SVG" + # Every y tick label shares one anchor x; other end-anchored text left of + # the plot (annotations, legends) does not. + pin = max(box[2] for box in ticks) + ticks = [box for box in ticks if math.isclose(box[2], pin, abs_tol=0.01)] + return title_box, ticks + + +def _assert_clear(svg, plot, title, *, canvas_width): + title_box, ticks = _boxes(svg, plot, title) + assert ticks, "expected y tick labels" + tick_lo = min(box[1] for box in ticks) + tick_hi = max(box[2] for box in ticks) + overlap = min(title_box[1], tick_hi) - max(title_box[0], tick_lo) + assert overlap < 0, ( + f"y title {title_box} overlaps tick labels [{tick_lo}, {tick_hi}] by {overlap:.1f}px" + ) + assert title_box[1] < tick_lo, "the y title must sit outside the tick strip, not inside it" + assert title_box[0] > 0, f"y title ink starts at x={title_box[0]:.1f}, clipped by the viewport" + assert tick_lo > 0, f"tick ink starts at x={tick_lo:.1f}, clipped by the viewport" + assert tick_hi < canvas_width and title_box[1] < canvas_width + return title_box, (tick_lo, tick_hi) + + +def _first_ink_column(spec, blob, plot) -> int: + """Leftmost column of the native raster carrying non-background ink.""" + rgba = _raster.render_raster(spec, blob, 1.0) + assert isinstance(rgba, np.ndarray) + gutter = rgba[:, : int(plot["x"]) - 1, :3].astype(np.int16) + ink = np.abs(gutter - gutter[2, 2]).max(axis=2) > 24 + columns = np.where(ink.any(axis=0))[0] + assert columns.size, "expected axis text in the left gutter" + return int(columns.min()) + + +def _chart(*, y_label, y_values, width=760, height=420, padding=None, style=None, **axis): + """A minimal core (non-pyplot) line chart with a labeled y axis.""" + resolved = {"label_size": 14, "tick_label_size": 14} if style is None else style + return xy.line_chart( + xy.line(x=[float(index) for index in range(len(y_values))], y=list(y_values)), + xy.y_axis(label=y_label, style=resolved, **axis), + width=width, + height=height, + padding=padding, + ) + + +def test_wide_numeric_tick_labels_keep_the_y_title_clear() -> None: + chart = _chart(y_label="average daily births", y_values=[3_600_000.0, 5_400_000.5]) + spec, blob = _payload(chart) + _width, _height, _compact, plot = _svg.layout(spec) + svg = _svg.render_svg(spec, blob) + + title_box, tick_span = _assert_clear(svg, plot, "average daily births", canvas_width=760) + # The gutter grew past the 62 px default because the ink genuinely needs it. + assert plot["x"] > 62.0 + # Matplotlib 3.11.1 leaves 5.6 px between the title ink and the tick ink at + # its 13.89 px default; 0.4 em reproduces that ratio at any size. + assert tick_span[0] - title_box[1] == pytest.approx(0.4 * 14, abs=0.05) + assert _first_ink_column(spec, blob, plot) > 0 + + +def test_long_categorical_tick_labels_keep_the_y_title_clear() -> None: + categories = [f"Questionnaire item {index}" for index in range(1, 7)] + chart = xy.bar_chart( + xy.bar(x=categories, y=[10.0, 20.0, 30.0, 40.0, 50.0, 60.0], orientation="horizontal"), + xy.y_axis(label="survey question", style={"label_size": 14, "tick_label_size": 14}), + width=640, + height=480, + ) + spec, blob = _payload(chart) + _width, _height, _compact, plot = _svg.layout(spec) + svg = _svg.render_svg(spec, blob) + + _assert_clear(svg, plot, "survey question", canvas_width=640) + assert plot["x"] > 150.0, "long category names need far more than the 62 px default" + assert _first_ink_column(spec, blob, plot) > 0 + + +def test_authored_padding_too_narrow_for_the_text_still_reserves_the_gutter() -> None: + """An explicit `padding` is a floor, not a licence to clip. + + This is the shape of the pyplot notebook path, which pins + `padding=[15, 20, 34, 41]` to match Matplotlib's inline `bbox_inches` + footprint — 41 px is 27 px short of the ink it has to hold. + """ + chart = _chart( + y_label="average daily births", + y_values=[3600.0, 5400.0], + padding=[15.0, 20.0, 34.0, 41.0], + ) + spec, blob = _payload(chart) + assert spec["padding"] == [15.0, 20.0, 34.0, 41.0], "the authored padding still ships" + _width, _height, _compact, plot = _svg.layout(spec) + assert plot["x"] > 41.0, "the measured gutter has to win over a too-narrow authored one" + _assert_clear(_svg.render_svg(spec, blob), plot, "average daily births", canvas_width=760) + assert _first_ink_column(spec, blob, plot) > 0 + + +def test_ordinary_numeric_axis_keeps_the_default_gutter() -> None: + """The measured reservation is a floor: it must not inflate ordinary charts. + + Default 11 px ticks under a 12 px title fit inside 62 px, so a chart that + was laid out correctly before this change is laid out identically after it. + """ + chart = xy.line_chart( + xy.line(x=[0.0, 1.0, 2.0], y=[0.0, 1.0, 2.0]), + xy.y_axis(label="value"), + width=760, + height=420, + ) + spec, blob = _payload(chart) + _width, _height, _compact, plot = _svg.layout(spec) + assert plot["x"] == 62.0 + _assert_clear(_svg.render_svg(spec, blob), plot, "value", canvas_width=760) + + +def test_titleless_axis_reserves_only_its_tick_labels() -> None: + chart = xy.line_chart( + xy.line(x=[0.0, 1.0, 2.0], y=[1e9, 2e9, 3e9]), + xy.y_axis(style={"tick_label_size": 18}), + width=760, + height=420, + ) + spec, blob = _payload(chart) + _width, _height, _compact, plot = _svg.layout(spec) + svg = _svg.render_svg(spec, blob) + root = ElementTree.fromstring(svg) + lefts = [ + float(element.attrib["x"]) - _fontmetrics.advance("".join(element.itertext()), 18.0) + for element in root.iter() + if element.tag.endswith("text") + and element.attrib.get("text-anchor") == "end" + and float(element.attrib.get("font-size", 0)) == 18.0 + ] + assert lefts and min(lefts) > 0, "wide tick labels must not fall off the canvas" + + +def test_python_font_metrics_match_the_rust_atlas() -> None: + """A gutter measured from advances the rasterizer does not use is a guess. + + `scripts/gen_font.py` emits `src/font.rs` and `python/xy/_fontmetrics.py` + from one face in one run. This pins them together so a regenerated atlas + cannot silently leave the reservation measuring a different font than the + one being drawn. + """ + source = (Path(__file__).resolve().parents[1] / "src" / "font.rs").read_text() + + def constant(name: str) -> int: + match = re.search(rf"pub const {name}: (?:u8|i32) = (\d+);", source) + assert match, f"src/font.rs lost its {name}" + return int(match.group(1)) + + assert constant("BASE_PX") == _fontmetrics.BASE_PX + assert constant("CELL_H") == _fontmetrics.CELL_H + assert constant("ASCENT") == _fontmetrics.ASCENT + assert _fontmetrics.CELL_H - _fontmetrics.ASCENT == _fontmetrics.DESCENT + + body = re.search(r"GLYPHS: \[\(.*?\); \d+\] = \[\s*(.*?)\n\];", source, re.S) + assert body + advances = [int(value) for value in re.findall(r"\(\s*(-?\d+),", body.group(1))] + first, last = constant("FIRST"), constant("LAST") + ascii_count = last - first + 1 + for index, expected in enumerate(advances[:ascii_count]): + char = chr(first + index) + assert _fontmetrics.advance(char, float(_fontmetrics.BASE_PX)) == expected, ( + f"advance drift for {char!r}" + ) + + extra = re.search(r"EXTRA_CODEPOINTS: \[u32; \d+\] = \[\s*(.*?)\s*\];", source, re.S) + assert extra + codepoints = [int(v) for v in extra.group(1).replace("\n", "").split(",") if v.strip()] + assert len(codepoints) + ascii_count == len(advances) + for offset, codepoint in enumerate(codepoints): + expected = advances[ascii_count + offset] + got = _fontmetrics.advance(chr(codepoint), float(_fontmetrics.BASE_PX)) + assert got == expected, f"advance drift for U+{codepoint:04X}" + + +def test_hidden_tick_labels_do_not_reserve_tick_room() -> None: + chart = _chart( + y_label="value", + y_values=[3600.0, 5400.0], + style={"label_size": 14, "tick_label_size": 14}, + tick_label_strategy="none", + ) + spec, _blob = _payload(chart) + _width, _height, _compact, plot = _svg.layout(spec) + assert plot["x"] == 62.0 diff --git a/tests/test_components.py b/tests/test_components.py index 7faab1e5..32bb9ea4 100644 --- a/tests/test_components.py +++ b/tests/test_components.py @@ -1579,6 +1579,32 @@ def test_component_axis_types_emit_log_domain_reverse_and_format(): assert spec["y_axis"]["style"] == {"axis_color": "#dc2626", "label_size": 13} +def test_component_axis_margin_controls_automatic_range(): + chart = xy.chart( + xy.line(x=np.array([0.0, 10.0]), y=np.array([2.0, 4.0])), + xy.x_axis(margin=0.1), + xy.y_axis(margin=0.0), + ) + + assert chart.figure().x_range() == pytest.approx((-1.0, 11.0)) + assert chart.figure().y_range() == pytest.approx((2.0, 4.0)) + with pytest.raises(ValueError, match="x_axis margin"): + xy.x_axis(margin=-0.1) + with pytest.raises(ValueError, match="y_axis margin"): + xy.y_axis(margin=np.nan) + + +def test_component_axis_margin_controls_singleton_range(): + chart = xy.chart( + xy.line(x=np.array([5.0]), y=np.array([1.0])), + xy.x_axis(margin=0.0), + xy.y_axis(margin=0.1), + ) + + assert chart.figure().x_range() == pytest.approx((5.0, 6.0)) + assert chart.figure().y_range() == pytest.approx((0.9, 2.1)) + + def test_component_axis_label_position_controls_emit_to_payload(): chart = xy.chart( xy.scatter(x=np.arange(3.0), y=np.arange(3.0)), diff --git a/tests/test_css_mark_styles.py b/tests/test_css_mark_styles.py index 156d1e35..941026e8 100644 --- a/tests/test_css_mark_styles.py +++ b/tests/test_css_mark_styles.py @@ -172,6 +172,7 @@ def test_axis_style_reaches_svg_and_native_renderers() -> None: "axis_color": "#0000ff", "axis_width": 2, "tick_length": 6, + "tick_padding": 5, "tick_width": 2, "tick_color": "#00aa00", "tick_label_color": "#cc5500", @@ -187,7 +188,9 @@ def test_axis_style_reaches_svg_and_native_renderers() -> None: assert 'stroke="#0000ff" stroke-width="2"' in svg assert 'stroke="#00aa00" stroke-width="2"' in svg assert 'fill="#cc5500" font-size="13" text-anchor="middle"' in svg - assert 'font-size="15" font-weight="500" fill="#aa00aa"' in svg + # 400 is the matplotlib-parity axis-label default; this style sets no + # `label_font_weight`, so the default is what lands in the SVG. + assert 'font-size="15" font-weight="400" fill="#aa00aa"' in svg assert _raster.render_raster(*fig.build_payload(), scale=1).shape[-1] == 4 @@ -196,6 +199,7 @@ def test_axis_style_is_normalized_and_rejected_before_render() -> None: style={ "grid-width": "3px", "tick_label_size": "13px", + "tick-label-pad": "5px", "tick-direction": "inout", "tick-label-anchor": "right", # mpl `ha` alias -> canonical "end" "label-color": "rebeccapurple", @@ -204,6 +208,7 @@ def test_axis_style_is_normalized_and_rejected_before_render() -> None: assert axis.style == { "grid_width": 3.0, "tick_label_size": 13.0, + "tick_padding": 5.0, "tick_direction": "inout", "tick_label_anchor": "end", "label_color": "rebeccapurple", diff --git a/tests/test_kernels.py b/tests/test_kernels.py index 83200e70..b7b8ec7b 100644 --- a/tests/test_kernels.py +++ b/tests/test_kernels.py @@ -514,6 +514,20 @@ def test_marching_squares_skips_nonfinite_cells_and_empty_levels(impl): assert all(len(values) == 0 for values in empty) +def test_marching_squares_corner_mask_keeps_only_the_valid_triangle(impl): + z = np.array([[np.nan, 1.0], [0.0, 0.0]]) + args = (z, np.array([0.0, 1.0]), np.array([0.0, 1.0]), np.array([0.5])) + discarded = impl.marching_squares(*args, corner_mask=False) + assert all(len(values) == 0 for values in discarded) + + x0, x1, y0, y1, emitted_levels = impl.marching_squares(*args, corner_mask=True) + np.testing.assert_allclose(np.minimum(x0, x1), [0.5]) + np.testing.assert_allclose(np.maximum(x0, x1), [1.0]) + np.testing.assert_allclose(y0, [0.5]) + np.testing.assert_allclose(y1, [0.5]) + np.testing.assert_allclose(emitted_levels, [0.5]) + + # -- chart-prep kernels ------------------------------------------------------- diff --git a/tests/test_png_export.py b/tests/test_png_export.py index 1dc18f0e..e491ed50 100644 --- a/tests/test_png_export.py +++ b/tests/test_png_export.py @@ -553,6 +553,80 @@ def test_native_named_axis_collision_and_title_placement_controls(monkeypatch) - assert title_anchor == 2 | _raster._TEXT_ROT_CW +def test_native_vertical_colorbar_label_is_rotated_beside_the_bar_inside_the_canvas( + monkeypatch, +) -> None: + """A vertical colorbar's label must match Matplotlib: rotated 90° CCW, + centered alongside the bar and outboard of its ticks, fully on canvas. + + It previously rendered horizontally above the bar at `plot.y - 5`, so the + glyph ascent overflowed the canvas top edge and the label was clipped. + """ + from xy import _svg + + chart = xy.heatmap_chart( + xy.heatmap([[0.0, 1.0], [2.0, 3.0]], colormap="viridis", domain=(0.0, 3.0)), + xy.colorbar(title="counts in bin"), + width=560, + height=320, + ) + spec, blob = chart.figure().build_payload() + width, _height, _compact, plot = _svg.layout(spec) + recorded = _record_text(monkeypatch) + _raster.render_raster(spec, blob, scale=1) + + label_x, label_y, anchor, size, _text = next( + entry for entry in recorded if entry[4] == "counts in bin" + ) + # Rotated bottom-to-top (mpl rotation=90), centered along the reading axis. + assert anchor == 1 | _raster._TEXT_ROT_CCW + assert label_y == plot["y"] + plot["h"] / 2 + # Beside the bar, past every tick label — not above the bar. + tick_x = max(entry[0] for entry in recorded if entry[4] in {"0", "1", "2", "3"}) + assert label_x > tick_x + assert plot["y"] < label_y < plot["y"] + plot["h"] + # Inside the canvas across the rotated label's baseline: the glyph box + # spans [x - ascent, x + descent] (ascent ~0.78em, descent ~0.22em). + assert label_x + 0.22 * size < width + + +def test_native_vertical_colorbar_label_leaves_the_canvas_edges_unpainted() -> None: + """The clipping symptom itself: no label ink may reach the canvas border.""" + chart = xy.heatmap_chart( + xy.heatmap([[0.0, 1.0], [2.0, 3.0]], colormap="viridis", domain=(0.0, 3.0)), + xy.colorbar(title="counts in bin"), + width=560, + height=320, + ) + pixels = _decode_rgba(chart.to_png()) + ink = pixels[:, :, :3].astype(int).sum(axis=2) < 200 + assert not ink[0].any() and not ink[-1].any() + assert not ink[:, 0].any() and not ink[:, -1].any() + + +def test_native_horizontal_colorbar_label_stays_upright_below_the_bar(monkeypatch) -> None: + """The horizontal orientation reads left-to-right, so it must not rotate.""" + from xy import _svg + + chart = xy.heatmap_chart( + xy.heatmap([[0.0, 1.0], [2.0, 3.0]], colormap="viridis", domain=(0.0, 3.0)), + xy.colorbar(title="counts in bin", orientation="horizontal"), + width=560, + height=320, + ) + spec, blob = chart.figure().build_payload() + _width, _height, _compact, plot = _svg.layout(spec) + recorded = _record_text(monkeypatch) + _raster.render_raster(spec, blob, scale=1) + + label_x, label_y, anchor, _size, _text = next( + entry for entry in recorded if entry[4] == "counts in bin" + ) + assert anchor & (_raster._TEXT_ROT_CCW | _raster._TEXT_ROT_CW) == 0 + assert label_x == plot["x"] + plot["w"] / 2 + assert label_y > plot["y"] + plot["h"] + + def test_native_diagonal_tick_angle_keeps_all_labels_when_they_fit(monkeypatch) -> None: # The native glyph protocol only rotates in quarter-turns, so a diagonal # tick_label_angle falls back to horizontal strategy="hide" — which must @@ -729,6 +803,15 @@ def test_affine_static_scatter_full_render_matches_expanded(monkeypatch) -> None stroke="#111827", stroke_width=0.5, ), + Figure(width=360, height=220).scatter( + x, + y, + color="transparent", + size=9, + symbol="diamond", + stroke="#666666", + stroke_width=1.0, + ), Figure(width=360, height=220).scatter(x, y, color=color_values, colormap="plasma"), Figure(width=360, height=220).scatter(x, y, color=categories), Figure(width=360, height=220).scatter( @@ -915,3 +998,165 @@ def test_scatter_direct_edges_with_colormap_c_render_in_png() -> None: opacity=1.0, ) assert _dark_pixel_count(fig.to_png(width=300, height=200)) > 200 + + +def _text_commands(monkeypatch, chart) -> dict[str, tuple[float, float]]: + """``{text: (x, y)}`` for every text op the raster display list emits.""" + emitted: dict[str, tuple[float, float]] = {} + original = _raster._Cmd.text + + def record(self, x, y, anchor, size, color, s): + emitted[str(s)] = (x, y) + return original(self, x, y, anchor, size, color, s) + + monkeypatch.setattr(_raster._Cmd, "text", record) + _raster.render_raster(*chart.figure().build_payload(), scale=1) + return emitted + + +def _tick_geometry_chart(style=None) -> xy.Chart: + """A 3x3 tick grid with a pinned plot rect, so offsets are exact integers.""" + return xy.chart( + xy.line([0.0, 1.0, 2.0], [0.0, 1.0, 0.5]), + xy.x_axis(domain=(0.0, 2.0), tick_values=[0.0, 1.0, 2.0], style=style), + xy.y_axis(domain=(0.0, 1.0), tick_values=[0.0, 0.5, 1.0], style=style), + width=400, + height=300, + padding=(40, 50, 40, 50), + ) + + +def test_unstyled_tick_labels_keep_their_historical_raster_placement(monkeypatch) -> None: + """The native display list must place unstyled tick labels where it always + has. + + `tick_padding` derives the spine-to-label gap from tick geometry, but + core's default `tick_length` is 0, so deriving it unconditionally silently + pulls every unstyled chart's labels toward the spine — see + `_axis_tick_label_offset`. The 15 px bottom gap is one pixel tighter than + the SVG exporter's 16 and has always been; this seam does not reconcile it. + """ + plot = _raster.layout(_tick_geometry_chart().figure().build_payload()[0])[3] + assert (plot["x"], plot["y"], plot["w"], plot["h"]) == (50.0, 40.0, 300.0, 220.0) + + unstyled = _text_commands(monkeypatch, _tick_geometry_chart()) + # x, bottom: baseline 15 px below the spine, centered on the tick. + assert unstyled["0"] == (50.0, 275.0) + assert unstyled["1"] == (200.0, 275.0) + assert unstyled["2"] == (350.0, 275.0) + # y, left: 8 px outside the spine, baseline nudged 4 px below the tick. + assert unstyled["0.0"] == (42.0, 264.0) + assert unstyled["0.5"] == (42.0, 154.0) + assert unstyled["1.0"] == (42.0, 44.0) + + # Flat constants, as before `tick_padding`: the tick font must not move them. + big_font = _text_commands(monkeypatch, _tick_geometry_chart(style={"tick_size": 20})) + assert big_font["0"] == unstyled["0"] + assert big_font["1.0"] == unstyled["1.0"] + + +def test_authored_tick_geometry_moves_raster_labels_off_the_spine(monkeypatch) -> None: + """Authored geometry takes matplotlib's rule in the raster path too, and + lands on the same coordinates the SVG exporter uses.""" + styled = _text_commands( + monkeypatch, _tick_geometry_chart(style={"tick_length": 6, "tick_padding": 5}) + ) + # 6 px outward tick + 5 px pad = 11 px, then 0.8 * the 11 px font to the baseline. + assert styled["0"] == (50.0, 279.8) + # y: 11 px outside the spine, baseline centered on 0.35 * the font size. + assert styled["0.0"] == (39.0, 263.85) + + +def mixed_anchor_legend_spec() -> tuple[dict, bytes]: + """A figure carrying one anchored and one bounded legend box.""" + spec, blob = Figure().line([0.0, 1.0], [0.0, 1.0], name="a").build_payload() + spec["show_legend"] = False + spec["extra_legends"] = [ + { + "title": "anchored", + "loc": "lower left", + "anchor": [0.0, 1.0], + "items": [{"name": "outside", "kind": "line", "style": {}}], + }, + { + "title": "bounded", + "loc": "upper right", + "items": [{"name": "inside", "kind": "line", "style": {}}], + }, + ] + return spec, blob + + +def test_raster_scopes_the_legend_clip_exemption_per_legend(monkeypatch) -> None: + """An anchored legend is exempt from the plot-rect clip that bounds static + legends, but the exemption is that legend's alone (parity with `_svg.py`): + one anchored box must not lift the clip off its non-anchored siblings.""" + spec, blob = mixed_anchor_legend_spec() + _width, _height, _compact, plot = _raster.layout(spec) + plot_rect = (plot["x"], plot["y"], plot["w"], plot["h"]) + + events: list[tuple[str, object]] = [] + original_clip = _raster._Cmd.clip + original_legend = _raster._emit_legend + + def record_clip(self, x, y, w, h): + events.append(("clip", (float(x), float(y), float(w), float(h)))) + return original_clip(self, x, y, w, h) + + def record_legend(cmd, named, legend_plot, options, text_color=_raster._TEXT): + events.append(("legend", options.get("title"))) + return original_legend(cmd, named, legend_plot, options, text_color) + + monkeypatch.setattr(_raster._Cmd, "clip", record_clip) + monkeypatch.setattr(_raster, "_emit_legend", record_legend) + _raster.render_raster(spec, blob, scale=1) + + # The clip is stateful in the command stream, so the rectangle in force for + # a legend is the last clip recorded before that legend's emission. + in_force: dict[str, tuple[float, ...]] = {} + current: tuple[float, ...] | None = None + for kind, value in events: + if kind == "clip": + assert isinstance(value, tuple) + current = value + else: + assert isinstance(value, str) + assert current is not None, "legend emitted before any clip was set" + in_force[value] = current + + assert set(in_force) == {"anchored", "bounded"} + assert in_force["bounded"] == plot_rect + assert in_force["anchored"] != plot_rect # the full-frame chrome clip + + +def test_raster_uniform_anchor_legends_keep_their_whole_frame_clip_decision( + monkeypatch, +) -> None: + """The per-legend scoping must not change the all-anchored or the + none-anchored figure: one keeps no plot-rect clip, the other keeps one.""" + original_clip = _raster._Cmd.clip + + def plot_clips(anchors: list[list[float] | None]) -> int: + spec, blob = mixed_anchor_legend_spec() + for extra, anchor in zip(spec["extra_legends"], anchors, strict=True): + if anchor is None: + extra.pop("anchor", None) + else: + extra["anchor"] = anchor + _width, _height, _compact, plot = _raster.layout(spec) + rect = (plot["x"], plot["y"], plot["w"], plot["h"]) + seen: list[tuple[float, ...]] = [] + + def record_clip(self, x, y, w, h): + seen.append((float(x), float(y), float(w), float(h))) + return original_clip(self, x, y, w, h) + + monkeypatch.setattr(_raster._Cmd, "clip", record_clip) + _raster.render_raster(spec, blob, scale=1) + monkeypatch.undo() + # The marks pass clips to the plot rect too; the legend pass is the + # only source of a second one. + return seen.count(rect) - 1 + + assert plot_clips([[0.0, 1.0], [0.0, 1.0]]) == 0 + assert plot_clips([None, None]) == 1 diff --git a/tests/test_static_client_security.py b/tests/test_static_client_security.py index 2f6e5f05..e6a113b2 100644 --- a/tests/test_static_client_security.py +++ b/tests/test_static_client_security.py @@ -698,6 +698,9 @@ def test_client_axis_tick_labels_have_collision_layout() -> None: "tick_label_angle", "tick_label_anchor", "tick_label_min_gap", + '"tick_padding"', + "const tick = tickParts(xAxis)", + "tick.outward", ) for path, text in CLIENT_FILES: @@ -801,6 +804,7 @@ def test_client_renders_mark_level_styling() -> None: "xySmoothResample(", # monotone cubic (Fritsch–Carlson) "xyMonotoneTangents(", "xyMarkerSdf(d, u_symbol)", # scatter symbol shapes (circle/square/diamond/triangle/cross) + "symbolScale = symbol == 2 || symbol == 14", # mpl diamond paths exceed marker box by sqrt(2) "_pointMarkStyle(", # point stroke + symbol resolution "rgb = mix(rgb, sc.rgb, sc.a);", # selected/unselected recolor (mark_style) "v_dash = mix(a_len0, mix(a_len0, a_len1, reveal), c.x);", # fractional reveal preserves line dashes diff --git a/tests/test_svg_export.py b/tests/test_svg_export.py index ec25bba3..7c076f06 100644 --- a/tests/test_svg_export.py +++ b/tests/test_svg_export.py @@ -12,8 +12,16 @@ import pytest import xy +from xy import channels from xy._figure import Figure -from xy._svg import COLORMAP_STOPS, _axis_tick_label_layout, _Scale +from xy._svg import ( + COLORMAP_STOPS, + _axis_tick_label_layout, + _colormap_stops, + _Scale, + layout, + render_svg, +) ROOT = Path(__file__).resolve().parents[1] @@ -103,6 +111,29 @@ def test_svg_honors_tick_label_anchor() -> None: assert 'text-anchor="end"' in default_svg +def test_svg_tick_padding_starts_after_the_outward_tick() -> None: + from xy import _svg + + chart = xy.line_chart( + xy.line(x=[0.0, 1.0], y=[0.0, 1.0]), + xy.x_axis( + tick_values=(0.5,), + tick_labels=("middle",), + style={"tick_length": 6, "tick_padding": 5, "tick_label_size": 10}, + ), + width=300, + height=200, + ) + spec, _blob = chart.figure().build_payload() + _width, _height, _compact, plot = _svg.layout(spec) + root = _parse(chart.figure().to_svg()) + label = next(node for node in root.iter() if node.text == "middle") + + # SVG text y is its baseline. The label's top begins after the 6 px + # outward tick plus the independent 5 px Matplotlib-style pad. + assert float(label.get("y", "nan")) == pytest.approx(plot["y"] + plot["h"] + 6 + 5 + 8) + + def test_svg_tick_label_anchor_collision_parity() -> None: """Anchor-aware collision model matches JS _tickLabelsCollide. @@ -384,6 +415,59 @@ def test_svg_vertical_colorbar_clears_right_named_axis_chrome() -> None: assert float(bar.get("x", "nan")) > plot["x"] + plot["w"] + 40 +def test_svg_vertical_colorbar_label_is_rotated_beside_the_bar_inside_the_canvas() -> None: + """SVG places a vertical colorbar's label like Matplotlib — rotated 90° CCW, + centered beside the bar, on canvas — and the native PNG exporter must agree + on the baseline so the two static paths cannot drift apart.""" + from xy import _raster, _svg + + chart = xy.heatmap_chart( + xy.heatmap([[0.0, 1.0], [2.0, 3.0]], colormap="viridis", domain=(0.0, 3.0)), + xy.colorbar(title="counts in bin"), + width=560, + height=320, + ) + fig = chart.figure() + spec, blob = fig.build_payload() + width, _height, _compact, plot = _svg.layout(spec) + root = _parse(fig.to_svg()) + + label = next(node for node in root.iter() if node.text == "counts in bin") + label_x, label_y = float(label.get("x", "nan")), float(label.get("y", "nan")) + bar = next( + node for node in root.iter() if (node.get("fill") or "").startswith("url(#xy-colorbar-") + ) + bar_x, bar_w = float(bar.get("x", "nan")), float(bar.get("width", "nan")) + + # Rotated a quarter turn counter-clockwise about its own anchor. + assert label.get("transform") == f"rotate(-90 {label_x:g} {label_y:g})" + assert label.get("text-anchor") == "middle" + # Beside the bar and centered on it, never above it. + assert label_x > bar_x + bar_w + assert label_y == plot["y"] + plot["h"] / 2 + # Inside the canvas the labeled colorbar reserved room for. + assert label_x < width + + # The native PNG exporter shares this baseline. + recorded: list[tuple[float, float, int, float, str]] = [] + original_text = _raster._Cmd.text + + def record_text(self, x, y, anchor, size, color, value): + recorded.append((float(x), float(y), int(anchor), float(size), str(value))) + return original_text(self, x, y, anchor, size, color, value) + + _raster._Cmd.text = record_text + try: + _raster.render_raster(spec, blob, scale=1) + finally: + _raster._Cmd.text = original_text + native_x, native_y, anchor, _size, _text = next( + entry for entry in recorded if entry[4] == "counts in bin" + ) + assert (native_x, native_y) == (label_x, label_y) + assert anchor == 1 | _raster._TEXT_ROT_CCW + + def test_svg_colorbar_clears_primary_right_axis_and_bottom_axis_chrome() -> None: from xy import _svg @@ -684,6 +768,84 @@ def test_colormap_stops_stay_in_sync_with_js_client() -> None: assert f"[{r}, {g}, {b}]" in body, ( f"{name} stop ({r},{g},{b}) missing in 10_colormaps.ts" ) + assert set(COLORMAP_STOPS) == set(channels.COLORMAPS), ( + "renderer and public colormap registries diverged" + ) + + +def test_matplotlib_gallery_colormap_stops_and_reversal() -> None: + expected = { + "reds": [ + (255, 245, 240), + (254, 229, 216), + (253, 202, 181), + (252, 171, 143), + (252, 138, 106), + (251, 105, 74), + (241, 68, 50), + (217, 37, 35), + (188, 20, 26), + (152, 12, 19), + (103, 0, 13), + ], + "bone": [ + (0, 0, 0), + (22, 22, 30), + (45, 45, 62), + (66, 66, 93), + (89, 92, 121), + (112, 123, 144), + (134, 154, 166), + (157, 185, 188), + (185, 210, 210), + (221, 233, 233), + (255, 255, 255), + ], + "autumn": [ + (255, 0, 0), + (255, 25, 0), + (255, 51, 0), + (255, 76, 0), + (255, 102, 0), + (255, 128, 0), + (255, 153, 0), + (255, 179, 0), + (255, 204, 0), + (255, 230, 0), + (255, 255, 0), + ], + "winter": [ + (0, 0, 255), + (0, 25, 242), + (0, 51, 230), + (0, 76, 217), + (0, 102, 204), + (0, 128, 191), + (0, 153, 178), + (0, 179, 166), + (0, 204, 153), + (0, 230, 140), + (0, 255, 128), + ], + "bupu": [ + (247, 252, 253), + (229, 239, 246), + (204, 221, 236), + (178, 202, 225), + (154, 180, 214), + (140, 149, 198), + (140, 116, 181), + (138, 81, 165), + (133, 45, 144), + (118, 12, 113), + (77, 0, 75), + ], + } + for name, stops in expected.items(): + assert COLORMAP_STOPS[name] == stops + assert channels.is_colormap(name) + assert channels.is_colormap(f"{name}_r") + assert _colormap_stops(f"{name}_r") == list(reversed(stops)) def test_scalar_stroke_color_survives_vectorized_style_path() -> None: @@ -731,3 +893,158 @@ def test_segment_constant_translucent_color_applies_alpha_once() -> None: entry for entry in re.findall(r"]*/>", opaque) if 'stroke="red"' in entry ] assert opaque_lines, "opaque constant color should pass through verbatim" + + +def _tick_label_positions(svg: str) -> dict[str, tuple[float, float]]: + """``{label text: (x, y)}`` for every ```` node in an export.""" + return { + match.group(3): (float(match.group(1)), float(match.group(2))) + for match in re.finditer(r']*>([^<]*)', svg) + } + + +def _geometry_chart(side_x: str = "bottom", side_y: str = "left", style=None) -> xy.Chart: + """A 3x3 tick grid with a pinned plot rect, so offsets are exact integers.""" + return xy.chart( + xy.line([0.0, 1.0, 2.0], [0.0, 1.0, 0.5]), + xy.x_axis(domain=(0.0, 2.0), tick_values=[0.0, 1.0, 2.0], side=side_x, style=style), + xy.y_axis(domain=(0.0, 1.0), tick_values=[0.0, 0.5, 1.0], side=side_y, style=style), + width=400, + height=300, + padding=(40, 50, 40, 50), + ) + + +def test_unstyled_tick_labels_keep_their_historical_svg_placement() -> None: + """A chart that authors no tick styling places its tick labels at the exact + pixels it always has. + + `tick_padding` derives the spine-to-label gap from tick geometry, but + core's default `tick_length` is 0, so deriving it unconditionally silently + pulls every unstyled chart's labels toward the spine. The per-side unstyled + defaults in `_axis_tick_label_offset` exist to prevent that, and these are + the literal numbers they have to reproduce. + """ + plot = layout(_geometry_chart().figure().build_payload()[0])[3] + assert (plot["x"], plot["y"], plot["w"], plot["h"]) == (50.0, 40.0, 300.0, 220.0) + + bottom_left = _tick_label_positions(_geometry_chart().to_svg()) + # x, bottom: baseline 16 px below the spine, centered on the tick. + assert bottom_left["0"] == (50.0, 276.0) + assert bottom_left["1"] == (200.0, 276.0) + assert bottom_left["2"] == (350.0, 276.0) + # y, left: 8 px outside the spine, baseline nudged 4 px below the tick. + assert bottom_left["0.0"] == (42.0, 264.0) + assert bottom_left["0.5"] == (42.0, 154.0) + assert bottom_left["1.0"] == (42.0, 44.0) + + flipped = _geometry_chart(side_x="top", side_y="right") + top_plot = layout(flipped.figure().build_payload()[0])[3] + assert (top_plot["x"], top_plot["y"], top_plot["w"], top_plot["h"]) == ( + 50.0, + 66.0, + 258.0, + 194.0, + ) + top_right = _tick_label_positions(flipped.to_svg()) + # x, top: baseline 7 px above the spine. y, right: 8 px outside it. + assert top_right["0"] == (50.0, 59.0) + assert top_right["2"] == (308.0, 59.0) + assert top_right["0.0"] == (316.0, 264.0) + assert top_right["1.0"] == (316.0, 70.0) + + +def test_unstyled_tick_label_placement_ignores_the_tick_font_size() -> None: + """The unstyled gaps are flat constants, as they were before + `tick_padding` existed: a bigger tick font must not move the labels, + because scaling the gap with the font belongs to the authored rule.""" + plain = _tick_label_positions(_geometry_chart().to_svg()) + big = _tick_label_positions(_geometry_chart(style={"tick_size": 20}).to_svg()) + assert big["0"] == plain["0"] + assert big["1.0"] == plain["1.0"] + + +def test_authored_tick_geometry_moves_the_labels_off_the_spine() -> None: + """Authoring `tick_length`/`tick_padding` switches to matplotlib's rule: + padding measured from the outward end of the tick mark, with the anchor + then clearing the glyph box.""" + styled = _tick_label_positions( + _geometry_chart(style={"tick_length": 6, "tick_padding": 5}).to_svg() + ) + # 6 px outward tick + 5 px pad = 11 px, then 0.8 * the 11 px font to the baseline. + assert styled["0"] == (50.0, 279.8) + # y: 11 px outside the spine, baseline centered on 0.35 * the font size. + assert styled["0.0"] == (39.0, 263.85) + + # tick_direction decides how much of tick_length counts as outward. + inward = _tick_label_positions( + _geometry_chart( + style={"tick_length": 6, "tick_padding": 5, "tick_direction": "in"} + ).to_svg() + ) + assert inward["0.0"] == (45.0, 263.85) + halfway = _tick_label_positions( + _geometry_chart( + style={"tick_length": 6, "tick_padding": 5, "tick_direction": "inout"} + ).to_svg() + ) + assert halfway["0.0"] == (42.0, 263.85) + + # A pad alone opts in; tick_length then contributes its default 0. + pad_only = _tick_label_positions(_geometry_chart(style={"tick_padding": 5}).to_svg()) + assert pad_only["0.0"] == (45.0, 263.85) + + +def test_tick_label_offset_defaults_stay_in_sync_with_js_client() -> None: + """`tickLabelOffset` in 50_chartview.ts is the third implementation of this + rule and carries its own unstyled per-side gaps (the client positions a + label's box, not its baseline, so its numbers differ from the exporters'). + Pin them at the source: this suite has no browser.""" + js = (ROOT / "js" / "src" / "50_chartview.ts").read_text(encoding="utf-8") + body = js.split("const tickLabelOffset = (axis, unstyled, fontRoom = 0) => {", 1) + assert len(body) == 2, "tickLabelOffset signature changed; re-check the unstyled gaps" + assert 'this._axisStyleValue(axis, "tick_padding") !== undefined' in body[1] + assert 'this._axisStyleValue(axis, "tick_length") !== undefined' in body[1] + assert "if (!authored) return unstyled;" in body[1] + # x bottom 6, x top 18 (plus its own line box), y 8 — unchanged since before + # tick_padding existed. Primary and extra axes each have one call site. + assert js.count("tickLabelOffset(xAxis, 6)") == 1 + assert js.count("tickLabelOffset(axis, 6)") == 1 + assert js.count("tickLabelOffset(xAxis, 18, Math.max(8, tickLabelSize) * 1.2)") == 1 + assert js.count("tickLabelOffset(axis, 18, Math.max(8, tickLabelSize) * 1.2)") == 1 + assert js.count("tickLabelOffset(axis, 8)") == 1 + + +def test_svg_scopes_the_legend_clip_exemption_per_legend() -> None: + """An anchored legend escapes the plot-rect clip that bounds static + legends; a non-anchored sibling in the same figure must still be clipped + (the native raster exporter mirrors this).""" + spec, blob = Figure().line([0.0, 1.0], [0.0, 1.0], name="a").build_payload() + spec["show_legend"] = False + spec["extra_legends"] = [ + { + "title": "anchored", + "loc": "lower left", + "anchor": [0.0, 1.0], + "items": [{"name": "outside", "kind": "line", "style": {}}], + }, + { + "title": "bounded", + "loc": "upper right", + "items": [{"name": "inside", "kind": "line", "style": {}}], + }, + ] + + svg = render_svg(spec, blob) + groups = { + title: match + for title, match in ( + (title, match) + for match in re.findall(r"]*)?>(?:(?!", svg, re.S) + for title in ("anchored", "bounded") + if f">{title}" in match + ) + } + assert set(groups) == {"anchored", "bounded"}, "both legend boxes should render" + assert "clip-path=" not in groups["anchored"].split(">", 1)[0] + assert "clip-path=" in groups["bounded"].split(">", 1)[0] diff --git a/tests/test_text_weight_defaults.py b/tests/test_text_weight_defaults.py new file mode 100644 index 00000000..615a0779 --- /dev/null +++ b/tests/test_text_weight_defaults.py @@ -0,0 +1,201 @@ +"""Chrome text weight defaults must match Matplotlib, in every renderer. + +Matplotlib 3.11's `axes.titleweight`, `axes.labelweight` and `font.weight` all +default to `normal`, and its legend titles and colorbar labels are normal too. +So every xy chrome text default is 400, and the three renderers — the browser +render client (`js/src/`), the SVG exporter (`python/xy/_svg.py`) and the native +raster exporter (`python/xy/_raster.py`) — must agree on it. A renderer that +quietly drifts heavier is the bug these tests exist to catch. + +The TypeScript source guard is a source-level assertion on purpose: the render +client's bundles are a generated, git-ignored artifact, so a test that can only +read the bundle cannot run from a fresh checkout. +""" + +from __future__ import annotations + +import re +import struct +from pathlib import Path + +import pytest + +import xy +from xy import _raster + +_ROOT = Path(__file__).resolve().parents[1] +_JS = _ROOT / "js" / "src" + +# Native text-record header sizes, from `_Cmd.text` in python/xy/_raster.py. +# Both records end with `u32 byte_length` + UTF-8 payload, so a unique payload +# is an unambiguous anchor to walk back from. +# _TEXT_OP : op(1) x(4) y(4) anchor(1) size(4) rgba(4) len(4) = 22 +# _STYLED_TEXT : op(1) x(4) y(4) anchor(1) size(4) angle(4) flags(1) +# range_count(4) [range(8) * n] rgba(4) len(4) = 31 + 8n +_TEXT_OP_HEADER = 22 +_STYLED_HEADER = 31 + + +def _title_axis_legend_figure(**axis_style): + """A chart exercising title, both axis labels, legend title and annotation.""" + fig = xy.chart( + xy.line(x=[0.0, 1.0, 2.0], y=[1.0, 2.0, 1.5], name="series-a"), + xy.x_axis(label="XLABEL", style=axis_style or None), + xy.y_axis(label="YLABEL", style=axis_style or None), + title="TITLE", + ).figure() + fig.legend_options = {"title": "LEGENDTITLE"} + fig.text(1.0, 2.0, "ANNOTATION") + return fig + + +def _svg_text_weights(svg: str) -> dict[str, str]: + """Map each `` body to the `font-weight` the SVG exporter emitted.""" + weights: dict[str, str] = {} + for attrs, body in re.findall(r"]*)>(?:]*>)?([^<]*)", svg): + match = re.search(r'font-weight="([^"]+)"', attrs) + weights[body.strip()] = match.group(1) if match else "unset" + return weights + + +def _raster_stream(fig) -> bytes: + """The native command stream `to_png` hands to the Rust rasterizer.""" + captured: dict[str, object] = {} + original = _raster._Cmd.__init__ + + def spy(self, *args, **kwargs): + original(self, *args, **kwargs) + captured.setdefault("cmd", self) + + _raster._Cmd.__init__ = spy + try: + fig.to_png(scale=1) + finally: + _raster._Cmd.__init__ = original + return bytes(captured["cmd"].buf) # type: ignore[union-attr] + + +def _raster_text_bold(stream: bytes, text: str) -> bool: + """Whether the native record carrying `text` sets the bold emphasis flag.""" + payload = text.encode("utf-8") + at = stream.find(struct.pack("= 0, f"no native text record carries {text!r}" + body = at + 4 + styled = body - _STYLED_HEADER + if styled >= 0 and stream[styled] == _raster._STYLED_TEXT: + (ranges,) = struct.unpack("= 0 and stream[plain] == _raster._TEXT_OP, ( + f"record for {text!r} is neither a plain nor a styled text record" + ) + return False # the plain opcode carries no emphasis byte at all + + +# --- SVG exporter ---------------------------------------------------------- + + +def test_svg_chrome_text_defaults_to_normal_weight() -> None: + weights = _svg_text_weights(_title_axis_legend_figure().to_svg()) + + assert weights["TITLE"] == "400" + assert weights["XLABEL"] == "400" + assert weights["YLABEL"] == "400" + assert weights["LEGENDTITLE"] == "400" + # The annotation and legend-entry paths emit no weight at all, so they + # inherit the document's 400. Asserted so a later default cannot sneak in. + assert weights["ANNOTATION"] == "unset" + assert weights["series-a"] == "unset" + + +def test_svg_honors_an_explicit_heavier_axis_label_weight() -> None: + fig = _title_axis_legend_figure(label_font_weight="bold") + assert _svg_text_weights(fig.to_svg())["XLABEL"] == "bold" + + +def test_svg_honors_an_explicit_heavier_title_weight() -> None: + fig = _title_axis_legend_figure() + fig.chrome_styles["title"] = {"font-weight": "700"} + assert _svg_text_weights(fig.to_svg())["TITLE"] == "700" + + +# --- native raster exporter ------------------------------------------------ + + +def test_native_raster_chrome_text_carries_no_bold_by_default() -> None: + stream = _raster_stream(_title_axis_legend_figure()) + + for label in ("TITLE", "XLABEL", "YLABEL", "LEGENDTITLE", "ANNOTATION"): + assert not _raster_text_bold(stream, label), f"{label} is bold in the raster stream" + + +@pytest.mark.parametrize("weight", ["bold", "700", 800]) +def test_native_raster_emits_bold_only_when_asked(weight) -> None: + fig = _title_axis_legend_figure() + fig.chrome_styles["title"] = {"font-weight": weight} + stream = _raster_stream(fig) + + assert _raster_text_bold(stream, "TITLE") + # Opting the title in must not drag the axis labels along with it. + assert not _raster_text_bold(stream, "XLABEL") + + +def test_native_raster_and_svg_agree_on_the_axis_label_default() -> None: + fig = _title_axis_legend_figure() + svg_weight = _svg_text_weights(fig.to_svg())["XLABEL"] + raster_bold = _raster_text_bold(_raster_stream(fig), "XLABEL") + + assert svg_weight == "400" + assert raster_bold is False + + +# --- browser render client (source-level guard) ----------------------------- + +# Slot rules in js/src/20_theme.ts that carry chrome *text*. Each must declare +# 400, or declare nothing and inherit it. +_TEXT_SLOTS = ( + "title", + "axis_title", + "tick_label", + "legend", + "colorbar", + "colorbar_title", + "annotation_label", +) + + +def test_theme_css_chrome_text_slots_declare_normal_weight() -> None: + css = (_JS / "20_theme.ts").read_text(encoding="utf-8") + rules = dict(re.findall(r'data-xy-slot="(\w+)"\]\)\{([^}]*)\}', css)) + + for slot in _TEXT_SLOTS: + assert slot in rules, f"no `{slot}` slot rule in 20_theme.ts" + weight = re.search(r"font-weight:\s*([^;}]+)", rules[slot]) + assert weight is None or weight.group(1).strip() in {"400", "normal"}, ( + f'slot "{slot}" declares font-weight:{weight.group(1).strip()}; ' + "Matplotlib renders every chrome text element at normal weight" + ) + + +def test_chartview_inline_text_weights_are_all_normal() -> None: + """The inline axis-label/legend-title weights beat the slot stylesheet. + + They are written out at ten sites in `_axisLabelCss`/`_drawChrome`/ + `_legendBox`, so a guard on the stylesheet alone would not catch a drift + here. + """ + source = (_JS / "50_chartview.ts").read_text(encoding="utf-8") + + inline = set(re.findall(r"font-weight:\s*(\d+|normal|bold)", source)) + assert inline, "expected inline font-weight declarations in 50_chartview.ts" + assert inline <= {"400", "normal"}, ( + f"50_chartview.ts declares inline chrome weights {sorted(inline)}; " + "only normal/400 matches Matplotlib" + ) + + assigned = set(re.findall(r"\.style\.fontWeight\s*=\s*\"(\d+|normal|bold)\"", source)) + assert assigned <= {"400", "normal"}, ( + f"50_chartview.ts assigns chrome fontWeight {sorted(assigned)}; " + "only normal/400 matches Matplotlib" + ) diff --git a/tests/test_ui_issue_regressions.py b/tests/test_ui_issue_regressions.py index 3fe0fb66..f16842b7 100644 --- a/tests/test_ui_issue_regressions.py +++ b/tests/test_ui_issue_regressions.py @@ -264,6 +264,105 @@ def test_narrow_categorical_tick_labels_are_ellipsized_inside_chart(tmp_path: Pa assert result["documentOverflow"] is False, result +def test_tick_label_padding_starts_after_outward_tick_and_text_bottom_aligns( + tmp_path: Path, +) -> None: + chart = xy.chart( + xy.line([0, 1, 2], [0.25, 1.0, 0.5]), + xy.text( + 1, + 1, + "peak", + dx=0, + dy=-5, + anchor="middle", + style={"vertical_align": "bottom"}, + ), + xy.x_axis( + domain=(0, 2), + tick_values=[0, 1, 2], + style={"tick_length": 6, "tick_label_pad": 5}, + ), + xy.y_axis( + domain=(0, 1), + tick_values=[0, 0.5, 1], + style={"tick_length": 6, "tick_label_pad": 5}, + ), + width=420, + height=300, + padding=(28, 24, 48, 52), + ) + script = ( + _PRELUDE + + """ + const root = view.root.getBoundingClientRect(); + const xTick = view.root.querySelector( + '[data-xy-label-kind="tick"][data-xy-axis="x"]' + ).getBoundingClientRect(); + const yTick = view.root.querySelector( + '[data-xy-label-kind="tick"][data-xy-axis="y"]' + ).getBoundingClientRect(); + const annotation = view.root.querySelector( + '[data-xy-slot="annotation_label"]' + ).getBoundingClientRect(); + const plotBottom = root.top + view.plot.y + view.plot.h; + const plotLeft = root.left + view.plot.x; + const annotationAnchor = root.top + view._dataPxY(1) - 5; + document.body.setAttribute("data-xy-issue-probe", JSON.stringify({ + xGap: xTick.top - (plotBottom + 6), + yGap: (plotLeft - 6) - yTick.right, + annotationBottomError: annotation.bottom - annotationAnchor, + })); +""" + + _POSTLUDE + ) + result = _probe(chart, script, tmp_path, "tick and annotation alignment") + + assert result["xGap"] == pytest.approx(5, abs=0.75), result + assert result["yGap"] == pytest.approx(5, abs=0.75), result + assert result["annotationBottomError"] == pytest.approx(0, abs=0.75), result + + +def test_y_axis_title_stays_attached_when_left_padding_is_wide(tmp_path: Path) -> None: + chart = xy.chart( + xy.line([0, 1], [3600, 5400]), + xy.x_axis(), + xy.y_axis( + label="average daily births", + domain=(3600, 5400), + tick_values=[3600, 4000, 4400, 4800, 5200, 5400], + style={"tick_length": 3.5, "tick_padding": 3.5, "label_size": 13.8889}, + ), + width=1200, + height=400, + padding=(48, 120, 44, 150), + ) + script = ( + _PRELUDE + + """ + const root = view.root.getBoundingClientRect(); + const title = view.root.querySelector( + '[data-xy-label-kind="label"][data-xy-axis="y"]' + ).getBoundingClientRect(); + const ticks = [...view.root.querySelectorAll( + '[data-xy-label-kind="tick"][data-xy-axis="y"]' + )].map((element) => element.getBoundingClientRect()); + const tickLeft = Math.min(...ticks.map((rect) => rect.left)); + document.body.setAttribute("data-xy-issue-probe", JSON.stringify({ + gap: tickLeft - title.right, + titleInside: title.left >= root.left, + tickInside: tickLeft >= root.left, + })); +""" + + _POSTLUDE + ) + result = _probe(chart, script, tmp_path, "wide left gutter title attachment") + + assert result["gap"] == pytest.approx(0.4 * 13.8889, abs=0.75), result + assert result["titleInside"] is True, result + assert result["tickInside"] is True, result + + def test_categorical_tick_bounds_follow_anchor_rotation_and_extra_axis_side( tmp_path: Path, ) -> None: From a1fe5085a0b4071415df7823a90e6486eebfd718 Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 20:43:58 -0700 Subject: [PATCH 02/15] Restore measured y-axis title gutters --- js/src/50_chartview.ts | 56 ++++++++++++++++++++++- python/xy/_svg.py | 72 +++++++++++------------------- tests/test_axis_title_gutter.py | 19 ++++++++ tests/test_ui_issue_regressions.py | 42 +++++++++++++++++ 4 files changed, 143 insertions(+), 46 deletions(-) diff --git a/js/src/50_chartview.ts b/js/src/50_chartview.ts index 106727f9..92b7f7b2 100644 --- a/js/src/50_chartview.ts +++ b/js/src/50_chartview.ts @@ -502,7 +502,6 @@ export class ChartView { // vertical colorbar to its gradient; the full tick/title chrome returns // automatically when the container widens again. const responsivePad = this.fluid && compact && pad; - const marginLeft = pad ? (responsivePad ? Math.min(pad[3], 46) : pad[3]) : compact ? 46 : MARGIN.l; this._compactVerticalColorbar = Boolean(this.fluid && compact && verticalColorbar); const colorbarRightRoom = verticalColorbar ? (this._compactVerticalColorbar @@ -528,6 +527,14 @@ export class ChartView { ? (compact ? 26 : 32) : 0; const top = marginTop + (this.spec.title ? (compact ? 26 : 30) : 0) + topAxisRoom; + const plotHeight = Math.max(40, this.size.h - top - marginBottom); + const authoredLeft = pad + ? (responsivePad ? Math.min(pad[3], 46) : pad[3]) + : (compact ? 46 : MARGIN.l); + // Explicit padding is a floor, not permission to clip. Long numeric or + // categorical ticks and an outside y title reserve the room their actual + // strings need before the plot rectangle is fixed. + const marginLeft = Math.max(authoredLeft, this._yAxisLeftRoom(plotHeight)); const rightAxes = Object.values(this.axes || {}).filter((axis: any) => axis && String(axis.id || "").startsWith("y") && axis.side === "right" && this._axisTickLabelStrategy(axis) !== "none"); @@ -543,6 +550,53 @@ export class ChartView { }; } + _yAxisLeftRoom(plotHeight) { + let room = 0; + for (const axis of Object.values(this.axes || {})) { + if (!axis || !String(axis.id || "").startsWith("y") || axis.side === "right") continue; + if (this._axisTickLabelStrategy(axis) === "none") continue; + const size = Math.max( + 8, + this._axisStyleNumber( + axis, + "tick_label_size", + this._axisStyleNumber(axis, "tick_size", 11), + ), + ); + const angle = Math.abs(Number(this._axisTickLabelAngle(axis) || 0)) * Math.PI / 180; + const ticks = this._axisTicks( + axis.id, + this._axisTickTarget(axis.id, Math.max(3, plotHeight / 45)), + ); + let tickRoom = 0; + for (const value of (ticks.labels || ticks.ticks)) { + const text = this._axisTickText(axis, value, ticks.step); + const estimate = this._estimateTickLabel(text, size); + tickRoom = Math.max( + tickRoom, + Math.abs(Math.cos(angle)) * estimate.w + Math.abs(Math.sin(angle)) * estimate.h, + ); + } + const length = Math.max(0, this._axisStyleNumber(axis, "tick_length", 0)); + const direction = String(this._axisStyleValue(axis, "tick_direction") || "out"); + const outward = direction === "in" ? 0 : direction === "inout" ? length / 2 : length; + const tickOffset = + outward + Math.max(0, this._axisStyleNumber(axis, "tick_padding", 4)); + let needed = 4 + tickOffset + tickRoom; + const rawPosition = axis.label_position; + const position = typeof rawPosition === "string" ? rawPosition.replace(/-/g, "_") : ""; + if (axis.label && !position.startsWith("inside_")) { + const labelSize = Math.max(8, this._axisStyleNumber(axis, "label_size", 12)); + const gap = Number.isFinite(Number(axis.label_offset)) + ? Number(axis.label_offset) + : 0.4 * labelSize; + needed += gap + 1.2 * labelSize; + } + room = Math.max(room, needed); + } + return room; + } + _normalizeAxes(spec) { const axes = { ...(spec.axes || {}) }; if (spec.x_axis) axes.x = spec.x_axis; diff --git a/python/xy/_svg.py b/python/xy/_svg.py index d39bd46c..049f3652 100644 --- a/python/xy/_svg.py +++ b/python/xy/_svg.py @@ -1193,17 +1193,9 @@ def _colorbar_right_axis_room( return 0.0 -# Canvas inset the browser's rotated y-title line box is centered on -# (`left:10px` / `plot-right+40px` in ChartView), and the smallest gap left -# between the canvas edge and the outermost axis ink when no title claims that -# inset. Antialiased leading glyphs must not land on the export boundary. -_Y_TITLE_INSET = 10.0 +# Smallest gap between the canvas edge and the outermost axis ink. +# Antialiased leading glyphs must not land on the export boundary. _AXIS_TEXT_EDGE_PAD = 4.0 -# Floor on the y title's leading ink, for a title whose line box is taller than -# twice the inset. Deliberately below `_AXIS_TEXT_EDGE_PAD`: at ordinary sizes -# the inset itself governs, and matching ChartView's placement matters more than -# a rounder outer margin (a 13.89 px title inks from x=1.75 in both renderers). -_Y_TITLE_MIN_INK = 1.0 # Gap between the y title's ink and the nearest tick label's ink, as a fraction # of the title's font size. Matplotlib leaves 5.6 px at its 13.89 px (10 pt at # 100 dpi) default — measured with `Text.get_window_extent` on 3.11.1. @@ -1218,15 +1210,16 @@ def _text_cell(font_size: float) -> tuple[float, float]: ) -def _y_title_baseline(axis: dict[str, Any], plot_right: float) -> Optional[float]: +def _y_title_baseline( + axis: dict[str, Any], + plot: dict[str, float], +) -> Optional[float]: """Baseline x of a quarter-turned y-axis title, or None when it has none. - ChartView positions the title as a rotated DOM line box *centered* on a - fixed canvas inset; a static exporter emits a baseline. The two differ by - half a line box, which is why the SVG/PNG title used to sit one full ascent - further toward the canvas edge than the browser draws it — the same - box-to-baseline correction the x-axis title already makes with - `font_size * 0.82`. Titles at any other angle keep the raw inset. + Matplotlib positions a y title from the outer edge of the tick-label union, + not from the canvas edge. A static exporter emits a baseline while the + browser positions a centered line box; the returned coordinate includes + that box-to-baseline correction. """ if not axis.get("label"): return None @@ -1237,17 +1230,17 @@ def _y_title_baseline(axis: dict[str, Any], plot_right: float) -> Optional[float style = axis.get("style") or {} font_size = float(style.get("label_size", 12)) side = axis.get("side", "left") - angle = float(axis.get("label_angle", 90.0 if side == "right" else -90.0)) ascent, descent = _text_cell(font_size) - # Ink is [x - ascent, x + descent] at -90° and [x - descent, x + ascent] at - # +90°, so centering the cell on the inset shifts the baseline by half the - # ascent/descent asymmetry, away from the plot in both cases. - shift = (ascent - descent) / 2 if abs(abs(angle) - 90.0) < 0.5 else 0.0 - offset = float(axis.get("label_offset", 0.0)) if side == "right": - return plot_right + 40.0 - shift + offset - # Clamp so an oversized title cannot be pushed off the canvas by the inset. - return max(_Y_TITLE_MIN_INK + ascent, _Y_TITLE_INSET + shift) - offset + # Right-side axes still use the existing fixed 42/54 px reservation. + # Keep their plot-relative placement unchanged; this repair only + # measures the left gutter that can otherwise clip against x=0. + angle = float(axis.get("label_angle", 90.0)) + shift = (ascent - descent) / 2 if abs(abs(angle) - 90.0) < 0.5 else 0.0 + return plot["x"] + plot["w"] + 40.0 - shift + float(axis.get("label_offset", 0.0)) + tick_offset, tick_room = _y_tick_label_room(axis, plot["h"]) + gap = float(axis.get("label_offset", _Y_TITLE_TICK_GAP * font_size)) + return plot["x"] - tick_offset - tick_room - gap - descent def _y_tick_label_room(axis: dict[str, Any], plot_h: float) -> tuple[float, float]: @@ -1296,14 +1289,16 @@ def _y_axis_left_room(spec: dict[str, Any], plot_h: float) -> float: if not axis_id.startswith("y") or axis.get("side", "left") == "right": continue tick_offset, tick_room = _y_tick_label_room(axis, plot_h) - baseline = _y_title_baseline(axis, 0.0) - if baseline is None: + if _y_title_baseline(axis, {"x": 0.0, "y": 0.0, "w": 0.0, "h": plot_h}) is None: room = max(room, _AXIS_TEXT_EDGE_PAD + tick_offset + tick_room) continue label_size = float((axis.get("style") or {}).get("label_size", 12)) - _ascent, descent = _text_cell(label_size) - gap = _Y_TITLE_TICK_GAP * label_size if tick_room else 0.0 - room = max(room, baseline + descent + gap + tick_offset + tick_room) + ascent, descent = _text_cell(label_size) + gap = float(axis.get("label_offset", _Y_TITLE_TICK_GAP * label_size)) + room = max( + room, + _AXIS_TEXT_EDGE_PAD + ascent + descent + gap + tick_offset + tick_room, + ) return room @@ -1649,20 +1644,7 @@ def _axis_label_geometry( # baseline. `_y_title_baseline` applies that half-line-box # correction and the axis's own `label_offset`, and is the same # function `layout()` reserves the gutter from. - baseline = _y_title_baseline(axis, plot["x"] + plot["w"]) - if baseline is not None and side != "right": - # Matplotlib positions a left title from the tick-label ink, - # not from the canvas edge. This matters when an explicit - # axes rectangle reserves more left room than the minimum - # measured gutter: keep the title attached to the ticks - # instead of leaving the extra frame padding between them. - tick_offset, tick_room = _y_tick_label_room(axis, plot["h"]) - ascent, descent = _text_cell(font_size) - angle = float(axis.get("label_angle", -90.0)) - title_inner_ink = ascent if angle > 0 else descent - gap = _Y_TITLE_TICK_GAP * font_size if tick_room else 0.0 - attached = plot["x"] - tick_offset - tick_room - gap - title_inner_ink - offset - baseline = max(baseline, attached) + baseline = _y_title_baseline(axis, plot) x = ( baseline if baseline is not None diff --git a/tests/test_axis_title_gutter.py b/tests/test_axis_title_gutter.py index a2023556..159b9d4f 100644 --- a/tests/test_axis_title_gutter.py +++ b/tests/test_axis_title_gutter.py @@ -156,6 +156,25 @@ def test_authored_padding_too_narrow_for_the_text_still_reserves_the_gutter() -> assert _first_ink_column(spec, blob, plot) > 0 +def test_positive_label_offset_expands_the_gutter_instead_of_clipping() -> None: + """An explicit title-to-tick gap must reserve the canvas room it consumes.""" + chart = _chart( + y_label="average daily births", + y_values=[3600.0, 5400.0], + label_offset=20.0, + ) + spec, blob = _payload(chart) + _width, _height, _compact, plot = _svg.layout(spec) + title_box, tick_span = _assert_clear( + _svg.render_svg(spec, blob), + plot, + "average daily births", + canvas_width=760, + ) + assert tick_span[0] - title_box[1] == pytest.approx(20.0, abs=0.05) + assert title_box[0] > 0 + + def test_ordinary_numeric_axis_keeps_the_default_gutter() -> None: """The measured reservation is a floor: it must not inflate ordinary charts. diff --git a/tests/test_ui_issue_regressions.py b/tests/test_ui_issue_regressions.py index f16842b7..f681a46c 100644 --- a/tests/test_ui_issue_regressions.py +++ b/tests/test_ui_issue_regressions.py @@ -363,6 +363,48 @@ def test_y_axis_title_stays_attached_when_left_padding_is_wide(tmp_path: Path) - assert result["tickInside"] is True, result +def test_long_y_categories_expand_the_browser_gutter(tmp_path: Path) -> None: + categories = [f"Questionnaire item {index}" for index in range(1, 7)] + chart = xy.bar_chart( + xy.bar( + x=categories, + y=[10.0, 20.0, 30.0, 40.0, 50.0, 60.0], + orientation="horizontal", + ), + xy.y_axis(label="survey question", style={"label_size": 14, "tick_label_size": 14}), + width=640, + height=480, + ) + script = ( + _PRELUDE + + """ + const root = view.root.getBoundingClientRect(); + const title = view.root.querySelector( + '[data-xy-label-kind="label"][data-xy-axis="y"]' + ).getBoundingClientRect(); + const ticks = [...view.root.querySelectorAll( + '[data-xy-label-kind="tick"][data-xy-axis="y"]' + )]; + const tickBoxes = ticks.map((element) => element.getBoundingClientRect()); + document.body.setAttribute("data-xy-issue-probe", JSON.stringify({ + plotX: view.plot.x, + gap: Math.min(...tickBoxes.map((box) => box.left)) - title.right, + clipped: ticks.some((element) => element.scrollWidth > element.clientWidth), + titleInside: title.left >= root.left, + tickTexts: ticks.map((element) => element.textContent), + })); +""" + + _POSTLUDE + ) + result = _probe(chart, script, tmp_path, "long category y gutter") + + assert result["plotX"] > 150, result + assert result["gap"] == pytest.approx(0.4 * 14, abs=0.75), result + assert result["clipped"] is False, result + assert result["titleInside"] is True, result + assert sorted(result["tickTexts"]) == categories, result + + def test_categorical_tick_bounds_follow_anchor_rotation_and_extra_axis_side( tmp_path: Path, ) -> None: From 3539d24be7d258dacc1d0ec5ba2d60c83280012b Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 20:36:53 -0700 Subject: [PATCH 03/15] Fix core legend top and bottom aliases --- js/src/50_chartview.ts | 7 +- python/xy/_svg.py | 9 ++- tests/pyplot/test_best_legend_placement.py | 23 ++++++ tests/test_legend_resize_regression.py | 88 ++++++++++++++++++++++ 4 files changed, 123 insertions(+), 4 deletions(-) diff --git a/js/src/50_chartview.ts b/js/src/50_chartview.ts index 92b7f7b2..2d203c53 100644 --- a/js/src/50_chartview.ts +++ b/js/src/50_chartview.ts @@ -2387,7 +2387,12 @@ export class ChartView { // real left/right/top/bottom/transform declarations and win normally. const rightInset = this.size.w - (this.plot.x + this.plot.w); const h = loc.includes("left") ? "left" : loc.includes("right") ? "right" : "center"; - const v = loc.includes("upper") ? "upper" : loc.includes("lower") ? "lower" : "center"; + const locTokens = loc.split(/[\s_-]+/); + const v = loc.includes("upper") || locTokens.includes("top") + ? "upper" + : loc.includes("lower") || locTokens.includes("bottom") + ? "lower" + : "center"; let left = h === "left" ? this.plot.x + 6 : h === "center" ? this.plot.x + this.plot.w / 2 : null; let right = h === "right" ? rightInset + 6 : null; let top = v === "upper" ? this.plot.y + 6 : v === "center" ? this.plot.y + this.plot.h / 2 : null; diff --git a/python/xy/_svg.py b/python/xy/_svg.py index 049f3652..f897d590 100644 --- a/python/xy/_svg.py +++ b/python/xy/_svg.py @@ -3296,12 +3296,15 @@ def _legend_layout(named: list[dict], plot: dict, options: dict) -> dict[str, An ) loc = options.get("loc") or "upper right" + loc_tokens = set(re.split(r"[\s_-]+", loc)) + loc_is_upper = "upper" in loc or "top" in loc_tokens + loc_is_lower = "lower" in loc or "bottom" in loc_tokens anchor = options.get("anchor") if anchor and len(anchor) in (2, 4): ax, ay = float(anchor[0]), float(anchor[1]) aw, ah = (0.0, 0.0) if len(anchor) == 2 else (float(anchor[2]), float(anchor[3])) hx = 0.0 if "left" in loc else 1.0 if "right" in loc else 0.5 - vy = 0.0 if "lower" in loc else 1.0 if "upper" in loc else 0.5 + vy = 0.0 if loc_is_lower else 1.0 if loc_is_upper else 0.5 target_x = float(plot["x"]) + (ax + hx * aw) * float(plot["w"]) target_y = float(plot["y"]) + (1.0 - ay - vy * ah) * float(plot["h"]) x = target_x - hx * box_w @@ -3318,9 +3321,9 @@ def _legend_layout(named: list[dict], plot: dict, options: dict) -> dict[str, An x = float(plot["x"]) + float(plot["w"]) - box_w - inset else: x = float(plot["x"]) + (float(plot["w"]) - box_w) / 2 - if "upper" in loc: + if loc_is_upper: y = float(plot["y"]) + inset - elif "lower" in loc: + elif loc_is_lower: y = float(plot["y"]) + float(plot["h"]) - box_h - inset else: y = float(plot["y"]) + (float(plot["h"]) - box_h) / 2 diff --git a/tests/pyplot/test_best_legend_placement.py b/tests/pyplot/test_best_legend_placement.py index c71cbe20..7b226e1f 100644 --- a/tests/pyplot/test_best_legend_placement.py +++ b/tests/pyplot/test_best_legend_placement.py @@ -388,6 +388,29 @@ def test_pyplot_legend_loc_rejects_misspelled_locations(): assert xy.legend(loc="top left").loc == "top left" +@pytest.mark.parametrize( + ("alias", "canonical"), + [ + ("top", "upper"), + ("top left", "upper left"), + ("top-center", "upper-center"), + ("bottom", "lower"), + ("bottom right", "lower right"), + ("bottom_center", "lower_center"), + ], +) +def test_core_legend_vertical_aliases_match_static_layout(alias, canonical): + """Core aliases keep their public spelling but share SVG anchor geometry.""" + items = [{"name": "abc"}] + plot = {"x": 40.0, "y": 20.0, "w": 400.0, "h": 300.0} + for anchor in (None, (0.2, 0.3), (0.2, 0.3, 0.4, 0.5)): + options = {"loc": alias, "anchor": anchor} + canonical_options = {"loc": canonical, "anchor": anchor} + actual = _legend_layout(items, plot, options) + expected = _legend_layout(items, plot, canonical_options) + assert (actual["x"], actual["y"]) == pytest.approx((expected["x"], expected["y"])) + + def test_every_matplotlib_loc_places_the_box_at_its_anchor(): items = [{"name": "abc"}] plot = {"x": 40.0, "y": 20.0, "w": 400.0, "h": 300.0} diff --git a/tests/test_legend_resize_regression.py b/tests/test_legend_resize_regression.py index 60f536c0..6c404156 100644 --- a/tests/test_legend_resize_regression.py +++ b/tests/test_legend_resize_regression.py @@ -347,6 +347,47 @@ """ +_LEGEND_LOC_ALIAS_PROBE = """ + +""" + def _probe_maxheight(chromium: str, document: str, page: Path) -> dict: """Render + probe the legend max-height across a responsive resize.""" @@ -387,6 +428,53 @@ def _probe_atomic_resize(chromium: str, document: str, page: Path) -> dict: ) +def _probe_legend_loc_alias(chromium: str, document: str, page: Path) -> dict: + """Render core top/bottom aliases and read their browser edge positions.""" + return run_browser_probe( + chromium, + document, + page, + "data-xy-legend-loc-alias", + label="legend loc alias probe", + ) + + +def test_core_legend_top_and_bottom_aliases_reach_browser_edges() -> None: + chromium = find_chromium() + if not chromium: + pytest.skip("no chromium available for the legend loc alias probe") + + chart = xy.chart( + xy.line([0, 1, 2], [1, 2, 1], name="series"), + xy.legend(loc="top left"), + width=480, + height=320, + ) + document = chart.to_html() + render_call = next((call for call in _RENDER_CALLS if call in document), None) + assert render_call is not None + document = document.replace( + render_call, + render_call.replace( + "xy.renderStandalone(", "window.__fcProbeView = xy.renderStandalone(", 1 + ), + 1, + ) + document = document.replace("", _LEGEND_LOC_ALIAS_PROBE + "\n", 1) + + with tempfile.TemporaryDirectory() as td: + payload = _probe_legend_loc_alias( + chromium, + document, + Path(td) / "legend_loc_alias.html", + ) + + assert payload["topLeft"]["leftError"] <= 1, payload + assert payload["topLeft"]["topError"] <= 1, payload + assert payload["bottomRight"]["rightError"] <= 1, payload + assert payload["bottomRight"]["bottomError"] <= 1, payload + + def test_snake_case_legend_max_height_survives_resize() -> None: chromium = find_chromium() if not chromium: From c60ee9b4a4e54a5bc8a82d2a3ef4539db439feb3 Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 20:38:57 -0700 Subject: [PATCH 04/15] Preserve fitting anchored legend labels --- python/xy/_svg.py | 14 +++++++++-- .../pyplot/test_line_legend_gallery_compat.py | 25 +++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/python/xy/_svg.py b/python/xy/_svg.py index f897d590..cc925580 100644 --- a/python/xy/_svg.py +++ b/python/xy/_svg.py @@ -3226,7 +3226,18 @@ def _legend_layout(named: list[dict], plot: dict, options: dict) -> dict[str, An title = options.get("title") title_h = line_h if title else 0.0 inset = 6.0 - available_w = max(1.0, float(plot["w"]) - 2 * inset) + anchor = options.get("anchor") + # An anchored legend is positioned from ``bbox_to_anchor`` rather than + # inset from both plot edges. Charging it the unanchored 6 px inset on + # both sides unnecessarily shortened otherwise fitting labels. The + # Matplotlib survey-gallery legend is the boundary case: its measured + # five-column box fits the axes width, but not ``axes width - 12 px``. + # Keep the plot-width cap so genuinely oversized static legends still + # ellipsize instead of escaping the bounded export. + available_w = max( + 1.0, + float(plot["w"]) if anchor and len(anchor) in (2, 4) else float(plot["w"]) - 2 * inset, + ) ncols = requested_cols min_column_w = handle + gap + 4 * char_width if ncols * min_column_w + (ncols - 1) * column_gap + pad > available_w: @@ -3299,7 +3310,6 @@ def _legend_layout(named: list[dict], plot: dict, options: dict) -> dict[str, An loc_tokens = set(re.split(r"[\s_-]+", loc)) loc_is_upper = "upper" in loc or "top" in loc_tokens loc_is_lower = "lower" in loc or "bottom" in loc_tokens - anchor = options.get("anchor") if anchor and len(anchor) in (2, 4): ax, ay = float(anchor[0]), float(anchor[1]) aw, ah = (0.0, 0.0) if len(anchor) == 2 else (float(anchor[2]), float(anchor[3])) diff --git a/tests/pyplot/test_line_legend_gallery_compat.py b/tests/pyplot/test_line_legend_gallery_compat.py index cdd5a241..637b785a 100644 --- a/tests/pyplot/test_line_legend_gallery_compat.py +++ b/tests/pyplot/test_line_legend_gallery_compat.py @@ -92,7 +92,7 @@ def test_multicolumn_legend_sizes_each_column_to_its_own_labels(): assert layout["box_w"] < equal_width_box -def test_outside_top_legend_reserves_its_measured_box_and_axes_gap(): +def test_outside_top_legend_preserves_gallery_labels_and_reserves_its_box(monkeypatch): fig, ax = plt.subplots(figsize=(9.2, 5)) labels = [ "Strongly disagree", @@ -110,7 +110,7 @@ def test_outside_top_legend_reserves_its_measured_box_and_axes_gap(): fontsize="small", ) - spec, _ = ax._build_chart(920, 500).figure().build_payload() + spec, blob = ax._build_chart(920, 500).figure().build_payload() _, _, _, plot = layout(spec) legend = _legend_layout( [trace for trace in spec["traces"] if trace.get("name")], @@ -118,12 +118,33 @@ def test_outside_top_legend_reserves_its_measured_box_and_axes_gap(): spec["legend"], ) + assert legend["names"] == labels assert spec["padding"][0] >= legend["box_h"] + spec["legend"]["border_pad"] + 6 assert legend["y"] >= 6 assert plot["y"] - (legend["y"] + legend["box_h"]) == pytest.approx( spec["legend"]["border_pad"] ) + output = BytesIO() + fig.savefig(output, format="svg", dpi=100) + texts = { + element.text + for element in ElementTree.fromstring(output.getvalue()).iter() + if element.tag.endswith("text") + } + assert set(labels) <= texts + + raster_text: set[str] = set() + original_text = _raster._Cmd.text + + def record_text(self, x, y, anchor, size, color, text, **kwargs): + raster_text.add(str(text)) + return original_text(self, x, y, anchor, size, color, text, **kwargs) + + monkeypatch.setattr(_raster._Cmd, "text", record_text) + _raster.render_raster(spec, blob, scale=1) + assert set(labels) <= raster_text + def test_titled_scatter_legend_box_fits_title_and_every_entry(): _, ax = plt.subplots() From 16ccc4129d580026419fd00ebdb6f5f02f945570 Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 20:40:20 -0700 Subject: [PATCH 05/15] Add anchored legend comparison evidence --- .../horizontal-barchart-legend.png | Bin 0 -> 140231 bytes .../provenance.json | 14 ++++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 pr-assets/matplotlib-gallery-consolidation/horizontal-barchart-legend.png diff --git a/pr-assets/matplotlib-gallery-consolidation/horizontal-barchart-legend.png b/pr-assets/matplotlib-gallery-consolidation/horizontal-barchart-legend.png new file mode 100644 index 0000000000000000000000000000000000000000..6ad4d3841e70026b4ca49bbd6c1a283f95b79733 GIT binary patch literal 140231 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%0DvgBM~KH*AS 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

m;<=tr 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 VeaR^J6zl07 Date: Fri, 24 Jul 2026 20:53:25 -0700 Subject: [PATCH 06/15] Refresh legend evidence at integrated Stack A --- .../horizontal-barchart-legend.png | Bin 140231 -> 140212 bytes .../provenance.json | 9 ++++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pr-assets/matplotlib-gallery-consolidation/horizontal-barchart-legend.png b/pr-assets/matplotlib-gallery-consolidation/horizontal-barchart-legend.png index 6ad4d3841e70026b4ca49bbd6c1a283f95b79733..3cdb77255a08bab9dd688e33b43fb18847d30f7b 100644 GIT binary patch delta 126349 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%0DZBO+7H8CW7Hz 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�LJc4SqDv}uyOIkOr5WWz*LS$eecly?QdQ*Dn=8} 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

G<0l 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 diff --git a/pr-assets/matplotlib-gallery-consolidation/provenance.json b/pr-assets/matplotlib-gallery-consolidation/provenance.json index 397eba63..0f5c03d9 100644 --- a/pr-assets/matplotlib-gallery-consolidation/provenance.json +++ b/pr-assets/matplotlib-gallery-consolidation/provenance.json @@ -3,6 +3,9 @@ "live_base_commit": "077c53f761ae5a9de2324daa527aadc48cd8bb17", "rendered_base_commit": "58a3782082cb80507033af19a79ec683f6438936", "head_code_commit": "47871a01db1ad02d1f64bda71fd1a50f9ab89853", + "head_code_commit_note": "Render boundary for the original bar-label and annotation comparison sheets; this is not the current integrated Stack A head.", + "full_gallery_verified_code_commit": "16ccc4129d580026419fd00ebdb6f5f02f945570", + "full_gallery_verification_note": "77/88 examples were execution-paired at this commit, producing 133 paired figures; execution pairing does not itself assert pixel equivalence.", "base_source_tree_note": "The rendered base and live base are byte-identical under js, python/xy, and src; intervening commits only changed release infrastructure and documentation.", "full_frame": true, "comparisons": [ @@ -25,12 +28,12 @@ "figure": 0, "file": "horizontal-barchart-legend.png", "dimensions": [2760, 545], - "sha256": "47b0108806b747d32eb54a41b5c6c665af10e40b0b83bd00e14e0e75326249f6", - "rendered_code_commit": "e4bc640c0f04a5aca55cb54eb14f0674fae3af9e", + "sha256": "4784091a9365701b4bf83e6dc54999cd8415b38673e73a20a520f5979beadfa9", + "rendered_code_commit": "16ccc4129d580026419fd00ebdb6f5f02f945570", "panels": [ "Matplotlib 3.11.0 reference", "Stack A legend behavior before e4bc640", - "Stack A legend behavior at e4bc640" + "Integrated Stack A legend behavior at 16ccc4129d580026419fd00ebdb6f5f02f945570" ], "before_render_note": "The before panel comes from the exact final-stack gallery run; Stack B does not modify the shared legend layout inherited from Stack A." } From f9f13281a30dc76bde726389eca35d66b3ff410f Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 21:10:12 -0700 Subject: [PATCH 07/15] Cap measured gutter growth on narrow charts --- js/src/50_chartview.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/js/src/50_chartview.ts b/js/src/50_chartview.ts index 2d203c53..4106b0ab 100644 --- a/js/src/50_chartview.ts +++ b/js/src/50_chartview.ts @@ -534,7 +534,7 @@ export class ChartView { // Explicit padding is a floor, not permission to clip. Long numeric or // categorical ticks and an outside y title reserve the room their actual // strings need before the plot rectangle is fixed. - const marginLeft = Math.max(authoredLeft, this._yAxisLeftRoom(plotHeight)); + const measuredLeft = Math.max(authoredLeft, this._yAxisLeftRoom(plotHeight)); const rightAxes = Object.values(this.axes || {}).filter((axis: any) => axis && String(axis.id || "").startsWith("y") && axis.side === "right" && this._axisTickLabelStrategy(axis) !== "none"); @@ -542,6 +542,12 @@ export class ChartView { // the Python SVG/raster exporters apply the identical 42/54 rule. this._rightAxisRoom = rightAxes.length ? (compact ? 42 : 54) : 0; const right = marginRight + this._rightAxisRoom; + // Measurement can consume spare canvas room, but it must not move the + // y-axis anchor past the viewport on a chart whose authored padding has + // already reached the 40 px plot floor. In that compact case the tick + // labels retain their full text in `title`/ARIA and ellipsize in bounds. + const measuredLeftCap = Math.max(authoredLeft, this.size.w - right - 40); + const marginLeft = Math.min(measuredLeft, measuredLeftCap); this.plot = { x: marginLeft, y: top, From 1bc0ec68c3a38c2b920fe2025602a88f36d74670 Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 22:20:06 -0700 Subject: [PATCH 08/15] Address consolidated gallery review findings --- js/src/50_chartview.ts | 25 +++-- python/xy/_figure.py | 13 ++- python/xy/_paint.py | 6 +- python/xy/_svg.py | 98 +++++++++++-------- python/xy/components.py | 13 +-- python/xy/marks.py | 17 +++- python/xy/pyplot/__init__.py | 10 +- python/xy/pyplot/_artists.py | 17 +++- python/xy/pyplot/_axes.py | 60 +++++++++--- python/xy/pyplot/_grid.py | 5 +- python/xy/pyplot/_mathtext.py | 91 +++++++++++++---- python/xy/pyplot/_plot_types.py | 18 ++-- python/xy/pyplot/_ticker.py | 36 +++++-- spec/api/styling.md | 2 +- spec/matplotlib/compat.md | 4 +- spec/matplotlib/shim-todo.md | 12 +-- src/raster.rs | 50 +++++++++- tests/pyplot/test_adversarial_parity_fixes.py | 8 +- tests/pyplot/test_color_pipeline_fixes.py | 9 +- .../pyplot/test_gallery_auto_ticks_compat.py | 32 +++++- .../test_gallery_hist_errorbar_compat.py | 24 +++++ tests/pyplot/test_gallery_text_pie_compat.py | 68 +++++++++++++ tests/pyplot/test_layout_text_parity_fixes.py | 2 +- .../pyplot/test_line_legend_gallery_compat.py | 21 ++++ .../test_matplotlib_mismatch_regressions.py | 71 ++++++++++++++ tests/pyplot/test_p3_option_contracts.py | 24 ++++- tests/pyplot/test_pdsh_gap_features.py | 15 ++- tests/test_components.py | 96 ++++++++++++++++++ tests/test_figure.py | 10 ++ tests/test_plot_families.py | 15 +++ tests/test_svg_export.py | 15 ++- tests/test_svg_text_metrics.py | 72 ++++++++++++++ tests/test_text_weight_defaults.py | 38 ++++++- tests/test_ui_issue_regressions.py | 63 +++++++++++- tests/test_width_validation_regressions.py | 47 +++++++++ 35 files changed, 937 insertions(+), 170 deletions(-) create mode 100644 tests/test_svg_text_metrics.py create mode 100644 tests/test_width_validation_regressions.py diff --git a/js/src/50_chartview.ts b/js/src/50_chartview.ts index 4106b0ab..847cf6c0 100644 --- a/js/src/50_chartview.ts +++ b/js/src/50_chartview.ts @@ -5264,13 +5264,17 @@ export class ChartView { : Math.min(...tickRects.map((rect) => rect.left)) - 0.4 * fontSize - labelOffset; const currentEdge = onRight ? titleRect.left : titleRect.right; const currentLeft = parseFloat(title.style.left) || 0; - title.style.left = `${currentLeft + targetEdge - currentEdge}px`; - // Keep an unusually large title inside the chart canvas. - const adjusted = title.getBoundingClientRect(); - const correction = adjusted.left < root.left - ? root.left - adjusted.left + 1 - : adjusted.right > root.right ? root.right - adjusted.right - 1 : 0; - if (correction) title.style.left = `${parseFloat(title.style.left) + correction}px`; + const delta = targetEdge - currentEdge; + // Keep an unusually large title inside the chart canvas. Moving an + // absolutely positioned label by `delta` translates its measured box by + // the same amount, so derive the clamp from the captured geometry and + // avoid a write-then-layout-read on every chrome redraw. + const adjustedLeft = titleRect.left + delta; + const adjustedRight = titleRect.right + delta; + const correction = adjustedLeft < root.left + ? root.left - adjustedLeft + 1 + : adjustedRight > root.right ? root.right - adjustedRight - 1 : 0; + title.style.left = `${currentLeft + delta + correction}px`; }; if (s.x_axis.label && !hideX) { const top = xAxis.side === "top" ? p.y - 34 : p.y + p.h + 24; @@ -5284,7 +5288,12 @@ export class ChartView { : `left:10px;top:${p.y + p.h / 2}px;transform:rotate(-90deg) translateX(50%);transform-origin:left;font-weight:400;`; const placement = this._axisLabelCss(yAxis, "y", fallbackCss); const title = label(s.y_axis.label, placement.css, yAxis, "label", placement.style); - attachYTitleToTicks(title, yAxis, yAxis.side === "right"); + // A structured CSS label_position is the placement authority. It may + // deliberately omit `left` in favor of `right`, so tick attachment must + // not synthesize a competing left offset. + if (placement.style === null) { + attachYTitleToTicks(title, yAxis, yAxis.side === "right"); + } } this._drawAnnotationLabels(updateLabels); // Label layout resolves responsive callout offsets before the pointer is diff --git a/python/xy/_figure.py b/python/xy/_figure.py index 1f1f0c3a..6c151924 100644 --- a/python/xy/_figure.py +++ b/python/xy/_figure.py @@ -1044,8 +1044,8 @@ def _range(self, axis_id: str, *, use_domain: bool = True) -> tuple[float, float if not positive_los: raise ValueError(f"{axis_id} log axis requires at least one positive value") lo, hi = min(positive_los), max(positive_his) - margin = opts.get("margin") - if lo == hi and margin is None: + configured_margin = opts.get("margin") + if lo == hi and configured_margin is None: pad = abs(lo) * 0.05 or 0.5 lo, hi = lo - pad, hi + pad if scale == "log" and lo <= 0: @@ -1056,9 +1056,8 @@ def _range(self, axis_id: str, *, use_domain: bool = True) -> tuple[float, float # to a stable unit interval instead of being silently replaced by # the core's legacy 5% nonsingular fallback. hi = lo + 1.0 - if margin is None: - margin = 0.03 - if scale == "log" and opts.get("margin") is not None: + margin = 0.03 if configured_margin is None else configured_margin + if scale == "log" and configured_margin is not None: transformed_lo, transformed_hi = np.log10((lo, hi)) pad = (transformed_hi - transformed_lo) * margin out_lo = 10.0 ** (transformed_lo - pad) @@ -1072,7 +1071,7 @@ def _range(self, axis_id: str, *, use_domain: bool = True) -> tuple[float, float out_lo = 0.0 elif anchor == "hi" and hi == 0.0 and lo < 0.0: out_hi = 0.0 - if scale == "log" and opts.get("margin") is None: + if scale == "log" and configured_margin is None: out_lo = max(out_lo, lo / 10.0, np.nextafter(0.0, 1.0)) return (out_hi, out_lo) if opts.get("reverse") else (out_lo, out_hi) @@ -1088,7 +1087,7 @@ def _zero_baseline_anchor(self, axis_id: str) -> Optional[str]: # Only rectangle families have a sticky zero edge. Segment-based # marks such as stem/errorbar also carry x0/x1/y0/y1 columns, but # Matplotlib pads their baseline like ordinary line data. - if t.kind not in {"bar", "histogram"}: + if t.kind not in {"bar", "column", "histogram"}: continue if axis == "x" and t.x_axis != axis_id: continue diff --git a/python/xy/_paint.py b/python/xy/_paint.py index e9edcec7..06f5ba08 100644 --- a/python/xy/_paint.py +++ b/python/xy/_paint.py @@ -24,8 +24,10 @@ def triangle_mesh_boundary(*vertices: np.ndarray) -> np.ndarray | None: n = min((len(values) for values in arrays), default=0) if n == 0: return None - finite = np.concatenate(arrays) - span = float(np.nanmax(finite) - np.nanmin(finite)) + coordinates = np.concatenate([values[:n] for values in arrays]) + if not np.isfinite(coordinates).all(): + return None + span = float(coordinates.max() - coordinates.min()) # Each triangle coordinate is transported in an independently offset # float32 column, so the same source vertex may decode a few ULPs apart in # x0/x1/x2. The joined-fill flag is only used for one simple polygon; a diff --git a/python/xy/_svg.py b/python/xy/_svg.py index cc925580..e029d523 100644 --- a/python/xy/_svg.py +++ b/python/xy/_svg.py @@ -1210,6 +1210,15 @@ def _text_cell(font_size: float) -> tuple[float, float]: ) +def _has_outside_y_title(axis: dict[str, Any]) -> bool: + """Whether a y-axis title needs space outside the plot rectangle.""" + if not axis.get("label"): + return False + raw_position = axis.get("label_position") + position = raw_position if isinstance(raw_position, str) else "center" + return not position.replace("-", "_").startswith("inside_") + + def _y_title_baseline( axis: dict[str, Any], plot: dict[str, float], @@ -1221,12 +1230,8 @@ def _y_title_baseline( browser positions a centered line box; the returned coordinate includes that box-to-baseline correction. """ - if not axis.get("label"): - return None - raw_position = axis.get("label_position") - position = raw_position if isinstance(raw_position, str) else "center" - if position.replace("-", "_").startswith("inside_"): - return None # drawn over the plot; it needs no gutter + if not _has_outside_y_title(axis): + return None # absent or drawn over the plot; it needs no gutter style = axis.get("style") or {} font_size = float(style.get("label_size", 12)) side = axis.get("side", "left") @@ -1289,7 +1294,7 @@ def _y_axis_left_room(spec: dict[str, Any], plot_h: float) -> float: if not axis_id.startswith("y") or axis.get("side", "left") == "right": continue tick_offset, tick_room = _y_tick_label_room(axis, plot_h) - if _y_title_baseline(axis, {"x": 0.0, "y": 0.0, "w": 0.0, "h": plot_h}) is None: + if not _has_outside_y_title(axis): room = max(room, _AXIS_TEXT_EDGE_PAD + tick_offset + tick_room) continue label_size = float((axis.get("style") or {}).get("label_size", 12)) @@ -2329,9 +2334,20 @@ def _svg_mathtext_spans(line: str, style: dict[str, Any], offset: int) -> str: ranges.append((start, end)) if not ranges: return escape(line) + ranges.sort() + merged: list[tuple[int, int]] = [] + for start, end in ranges: + if merged and start <= merged[-1][1]: + previous_start, previous_end = merged[-1] + merged[-1] = previous_start, max(previous_end, end) + else: + merged.append((start, end)) out: list[str] = [] cursor = 0 - for start, end in ranges: + for start, end in merged: + start = max(start, cursor) + if start >= end: + continue if cursor < start: out.append(escape(line[cursor:start])) out.append(f'{escape(line[start:end])}') @@ -2407,33 +2423,37 @@ def _box_corner_radius(style: dict[str, Any], width: float, height: float) -> fl return max(0.0, min(radius, width / 2.0, height / 2.0)) -def _estimated_text_width(lines: list[str], font_size: float) -> float: - """Dependency-free label-box width using glyph-shaped em advances. - - Static SVG leaves final glyph layout to the viewer and the native stream - owns its atlas in Rust, so neither Python emitter has a browser text - measurer. A flat character count made narrow and wide strings equally - wide and visibly let labels such as ``Thanksgiving`` escape their box. - These bounded advances follow ordinary sans-serif proportions closely - enough to keep boxes readable without shipping a second font table. - """ +def _fontmetrics_text_width( + value: Any, + font_size: float, + *, + missing_advance: float, +) -> float: + """Embedded-face advance with a conservative fallback for unknown glyphs.""" + text = str(value) + missing = sum( + 1 + for char in text + if not ( + _fontmetrics.FIRST <= ord(char) <= _fontmetrics.LAST + or ord(char) in _fontmetrics.EXTRA_ADVANCES + ) + ) + return _fontmetrics.advance(text, font_size) + missing * missing_advance - def line_width(line: str) -> float: - advance = 0.0 - for char in line: - if char in " !'.,:;|ijlI": - advance += 0.28 - elif char in "MW@%&": - advance += 0.9 - elif char.isupper(): - advance += 0.66 - elif char.isdigit(): - advance += 0.64 - else: - advance += 0.56 - return advance * font_size - return max((line_width(line) for line in lines), default=0.0) +def _estimated_text_width(lines: list[str], font_size: float) -> float: + """Measured label-box width using the embedded DejaVu face. + + The native rasterizer blits the same generated face metrics, and DejaVu is + also the default SVG/Matplotlib face. SVG viewers may still resolve an + unbaked Unicode glyph through another font, so reserve one em for each + unknown codepoint instead of inheriting the native atlas's zero advance. + """ + return max( + (_fontmetrics_text_width(line, font_size, missing_advance=font_size) for line in lines), + default=0.0, + ) def _segment_marks( @@ -3157,16 +3177,8 @@ def _legend_text_width(value: Any, char_width: float = _LEGEND_CHAR_WIDTH) -> fl fonts and does paint it, and over-reserving only widens the frame, which can never spill a label. """ - scale = char_width * (_LEGEND_FONT_PX / _LEGEND_CHAR_WIDTH) / _fontmetrics.BASE_PX - total = 0.0 - for ch in str(value): - code = ord(ch) - if _fontmetrics.FIRST <= code <= _fontmetrics.LAST: - total += _fontmetrics.ASCII_ADVANCES[code - _fontmetrics.FIRST] * scale - else: - advance = _fontmetrics.EXTRA_ADVANCES.get(code) - total += char_width if advance is None else advance * scale - return total + font_size = char_width * (_LEGEND_FONT_PX / _LEGEND_CHAR_WIDTH) + return _fontmetrics_text_width(value, font_size, missing_advance=char_width) def _legend_text(value: Any, max_width: float, char_width: float = _LEGEND_CHAR_WIDTH) -> str: diff --git a/python/xy/components.py b/python/xy/components.py index a1e8a897..c564dbb1 100644 --- a/python/xy/components.py +++ b/python/xy/components.py @@ -215,7 +215,6 @@ class Axis(Component): type_: Optional[str] = None # "linear" | "time" | "log" | "symlog" constant: Optional[float] = None domain: Optional[tuple[float, float]] = None - margin: Optional[float] = None bounds: Union[tuple[float, float], Literal["data"], None] = None reverse: bool = False format: Optional[str] = None @@ -228,6 +227,8 @@ class Axis(Component): tick_label_min_gap: Optional[float] = None side: Optional[str] = None style: dict[str, StyleValue] = field(default_factory=dict) + # New fields append after the v0.0.3 positional surface. + margin: Optional[float] = None @dataclass @@ -236,7 +237,6 @@ class Legend(Component): show: bool = True loc: Optional[str] = None - anchor: Optional[tuple[float, ...]] = None ncols: int = 1 title: Optional[str] = None class_name: Optional[str] = None @@ -246,6 +246,7 @@ class Legend(Component): # construction over the released field order must keep binding. highlight: bool = True toggle: bool = True + anchor: Optional[tuple[float, ...]] = None @dataclass @@ -1262,7 +1263,7 @@ def violin( group: Union[str, ArrayLike, None] = None, name: Optional[str] = None, color: Optional[str] = None, - width: Any = 0.8, + width: float = 0.8, bins: int = 64, opacity: float = 0.55, orientation: str = "vertical", @@ -1560,7 +1561,7 @@ def bar( name: Optional[str] = None, color: Any = None, colors: Optional[list[str]] = None, - width: float = 0.8, + width: Union[Scalar, ArrayLike] = 0.8, base: Union[str, Scalar, ArrayLike] = 0.0, mode: str = "grouped", orientation: str = "vertical", @@ -1643,7 +1644,7 @@ def column( name: Optional[str] = None, color: Union[str, Sequence[str], None] = None, colors: Optional[list[str]] = None, - width: Any = 0.8, + width: Union[Scalar, ArrayLike] = 0.8, base: Union[str, Scalar, ArrayLike] = 0.0, mode: str = "grouped", orientation: str = "vertical", @@ -1669,7 +1670,7 @@ def column( name: Series label used by legends and tooltips. color: Constant color, values, or a column name. colors: Colors assigned to multiple series. - width: Column width in category units. + width: Scalar or per-column widths in category units. base: Baseline value, values, or a column name. mode: ``grouped``, ``stacked``, or ``normalized`` layout. orientation: Orientation forwarded to the bar renderer. diff --git a/python/xy/marks.py b/python/xy/marks.py index f3cccb3d..775f9a11 100644 --- a/python/xy/marks.py +++ b/python/xy/marks.py @@ -642,10 +642,16 @@ def _bar_like( raise ValueError(f"{kind} orientation must be 'vertical' or 'horizontal'") category_axis = "x" if orientation == "vertical" else "y" pos, category_labels = self._axis_positions_with_labels(x, category_axis) - raw_width_array = np.asarray(width) + try: + raw_width_array = np.asarray(width) + except (TypeError, ValueError) as exc: + raise ValueError(f"{kind} width must be scalar or contain numeric values") from exc if np.issubdtype(raw_width_array.dtype, np.bool_): raise ValueError(f"{kind} width must be scalar or contain numeric values") - width_array = np.asarray(width, dtype=np.float64) + try: + width_array = np.asarray(width, dtype=np.float64) + except (TypeError, ValueError) as exc: + raise ValueError(f"{kind} width must be scalar or contain numeric values") from exc if width_array.ndim == 0: width_values: float | np.ndarray = self._positive_scalar( float(width_array), f"{kind} width" @@ -2313,8 +2319,11 @@ def contour( raise ValueError("contour color arrays must contain direct RGB/RGBA rows") color_table = color_channel.rgba color = None - if np.isscalar(width): - width = self._positive_scalar(width, "contour width") + width_array = np.asarray(width) + if width_array.ndim == 0: + # Unwrap before scalar validation so a 0-D boolean array remains a + # boolean (and is rejected) instead of coercing silently to 0.0/1.0. + width = self._positive_scalar(width_array.item(), "contour width") width_values = None else: width_values = self._as_1d_float(width, "contour width") diff --git a/python/xy/pyplot/__init__.py b/python/xy/pyplot/__init__.py index 987b94ac..96008243 100644 --- a/python/xy/pyplot/__init__.py +++ b/python/xy/pyplot/__init__.py @@ -292,6 +292,10 @@ def subplots( ``gridspec_kw``). subplot_kw : dict, optional Properties applied to every created axes via ``Axes.set``. + layout : {"none", "tight", "constrained", "compressed"}, optional + Layout mode applied after axes are created. ``"tight"``, + ``"constrained"``, and ``"compressed"`` use the shim's deterministic + tight-layout pass; ``None`` and ``"none"`` leave layout unchanged. **kwargs Remaining keywords are forwarded to `figure` (e.g. ``facecolor``, ``toolbar``). @@ -343,7 +347,11 @@ def subplot_mosaic(mosaic: str | list[Any], **kwargs: Any) -> tuple[Figure, dict ``mosaic`` is a string like ``"AB;CC"`` or a nested list of labels; the result maps each label to its `Axes`. ``figsize``/``dpi`` size - the figure; other keywords go to ``Figure.subplot_mosaic``. + the figure. ``layout`` accepts ``None``, ``"none"``, ``"tight"``, + ``"constrained"``, or ``"compressed"`` and is applied after the axes are + created; ``None``/``"none"`` leave layout unchanged, while the latter three + use the shim's deterministic tight-layout pass. All other keywords go to + ``Figure.subplot_mosaic``. """ figsize = kwargs.pop("figsize", None) dpi = kwargs.pop("dpi", None) diff --git a/python/xy/pyplot/_artists.py b/python/xy/pyplot/_artists.py index b2cf5d38..53d3649d 100644 --- a/python/xy/pyplot/_artists.py +++ b/python/xy/pyplot/_artists.py @@ -517,7 +517,8 @@ def legend_elements( if not unique.size: return [], [] transformed = np.asarray(func(unique), dtype=np.float64) - if num == "auto" and len(unique) <= 9: + auto = isinstance(num, str) and num == "auto" + if num is None or (auto and len(unique) <= 9): chosen = unique label_values = transformed elif not np.isscalar(num): @@ -1054,18 +1055,26 @@ def set(self, **kwargs: Any) -> "ContourSet": }, ) if "linewidth" in kwargs: - self._entry["kwargs"]["width"] = float(kwargs.pop("linewidth")) + self.set_linewidth(kwargs.pop("linewidth")) self._touch() return self def get_linewidth(self) -> list[float]: - return np.asarray(self._entry["kwargs"].get("width", 1.1), dtype=float).reshape(-1).tolist() + authored = self._entry.get( + "source_linewidths", + np.asarray(self._entry["kwargs"].get("width", 1.1), dtype=float) + / self._axes._point_scale(), + ) + return np.asarray(authored, dtype=float).reshape(-1).tolist() def set_linewidth(self, width: Any) -> None: values = np.asarray(width, dtype=float).reshape(-1) if not len(values) or not np.isfinite(values).all() or np.any(values <= 0): raise ValueError("contour linewidth must contain positive finite values") - self._entry["kwargs"]["width"] = float(values[0]) if len(values) == 1 else values + authored: Any = float(values[0]) if len(values) == 1 else values + rendered = values * self._axes._point_scale() + self._entry["source_linewidths"] = authored + self._entry["kwargs"]["width"] = float(rendered[0]) if len(rendered) == 1 else rendered self._touch() def set_linestyle(self, style: Any) -> None: diff --git a/python/xy/pyplot/_axes.py b/python/xy/pyplot/_axes.py index 2a7b0dc2..21668fec 100644 --- a/python/xy/pyplot/_axes.py +++ b/python/xy/pyplot/_axes.py @@ -171,7 +171,6 @@ def _path_intersects_boxes( hit = True break if hit: - hit = True break result.append(hit) return result @@ -1841,7 +1840,6 @@ def _bar_like( except (TypeError, ValueError): raise ValueError("bar align='edge' requires numeric positions") from None check_unsupported(kwargs, "bar()/barh()") - n_bars = int(np.asarray(vals).size) patch_labels: Optional[list[str]] = None if label is not None and not isinstance(label, str) and np.iterable(label): patch_labels = [_plain_text(value) for value in label] @@ -2051,7 +2049,11 @@ def dataset_values(value: Any, name: str, *, color_value: bool = False) -> list[ linewidths = dataset_values(linewidth, "linewidth") linestyles = dataset_values(linestyle, "linestyle") hatches = dataset_values(hatch, "hatch") - labels = label if isinstance(label, (list, tuple)) else [label] * len(datasets) + # Matplotlib intentionally tolerates label-count mismatches: a scalar + # labels only the first dataset, short sequences leave later datasets + # unlabeled, and extra labels are ignored. + label_values = [] if label is None else np.atleast_1d(np.asarray(label, dtype=str)).tolist() + labels = (label_values + [None] * len(datasets))[: len(datasets)] containers: list[BarContainer] = [] base = np.zeros(len(edges) - 1, dtype=np.float64) centers = (edges[:-1] + edges[1:]) * 0.5 @@ -2603,12 +2605,14 @@ def extreme(name: str, default: tuple[float, float, float, float]) -> np.ndarray # The notebook's ordinary image box is ~369 px per side. A 128² # intermediate left each interpolated sample covering about 3×3 # display pixels because heatmaps intentionally use nearest texture - # sampling. Keep a bounded 512² surface so non-nearest imshow output - # is at least display-resolution while nearest retains source cells. + # sampling. Keep a bounded 512–1024 px surface so non-nearest + # imshow output is at least display-resolution without making a + # large source image allocate or multiply dense source-sized + # resampling matrices. Nearest retains the original source cells. grid = _resample_grid( grid, - max(512, grid.shape[1]), - max(512, grid.shape[0]), + min(1024, max(512, grid.shape[1])), + min(1024, max(512, grid.shape[0])), effective_interpolation, ) if transform == self.transAxes and extent is not None: @@ -7039,10 +7043,16 @@ def _masked_float(value: Any) -> np.ndarray: return np.ma.asarray(value, dtype=np.float64).filled(np.nan) -def _interpolation_weights(source: int, target: int, method: str) -> np.ndarray: - """Return a normalized target-by-source matrix for a separable filter.""" +def _interpolation_taps(source: int, target: int, method: str) -> tuple[np.ndarray, np.ndarray]: + """Return source indices and normalized local taps for a separable filter.""" positions = np.linspace(0.0, source - 1.0, target)[:, None] - distance = positions - np.arange(source, dtype=np.float64)[None, :] + # Every supported kernel has radius at most four. Gathering those local + # taps avoids the old target-by-source dense matrix, whose mostly-zero + # allocation and matrix multiplies made ordinary large-image imshow + # quadratic in memory and cubic in work. + indices = np.floor(positions).astype(np.int64) + np.arange(-4, 5, dtype=np.int64) + valid = (indices >= 0) & (indices < source) + distance = positions - indices absolute = np.abs(distance) def keys(a: float) -> np.ndarray: @@ -7096,24 +7106,42 @@ def keys(a: float) -> np.ndarray: "antialiased": -0.5, }.get(method, -0.5) weights = keys(cubic_a) + weights = np.where(valid, weights, 0.0) totals = weights.sum(axis=1, keepdims=True) - return weights / np.where(np.abs(totals) > 1e-12, totals, 1.0) + return ( + np.clip(indices, 0, source - 1), + weights / np.where(np.abs(totals) > 1e-12, totals, 1.0), + ) def _resample_grid(grid: np.ndarray, width: int, height: int, method: str) -> np.ndarray: """Dependency-free separable resampling for scalar and RGB(A) images.""" values = np.asarray(grid, dtype=np.float64) - wy = _interpolation_weights(values.shape[0], height, method) - wx = _interpolation_weights(values.shape[1], width, method) + iy, wy = _interpolation_taps(values.shape[0], height, method) + ix, wx = _interpolation_taps(values.shape[1], width, method) + + def apply_taps(array: np.ndarray) -> np.ndarray: + # Accumulate one tap at a time. A vectorized ``take`` over the whole + # tap matrix materializes target × taps × source intermediates and can + # consume more memory than the dense weights this replaces. + vertical = np.zeros((len(iy), *array.shape[1:]), dtype=np.float64) + y_shape = (len(iy),) + (1,) * (array.ndim - 1) + for tap in range(iy.shape[1]): + vertical += np.take(array, iy[:, tap], axis=0) * wy[:, tap].reshape(y_shape) + horizontal = np.zeros((vertical.shape[0], len(ix), *vertical.shape[2:]), dtype=np.float64) + x_shape = (1, len(ix)) + (1,) * (array.ndim - 2) + for tap in range(ix.shape[1]): + horizontal += np.take(vertical, ix[:, tap], axis=1) * wx[:, tap].reshape(x_shape) + return horizontal def resample(channel: np.ndarray) -> np.ndarray: finite = np.isfinite(channel) if finite.all(): - return wy @ channel @ wx.T + return apply_taps(channel) # Renormalize around masked samples instead of allowing IEEE # ``0 * nan`` terms to poison every output pixel touched by a filter. - numerator = wy @ np.where(finite, channel, 0.0) @ wx.T - denominator = wy @ finite.astype(np.float64) @ wx.T + numerator = apply_taps(np.where(finite, channel, 0.0)) + denominator = apply_taps(finite.astype(np.float64)) return np.divide( numerator, denominator, diff --git a/python/xy/pyplot/_grid.py b/python/xy/pyplot/_grid.py index 1a24d8b9..59738f33 100644 --- a/python/xy/pyplot/_grid.py +++ b/python/xy/pyplot/_grid.py @@ -435,7 +435,4 @@ def _blend_raster_suptitle( in {"bold", "semibold", "demibold", "heavy", "black"}, ) overlay = kernels.rasterize(bytes(cmd.buf), canvas.shape[1], title_h) - alpha = overlay[:, :, 3:4].astype(np.float64) / 255.0 - canvas[:title_h, :, :3] = np.round( - overlay[:, :, :3] * alpha + canvas[:title_h, :, :3] * (1.0 - alpha) - ).astype(np.uint8) + _composite_rgba(canvas[:title_h], overlay) diff --git a/python/xy/pyplot/_mathtext.py b/python/xy/pyplot/_mathtext.py index 195020a1..5af98082 100644 --- a/python/xy/pyplot/_mathtext.py +++ b/python/xy/pyplot/_mathtext.py @@ -111,14 +111,31 @@ "tan": "tan", } -_UPRIGHT_WORDS = frozenset( - value - for name, value in _COMMANDS.items() - if name.isalpha() and value.isascii() and value.isalpha() +_UPRIGHT_COMMANDS = frozenset( + { + "Gamma", + "Delta", + "Theta", + "Lambda", + "Xi", + "Pi", + "Sigma", + "Phi", + "Psi", + "Omega", + "sum", + "prod", + } + | { + name + for name, value in _COMMANDS.items() + if name.isalpha() and value.isascii() and value.isalpha() + } ) # Wrappers whose braces disappear and whose contents pass through. _WRAPPERS = ("mathdefault", "mathrm", "mathit", "mathbf", "text", "textrm", "operatorname") +_UPRIGHT_WRAPPERS = frozenset({"mathdefault", "mathrm", "mathbf", "text", "textrm", "operatorname"}) _SUPERSCRIPTS = dict(zip("0123456789+-=()ni", "⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ⁿⁱ", strict=True)) _SUBSCRIPTS = dict( @@ -129,6 +146,9 @@ _FRAC = re.compile(r"\\frac\{([^{}]*)\}\{([^{}]*)\}") _SCRIPT = re.compile(r"([\^_])(\{[^{}]*\}|[^\s{}])") _COMMAND = re.compile(r"\\([A-Za-z]+|[%,;! ])") +_STYLE_ITALIC = "\x02" +_STYLE_UPRIGHT = "\x03" +_STYLE_POP = "\x04" def _convert_script(kind: str, body: str) -> str | None: @@ -140,8 +160,8 @@ def _convert_script(kind: str, body: str) -> str | None: return "".join(table[ch] for ch in body) -def _convert_math(body: str) -> str | None: - """Convert one $...$ span; None when it needs more TeX than we speak.""" +def _convert_math_styled(body: str) -> tuple[str, list[bool]] | None: + """Convert one math span while retaining each glyph's source font style.""" out = body for _ in range(4): # nested \frac replaced = _FRAC.sub(lambda m: f"{m.group(1)}/{m.group(2)}", out) @@ -159,19 +179,53 @@ def script(match: re.Match[str]) -> str: if "\x00" in out: return None for name in _WRAPPERS: - out = re.sub(r"\\" + name + r"\{([^{}]*)\}", r"\1", out) + marker = _STYLE_UPRIGHT if name in _UPRIGHT_WRAPPERS else _STYLE_ITALIC + out = re.sub( + r"\\" + name + r"\{([^{}]*)\}", + lambda match, marker=marker: marker + match.group(1) + _STYLE_POP, + out, + ) out = out.replace("\\left", "").replace("\\right", "") def command(match: re.Match[str]) -> str: - return _COMMANDS.get(match.group(1), "\x00") + name = match.group(1) + converted = _COMMANDS.get(name) + if converted is None: + return "\x00" + if name in _UPRIGHT_COMMANDS: + return _STYLE_UPRIGHT + converted + _STYLE_POP + return converted out = _COMMAND.sub(command, out) if "\x00" in out or "\\" in out: return None - # Unescaped spaces are insignificant in math mode. Match Matplotlib's - # Unicode minus while retaining deliberate ``\,``/``\;``/``\ `` gaps. - out = re.sub(r"\s+", "", out) - return out.replace("-", "−").replace("\x01", " ").replace("{", "").replace("}", "") + + # Unescaped spaces are insignificant in math mode. Explicit spacing + # commands survive as ``\x01``. A stack lets command-local upright spans + # restore an enclosing wrapper rather than flattening all provenance. + pieces: list[str] = [] + italic: list[bool] = [] + style_stack = [True] + for character in out: + if character == _STYLE_ITALIC: + style_stack.append(True) + elif character == _STYLE_UPRIGHT: + style_stack.append(False) + elif character == _STYLE_POP: + if len(style_stack) > 1: + style_stack.pop() + elif character.isspace(): + continue + elif character not in "{}": + pieces.append(" " if character == "\x01" else "−" if character == "-" else character) + italic.append(style_stack[-1]) + return "".join(pieces), italic + + +def _convert_math(body: str) -> str | None: + """Convert one $...$ span; None when it needs more TeX than we speak.""" + converted = _convert_math_styled(body) + return None if converted is None else converted[0] def mathtext_to_unicode(text: str) -> str: @@ -209,19 +263,18 @@ def mathtext_italic_ranges(text: str) -> tuple[str, list[tuple[int, int]]]: for match in _MATH_SPAN.finditer(text): prefix = text[source_cursor : match.start()] output_cursor += len(prefix) - body = _convert_math(match.group(1)) - if body is None: # guarded by ``converted == text`` above + styled = _convert_math_styled(match.group(1)) + if styled is None: # guarded by ``converted == text`` above return converted, [] + body, italic = styled token_start: int | None = None - for index, character in enumerate(body + "\0"): - if character.isalpha(): + for index in range(len(body) + 1): + if index < len(body) and body[index].isalpha() and italic[index]: if token_start is None: token_start = index continue if token_start is not None: - token = body[token_start:index] - if token not in _UPRIGHT_WORDS: - ranges.append((output_cursor + token_start, output_cursor + index)) + ranges.append((output_cursor + token_start, output_cursor + index)) token_start = None output_cursor += len(body) source_cursor = match.end() diff --git a/python/xy/pyplot/_plot_types.py b/python/xy/pyplot/_plot_types.py index 777c91ad..a35352b1 100644 --- a/python/xy/pyplot/_plot_types.py +++ b/python/xy/pyplot/_plot_types.py @@ -2932,16 +2932,21 @@ def _contour(self, filled: bool, args: tuple[Any, ...], kwargs: dict[str, Any]) resolve_rgba(color_values[-1]) if use_extreme_colors else resolved[-1], ) color = np.ascontiguousarray(resolved, dtype=np.float64) - # Matplotlib contour linewidths are points. The browser renderer uses - # CSS pixels, so the 1.5 pt default becomes 2 px at 96 dpi. + # Keep Matplotlib's public linewidth state in points while the render + # trace uses output pixels. if linewidths is None: - width: Any = float(rcParams["lines.linewidth"]) * (4.0 / 3.0) + public_width: Any = float(rcParams["lines.linewidth"]) elif np.isscalar(linewidths): - width = _float(linewidths) * (4.0 / 3.0) + public_width = _float(linewidths) else: - width = np.asarray(linewidths, dtype=float).reshape(-1) * (4.0 / 3.0) - if not len(width): + public_width = np.asarray(linewidths, dtype=float).reshape(-1) + if not len(public_width): raise ValueError("linewidths must contain at least one value") + public_values = np.asarray(public_width, dtype=float).reshape(-1) + if not np.isfinite(public_values).all() or np.any(public_values <= 0): + raise ValueError("linewidths must contain positive finite values") + width_values = public_values * self._point_scale() + width: Any = float(width_values[0]) if len(width_values) == 1 else width_values transparent_fill = filled and isinstance(colors, str) and colors.lower() == "none" entry = self._add( "@mark", @@ -2970,6 +2975,7 @@ def _contour(self, filled: bool, args: tuple[Any, ...], kwargs: dict[str, Any]) "corner_mask": bool(corner_mask), }, "source_z": za, + "source_linewidths": public_width, "corner_mask": bool(corner_mask), "domain": (float(public_levels[0]), float(public_levels[-1])), "hatches": list(hatches) if hatches is not None else None, diff --git a/python/xy/pyplot/_ticker.py b/python/xy/pyplot/_ticker.py index a461c9f8..734ab115 100644 --- a/python/xy/pyplot/_ticker.py +++ b/python/xy/pyplot/_ticker.py @@ -33,6 +33,28 @@ def _scale_range(vmin: float, vmax: float, n: int) -> tuple[float, float]: return scale, offset +def _nonsingular( + vmin: float, + vmax: float, + *, + expander: float, + tiny: float, +) -> tuple[float, float]: + """Matplotlib's finite, increasing fallback for a singular interval.""" + if not (np.isfinite(vmin) and np.isfinite(vmax)): + return -expander, expander + if vmax < vmin: + vmin, vmax = vmax, vmin + vmin, vmax = float(vmin), float(vmax) + max_abs = max(abs(vmin), abs(vmax)) + if max_abs < (1e6 / tiny) * np.finfo(float).tiny: + return -expander, expander + if vmax - vmin <= max_abs * tiny: + vmin -= expander * abs(vmin) + vmax += expander * abs(vmax) + return vmin, vmax + + class _EdgeInteger: """matplotlib's ``ticker._Edge_integer``: offset-tolerant edge rounding.""" @@ -135,7 +157,9 @@ def __init__(self, nbins: Any = 10, **kwargs: Any) -> None: ] ) - def _raw_ticks(self, vmin: float, vmax: float, *, round_numbers: bool = False) -> np.ndarray: + def _raw_ticks(self, vmin: float, vmax: float) -> np.ndarray: + from ._rc import rcParams + vmin, vmax = sorted((float(vmin), float(vmax))) if not (np.isfinite(vmin) and np.isfinite(vmax)) or vmin == vmax: return np.asarray([vmin], dtype=float) @@ -153,7 +177,7 @@ def _raw_ticks(self, vmin: float, vmax: float, *, round_numbers: bool = False) - steps = steps[(steps < 1) | (np.abs(steps - np.round(steps)) < 0.001)] raw_step = (_vmax - _vmin) / nbins large_steps = steps >= raw_step - if round_numbers: + if rcParams["axes.autolimit_mode"] == "round_numbers": # Match Matplotlib's MaxNLocator round-number mode: reject a step # that cannot span the entire padded view in ``nbins`` intervals. floored_vmins = (_vmin // steps) * steps @@ -178,17 +202,17 @@ def _raw_ticks(self, vmin: float, vmax: float, *, round_numbers: bool = False) - return ticks + offset def tick_values(self, vmin: float, vmax: float) -> np.ndarray: + vmin, vmax = _nonsingular(vmin, vmax, expander=1e-13, tiny=1e-14) return self._raw_ticks(vmin, vmax) def view_limits(self, vmin: float, vmax: float) -> tuple[float, float]: """Return data limits, or edge ticks in Matplotlib round-number mode.""" from ._rc import rcParams + vmin, vmax = _nonsingular(vmin, vmax, expander=1e-12, tiny=1e-13) if rcParams["axes.autolimit_mode"] != "round_numbers": - return float(vmin), float(vmax) - ticks = self._raw_ticks(vmin, vmax, round_numbers=True) - if len(ticks) < 2: - return float(vmin), float(vmax) + return vmin, vmax + ticks = self._raw_ticks(vmin, vmax) return float(ticks[0]), float(ticks[-1]) diff --git a/spec/api/styling.md b/spec/api/styling.md index a9dd01c6..18b7cd64 100644 --- a/spec/api/styling.md +++ b/spec/api/styling.md @@ -208,7 +208,7 @@ subtracting these reservations. The **left** gutter is additionally floored at what the left y axis's own text measures, rather than trusting the flat `46/62 px`: -``` +```text left ≥ 10 px inset + half the title's line box + 0.4 em title-to-tick gap + tick_padding (+ the outward part of tick_length) diff --git a/spec/matplotlib/compat.md b/spec/matplotlib/compat.md index ef5009be..0d5f39aa 100644 --- a/spec/matplotlib/compat.md +++ b/spec/matplotlib/compat.md @@ -58,7 +58,7 @@ dependency-free `triangles=` shorthand into Matplotlib's equivalent | `boxplot`, `violinplot`, `bxp`, `violin`, `errorbar` | Boxplots support notches, bootstrap/user confidence intervals, median overrides (drawn median only; notch CIs stay data-derived like Matplotlib), percentile/custom whiskers, cap widths, `sym`, and component colors/widths/alpha — dashed component linestyles fail loudly. Violins support Scott/Silverman/scalar/callable Gaussian-KDE bandwidths, quantiles, and low/high sides; the default (bw_method omitted) uses the native histogram violin mark, whose shape differs from the explicit KDE path. `boxplot` autoscales its value axis over the Tukey whiskers plus, when `showfliers` is on, the flier points. Its default category positions are 1-based and `manage_ticks=True` reserves half a unit around the outer positions, matching Matplotlib | | `fill_between(x, y1, y2, where=, step=)` / `fill_betweenx` | Masks are split into finite contiguous polygons; step geometry is expanded exactly | | `stackplot` | All four baselines are computed by the native stacked-bounds kernel | -| `imshow` / `pcolormesh` (`cmap=`, `vmin=`/`vmax=`, `origin=`) | `imshow` defaults to `rcParams['image.origin']`; nearest stays cell-exact and Matplotlib's smoothing mode names all collapse to the shim's single bounded gradient upsampling (a visual approximation, not per-mode kernels) and apply to scalar data only — RGB(A) truecolor arrays render unresampled — while unsupported stages/transforms fail loudly. Uniform meshes retain the texture fast path; nonuniform and curvilinear grids use native quad-to-triangle expansion. Both hug their outer cell edge with no margin, as Matplotlib's sticky image/mesh edges do | +| `imshow` / `pcolormesh` (`cmap=`, `vmin=`/`vmax=`, `origin=`) | `imshow` defaults to `rcParams['image.origin']`; nearest stays cell-exact, while named smoothing modes use dependency-free per-kernel approximations over a bounded 512–1024 px intermediate for both scalar and RGB(A) data. Filter choice and intermediate size do not yet depend on final display resolution, and explicit `interpolation="auto"` remains unsupported. Unsupported stages/transforms fail loudly. Uniform meshes retain the texture fast path; nonuniform and curvilinear grids use native quad-to-triangle expansion. Both hug their outer cell edge with no margin, as Matplotlib's sticky image/mesh edges do | | `step`, `stairs`, `stem`, `eventplot` | Compact step/stem/segment marks; no Python-side vertex expansion | | `contour` / `contourf` / `clabel` | Native marching squares over rectilinear grids; warped grids route through native Delaunay/marching-triangle kernels; automatic labels repeat at bounded, separated positions along each level (line knockout for `inline=True` remains a visual approximation) | | `quiver`, `barbs`, `streamplot` | Quiver supports Matplotlib's width-unit vocabulary independently from length scaling. Barbs use fixed-length staffs and Matplotlib's flag/full/half decomposition, including increments, rounding, empty glyphs, colors, sizes, flipping, and pivots. Streamplot uses a dependency-free adaptive Heun integrator with occupancy-aware seeding; `start_points`, `integration_direction`, `broken_streamlines`, integration step/error scales, array widths/colors, and `num_arrows` are honored | @@ -66,7 +66,7 @@ dependency-free `triangles=` shorthand into Matplotlib's equivalent | `pie` / `pie_label` | Native pie/donut tessellation and the Matplotlib 3.11 `PieContainer` (`values`, `fracs`, grouped text labels), including dtype-preserving value formats, radial label rotation/alignment, and common text properties | | `axhline` / `axvline` / `axhspan` / `axvspan`, `text`, `annotate`, `table` | Fractional span bounds plus data/axes/figure text coordinates are supported. `annotate(arrowprops=)` draws real arrows in every output: offset-point text becomes an engine callout (arrow pinned from label to point across zoom), data-coordinate text an arrow annotation; date-string coordinates convert on datetime axes. Arrowstyles map to head/tail shapes (`->` open V, `-\|>` filled, `\|-\|`/brackets bar caps, `fancy`/`simple`/`wedge` filled tapered shafts sized by the text's mutation scale) and `connectionstyle` arc3/angle3/angle become quadratic curves (corner rounding approximated); `alpha` dims the arrow only. `bbox=` becomes label box styles (fill/edge/round corners/`pad`) in browser and static exports; its `alpha` is the *patch* alpha and dims face and edge together, as Matplotlib's element `opacity` does, and `boxstyle="round"`/`round4` corners are rounded in SVG (`rx`) and native PNG as well as in the browser. An arrow-less `text`/`annotate` label is painted with `rcParams["text.color"]` in all three renderers rather than each renderer's own annotation-label default. Text is unclipped like Matplotlib (`clip_on=False`), and axes-fraction text right of the axes box (x > 1, e.g. seaborn-style row titles) reserves right margin in every exporter. `rotation=90/270` renders vertical text in browser, PNG, and SVG with Matplotlib's rotate-then-align box semantics; other angles rotate in browser and SVG output only (native PNG draws them horizontally) | | `from xy.pyplot import FacetGrid` (seaborn-shaped) | Row/column small multiples with seaborn's `map` contract (subset → activate panel → call the pyplot function), shared domains, edge-only axis labels, top-row column titles, and `margin_titles=True` rotated row titles. `hue=`/`palette=`, `col_wrap=`, `map_dataframe`, and `add_legend` fail loudly | -| `xlabel` / `ylabel` / `title` / `suptitle` | Suptitles are retained in HTML and multi-panel PNG/SVG. `ylabel` sits clear of the y tick labels in every renderer: the left gutter is reserved from the measured advances of the tick labels and the rotated title rather than from a fixed constant, leaving Matplotlib's `0.4 em` (5.6 px at the 10 pt/100 dpi default) title-to-tick gap — see *Chrome gutters and the rotated y-axis title* in `spec/api/styling.md` for the formula and its two documented asymmetries | +| `xlabel` / `ylabel` / `title` / `suptitle` | Suptitles are retained in HTML and multi-panel PNG/SVG. `ylabel` sits clear of the y tick labels in every renderer: the left gutter is reserved from the measured advances of the tick labels and the rotated title rather than from a fixed constant, leaving Matplotlib's `0.4 em` (5.6 px at the 10 pt/100 dpi default) title-to-tick gap — see *Measured left gutter and the rotated y-axis title* in `spec/api/styling.md` for the formula and its two documented asymmetries | | `legend()` | `loc`, columns, title/font size/colors, frame styling, `borderpad`, `labelspacing`, `borderaxespad`, `fancybox`, `framealpha`, and `shadow` are retained across browser and static output. `loc='best'` scores the measured displayed legend box in Matplotlib location-code order using path vertices/crossings, collection offsets, and bar-rectangle overlaps. It resolves before the wire; pyplot rejects misspelled Matplotlib locations without narrowing core `xy.legend()`'s independent location vocabulary. Text-box scoring and bounded long-path sampling are documented in `spec/api/styling.md` § Legend placement | | `grid(True/False)` | toggles the grid via the theme | | `xlim` / `ylim`, `set_xmargin` / `set_ymargin`, axis scales, `invert_xaxis/yaxis` | linear/log are native; symlog/logit/asinh use dependency-free monotone data transforms with inverse limit/tick semantics. Automatic linear ticks include Matplotlib's 2.5 step and use uniform decimal padding across a tick set; locations refresh as data arrives. `axes.autolimit_mode="round_numbers"` expands automatic linear limits to the first and last AutoLocator ticks after applying the configured margins. Artist `get_data()` reflects the transformed space; logit masks values at/outside (0, 1) | diff --git a/spec/matplotlib/shim-todo.md b/spec/matplotlib/shim-todo.md index 4a7bccdc..0b3d299d 100644 --- a/spec/matplotlib/shim-todo.md +++ b/spec/matplotlib/shim-todo.md @@ -653,13 +653,11 @@ streamplot ### Accepted approximations (documented, still divergent) -- Barbs glyph is a bounded tick count, not WMO 50/10/5 geometry. -- Streamplot uses a fixed-step integrator; paths differ from Matplotlib's - adaptive one; density tuples reduce to their max. -- imshow smoothing-mode names collapse to one bilinear upsample; truecolor - RGB(A) is unresampled. -- `annotate(arrowprops=)` reduces to callout text; errorbar limit flags drop - caret arrows. +- imshow's dependency-free named filters approximate Matplotlib's AGG kernels + and use a bounded 512–1024 px intermediate rather than selecting the filter + and target size from the final display resolution; explicit + `interpolation="auto"` remains unsupported. +- Errorbar limit flags render one-sided bars without Matplotlib's caret arrows. - stem/eventplot/triplot/hlines/vlines dashes are data-space geometry (they scale with zoom). - Exception types diverge by design: TypeError/NotImplementedError where diff --git a/src/raster.rs b/src/raster.rs index 12aadfa3..437a5aaf 100644 --- a/src/raster.rs +++ b/src/raster.rs @@ -2174,7 +2174,7 @@ fn rasterize_with_spans( let angle = r.f32()?; let flags = r.u8()?; let range_count = r.u32()? as usize; - let mut italic_ranges = Vec::with_capacity(range_count); + let mut italic_ranges = Vec::with_capacity(r.bounded_capacity(range_count, 8)); for _ in 0..range_count { italic_ranges.push((r.u32()?, r.u32()?)); } @@ -2701,6 +2701,37 @@ mod tests { assert!(symbol_sdf(0.6 * extent, 0.0, radius, 14).abs() < 1e-6); } + #[test] + fn axis_aligned_symbol_bounds_do_not_use_radial_corner_distance() { + let radius = 3.0; + let corner = radius * std::f32::consts::SQRT_2; + let boundary_points = [ + (1, (radius, radius)), + (3, (-radius, radius)), + (8, (-radius, -radius)), + (9, (radius, radius)), + (10, (-radius, -radius)), + (13, (radius, radius)), + ]; + + for (symbol, (x, y)) in boundary_points { + assert_eq!( + symbol_extent(radius, symbol), + radius, + "symbol {symbol} has an axis-aligned half-extent of r" + ); + assert!( + symbol_sdf(x, y, radius, symbol).abs() < 1e-6, + "symbol {symbol} must reach its diagonal boundary point" + ); + assert_eq!( + x.abs().max(y.abs()), + radius, + "the AABB extent is not the corner's {corner} radial distance" + ); + } + } + fn px(out: &[u8], w: usize, x: usize, y: usize) -> [u8; 4] { let o = (y * w + x) * 4; [out[o], out[o + 1], out[o + 2], out[o + 3]] @@ -2908,7 +2939,22 @@ mod tests { smooth_dashes.extend([0; 8]); // width and RGBA smooth_dashes.extend(huge); - for cmd in [points, gradient_stops, stroke_dashes, smooth_dashes] { + let mut styled_text_ranges = vec![OP_STYLED_TEXT]; + styled_text_ranges.extend(f32le(0.0)); // x + styled_text_ranges.extend(f32le(0.0)); // y + styled_text_ranges.push(0); // anchor + styled_text_ranges.extend(f32le(12.0)); // size + styled_text_ranges.extend(f32le(0.0)); // angle + styled_text_ranges.push(0); // flags + styled_text_ranges.extend(u32le(u32::MAX)); // no range bytes follow + + for cmd in [ + points, + gradient_stops, + stroke_dashes, + smooth_dashes, + styled_text_ranges, + ] { assert!(!rasterize_into(&cmd, 4, 4, &mut out)); } } diff --git a/tests/pyplot/test_adversarial_parity_fixes.py b/tests/pyplot/test_adversarial_parity_fixes.py index c7346436..c8052a28 100644 --- a/tests/pyplot/test_adversarial_parity_fixes.py +++ b/tests/pyplot/test_adversarial_parity_fixes.py @@ -41,8 +41,12 @@ def test_maxn_locator_keeps_scale_for_narrow_far_offset_ranges(): assert inside.sum() == 3 -def test_singular_range_still_returns_a_tick(): - assert list(plt.MaxNLocator(4).tick_values(2.0, 2.0)) == [2.0] +def test_singular_range_expands_to_multiple_finite_ticks(): + ticks = plt.MaxNLocator(4).tick_values(2.0, 2.0) + + assert len(ticks) >= 2 + assert np.isfinite(ticks).all() + assert ticks[0] < 2.0 < ticks[-1] # -- absolute panel placement: titled axes ------------------------------------ diff --git a/tests/pyplot/test_color_pipeline_fixes.py b/tests/pyplot/test_color_pipeline_fixes.py index b30ae12b..c0cae0e3 100644 --- a/tests/pyplot/test_color_pipeline_fixes.py +++ b/tests/pyplot/test_color_pipeline_fixes.py @@ -227,9 +227,12 @@ def test_monochrome_contour_dashes_negative_levels(): plt.contour(xx, yy, zz, colors="black") contours = [t for t in _compiled_traces() if t.kind == "contour"] assert len(contours) == 2 - dashes = sorted(str(t.style.get("dash")) for t in contours) - assert dashes == ["None", "[7.4, 3.2]"] # negatives dashed, non-negatives solid - assert all(t.style["width"] == pytest.approx(2.0) for t in contours) + expected_width = plt.rcParams["lines.linewidth"] * plt.rcParams["figure.dpi"] / 72.0 + dashed = [trace for trace in contours if trace.style.get("dash") is not None] + solid = [trace for trace in contours if trace.style.get("dash") is None] + assert len(dashed) == len(solid) == 1 + assert dashed[0].style["dash"] == pytest.approx([3.7 * expected_width, 1.6 * expected_width]) + assert all(t.style["width"] == pytest.approx(expected_width) for t in contours) assert all(t.style["opacity"] == pytest.approx(1.0) for t in contours) diff --git a/tests/pyplot/test_gallery_auto_ticks_compat.py b/tests/pyplot/test_gallery_auto_ticks_compat.py index 34a44b72..bb2dbfab 100644 --- a/tests/pyplot/test_gallery_auto_ticks_compat.py +++ b/tests/pyplot/test_gallery_auto_ticks_compat.py @@ -6,7 +6,7 @@ import pytest import xy.pyplot as plt -from xy.pyplot._ticker import AutoLocator +from xy.pyplot._ticker import AutoLocator, MaxNLocator def _auto_ticks_data() -> tuple[np.ndarray, np.ndarray]: @@ -87,6 +87,36 @@ def test_auto_locator_round_view_limits_use_edge_ticks() -> None: assert locator.view_limits(-0.42, 1.92) == pytest.approx((-0.5, 2.0)) +def test_maxn_locator_round_mode_uses_the_same_step_for_ticks_and_limits() -> None: + locator = MaxNLocator(4) + + np.testing.assert_allclose(locator.tick_values(0.25, 0.35), [0.25, 0.275, 0.3, 0.325, 0.35]) + assert locator.view_limits(0.25, 0.35) == (0.25, 0.35) + + with plt.rc_context({"axes.autolimit_mode": "round_numbers"}): + np.testing.assert_allclose(locator.tick_values(0.25, 0.35), [0.24, 0.27, 0.3, 0.33, 0.36]) + assert locator.view_limits(0.25, 0.35) == pytest.approx((0.24, 0.36)) + + +@pytest.mark.parametrize("mode", ["data", "round_numbers"]) +def test_maxn_locator_expands_singular_and_nonfinite_limits(mode: str) -> None: + locator = MaxNLocator(4) + + with plt.rc_context({"axes.autolimit_mode": mode}): + lo, hi = locator.view_limits(2.0, 2.0) + assert np.isfinite([lo, hi]).all() + assert lo < 2.0 < hi + + lo, hi = locator.view_limits(np.nan, np.inf) + assert np.isfinite([lo, hi]).all() + assert lo < hi + + ticks = locator.tick_values(2.0, 2.0) + assert len(ticks) >= 2 + assert np.isfinite(ticks).all() + assert ticks[0] < ticks[-1] + + def test_autolimit_mode_rejects_unknown_values() -> None: with pytest.raises(ValueError, match=r"data.*round_numbers"): plt.rcParams["axes.autolimit_mode"] = "rounded" diff --git a/tests/pyplot/test_gallery_hist_errorbar_compat.py b/tests/pyplot/test_gallery_hist_errorbar_compat.py index 866399db..08d73d62 100644 --- a/tests/pyplot/test_gallery_hist_errorbar_compat.py +++ b/tests/pyplot/test_gallery_hist_errorbar_compat.py @@ -62,6 +62,30 @@ def test_hist_dataset_style_lengths_must_match_dataset_count() -> None: ax.hist([[0, 1], [2, 3]], bins=2, linewidth=[1, 2, 3]) +@pytest.mark.parametrize( + ("label", "expected"), + [ + ("first", ["first", None]), + (["first"], ["first", None]), + (["first", "second"], ["first", "second"]), + (["first", "second", "unused"], ["first", "second"]), + (None, [None, None]), + ], +) +def test_hist_labels_are_padded_or_truncated_like_matplotlib( + label: object, expected: list[str | None] +) -> None: + _fig, ax = plt.subplots() + + _counts, _edges, containers = ax.hist( + [[0, 1], [2, 3]], + bins=2, + label=label, + ) + + assert [container.get_label() for container in containers] == expected + + @pytest.mark.parametrize("histtype", ["step", "stepfilled"]) def test_hist_step_geometry_contributes_to_autoscale(histtype: str) -> None: _fig, ax = plt.subplots() diff --git a/tests/pyplot/test_gallery_text_pie_compat.py b/tests/pyplot/test_gallery_text_pie_compat.py index a9d03c68..0285bfbe 100644 --- a/tests/pyplot/test_gallery_text_pie_compat.py +++ b/tests/pyplot/test_gallery_text_pie_compat.py @@ -6,6 +6,8 @@ import pytest import xy.pyplot as plt +from xy.pyplot import _grid +from xy.pyplot._mathtext import mathtext_italic_ranges @pytest.fixture(autouse=True) @@ -50,6 +52,43 @@ def test_positioned_png_keeps_figure_suptitle() -> None: assert np.any(pixels[:48, :, :3] < 200) +def test_raster_suptitle_composites_as_straight_alpha() -> None: + canvas = np.zeros((48, 320, 4), dtype=np.uint8) + + _grid._blend_raster_suptitle( + canvas, + "visible figure title", + None, + scale=1.0, + title_h=48, + ) + + ink = canvas[:, :, 3] > 0 + assert np.any(ink) + # The native text overlay is straight-alpha RGBA: antialiasing belongs in + # alpha, while every covered pixel retains the authored #262626 RGB. + np.testing.assert_array_equal( + np.unique(canvas[:, :, :3][ink], axis=0), + np.array([[38, 38, 38]], dtype=np.uint8), + ) + + +@pytest.mark.parametrize("absolute", [False, True]) +def test_transparent_png_keeps_suptitle_in_grid_and_absolute_layouts(absolute: bool) -> None: + fig, ax = plt.subplots(figsize=(3.2, 2.4), dpi=100) + ax.set_axis_off() + fig.suptitle("visible figure title") + if absolute: + fig.subplots_adjust(top=0.8) + output = BytesIO() + + fig.savefig(output, format="png", transparent=True) + output.seek(0) + pixels = np.asarray(plt.imread(output)) + + assert np.any(pixels[:48, :, 3] > 0) + + @pytest.mark.parametrize( ("distance", "rotate", "expected"), [ @@ -213,6 +252,35 @@ def test_text_preserves_mathtext_italic_span_across_all_exporters() -> None: assert np.any(rgba[..., :3] < 0.5) +@pytest.mark.parametrize( + ("source", "rendered", "ranges"), + [ + (r"$\sum+\prod+\Sigma+\Gamma$", "Σ+Π+Σ+Γ", []), + (r"$\min+min$", "min+min", [(4, 7)]), + (r"$\cos x$", "cosx", [(3, 4)]), + (r"$\Sigma x+\pi$", "Σx+π", [(1, 2), (3, 4)]), + (r"$\mathrm{abc}+\mathit{def}$", "abc+def", [(4, 7)]), + ], +) +def test_mathtext_italic_ranges_preserve_source_command_provenance( + source: str, + rendered: str, + ranges: list[tuple[int, int]], +) -> None: + assert mathtext_italic_ranges(source) == (rendered, ranges) + + +def test_mathtext_operator_stays_upright_next_to_italic_variable_in_svg() -> None: + fig, ax = plt.subplots() + label = ax.text(0, 0, r"$\Sigma x$") + + assert label.get_text() == "Σx" + assert label._entry["kwargs"]["style"]["math_italic_ranges"] == "1:2" + svg = ax._build_chart(*fig._panel_px()).figure().to_svg() + assert ">Σx' in svg + + def test_text_fontdict_styles_title_labels_and_named_math_functions() -> None: fig, ax = plt.subplots(figsize=(6.4, 4.8), dpi=100) font = {"family": "serif", "color": "darkred", "weight": "normal", "size": 16} diff --git a/tests/pyplot/test_layout_text_parity_fixes.py b/tests/pyplot/test_layout_text_parity_fixes.py index 50f7687d..d22fd5cc 100644 --- a/tests/pyplot/test_layout_text_parity_fixes.py +++ b/tests/pyplot/test_layout_text_parity_fixes.py @@ -251,7 +251,7 @@ def test_ylabel_renders_rotated_in_png_left_margin() -> None: height, width = pixels.shape[:2] # Ink confined to a tall, narrow left-margin band — rotated text; the old # horizontal top-left placement would change the top band instead. Compare - # against the same axes without a title so tick-label ink cannot satisfy + # against the same axes without the y-label so tick-label ink cannot satisfy # the assertion by accident. left_band = np.s_[height // 4 : 3 * height // 4, : width // 12, :3] assert (pixels[left_band] != plain[left_band]).any() diff --git a/tests/pyplot/test_line_legend_gallery_compat.py b/tests/pyplot/test_line_legend_gallery_compat.py index 637b785a..07850b6f 100644 --- a/tests/pyplot/test_line_legend_gallery_compat.py +++ b/tests/pyplot/test_line_legend_gallery_compat.py @@ -266,6 +266,27 @@ def test_scatter_legend_elements_return_real_legend_artists_and_two_boxes(): assert all(item["name"].startswith("$ ") for item in spec["extra_legends"][1]["items"]) +def test_scatter_legend_elements_none_and_array_num_follow_matplotlib() -> None: + _, ax = plt.subplots() + scatter = ax.scatter( + np.arange(4), + np.arange(4), + c=np.array([1.0, 2.0, 2.0, 4.0]), + s=np.array([10.0, 20.0, 20.0, 40.0]), + ) + + color_handles, color_labels = scatter.legend_elements(num=None) + size_handles, size_labels = scatter.legend_elements(prop="sizes", num=None) + fixed_handles, fixed_labels = scatter.legend_elements(num=np.array([1.0, 4.0])) + + assert len(color_handles) == len(color_labels) == 3 + assert color_labels == ["1", "2", "4"] + assert len(size_handles) == len(size_labels) == 3 + assert size_labels == ["10", "20", "40"] + assert len(fixed_handles) == len(fixed_labels) == 2 + assert fixed_labels == ["1", "4"] + + def test_round_dash_capstyle_mutation_matches_fixed_round_renderers(): _, ax = plt.subplots() line = ax.plot([0, 1], [0, 1], "--")[0] diff --git a/tests/pyplot/test_matplotlib_mismatch_regressions.py b/tests/pyplot/test_matplotlib_mismatch_regressions.py index 03698561..f1a73403 100644 --- a/tests/pyplot/test_matplotlib_mismatch_regressions.py +++ b/tests/pyplot/test_matplotlib_mismatch_regressions.py @@ -5,6 +5,7 @@ import xy.pyplot as plt from xy._figure import Figure +from xy.pyplot import _axes as axes_module def test_axis_equal_before_fill_keeps_data_autoscaling() -> None: @@ -90,6 +91,76 @@ def test_imshow_interpolation_does_not_spread_one_nan_over_the_image() -> None: assert np.isfinite(interpolated[-1, -1]) +def test_sparse_imshow_resampling_matches_dense_bilinear_reference() -> None: + values = np.arange(12.0).reshape(3, 4) + + def dense_weights(source: int, target: int) -> np.ndarray: + positions = np.linspace(0.0, source - 1.0, target)[:, None] + distance = np.abs(positions - np.arange(source, dtype=np.float64)[None, :]) + weights = np.maximum(0.0, 1.0 - distance) + return weights / weights.sum(axis=1, keepdims=True) + + wy = dense_weights(values.shape[0], 5) + wx = dense_weights(values.shape[1], 7) + expected = wy @ values @ wx.T + + np.testing.assert_allclose( + axes_module._resample_grid(values, 7, 5, "bilinear"), + expected, + atol=1e-12, + ) + + +def test_sparse_imshow_resampling_matches_dense_lanczos_with_nan() -> None: + values = np.arange(20.0).reshape(4, 5) + values[1, 2] = np.nan + + def dense_weights(source: int, target: int) -> np.ndarray: + positions = np.linspace(0.0, source - 1.0, target)[:, None] + distance = positions - np.arange(source, dtype=np.float64)[None, :] + absolute = np.abs(distance) + weights = np.where( + absolute < 3.0, + np.sinc(distance) * np.sinc(distance / 3.0), + 0.0, + ) + return weights / weights.sum(axis=1, keepdims=True) + + wy = dense_weights(values.shape[0], 7) + wx = dense_weights(values.shape[1], 9) + finite = np.isfinite(values) + numerator = wy @ np.where(finite, values, 0.0) @ wx.T + denominator = wy @ finite.astype(np.float64) @ wx.T + expected = np.divide( + numerator, + denominator, + out=np.full_like(numerator, np.nan), + where=np.abs(denominator) > 1e-12, + ) + + np.testing.assert_allclose( + axes_module._resample_grid(values, 9, 7, "lanczos"), + expected, + atol=1e-12, + equal_nan=True, + ) + + +def test_imshow_bounds_large_non_nearest_resampling(monkeypatch: pytest.MonkeyPatch) -> None: + requested: list[tuple[int, int]] = [] + + def record_target(grid: np.ndarray, width: int, height: int, method: str) -> np.ndarray: + del method + requested.append((width, height)) + return grid + + monkeypatch.setattr(axes_module, "_resample_grid", record_target) + _fig, ax = plt.subplots() + ax.imshow(np.zeros((1025, 1537)), interpolation="bilinear") + + assert requested == [(1024, 1024)] + + def test_regular_gouraud_pcolormesh_uses_a_smooth_scalar_surface() -> None: _fig, ax = plt.subplots() values = np.arange(15.0).reshape(3, 5) diff --git a/tests/pyplot/test_p3_option_contracts.py b/tests/pyplot/test_p3_option_contracts.py index 596e2be3..f5a403a5 100644 --- a/tests/pyplot/test_p3_option_contracts.py +++ b/tests/pyplot/test_p3_option_contracts.py @@ -491,15 +491,32 @@ def test_contour_solid_style_and_negative_rc_setting() -> None: def test_contour_linewidths_cycle_by_level_and_artist_updates_preserve_arrays() -> None: _fig, ax = plt.subplots() + point_scale = ax._point_scale() contour = ax.contour( np.arange(25.0).reshape(5, 5), levels=[4, 8, 12, 16, 20], colors="black", linewidths=[0.5, 2.0], ) - np.testing.assert_allclose(contour.get_linewidth(), [2 / 3, 8 / 3]) + np.testing.assert_allclose(contour.get_linewidth(), [0.5, 2.0]) + np.testing.assert_allclose( + contour._entry["kwargs"]["width"], + np.array([0.5, 2.0]) * point_scale, + ) + contour.set_linewidth([1.0, 3.0, 2.0]) np.testing.assert_allclose(contour.get_linewidth(), [1.0, 3.0, 2.0]) + np.testing.assert_allclose( + contour._entry["kwargs"]["width"], + np.array([1.0, 3.0, 2.0]) * point_scale, + ) + + contour.set(linewidth=[0.75, 1.5]) + np.testing.assert_allclose(contour.get_linewidth(), [0.75, 1.5]) + np.testing.assert_allclose( + contour._entry["kwargs"]["width"], + np.array([0.75, 1.5]) * point_scale, + ) traces = ax._build_chart(640, 480).figure().traces widths = np.concatenate( @@ -509,7 +526,10 @@ def test_contour_linewidths_cycle_by_level_and_artist_updates_preserve_arrays() if trace.kind == "contour" and "width" in trace.style_channels ] ) - assert set(widths) == {1.0, 2.0, 3.0} + np.testing.assert_allclose( + sorted(set(widths)), + np.array([0.75, 1.5]) * point_scale, + ) def test_stem_dashed_linefmt_emits_dash_segments_and_markers() -> None: diff --git a/tests/pyplot/test_pdsh_gap_features.py b/tests/pyplot/test_pdsh_gap_features.py index 2865ea96..98cc6f54 100644 --- a/tests/pyplot/test_pdsh_gap_features.py +++ b/tests/pyplot/test_pdsh_gap_features.py @@ -309,7 +309,9 @@ def test_colorbar_returns_handle_and_set_label_lands(): assert ax._colorbar["label"] == "counts in bin" -def test_colorbar_set_label_renders_rotated_beside_the_bar_in_both_exports(): +def test_colorbar_set_label_renders_rotated_beside_the_bar_in_both_exports( + monkeypatch: pytest.MonkeyPatch, +): """PDSH ch. 4.05 (`hist2d`/`hexbin`/`imshow` + `set_label`) expects Matplotlib's rotated label alongside a vertical colorbar. It used to render horizontally above the bar, clipped off the top of the native PNG canvas.""" @@ -326,15 +328,12 @@ def test_colorbar_set_label_renders_rotated_beside_the_bar_in_both_exports(): recorded: list[tuple[float, float, int, str]] = [] original_text = _raster._Cmd.text - def record_text(self, x, y, anchor, size, color, value): + def record_text(self, x, y, anchor, size, color, value, *args, **kwargs): recorded.append((float(x), float(y), int(anchor), str(value))) - return original_text(self, x, y, anchor, size, color, value) + return original_text(self, x, y, anchor, size, color, value, *args, **kwargs) - _raster._Cmd.text = record_text - try: - _png() - finally: - _raster._Cmd.text = original_text + monkeypatch.setattr(_raster._Cmd, "text", record_text) + _png() native_x, native_y, anchor, _text = next( entry for entry in recorded if entry[3] == "counts in bin" diff --git a/tests/test_components.py b/tests/test_components.py index 32bb9ea4..45b9928b 100644 --- a/tests/test_components.py +++ b/tests/test_components.py @@ -6,6 +6,7 @@ from __future__ import annotations import json +from dataclasses import fields from pathlib import Path import numpy as np @@ -1489,6 +1490,101 @@ def test_legend_location_and_columns_are_serialized(): assert spec["legend"] == {"loc": "upper left", "ncols": 2} +def test_public_component_dataclasses_preserve_v003_positional_prefix(): + released_axis_fields = ( + "which", + "id", + "label", + "label_position", + "label_offset", + "label_angle", + "type_", + "constant", + "domain", + "bounds", + "reverse", + "format", + "tick_count", + "tick_values", + "tick_labels", + "tick_label_angle", + "tick_label_strategy", + "tick_label_anchor", + "tick_label_min_gap", + "side", + "style", + ) + released_legend_fields = ( + "show", + "loc", + "ncols", + "title", + "class_name", + "style", + "render", + "highlight", + "toggle", + ) + + axis_fields = tuple(item.name for item in fields(Axis)) + legend_fields = tuple(item.name for item in fields(Legend)) + assert axis_fields[: len(released_axis_fields)] == released_axis_fields + assert axis_fields[len(released_axis_fields)] == "margin" + assert legend_fields[: len(released_legend_fields)] == released_legend_fields + assert legend_fields[len(released_legend_fields)] == "anchor" + + renderer = object() + axis = Axis( + "x", + "x", + "label", + None, + None, + None, + "linear", + None, + (0.0, 1.0), + (0.0, 2.0), + True, + ".1f", + 3, + [0.0, 1.0], + ["zero", "one"], + 15.0, + "rotate", + "end", + 2.0, + "top", + {}, + ) + legend = Legend(False, "upper right", 2, "Title", "legend-class", {}, renderer, False, False) + + assert axis.bounds == (0.0, 2.0) + assert axis.reverse is True + assert axis.format == ".1f" + assert axis.margin is None + assert legend.ncols == 2 + assert legend.title == "Title" + assert legend.render is renderer + assert legend.anchor is None + + anchored = xy.legend(anchor=(0.25, 0.75)) + assert anchored.anchor == (0.25, 0.75) + + +def test_component_bar_width_contracts_match_runtime_behavior(): + widths = np.array([0.25, 0.75]) + for mark in ( + xy.bar(x=["a", "b"], y=[1.0, 2.0], width=widths), + xy.column(x=["a", "b"], y=[1.0, 2.0], width=widths), + ): + trace = xy.chart(mark).figure().traces[0] + np.testing.assert_allclose(trace.x1.values - trace.x0.values, widths) + + with pytest.raises(ValueError, match="violin width must be a finite real number"): + xy.violin_chart(xy.violin(values=[[1.0, 2.0], [2.0, 3.0]], width=[0.25, 0.75])).figure() + + def test_component_axis_and_legend_validate_public_props_without_caching_failure(): with pytest.raises(ValueError, match="axis type_"): xy.x_axis(type_="logg") diff --git a/tests/test_figure.py b/tests/test_figure.py index 8cd467c2..e5a142c7 100644 --- a/tests/test_figure.py +++ b/tests/test_figure.py @@ -606,11 +606,21 @@ def test_column_alias_and_negative_bars_range_from_baseline(): def test_positive_bar_and_histogram_baselines_touch_value_axis(): bar_spec, _bar_blob = Figure().bar(["A", "B"], [2.0, 4.0]).build_payload() + column_spec, _column_blob = Figure().column(["A", "B"], [2.0, 4.0]).build_payload() hist_spec, _hist_blob = Figure().histogram([0.0, 0.1, 0.2], bins=2).build_payload() assert bar_spec["y_axis"]["range"][0] == 0.0 + assert column_spec["y_axis"]["range"][0] == 0.0 assert hist_spec["y_axis"]["range"][0] == 0.0 +def test_column_baseline_stays_sticky_for_negative_and_horizontal_values(): + negative = Figure().column(["A", "B"], [-2.0, -4.0]) + horizontal = Figure().column(["A", "B"], [2.0, 4.0], orientation="horizontal") + + assert negative.y_range()[1] == 0.0 + assert horizontal.x_range()[0] == 0.0 + + def test_negative_horizontal_bar_baseline_touches_value_axis(): spec, _blob = Figure().bar(["A", "B"], [-2.0, -4.0], orientation="horizontal").build_payload() assert spec["x_axis"]["range"][0] < -4.0 diff --git a/tests/test_plot_families.py b/tests/test_plot_families.py index fadf5952..c54a8c15 100644 --- a/tests/test_plot_families.py +++ b/tests/test_plot_families.py @@ -4,6 +4,7 @@ import pytest import xy +from xy import _paint from xy._figure import Figure @@ -129,6 +130,20 @@ def test_triangle_mesh_filters_nonfinite_geometry_and_color_rows() -> None: assert spec["columns"][trace["color"]["buf"]]["len"] == 1 +@pytest.mark.parametrize("nonfinite", [np.nan, np.inf, -np.inf]) +def test_triangle_mesh_boundary_rejects_nonfinite_coordinates(nonfinite: float) -> None: + boundary = _paint.triangle_mesh_boundary( + np.array([0.0]), + np.array([0.0]), + np.array([1.0]), + np.array([0.0]), + np.array([nonfinite]), + np.array([1.0]), + ) + + assert boundary is None + + def test_new_marks_reject_invalid_inputs_without_mutating_figure() -> None: fig = Figure().line([0, 1], [1, 2]) with pytest.raises(ValueError, match="errorbar requires"): diff --git a/tests/test_svg_export.py b/tests/test_svg_export.py index 7c076f06..a3ab8b3b 100644 --- a/tests/test_svg_export.py +++ b/tests/test_svg_export.py @@ -415,7 +415,9 @@ def test_svg_vertical_colorbar_clears_right_named_axis_chrome() -> None: assert float(bar.get("x", "nan")) > plot["x"] + plot["w"] + 40 -def test_svg_vertical_colorbar_label_is_rotated_beside_the_bar_inside_the_canvas() -> None: +def test_svg_vertical_colorbar_label_is_rotated_beside_the_bar_inside_the_canvas( + monkeypatch: pytest.MonkeyPatch, +) -> None: """SVG places a vertical colorbar's label like Matplotlib — rotated 90° CCW, centered beside the bar, on canvas — and the native PNG exporter must agree on the baseline so the two static paths cannot drift apart.""" @@ -452,15 +454,12 @@ def test_svg_vertical_colorbar_label_is_rotated_beside_the_bar_inside_the_canvas recorded: list[tuple[float, float, int, float, str]] = [] original_text = _raster._Cmd.text - def record_text(self, x, y, anchor, size, color, value): + def record_text(self, x, y, anchor, size, color, value, *args, **kwargs): recorded.append((float(x), float(y), int(anchor), float(size), str(value))) - return original_text(self, x, y, anchor, size, color, value) + return original_text(self, x, y, anchor, size, color, value, *args, **kwargs) - _raster._Cmd.text = record_text - try: - _raster.render_raster(spec, blob, scale=1) - finally: - _raster._Cmd.text = original_text + monkeypatch.setattr(_raster._Cmd, "text", record_text) + _raster.render_raster(spec, blob, scale=1) native_x, native_y, anchor, _size, _text = next( entry for entry in recorded if entry[4] == "counts in bin" ) diff --git a/tests/test_svg_text_metrics.py b/tests/test_svg_text_metrics.py new file mode 100644 index 00000000..b96cf58d --- /dev/null +++ b/tests/test_svg_text_metrics.py @@ -0,0 +1,72 @@ +"""Focused static-text layout regressions shared by SVG and native export.""" + +from __future__ import annotations + +import xml.etree.ElementTree as ET + +import pytest + +from xy import _fontmetrics, _svg + + +def test_text_box_width_uses_embedded_advances_with_unknown_glyph_fallback() -> None: + font_size = 11.0 + + assert _svg._estimated_text_width(["gamma"], font_size) == pytest.approx( + _fontmetrics.advance("gamma", font_size) + ) + assert _svg._estimated_text_width(["iiii", "gamma"], font_size) == pytest.approx( + _fontmetrics.advance("gamma", font_size) + ) + assert _svg._estimated_text_width(["🦉"], font_size) == pytest.approx(font_size) + assert _svg._estimated_text_width([], font_size) == 0.0 + + +def test_svg_mathtext_ranges_are_sorted_clamped_and_merged_without_duplicate_text() -> None: + rendered = _svg._svg_mathtext_spans( + "abcdef", + {"math_italic_ranges": "2:4,0:3,2:4,-5:1,5:99"}, + 0, + ) + root = ET.fromstring(f"{rendered}") + + assert "".join(root.itertext()) == "abcdef" + assert [node.text for node in root if node.tag.endswith("tspan")] == ["abcd", "f"] + + +def test_left_gutter_measures_y_tick_labels_once_for_an_outside_title( + monkeypatch: pytest.MonkeyPatch, +) -> None: + calls = 0 + + def measured_room(axis: dict[str, object], plot_h: float) -> tuple[float, float]: + nonlocal calls + calls += 1 + assert axis["label"] == "Y" + assert plot_h == 300.0 + return 7.0, 23.0 + + monkeypatch.setattr(_svg, "_y_tick_label_room", measured_room) + label_size = 12.0 + spec = { + "x_axis": {}, + "y_axis": { + "label": "Y", + "side": "left", + "style": {"label_size": label_size}, + }, + } + + room = _svg._y_axis_left_room(spec, 300.0) + ascent, descent = _svg._text_cell(label_size) + expected = ( + _svg._AXIS_TEXT_EDGE_PAD + + ascent + + descent + + _svg._Y_TITLE_TICK_GAP * label_size + + 7.0 + + 23.0 + ) + + assert calls == 1 + assert room == pytest.approx(expected) diff --git a/tests/test_text_weight_defaults.py b/tests/test_text_weight_defaults.py index 615a0779..7f94f172 100644 --- a/tests/test_text_weight_defaults.py +++ b/tests/test_text_weight_defaults.py @@ -81,11 +81,17 @@ def _raster_text_bold(stream: bytes, text: str) -> bool: at = stream.find(struct.pack("= 0, f"no native text record carries {text!r}" body = at + 4 - styled = body - _STYLED_HEADER - if styled >= 0 and stream[styled] == _raster._STYLED_TEXT: - (ranges,) = struct.unpack("= _STYLED_HEADER: + max_ranges = (body - _STYLED_HEADER) // 8 + for range_count in range(max_ranges + 1): + styled = body - _STYLED_HEADER - 8 * range_count + if stream[styled] != _raster._STYLED_TEXT: + continue + count_at = body - 12 - 8 * range_count + (declared_count,) = struct.unpack("= 0 and stream[plain] == _raster._TEXT_OP, ( f"record for {text!r} is neither a plain nor a styled text record" @@ -123,6 +129,28 @@ def test_svg_honors_an_explicit_heavier_title_weight() -> None: # --- native raster exporter ------------------------------------------------ +@pytest.mark.parametrize("bold", [False, True]) +def test_raster_text_bold_decodes_styled_math_ranges(bold: bool) -> None: + cmd = _raster._Cmd(scale=1) + text = "a+b+c+d+e+f+g+h+i" + ranges = [(start, start + 1) for start in range(0, len(text), 2)] + cmd.text( + 0, + 0, + 0, + 10, + (0, 0, 0, 255), + text, + bold=bold, + italic_ranges=ranges, + ) + + # Nine ranges also guard against replacing the old zero-range assumption + # with another arbitrary small-count cap. + assert len(ranges) == 9 + assert _raster_text_bold(bytes(cmd.buf), text) is bold + + def test_native_raster_chrome_text_carries_no_bold_by_default() -> None: stream = _raster_stream(_title_axis_legend_figure()) diff --git a/tests/test_ui_issue_regressions.py b/tests/test_ui_issue_regressions.py index f681a46c..89e6b181 100644 --- a/tests/test_ui_issue_regressions.py +++ b/tests/test_ui_issue_regressions.py @@ -10,6 +10,10 @@ from conftest import run_browser_probe from xy.export import find_chromium +# Browser renderer rule: rotated y titles clear the tick-label union by this +# multiple of the title's font size. +_Y_TITLE_TICK_GAP_EM = 0.4 + def _probe(chart: xy.Chart, script: str, tmp_path: Path, name: str) -> dict: chromium = find_chromium() @@ -340,6 +344,19 @@ def test_y_axis_title_stays_attached_when_left_padding_is_wide(tmp_path: Path) - script = ( _PRELUDE + """ + const realGetBoundingClientRect = Element.prototype.getBoundingClientRect; + let titleLayoutReads = 0; + Element.prototype.getBoundingClientRect = function () { + if (this.dataset && + this.dataset.xyLabelKind === "label" && + this.dataset.xyAxis === "y") { + titleLayoutReads += 1; + } + return realGetBoundingClientRect.call(this); + }; + view._drawNow(); + view._raf = null; + Element.prototype.getBoundingClientRect = realGetBoundingClientRect; const root = view.root.getBoundingClientRect(); const title = view.root.querySelector( '[data-xy-label-kind="label"][data-xy-axis="y"]' @@ -352,15 +369,57 @@ def test_y_axis_title_stays_attached_when_left_padding_is_wide(tmp_path: Path) - gap: tickLeft - title.right, titleInside: title.left >= root.left, tickInside: tickLeft >= root.left, + titleLayoutReads, })); """ + _POSTLUDE ) result = _probe(chart, script, tmp_path, "wide left gutter title attachment") - assert result["gap"] == pytest.approx(0.4 * 13.8889, abs=0.75), result + assert result["gap"] == pytest.approx(_Y_TITLE_TICK_GAP_EM * 13.8889, abs=0.75), result assert result["titleInside"] is True, result assert result["tickInside"] is True, result + assert result["titleLayoutReads"] == 1, result + + +def test_structured_y_axis_title_position_remains_authoritative(tmp_path: Path) -> None: + chart = xy.chart( + xy.line([0, 1], [0, 1]), + xy.x_axis(), + xy.y_axis( + label="author positioned", + label_position={ + "right": 18, + "top": "52%", + "transform": "rotate(-75deg)", + }, + ), + width=480, + height=320, + ) + script = ( + _PRELUDE + + """ + const title = view.root.querySelector( + '[data-xy-label-kind="label"][data-xy-axis="y"]' + ); + document.body.setAttribute("data-xy-issue-probe", JSON.stringify({ + left: title.style.left, + right: title.style.right, + top: title.style.top, + transform: title.style.transform, + })); +""" + + _POSTLUDE + ) + result = _probe(chart, script, tmp_path, "structured y title placement") + + assert result == { + "left": "", + "right": "18px", + "top": "52%", + "transform": "rotate(-75deg)", + } def test_long_y_categories_expand_the_browser_gutter(tmp_path: Path) -> None: @@ -399,7 +458,7 @@ def test_long_y_categories_expand_the_browser_gutter(tmp_path: Path) -> None: result = _probe(chart, script, tmp_path, "long category y gutter") assert result["plotX"] > 150, result - assert result["gap"] == pytest.approx(0.4 * 14, abs=0.75), result + assert result["gap"] == pytest.approx(_Y_TITLE_TICK_GAP_EM * 14, abs=0.75), result assert result["clipped"] is False, result assert result["titleInside"] is True, result assert sorted(result["tickTexts"]) == categories, result diff --git a/tests/test_width_validation_regressions.py b/tests/test_width_validation_regressions.py new file mode 100644 index 00000000..6420ac9c --- /dev/null +++ b/tests/test_width_validation_regressions.py @@ -0,0 +1,47 @@ +"""Focused regressions for scalar and malformed rectangle/contour widths.""" + +from __future__ import annotations + +import numpy as np +import pytest + +from xy._figure import Figure + + +def test_contour_accepts_numeric_zero_dimensional_width_arrays() -> None: + z = np.array([[0.0, 1.0], [1.0, 2.0]]) + + for width in (np.array(1.1), np.array(1.1, dtype=np.float32)): + spec, _blob = Figure().contour(z, levels=[0.5, 1.5], width=width).build_payload() + assert spec["traces"][0]["style"]["width"] == pytest.approx(1.1) + + +@pytest.mark.parametrize("width", [np.array(True), np.array(False)]) +def test_contour_zero_dimensional_boolean_widths_remain_invalid(width: np.ndarray) -> None: + z = np.array([[0.0, 1.0], [1.0, 2.0]]) + + with pytest.raises(ValueError, match="contour width"): + Figure().contour(z, levels=[0.5, 1.5], width=width) + + +@pytest.mark.parametrize("kind", ["bar", "column"]) +@pytest.mark.parametrize( + "width", + [ + "wide", + object(), + [[0.5], [0.5, 0.6]], + ], + ids=["string", "object", "ragged"], +) +def test_rectangle_width_conversion_errors_name_the_argument( + kind: str, + width: object, +) -> None: + build = getattr(Figure(), kind) + + with pytest.raises( + ValueError, + match=rf"{kind} width must be scalar or contain numeric values", + ): + build([0.0, 1.0], [1.0, 2.0], width=width) From a91ca2e35c741fb64793b02fdc7f20a1030f3e45 Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 22:25:52 -0700 Subject: [PATCH 09/15] Polish gallery review follow-ups --- js/src/50_chartview.ts | 6 +++--- python/xy/styles.py | 20 ++++++++------------ tests/pyplot/test_axes_layout.py | 15 +++------------ tests/svg_test_utils.py | 11 +++++++++++ tests/test_svg_export.py | 27 ++++++++++----------------- 5 files changed, 35 insertions(+), 44 deletions(-) create mode 100644 tests/svg_test_utils.py diff --git a/js/src/50_chartview.ts b/js/src/50_chartview.ts index 847cf6c0..4bba96b4 100644 --- a/js/src/50_chartview.ts +++ b/js/src/50_chartview.ts @@ -5125,7 +5125,7 @@ export class ChartView { this._axisStyleNumber(xAxis, "tick_size", 11), ); // Spine→label distance. mpl measures tick padding from the outward end of - // the tick mark, and a `top` label then needs `fontRoom` more to clear its + // the tick mark, and a `top` label then needs `fontRoomPx` more to clear its // own line box. That derived geometry only applies once the axis authors // tick geometry: core's default tick_length is 0 and it has no default // tick_label_pad, so deriving it unconditionally would move the labels of @@ -5133,7 +5133,7 @@ export class ChartView { // per-side gap this client has always used (pyplot supplies mpl's // {x,y}tick.major.pad, so it takes the derived branch). Mirrors // `_axis_tick_label_offset` in `_svg.py`/`_raster.py`. - const tickLabelOffset = (axis, unstyled, fontRoom = 0) => { + const tickLabelOffset = (axis, unstyled, fontRoomPx = 0) => { const authored = this._axisStyleValue(axis, "tick_padding") !== undefined || this._axisStyleValue(axis, "tick_length") !== undefined; if (!authored) return unstyled; @@ -5141,7 +5141,7 @@ export class ChartView { const direction = String(this._axisStyleValue(axis, "tick_direction") || "out"); const outward = direction === "in" ? 0 : direction === "inout" ? length / 2 : length; const pad = outward + this._axisStyleNumber(axis, "tick_padding", 4); - return pad + fontRoom; + return pad + fontRoomPx; }; for (const item of this._layoutTickLabels(xAxis, "x", xLabelCandidates)) { const rowOffset = Number(item.row || 0) * (Math.max(8, tickLabelSize) + 4); diff --git a/python/xy/styles.py b/python/xy/styles.py index 41140573..f2eb656e 100644 --- a/python/xy/styles.py +++ b/python/xy/styles.py @@ -141,16 +141,20 @@ def normalize_css_style(value: StyleMapping | None, label: str = "style") -> dic return out -def _px(value: StyleValue, label: str, *, positive: bool = False) -> float: +def _parse_px(value: StyleValue, label: str) -> float: if isinstance(value, (int, float)) and not isinstance(value, bool): - number = float(value) + return float(value) elif isinstance(value, str): match = _PX_RE.match(value) if match is None: raise ValueError(f"{label} must be a finite CSS px length") - number = float(match.group(1)) + return float(match.group(1)) else: # pragma: no cover - normalize_css_style rejects this first raise ValueError(f"{label} must be a finite CSS px length") + + +def _px(value: StyleValue, label: str, *, positive: bool = False) -> float: + number = _parse_px(value, label) if not np.isfinite(number) or number < 0 or (positive and number <= 0): qualifier = "positive " if positive else "non-negative " raise ValueError(f"{label} must be a {qualifier}finite CSS px length") @@ -158,15 +162,7 @@ def _px(value: StyleValue, label: str, *, positive: bool = False) -> float: def _signed_px(value: StyleValue, label: str) -> float: - if isinstance(value, (int, float)) and not isinstance(value, bool): - number = float(value) - elif isinstance(value, str): - match = _PX_RE.match(value) - if match is None: - raise ValueError(f"{label} must be a finite CSS px length") - number = float(match.group(1)) - else: # pragma: no cover - normalize_css_style rejects this first - raise ValueError(f"{label} must be a finite CSS px length") + number = _parse_px(value, label) if not np.isfinite(number): raise ValueError(f"{label} must be a finite CSS px length") return number diff --git a/tests/pyplot/test_axes_layout.py b/tests/pyplot/test_axes_layout.py index 2774389f..4e523f2b 100644 --- a/tests/pyplot/test_axes_layout.py +++ b/tests/pyplot/test_axes_layout.py @@ -1,9 +1,9 @@ from __future__ import annotations import builtins -import re import pytest +from tests.svg_test_utils import tick_label_positions import xy.pyplot as plt from xy._svg import layout @@ -201,15 +201,6 @@ def test_tick_params_records_supported_style_and_rejects_unknown() -> None: ax.tick_params(which="minor") -def _tick_label_positions(chart) -> dict[str, tuple[float, float]]: - return { - match.group(3): (float(match.group(1)), float(match.group(2))) - for match in re.finditer( - r']*>([^<]*)', chart.to_svg() - ) - } - - def test_rc_tick_padding_places_labels_by_the_matplotlib_rule() -> None: """The shim always supplies `{x,y}tick.major.size` and `.pad` from rcParams, so its tick labels follow matplotlib's geometry rule — padding measured from @@ -224,7 +215,7 @@ def test_rc_tick_padding_places_labels_by_the_matplotlib_rule() -> None: chart = ax._build_chart(400, 300) plot = layout(chart.figure().build_payload()[0])[3] - labels = _tick_label_positions(chart) + labels = tick_label_positions(chart.to_svg()) scale = 100.0 / 72.0 # figure.dpi 100: points -> px # 3.5 pt outward tick + 3.5 pt pad, then 0.8 * the 10 pt label font. @@ -248,7 +239,7 @@ def test_tick_params_pad_moves_the_labels_further_from_the_spine() -> None: chart = ax._build_chart(400, 300) plot = layout(chart.figure().build_payload()[0])[3] - labels = _tick_label_positions(chart) + labels = tick_label_positions(chart.to_svg()) scale = 100.0 / 72.0 assert labels["0.5"][0] == pytest.approx(plot["x"] - (3.5 + 12.0) * scale, abs=0.01) diff --git a/tests/svg_test_utils.py b/tests/svg_test_utils.py new file mode 100644 index 00000000..6daa9484 --- /dev/null +++ b/tests/svg_test_utils.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +import re + + +def tick_label_positions(svg: str) -> dict[str, tuple[float, float]]: + """Return ``{label text: (x, y)}`` for every SVG text node.""" + return { + match.group(3): (float(match.group(1)), float(match.group(2))) + for match in re.finditer(r']*>([^<]*)', svg) + } diff --git a/tests/test_svg_export.py b/tests/test_svg_export.py index a3ab8b3b..0980a467 100644 --- a/tests/test_svg_export.py +++ b/tests/test_svg_export.py @@ -10,6 +10,7 @@ import numpy as np import pytest +from tests.svg_test_utils import tick_label_positions import xy from xy import channels @@ -894,14 +895,6 @@ def test_segment_constant_translucent_color_applies_alpha_once() -> None: assert opaque_lines, "opaque constant color should pass through verbatim" -def _tick_label_positions(svg: str) -> dict[str, tuple[float, float]]: - """``{label text: (x, y)}`` for every ```` node in an export.""" - return { - match.group(3): (float(match.group(1)), float(match.group(2))) - for match in re.finditer(r']*>([^<]*)', svg) - } - - def _geometry_chart(side_x: str = "bottom", side_y: str = "left", style=None) -> xy.Chart: """A 3x3 tick grid with a pinned plot rect, so offsets are exact integers.""" return xy.chart( @@ -927,7 +920,7 @@ def test_unstyled_tick_labels_keep_their_historical_svg_placement() -> None: plot = layout(_geometry_chart().figure().build_payload()[0])[3] assert (plot["x"], plot["y"], plot["w"], plot["h"]) == (50.0, 40.0, 300.0, 220.0) - bottom_left = _tick_label_positions(_geometry_chart().to_svg()) + bottom_left = tick_label_positions(_geometry_chart().to_svg()) # x, bottom: baseline 16 px below the spine, centered on the tick. assert bottom_left["0"] == (50.0, 276.0) assert bottom_left["1"] == (200.0, 276.0) @@ -945,7 +938,7 @@ def test_unstyled_tick_labels_keep_their_historical_svg_placement() -> None: 258.0, 194.0, ) - top_right = _tick_label_positions(flipped.to_svg()) + top_right = tick_label_positions(flipped.to_svg()) # x, top: baseline 7 px above the spine. y, right: 8 px outside it. assert top_right["0"] == (50.0, 59.0) assert top_right["2"] == (308.0, 59.0) @@ -957,8 +950,8 @@ def test_unstyled_tick_label_placement_ignores_the_tick_font_size() -> None: """The unstyled gaps are flat constants, as they were before `tick_padding` existed: a bigger tick font must not move the labels, because scaling the gap with the font belongs to the authored rule.""" - plain = _tick_label_positions(_geometry_chart().to_svg()) - big = _tick_label_positions(_geometry_chart(style={"tick_size": 20}).to_svg()) + plain = tick_label_positions(_geometry_chart().to_svg()) + big = tick_label_positions(_geometry_chart(style={"tick_size": 20}).to_svg()) assert big["0"] == plain["0"] assert big["1.0"] == plain["1.0"] @@ -967,7 +960,7 @@ def test_authored_tick_geometry_moves_the_labels_off_the_spine() -> None: """Authoring `tick_length`/`tick_padding` switches to matplotlib's rule: padding measured from the outward end of the tick mark, with the anchor then clearing the glyph box.""" - styled = _tick_label_positions( + styled = tick_label_positions( _geometry_chart(style={"tick_length": 6, "tick_padding": 5}).to_svg() ) # 6 px outward tick + 5 px pad = 11 px, then 0.8 * the 11 px font to the baseline. @@ -976,13 +969,13 @@ def test_authored_tick_geometry_moves_the_labels_off_the_spine() -> None: assert styled["0.0"] == (39.0, 263.85) # tick_direction decides how much of tick_length counts as outward. - inward = _tick_label_positions( + inward = tick_label_positions( _geometry_chart( style={"tick_length": 6, "tick_padding": 5, "tick_direction": "in"} ).to_svg() ) assert inward["0.0"] == (45.0, 263.85) - halfway = _tick_label_positions( + halfway = tick_label_positions( _geometry_chart( style={"tick_length": 6, "tick_padding": 5, "tick_direction": "inout"} ).to_svg() @@ -990,7 +983,7 @@ def test_authored_tick_geometry_moves_the_labels_off_the_spine() -> None: assert halfway["0.0"] == (42.0, 263.85) # A pad alone opts in; tick_length then contributes its default 0. - pad_only = _tick_label_positions(_geometry_chart(style={"tick_padding": 5}).to_svg()) + pad_only = tick_label_positions(_geometry_chart(style={"tick_padding": 5}).to_svg()) assert pad_only["0.0"] == (45.0, 263.85) @@ -1000,7 +993,7 @@ def test_tick_label_offset_defaults_stay_in_sync_with_js_client() -> None: label's box, not its baseline, so its numbers differ from the exporters'). Pin them at the source: this suite has no browser.""" js = (ROOT / "js" / "src" / "50_chartview.ts").read_text(encoding="utf-8") - body = js.split("const tickLabelOffset = (axis, unstyled, fontRoom = 0) => {", 1) + body = js.split("const tickLabelOffset = (axis, unstyled, fontRoomPx = 0) => {", 1) assert len(body) == 2, "tickLabelOffset signature changed; re-check the unstyled gaps" assert 'this._axisStyleValue(axis, "tick_padding") !== undefined' in body[1] assert 'this._axisStyleValue(axis, "tick_length") !== undefined' in body[1] From 710ba107f058e5e0d9eccda0811a22a789b8e73c Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 22:49:04 -0700 Subject: [PATCH 10/15] Restore gallery compatibility benchmark performance --- python/xy/pyplot/_axes.py | 135 +++++++++++++++++---- src/kernels.rs | 81 ++++++++----- tests/pyplot/test_best_legend_placement.py | 2 +- 3 files changed, 164 insertions(+), 54 deletions(-) diff --git a/python/xy/pyplot/_axes.py b/python/xy/pyplot/_axes.py index 21668fec..95047b4e 100644 --- a/python/xy/pyplot/_axes.py +++ b/python/xy/pyplot/_axes.py @@ -106,7 +106,7 @@ # `loc="best"` slowness warning; the shim strides instead and weights the count # back up, so relative badness survives but a lone excursion into an otherwise # empty candidate box can be missed on a series far longer than this. -_BEST_LOC_SAMPLE = 4096 +_BEST_LOC_SAMPLE = 512 # Plot box of the default 640x480 figure, for direct `_best_legend_loc` callers # that have no chart geometry to hand. _DEFAULT_BEST_PLOT_SIZE = (564.0, 428.0) @@ -3490,7 +3490,43 @@ def _entry_sticky_edges(self, axis: str) -> np.ndarray: combined = np.concatenate(edges) return combined[np.isfinite(combined)] - def _fully_sticky_domain(self, axis: str) -> Optional[tuple[float, float]]: + def _has_fully_sticky_candidate(self, axis: str) -> bool: + """Whether an entry can pin both ends of *axis*. + + Ordinary bar baselines are deliberately absent: they are one-sided, + and the core already anchors them. Keeping this probe structural and + allocation-free avoids rescanning every bar coordinate during each + default chart build merely to rediscover that fact. + """ + host = self._y2_of or self + y_axis = "y2" if self._y2_of is not None else "y" + for entry in host._entries: + if axis == "y" and entry.get("y_axis", "y") != y_axis: + continue + if entry.get("_mpl_sticky_edges", {}).get(axis) is not None: + return True + if entry.get("kind") == "heatmap" and entry.get("extent") is not None: + return True + if entry.get("kind") != "@mark": + continue + factory = entry.get("factory") + if factory in {"contour", "heatmap"}: + return True + if factory == "ecdf" and axis == "y": + return True + if factory == "box": + orientation = entry.get("kwargs", {}).get("orientation", "vertical") + category_axis = "x" if orientation == "vertical" else "y" + if axis == category_axis: + return True + return False + + def _fully_sticky_domain( + self, + axis: str, + *, + dataless: Optional[bool] = None, + ) -> Optional[tuple[float, float]]: """The raw extent when sticky edges pin *both* ends of *axis*. Image- and mesh-like marks (imshow/pcolormesh/hist2d/specgram) hug @@ -3502,11 +3538,13 @@ def _fully_sticky_domain(self, axis: str) -> Optional[tuple[float, float]]: Deliberately requires *both* ends: a one-sided sticky edge is the bar and histogram baseline, which the core already anchors itself. """ - if self._axis_is_dataless(axis): + if not self._has_fully_sticky_candidate(axis): return None sticky = self._entry_sticky_edges(axis) if not sticky.size: return None + if dataless is True or (dataless is None and self._axis_is_dataless(axis)): + return None lo, hi = self._entry_extent(axis) tolerance = np.finfo(np.float64).eps * max(1.0, abs(lo), abs(hi)) * 8 pinned_lo = np.any(np.isclose(sticky, lo, rtol=0.0, atol=tolerance)) @@ -5743,7 +5781,10 @@ def _displayed_ranges( return x_props.get("domain"), y_props.get("domain") @staticmethod - def _displayed_plot_size(figure: Any) -> tuple[float, float]: + def _displayed_plot_size( + figure: Any, + displayed_ranges: tuple[Optional[tuple[float, float]], Optional[tuple[float, float]]], + ) -> tuple[float, float]: """The plot rectangle the static/browser layout model will display. Legend placement runs after the core figure exists, so estimating this @@ -5755,7 +5796,26 @@ def _displayed_plot_size(figure: Any) -> tuple[float, float]: """ from .._svg import layout - spec, _ = figure.build_payload() + known_ranges = {"x": displayed_ranges[0], "y": displayed_ranges[1]} + axis_specs = { + axis_id: figure._axis_spec( + axis_id, + known_ranges.get(axis_id) or figure._range(axis_id), + ) + for axis_id in figure.axis_options + } + spec = { + "width": figure.width, + "height": figure.height, + "title": figure.title, + "x_axis": axis_specs["x"], + "y_axis": axis_specs["y"], + "axes": axis_specs, + } + if figure.padding is not None: + spec["padding"] = list(figure.padding) + if figure.colorbar_options: + spec["colorbar"] = figure.colorbar_options *_, plot = layout(spec) return float(plot["w"]), float(plot["h"]) @@ -6011,19 +6071,43 @@ def normalize(values: Any, axis: str) -> np.ndarray: # series back to its true length to preserve that weighting. weight = total / float(sampled) entries_used += 1 - path_hits = ( - [False] * len(candidates) - if kind == "scatter" - else _path_intersects_boxes( + inside_counts = [ + int(np.count_nonzero((xn > xl) & (xn < xh) & (yn > yl) & (yn < yh))) + for _, xl, xh, yl, yh in candidates + ] + path_hits = [False] * len(candidates) + if kind != "scatter": + # A contained vertex proves the path intersects the box. Run + # the exact segment test only for edge-only crossings, which + # keeps dense oscillating lines from solving the same question + # twice for most candidates. + unresolved = [index for index, count in enumerate(inside_counts) if not count] + unresolved_hits = _path_intersects_boxes( path_xn, path_yn, - ((xl, xh, yl, yh) for _, xl, xh, yl, yh in candidates), + ( + ( + candidates[index][1], + candidates[index][2], + candidates[index][3], + candidates[index][4], + ) + for index in unresolved + ), ) - ) - for (name, xl, xh, yl, yh), path_hit in zip(candidates, path_hits, strict=True): + for index, hit in zip(unresolved, unresolved_hits, strict=True): + path_hits[index] = hit + for index, count in enumerate(inside_counts): + if count: + path_hits[index] = True + for (name, *_), inside_count, path_hit in zip( + candidates, + inside_counts, + path_hits, + strict=True, + ): # Strict, mirroring Bbox.count_contains. - inside = (xn > xl) & (xn < xh) & (yn > yl) & (yn < yh) - scores[name] += float(np.count_nonzero(inside)) * weight + scores[name] += float(inside_count) * weight # ``Line2D``, Patch paths, and PolyCollection paths contribute # one additional badness point when a segment crosses the # legend even if neither endpoint is contained. Scatter is a @@ -6254,14 +6338,14 @@ def _build_chart(self, width: int, height: int) -> Any: # Pin it so the engine's autorange padding cannot widen the empty view # (padding turns the 0.5 midpoint tick into a bare 0/1 pair). Render # snapshot only: data plotted after a render must autoscale as usual. - empty_view = { - axis + axis_dataless = { + axis: self._axis_is_dataless(axis) for axis in ("x", "y") if not adjusted_aspect and axis not in self._explicit_domains and self._axis[axis].get("domain") is None - and self._axis_is_dataless(axis) } + empty_view = {axis for axis, dataless in axis_dataless.items() if dataless} x_props = {k: v for k, v in self._axis["x"].items() if v is not None} y_props = {k: v for k, v in self._axis["y"].items() if v is not None} for axis, props in (("x", x_props), ("y", y_props)): @@ -6272,7 +6356,11 @@ def _build_chart(self, width: int, height: int) -> Any: # axis Matplotlib pins flush to the outer cell edge. `margin` and # `domain` never combine (spec/design/pan-and-zoom-configuration.md # §9), so send exactly one of them. - pinned = None if props.get("domain") is not None else self._fully_sticky_domain(axis) + pinned = ( + None + if props.get("domain") is not None + else self._fully_sticky_domain(axis, dataless=axis_dataless.get(axis)) + ) if pinned is not None: props["domain"] = pinned else: @@ -6363,10 +6451,13 @@ def _build_chart(self, width: int, height: int) -> Any: core_figure.legend_options["border_pad"] = self._legend_options["border_pad"] if self._legend_items is not None: core_figure.legend_options["items"] = list(self._legend_items) - best_ranges = self._displayed_ranges(core_figure, x_props, y_props) + best_ranges: Optional[ + tuple[Optional[tuple[float, float]], Optional[tuple[float, float]]] + ] = None best_plot_size: Optional[tuple[float, float]] = None if legend_needs_best: - best_plot_size = self._displayed_plot_size(core_figure) + best_ranges = self._displayed_ranges(core_figure, x_props, y_props) + best_plot_size = self._displayed_plot_size(core_figure, best_ranges) core_figure.legend_options["loc"] = self._best_legend_loc( *best_ranges, legend_options=self._legend_options, @@ -6389,8 +6480,10 @@ def _build_chart(self, width: int, height: int) -> Any: if self._legend_artist is not None: legends.append(self._legend_artist) if legends: + if best_ranges is None: + best_ranges = self._displayed_ranges(core_figure, x_props, y_props) if best_plot_size is None: - best_plot_size = self._displayed_plot_size(core_figure) + best_plot_size = self._displayed_plot_size(core_figure, best_ranges) extras = [] for leg in legends: spec = leg.spec() diff --git a/src/kernels.rs b/src/kernels.rs index 38134487..fcd247f3 100644 --- a/src/kernels.rs +++ b/src/kernels.rs @@ -2715,44 +2715,61 @@ where let v10 = z[row * cols + col + 1]; let v11 = z[(row + 1) * cols + col + 1]; let v01 = z[(row + 1) * cols + col]; - let finite = [ - v00.is_finite(), - v10.is_finite(), - v11.is_finite(), - v01.is_finite(), - ]; - let finite_count = finite.iter().filter(|&&value| value).count(); - if finite_count < 4 && (!corner_mask || finite_count != 3) { - continue; - } - let values = [v00, v10, v11, v01]; - let local_min = values - .iter() - .copied() - .filter(|value| value.is_finite()) - .fold(f64::INFINITY, f64::min); - let local_max = values - .iter() - .copied() - .filter(|value| value.is_finite()) - .fold(f64::NEG_INFINITY, f64::max); - let corners = [ - (x_coords[col], y_coords[row], v00), - (x_coords[col + 1], y_coords[row], v10), - (x_coords[col + 1], y_coords[row + 1], v11), - (x_coords[col], y_coords[row + 1], v01), - ]; - let triangle_edges: Option<&[(usize, usize); 3]> = if finite_count == 3 { - Some(match finite.iter().position(|value| !value).unwrap() { + let all_finite = + v00.is_finite() && v10.is_finite() && v11.is_finite() && v01.is_finite(); + let (local_min, local_max, triangle_edges): ( + f64, + f64, + Option<&[(usize, usize); 3]>, + ) = if all_finite { + ( + v00.min(v10).min(v11).min(v01), + v00.max(v10).max(v11).max(v01), + None, + ) + } else { + if !corner_mask { + continue; + } + let finite = [ + v00.is_finite(), + v10.is_finite(), + v11.is_finite(), + v01.is_finite(), + ]; + if finite.iter().filter(|&&value| value).count() != 3 { + continue; + } + let values = [v00, v10, v11, v01]; + let local_min = values + .iter() + .copied() + .filter(|value| value.is_finite()) + .fold(f64::INFINITY, f64::min); + let local_max = values + .iter() + .copied() + .filter(|value| value.is_finite()) + .fold(f64::NEG_INFINITY, f64::max); + let edges = match finite.iter().position(|value| !value).unwrap() { 0 => &[(1, 2), (2, 3), (3, 1)], 1 => &[(0, 2), (2, 3), (3, 0)], 2 => &[(0, 1), (1, 3), (3, 0)], 3 => &[(0, 1), (1, 2), (2, 0)], _ => unreachable!(), - }) - } else { - None + }; + ( + local_min, + local_max, + Some(edges), + ) }; + let corners = [ + (x_coords[col], y_coords[row], v00), + (x_coords[col + 1], y_coords[row], v10), + (x_coords[col + 1], y_coords[row + 1], v11), + (x_coords[col], y_coords[row + 1], v01), + ]; let mut process_level = |level: f64| { if let Some(edges) = triangle_edges { let mut intersections = [(0.0, 0.0); 2]; diff --git a/tests/pyplot/test_best_legend_placement.py b/tests/pyplot/test_best_legend_placement.py index 7b226e1f..d4749f10 100644 --- a/tests/pyplot/test_best_legend_placement.py +++ b/tests/pyplot/test_best_legend_placement.py @@ -204,7 +204,7 @@ def test_residual_divergence_is_attributable_to_the_plot_rect(monkeypatch): type(plt.subplots()[1]), "_displayed_plot_size", staticmethod( - lambda figure: ( + lambda figure, _ranges: ( figure.width * 0.775, figure.height * 0.77, ) From 10b22b97173e6e58c6aa3fcae58e7e8776903dcf Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 23:19:17 -0700 Subject: [PATCH 11/15] Preserve sparse scatter legend placement --- python/xy/pyplot/_axes.py | 19 +++++++++++-------- tests/pyplot/test_best_legend_placement.py | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/python/xy/pyplot/_axes.py b/python/xy/pyplot/_axes.py index 95047b4e..d17b06c5 100644 --- a/python/xy/pyplot/_axes.py +++ b/python/xy/pyplot/_axes.py @@ -101,12 +101,14 @@ "upper center", "center", ) -# Per-series vertex budget for occupancy scoring (§28: decimation is specified, -# never silent). Matplotlib counts every vertex and says so in its own -# `loc="best"` slowness warning; the shim strides instead and weights the count -# back up, so relative badness survives but a lone excursion into an otherwise -# empty candidate box can be missed on a series far longer than this. +# Per-series path-vertex budget for occupancy scoring (§28: decimation is +# specified, never silent). Path scoring also tests segment/box intersections, +# so 512 vertices preserve the gallery parity without restoring the old cost. _BEST_LOC_SAMPLE = 512 +# Scatter offsets have no connecting segments to recover a skipped excursion. +# Retain #274's 4,096-offset coverage for that one mark family while keeping +# the lower path budget that restored the compatibility benchmark performance. +_BEST_LOC_SCATTER_SAMPLE = 4096 # Plot box of the default 640x480 figure, for direct `_best_legend_loc` callers # that have no chart geometry to hand. _DEFAULT_BEST_PLOT_SIZE = (564.0, 428.0) @@ -6039,7 +6041,8 @@ def normalize(values: Any, axis: str) -> np.ndarray: xv, yv = xv.reshape(-1), yv.reshape(-1) total = len(xv) sampled = total - if total > _BEST_LOC_SAMPLE: + sample_budget = _BEST_LOC_SCATTER_SAMPLE if kind == "scatter" else _BEST_LOC_SAMPLE + if total > sample_budget: # Stride down before the finite scan: occupancy scoring is # already sampled, so the full-array isfinite pass was pure # O(n) per-build cost on large legended series. Sparse finite @@ -6047,11 +6050,11 @@ def normalize(values: Any, axis: str) -> np.ndarray: # a sample with no finite pair falls back to the full array — # a series the old full-array pass scored still scores instead # of vanishing from placement. - strided = np.linspace(0, total - 1, _BEST_LOC_SAMPLE, dtype=np.intp) + strided = np.linspace(0, total - 1, sample_budget, dtype=np.intp) sampled_x, sampled_y = xv[strided], yv[strided] if (np.isfinite(sampled_x) & np.isfinite(sampled_y)).any(): xv, yv = sampled_x, sampled_y - sampled = _BEST_LOC_SAMPLE + sampled = sample_budget path_xn = (xv - xlo) / (xhi - xlo) path_yn = (yv - ylo) / (yhi - ylo) if x_reverse: diff --git a/tests/pyplot/test_best_legend_placement.py b/tests/pyplot/test_best_legend_placement.py index d4749f10..7d872ed1 100644 --- a/tests/pyplot/test_best_legend_placement.py +++ b/tests/pyplot/test_best_legend_placement.py @@ -342,6 +342,26 @@ def test_bar_rectangle_overlap_is_not_reduced_to_its_anchor(): assert resolved_loc(ax) == "upper left" +def test_sparse_scatter_offset_outside_path_budget_disqualifies_the_corner(): + """Scatter keeps #274's offset budget because it has no segment fallback. + + Index 2 is absent from the 512-point path sample of these 1,000 offsets. + The other 999 points occupy the lower-right corner; this lone upper-right + offset therefore has to be observed for Matplotlib's upper-left choice. + """ + x = np.full(1000, 0.95) + y = np.full(1000, 0.05) + y[2] = 0.95 + + _, ax = plt.subplots() + ax.scatter(x, y, label="points") + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + ax.legend(loc="best") + + assert resolved_loc(ax) == "upper left" + + def test_datetime_paths_participate_in_best_placement(): """Datetime vertices use the same converted millisecond space as drawing.""" _, ax = plt.subplots() From c196c124f92aa41c2a7cd7d8d5b83859b58ffb77 Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 23:30:12 -0700 Subject: [PATCH 12/15] Refresh exact-head gallery evidence --- .../annotation-basic.png | Bin 199040 -> 199205 bytes .../bar-label-demo.png | Bin 114064 -> 114238 bytes .../horizontal-barchart-legend.png | Bin 140212 -> 118266 bytes .../provenance.json | 39 +++++++++++------- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/pr-assets/matplotlib-gallery-consolidation/annotation-basic.png b/pr-assets/matplotlib-gallery-consolidation/annotation-basic.png index b9791109c3dbe7035e7e092e6a99254de4306ccd..34c15bb13c298d53a70805a29554fff313ea0891 100644 GIT binary patch delta 184775 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∈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

    dx`?c2NC~o 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

    2Oe{?;o&m{z2e`F0{ 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 QuRyvyUHx3vIVCg!0L^`%@&Et; delta 184414 zcmZsD2RxO3|F@=!j510_NyscavtcA5dy~CM_Pj(QLUt0TC|ma4gv^udojs1tvB&c{ z{eJiVxu4hbzh1BV=FU0S_k^k zUDsPPIC@5LyQ`QiQdK}#vj5%G#rID(iiGvX5+U4%U4^@ux^#1Ypi$&sEf z%ojLL!pEOK#r-!NuTNj8sgBK%7g0mGk+PSodNJR-6(u70vW}1Oi#1lq z3i8UeEh+5Bf{lwIW@C;ufnvQA7vYT0xZ|r|n0N2QT;s(|(OjXu+Osi4XByj1k$&|A z>cd8^)#;Zzb8i>u3iUUfhAxk^rp^>K{T4ax(b7Ul=ecDa@snfp)i@$cU+%FvP<-~$ zz0vo0yr=*fyw%h$GoI$#X|o*KgtqEqPWz4RLs&N*jo2@H^1QGLaYc)5GS!=Zbgg?* zo>?keL@g{Q>=s8^>bXqEn@SOSZD+;g=h+|a_sDxDP?x%ntS6I>lW*~Sd@3e~+Mh(* z7iwm88kHqUoxsEUGlu+GZe);5y354063?%<@H;ntY3q;X3Gv9Vu%6te`x@b69*2Hz zj+T059@B9vN&Gg0RramvpYI>LUtO>oT6On}SL*uR^wb4AFz##Xt}CJNMvQ;j&0?@= zrFwp5fy?wLTS?c;Kj00K*CpFiczE7a#`_(WHznogJF~iq^}JG%&Q#~c!Q-A{?(aG> z32T#-n>mSsD(aO^5h*F<^sGqM*zaVOpap70ZSD2ma@3$rX^etwPt&MOjg&$psiCgG z%c&njN_tkE!V^E5x%Irb4;M@Odsr!6Q2RSG;@voL7LQmC6WvZkcQ4njE9AoYoQrWz z4$CBkcC8^&b7P9GNRFbcN&d9h3L-j}Rwd@SKOg*9>Cfdu|KlfX0h&nbT!k z8N+l;+V;+zzXOZ)aV7~}b@4lSfl;kP!tC2r`zGdixs5}4dr2{&&1Az+f2*akcKI!g zF*E=7v690e`LPT+letNBb;h0PIbBI!6*`%1lGTA6*QQZVf6@K9rQ4UANEFJ8*n2E` z3PP&}b6lm6>d}$4j?>o*?w|I?Z|aa6<49NW6IYY78O^<%;*MQZ)Svxf*=)#Er7D(K zsrOji-$wqZ=w+6*^?owDP!{iG(U}$ZE!u_7?O5-@_J^2aDzV*Q7B_5UObmh@d8fMM zzJHpRD7`CjrN)%sYE&0{JGEtR&mv*3ZD6DEE=*0!p_fG4eQR?q_ewMO~*kzCJzSfC> zLI-=A@3oy#K~1QpBMUz%Nav;Rij+I&+1#^RU?X*$@BY5tAulqJ5@>LcPIm?u%!`|` z8%^@@@w*!_hEf;z?b{orIja!tIFp{d`)toj_0imuhZ8xoj2f5KR6>JT9!pERW81f- zM1+h65@VN=G(9)!+ia^sljE{#(mTyUP{LiwhI(l4H;|ON?i;>7b@X}WuU)1s5*?3Q z?bHHN9b0FLJw=>(x_8&(<}C{MdSVi?J6uuM?i$S}Rv&6{apiebh#+ga&~{SI7y7b1 z7k|uG?h|VjzkbuLxrSNv@^t&f{*Xh3_|7}Vt{T(EwuE9Mhz?e-c#)lXuQ3lwk@;`M zwjambyw#A7X+h2-N-2i@#RKAk-eDc0tf@-4i=m`kDYHi?*$S80TGt~UHJ0r2J}&vF z+;BS+{cIeQF7L_O&~R(WdD(h2c^|4pq;aVrYXg^K4I!`&4@7Ni`p;x$46DEJO zACJV@9&%KkjeTk&q42wl8zWV)(r^7It?Mpa8}(X-_tJq zV|%EBZ6Qo_I$EoCSp*-R&}( zef0Vy+SgFN+}JLZxsM!r7C2TIAv8of(vJzV#ul1ulUjotbMC#Oy21|K0O+Z z$4kvpgGY;>kg&|I#WRvKkLZxJwh+2+(U@?1TVWSRU5DO`#SNR;P0lRTA&jNUhf`l} z6bcsE8Xgwup=fn=Y2%8Q(<^3MR4~IM+D*dz-DQ50C284m(G2E2AF^T(^Ob_)ChW?NTAChb+hA9+>N7l2$CA6z=PqnAC4L${D8E8kT3)J|k?oR@ zt;WyBE)rp*dV-O4y~WsG3L$ha^Hk2*KHk{FaLNmN&J34b)O!1KXvn^Hab@zm_R`*u zKQ%csBKsF*Wo1`>RRuF&aNcxFr(M8RmYn*xG16jkZsmbfPDj9nZuLd&)Cr?!CWONP}T;;_h(Y$`L#5 z7H!BRXF5A|sWSx8*?-EYG{(g8z5eQ-71q}E*6ixO?=r`N!GmYt@G{X$ho^hZ{Ly@c zlv}QPEWOw4%T7@lJ!Lv9o9Ps*ig8 z^Jm#>-2wFc8LO|KJXUjfmZ2g(H9y`_rIMyxbQ2{+McI>uT(*d_P|Q%_AKBOlJ-%%3 z;T)gy3=^%7CS*uFG)UH)Gj^p@ts?V@Y4MxTqNysYRlR@c04xha+^sj#7o8% z+DzT@uz&<=VZqN%`Ox!q-3~?QHQj?a0s<2&1hKw@g}!hfN)6SU06_RfiYy>Uf+eka zKC)0N+VEHuQdKaWI0xwFvws*K<_j}&L2J*ler5?W1-rhUnuE?G&p=(dBh18qTv@Dl zXxTHdkXa`o9%V{lPtBzKQCkT+?yUCK(K*HD>VU&9CC|R^+H;djyzZk075or#Ma8s&OE10tYQz>@ly$Qy z^y*#yy=xK*s#&8iq_R^2zjVy%9nCFF2piX#4F#*9Vsh2L-o30FTNS;*m@=nZxe!@lKH#e+=- zVSHADM{S=^#2smx9CD`1PVFJVLpEi{*{#O{9-BY-^*m}qj4}Bvfd)FMSXwFGV!^-b zr$?9lt}XL||MLN5Zz&%fMQ~ZguGx%ct~Ig?`4e3&@ocIp9{r%`ips8zQ($6q*qw;A zs{I`v{(C{#UU40JLCNvbcg7x~^WQ5>;|Fipt(`Z?m-x1K?B2SI5X1zeI+?BN93(*- zhlUm&rWyxYsJnN=jG{xi%lWpxx5*4v$$a>OBbyG76uY3c0r8bKZFMMWiqNr;c? z(uzCGuSfM}Y4vv`gjjV(2CNfYu-$h{=kC7ecF^51vM=_LugA%6YbYVcb*X*Zc||10 zV=YrPtR2pbK=XY?!KqWa(>I3fY$;i~QjlU7I%5O4xbjzQY9?oA?b+vTU&T}$_)Ic& z@DOFMOfE@?dsT_T67reUWhm+H%6nJq1C%aDVS3w%4 zpc8Bdzbg10iXBX8Nhr7xU(qkOgU*z2;^M|{gmYv+bw;&mwDsqm3I*SbaYa#)k(#Ld zl9H(>4-LjfMOFbED|?@)slWT#HoJ14$ay_@7r#G$*2*U=5%z1gXmfev9svgvY^34zZYv**WtT=X|w`vKK=9XITvDH8fEeIV-qcN_c;;Bo& zw;8m8Xq7tIY!>SX6*paj%JkU;N!R0FeA?#6S#>nvRPu65n{7nh-N%OFWty9J=QpMD z?t;xFp>56WWAny}@gznq)EDW=vnP(KS}7#U%LGENh};5lZu9&2MMO}(5+)jnd$b`Q z%0b<9=$OwDkfC;zXWz;)bQ}Q8hGBmKB3gyoo%3e>t5a@TY`-DuuOo4Sd_fXa0-yOu zWAR>Jz}1C9!v1|agmO`2kvrK0l$*GxDYRBzZ^$r!e`rSwEkM*xcqHEUE$YA zK>D?XCz;;4J52)r>Jr_f7rB{l-;|oiRiCJ*wm9NEH@Q7Vc%G=D=e8B<6-!j1ik*cP ztYfLsJe~YSn*H_2wTqZOS#;aSyOyt-t&UbwRxT;@>H4~DFKjjA+m6fPgp3}@7e6&! zkE75Y3_dY()ZVAJy7^+LaJFXnj0}L#*TJr%E{?yE$e6LKcU(3j&nJn9jBx5ytuKXg zA0B!%hEO>T^(kSW`3Gz*ia4yUu5pTbq6gPI(-$@X^9>M-p*?MWkcjD_E;FGuL(AsL zY~i9iDFyGW1ZPUW5X59&5in|-Gey}sI|tpP+@IVmEqvt5H2io=nW$7*q{d}w`aF

    u7Vqag%ULn1A@1ADy7&bL|!EnXcsDJyd4UJI2 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

  1. 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

    9#du3fFs#k~ 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%0APgLn9qky7FawB7*h&fd(vF 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 ITf!{B@~o9)nv;PGTn)YQ8>s81seED`_Xg{ zLgS=ljj)BcTn{#8y3}%$&-)t5M5M;{@K~yojQH~pdN_bBp-D*CWF3q9LXP|N zv{7!~Fg)476WPG32@Iq>sMw**l^2XhiO(-<72Eoptph6e<%^8>YabK$*)qU?36Ud_9aI0PEn#(uMskBup4To&6dM^GX_1M`F$* zvg~cq%F8^lH06vOXVu_LGI#u{vHk173wKpcM&%G1FFYhE;VUWotpxH4R{pQu*0hi{ zk;jl^c8vTElv88mG-xVcB6>-}CiRq2h>F)Ypoo22;EsqveEc#!>sA0}yXNz(Pka_i z*~utQB8|>h^L!*$i{wV;3F~}*oE<8!lzOU7W3CRpCpTEEOktA8=fKo?Qt|P%h8d4M z4PvuEL_4ye4j0iIEFkskf$;vc|6y%zE0}Jfe$X}M0{U9!Wnhw^^5CQh$3EnDv}P;a z8VX~97!v*ykYwKlmq|=a3{E~Ui-X(N9(I|qvv-8Y2ciMaatoFqoadMy8*JS3^@A2N zkj?`>(>`>RfQBlG|0gkI7&~A%5&a*}_K&mAZXi{mZWgKv5~YyITZDI|j?v*YB_s+` zGp|@XD@%1*WD#y&iUsSK`tt^H!F%q?lun-S)hkA2NM!p^sMlhkZbgP+`eOQ`ri9pg zp2*RvnClL13K%4`R}8+IrY1u1<&(3HNyjF9BU8A2lQ)122i(lx$W|T*X&79TgBWu708teBKVtX$VIvNFBpjvp_gxVW zNTA)~g#&{dtdVex~R0ev#(w|@gL)aWYw{+0sjRGF}IFNG{YbT3_Ncpuj@ z7<XASW4ab14YG<9v$5ZSR1obEY{ zkz?@?CtjV6O%Qr^twv6kAUK#>hWabD?ic;8XTxvsjmo@g>cXBTG*eTPEHy=M9aeX@ zg-eN(ye`=Ie1R2qM}sZBQ_c5shUCv%gO8~Oljg;ZXvc5ri~OOI7?q>JA2EZvH^BC; zP_Aket!B6La>>)|=%!}c@LSF^AL*T2jIs?SEk6hEbVkG^hj0aEzo_KbkJ6sXCrbEI zmhzX9@NZ#fdd2~o<%NwLnw_{Gcm*0kAlwdAQQ+HQU|~6he?bSUkdVYgMG@Y(!4F#y z@Iu0n1rqNugw>FS0&6cDO%3UE<`7$j2Hxvk?PP)PbUQ%vpKv5Ox{HBPpdg_#2!;1df%@zA(6{ERo5gwUpWaX%ntbQjjQtmrR*U?pg`O=9Z_ElJo{vOYBOlF(FjDKaaekf>6Yw4U;P~!%1JB-96v_+WpgF z|K^r3b^}$&w>6c^m+L!;u4ZJ|r#vO(N-+=NaZ%@buk5fWDgP$lD_F3&$0-x%S?v_j zDDFI%!0cV_8B4@=PjIlMzIynJf!<}*M0_OmeW|{AhptXUNCoo!RqLsT4Wdu1oe%V) zsXztz=i{Go?%xNz99Xr!r3mi9u5D;}2f_l-9c6$c`1$$4k_zgQ6ZD)SEq%6X<9!p- z7wAHuQWL%K-gaNOlh(}(6Zr4nzmt3{4%h?*s zSF_5cE5GMGlvNVCzA8jfFKLH>T=0T>KC-+$x~N*djKmzQCXG z0&BQ7mekDUy_wM>Lf}Y9u{gf998S zRDa!vo=1?z3zg7d5k^45O>Q6hI@N=AhgRWrI&cmOaZj}4g7e^92q|biT;UESL(Ba0 zrx%G-VIC)C(OYQLcJM|df*}hm+F9Sdx8P!;zx*mTM#@d<&uKgm9p(yLse$K)WLFK< zC5Yys)cbe=p=d17z{**LfIk@vwPA0P~rB(Wbm1V+(80_=TiluOOc3=|qrv=#q2uvXxI=w`CJ{2+!51eX*39t72EH#&a&;y> zisrAO`S%bNyLv<&r}gS~x*_X`S>=7~%Jrul2`ndWC}2>BKIHc;9^XK1UGhsGTJEmn zJeJd_>3e?acEk7J?&Yyn0nt#ZOAB(h7RsARNQP`mznLLd^i0IF6VL0B-PNNo?7nni zV680uW%siEgKH&`b2itnc+sBImuO_h)vOmu`}q7B8^e%iND?uvQDrXLTJ^8Q{(co@ z@y(I%FD~aAni#D<$79(Px?XcYIf<>Fc5>~_B)^-2H-WU+B#!OyNUE*)rq7wXNSQ#q z&+bF-Huvg+B<5trK+z=CM?}P3%QWIb@2^Sh{pI)gN7}1m%(vIc;&tdoY&BWmJb$3Z zdeJdB0fU<8XF;TdQogR$=#uLP>veF!Us-U;^>SBI#YmPDOPNTodj_3e%ASp3MC>f7$~-=d1QX z{BN5~30L3mGD7H75;!Mz@?EgNC8c5T2WcMf$Jy;4wQVXdF5}SsHIM&wxBmCF`PXOu z`ECC7ng6LH`PZlZ!;Aizp8oZs-;I$fe;yeh_aJs6BoWf+N{jgt-(7KP8UkVzyF{o@ z>%fO#9AsFDPKRk2=9wtMAeU7kIf{x++{Et-=EL`;c;}o>pL9vmu&oUJ`N98w^u%^p zQ$98r6cqeYiVwsXPPg!zkQbpnNPdGzKNo&^9?20^Do|v5?Gmnw8}~&sfnw`PpVpe9 zcBQnsUMtO-H+E2|K)y4mgs!415b=!qGfMt`Yn4WD&{(HZzx>dmrF{>FEaoa-a5TYW zbQnY5rFri3s7h-hNup^~bKy3g)*JQ~>J}V@Urs5VKLu1*ZmnMJ9o^3S^4g%KUeaf%esSeSMrYHOo1HH?vIRG)pO}yeb;W9OA8D&~Tu zqY+m=9rqwM)sF@ABk7;BT?UWC%lMScqN{HX$X)Keq_86)b+xj_#*!WP(E2V`@JV=NOs2LvJ2<^&wfpt#v406a<-ni<$qrW^gGi(Fx`aklF%)HC!(vjBg8m zcW?8rikNs<-uvs#ub*v(#ryMmLxJl__DxS#XFmP%iX<7QMTf>~(d`vi%4HXL_ zxEllgbT%>0EXM|He`sW>nh#CQE3Aj=_@=h+A_SjJrBtm~JBK>`N58$Q?H>1T8Qisr8oX=x3=2@RVA01j7Kj~{-Q zro0820!q1sSqNM|yB?X21so%-H>U6Tc}whyPNO}>6l)&`yORzl7`az`oIBn(10B6x zI0{8}dE4rWn4?< zkc(->T0yaHqP?yO1JfWlxU+CVyhH=8=G^`mFK&H|fY&tBau#-d=}6+aXV1243wqxqzFz zg$^bK{zy?-nU_2q08}@?O#!0t7&cr03gi^Ra{(}!Zd`N}0CxfF`b9UuhtRMn{q;TRsRTc>_BCJ_VQTW`!B^K*r!gU zgv0UNtM{b_wKyanoLUn-_pts<@I~h(4UOf|sdz|Gx1K& zL&j{@wbAhl%`$$cD(#xql^il@Jv0kCQHy;HymX19h#=aamx8*LE~PWC%+=ar-s zJU7{z%Q9E#);3Wy5*v%F@R$%i4q*C9JR0U!ve(r8%$uKMkstS^ai~P%t zH%uYNC8dC0!eBw@wyAb(z(B#Pis<|Mm1fZ z*8B*?%9D=I1Mwho$mkF^?F7$SUpt}uvh+!)9* znVXwadd+qRLYG-s)*$Q`9fA*`Ixi_j4OCUp`L!&7(n8QTq!j@s>%PMt_xUpjfgv`A zhl=VE;60$gK3#;7xBzn+@ETASN=Zh>2hm0#XgA!a=iuaodo%;$gb0W)H7a`tGgq9h zb$$h0xkbU9UsZA-E#Q`po$tAAXj&kW?V)y-t!5XPTl}l)Y43C57SlO8)0dgYC%_7 zb-Tl_I#^flw?G+|+ba0i))@FqwnpUjXW;A_qj@tWVp;y zUSY=!AiJQ-WzHZ>$E07o4G|Sba3z3sT}a!6kQ=C%f$N>d?;uq=)D1uZ=+I$aj`dzc zhr2-fB+%rO-dlipLy#svBpzvL{Qz45pTnF2`tS;=r1`n2z`!Q~+yafUsUYuw{05Po zel?|BP6mb$l!5!=y#@nA4^$93YXjnZgyBnp=xf3k^#nNmAeU9I+7>k1?}4j>ya049 zD(GJz@%=6}^{;yTav1R7_b34b2m*qT{V?Q#MI4-!D9|a7l(qjQJz3a-WrU0|ZkgY; z5tST0@h`T=(;Q=ZPM~Zki6j|~59Z(vr0(#hmwFoj5NtA+&cEiuL1AtKW)OKT0nw;EXHDkK_}TFg(@ zzG6GNKLWhPxy}p5W~Nq3A%UbF;A4vD? zKY!K!&V9#HQWf}S1MRpQ#sJ1cz8Emp5IqXHF#r}kVpD(kunQ<@;P!#Wh727L+CzW> zELdpg0XlgW2x$N^y)&Rx1h_I<5HE3aJ3*l+Eb}}G3YC-XfR=)WoLcs5zfCk*$qdkZ z$hCsb?EEzrA;FUM5osmMb$P)%QpnIxk5jXb%A|TIubhY>_3Sj(hYl#3$+V60(xbes z>+}`non$#UlUlyWq%h4eo`$T+;h55YqYF?!z`fRaADIzI%473E*?};sb--TvA*U5< zE9S({BaRm|&D1yCC7sIMR);kXkTL6Y1;2mPBHx|Ou2`en1e#-O85x8%=txwEap;&J z91lo(?nTT-FbYhg7Zu>-;bIgP6o5Cy(zHgeBr_9nHVKvYx4{GmVplHj(_SBY2L*Vo4fNcfIus&z=eKE0*=(#u%?;2zs3j;$1<<*O= zH*L`FSD-qdv5{HVZ%85R`6vKkzI5r*K14s~(|rXd6JEOkC|%l~IJ)H<^2EFaG7hbZ ztd&p5FX|bS^Hf|dE#FFp1%Wa1D2~2MEmS7>@Tz9IdolKgiJKpTy3o9EP z2}>D%wq)G+O`|#_%XYr?zP9P>JJyyyDmXV(tTndwW5RW!7ET1Gi!cpI}PZlk0Cf_)M(x6uA`#VEPPiazO zO*nB77U8>EFD9s71hh+KEo@ns^^Rj5OmyipMZZW>(gYyDs`Ej$5|@XDN6Cp#W=-%H zDy+C_wfx-xvrJi2DOQ(sBb76!h!sA%60`IP@+Wv_OWTS4Ay*Jkjd(D(9WkSWw|aA2 zg9IQ=FeF~%lT%?yry)||1O5$+mR(6dpgvuk02WLUAm2lUoPl*myTSHmVbw%O)|$ce z1Gz=<)QjNd07V`2t>6+uflVru{XyO>h&eq}__~2q26@yGcs7Ytfr5g#*j<=SV9SX# z;Yos?gXxGt^qoR0%LBS26B9?EtLk8D9-Y~rNe7YH-tcXsqN3)D>OQeA}KOY=-yGvkM9Q>q_`CHftcB?|eR={OW7XS3rKa5_~S06`*bV zBwcK^lw$XFyfxNT>#x#jLK?r92#}V3zmv}UISHgdcyy4MH@Fu@KX`e-vYRgM&qR8e za0je;uwKGe1(0Lzq)xPt6RKMv7_S%L{?NuCn6IE%2sqYm?|v8P_t@CjfSa&&k%UC@ z25^F|u6%?5Orw<-+}9fio^yhr8?8wOA0Taqy^#@mUYvv_7&;jeBdXxY3JgO3a~Y4& zHG7Q*At8NED{I2eA01pHl6!jDY+tbCHxyoK8aEP58KB$W?eAf z+Rc4SfYpu+++%QkuLPd`e&z)mjYRPdlsN<#U%t))WqW5lPzrA)a0)q?bo2))SE4fM zAY=|756|F(XHC=8{^;bXGcc}e!xe3!zmVaYhF(rEf;CN)TTC8y$a|l>WMU;`I&WTg zHdP&77z3>&?cWG>mfkDQzhcDQJK!^_a{8F{5Nm1X*n3o{M*PsQ?&6hRT6MQA{tQaC z^gtde!+V5S3rt9ps7~vF8D(066K{{bTLzM`BDTlEoDRC~GE{dmFxecDQHV>K7Z^yJ z{SdXJOrmeo%S)ax7g`y%Tp(4~Ybh^5g=G3YBOJf>wkHWQa^itZqto2+X*Gc{x%heF zgXgJ2B4agssr*}A{0^mi^$ss%0y`v}=_anp$DHGj$!g4@|7zZhgDV$ISnSS|x`yq>$JZbDy?o){@qsrf=bj!<*I6U$0txr;>kB&->Vs5S z^H(!(HCP3A8PYqeB%_Wq;@85T$8uj8VCr1m$kVTROhkeg-TPY!NB*(xE206!+H1YD z#By8fW}Mec^U2g5wxMxsyr~&cbXQ2PV}}lrTI(g(EggvOrHs{{^~bK?p3HPfY9{6N z-m&#j4_XRH zTl^CS4J!>OB*$THc=#|5HHK#LOurFCjat_g!wwKmhcRCFj-dtXtJ{aFXVQqMkQc#* z6FzG95e^{jiFtsQ2?;ta^@HRJqLkgCW@aFlqYmh$(A^Q(LY@yZv7McMEpArugO8A% zDB6?u%GKgW#pNU1>v!Xnk8D6 z0I#|V2SeW@R~F@xZPvQ;L*oO(p{?5DG08e1{e<)P+{8BLN%dMElsI`4^&@HSRf?1M zZH|T`2P>J6+Q0f$BFedJoRS&m`UgD*EyxF*BS#%sJC35#&)cJH@ZzOT+qP%U*{VF) zJeY}SlscddUu?C`f|VC~K;ev+f9$b1-4Y6$1;}D0QM_(jH~zfQaCf2*W=I}FSp|i# z&`==Lw%|mP3y2GRfanC0wn4B;xCm!IXiEZ}xdXIsJ_p?1r5@l zDcfqJ0-ZKHNEc;{CSu6-?2kJ|hXjJCz0Ho{`H>Sv8(SDdX?F=VJ^kW27R9-*-^yK{ z^-V>ZGgsXjE*p@sG-__%(0;fzue-?8aLhelD41Nj-Ye==z?2qaEjo63J@UB8zw^6u z4-0$jsCpbK=7n=>b>fQRvASK!yXfCaxs@_j67&s9@d5Lvuz;wgIGg`)DaL8 zwlu=Mui>hBN#DqBU1;#eC)UdJ|5x2tM@5~6;j(t3fC3_j64D?DilhsJbax2SIdn*~ zC@mn;NGRRiHA^cgjSL~(AxI7|_nlpL@7?`l&$;*9bI-Z_fy~JKnE8HRyzlcq@ALf9 zW%VUlB%d&d`rOuP z^7f@uKBnwhD}j&3w|1y|)rnMY=Dx2qS#}UTUg~3ApqFQ7otzP@EiE^p{uKwGdo?xu zsn-kER;j=o$<1X>8vwombPWzcU<6!Bd4!vQ&a-E&P&tPlS$Ba+SVNEjuuy@g3*;O) zmxo55%fKhu`2G@To0tD+wi~zH1LX=3pZwX>0KF1mh6Gv`8L6rJ$0sl+7dP^Y_bP?} z?lCej=zRaU0ImhO8mxWjWCY=eEUY}FhA9At!8*omjp#LK9dQ666o~Z$8SXbTKxoeimzy$VP?kaNOxw?Bx(}M^4>Wyp>1D zq2;Sg%FKEV6L5RhT1>7IdcJY(A3!<6c_aX@@0yPgP6Y&5ff-V;3rZA#||!J$8H{BRgc$A4crXhJ>F z*j$ALhs=95iD+nyg4}cx=xbjjx(_W3pUc-k@Evn}0t8B4T3QhVEPUt$IfPX$74zUD zq&*M^!tvR=2Si93I=Te_iL_ynyScgDy05BS=?_J9T@j2|4=mA%~b8 z_a@;ui=GxkNQl3GkJOgB`0b#D^J|0zU*TB#+RwvuQu*%7?n@^ZUF+@nz72m;vig@! z7N|G+2%71UJN<)CXk90EMRcr=We~&`I(@7~JN~;Fd7nCL-se-l(_kAZ+RsSt(ukQQ z^b_^=9$q;vF9R9pC=hTQpdG@sZUVSw048{bf^I}sMhF?#G91-`2r8Jj2^@xj{_(c$4Dd4) z8DyoTYJu&ute0Nhj@{s^s9P+qx8DS$)C{Fr^G%5sje7^?ML`TF046Q&!tux_OLyE#pDx>eIk z8DYJi*)i$wY;q^c5L>DN6nzbZk-f6Cl=prccbOsK!L|t=u~mzU4~6D*Y;QM7WR-HN zw#l$ZwNPCc%*N$Tbg!q{=9AS!6gE^!aNI`jM;t;y_#rWr#$AE zTaJ|-wmx__Hn=hCrf{A9Mp(j}bID^j2lZ$>)-~IZlmtpg z)})#_v^QQ;kcpa^+N30Y;}#vXwL@H24Y1v$^Fjikyfs@T2Mn(`RB2)OW+7&RjdM`gwYi3@K?<`py!Vlgv$^}pe!Or=O6VguvC{9n zE~~u7JYMcW5q?;wuRma`Jw9f~58lucrHV3q&c5C{J)G!1GobGjbs#-x;+ez|p-3#j z{Sl6oy!hg`q(@(N&tuB7X$YeRqOy%W!zOj3C}{P}`HeeN4X1>J)f?;XLTqDdx%Oy` zGXFBmSlOU)6}fcDc`{jSnS+$X>X@rQW%0^^EWaSbVPt^~g%B7hLZ=8fRO7%WaR&ra ztn7CRP(bdE_Sh_Ntu8gYQ6^346wj?&t=4oH=hpeabee|~b7~5aJ+>QwnO&qpJUT*t>_?AO5YJoBB zN|PLFc=dur00(02iIEMbQxf)2ERaw>IU$=}sg;fRuJB;}eGSRd^9bz67`>Ex74~0U zeM?OaT5irn%k~cZcKrV0GX~+cV?M{yd^J+F00jw=q`qW_v<$Dw4b4z8P(9e3YPxt9 z-a#q>EqzRSY+|C!7dU_JUfuB~maxR)hr``=Rd5Af>ySs7aS>U&OMq9^p_32mdaP~iRpdr*o-7nSqxEmd0dZ{CJ zWB5Z}F-?(=gauRLnL4|$2ulKXM1((ex@z2=tZB`_a)(~oV%G$d_ivRi`0SMD{g$lf z+7rAN!ik)3H(5_V=ITse=cqMhPaxE~)EwigK>f+B_*^6n=-!dQ;Ds6>Me~DA7rnClcXL+@GRx$Es97Tub0P4XJvD*tYhW+^s?_ z`rP5!{q60>s5B|X*eH&DN=4HTc62fA;{(G2E$D8!D1~Q6TA}#j8Lev4h|(b$4XK6Q z&l&rj1|6GalB6RX^%c{i=RVva&vR$BDk!C{NprN0jq0$zYC4YHVqM@25-$?LFmF_S z&4?fNFp1|KLRQLJ*){r5^hoW}aOWoDh-gn^{!m0U*=+CVNKvG2ZfQ}@9sN+o%Ekt9 zsIM+;cxq9~z!C?Gaj;On*O+6N zSe>S6hg;(xaF)*2Z2FSV?FJfcrkq@5f+*yfrT}$$m5FAl|HtNwl8pq}&TMrD=5JP&=k?}VtE4WMD9U4S+>8ugc0W32v8~7HCSCCZFzr1xX*m$vU!%{5@ zb-#j7a20Ww>V*2(X4qy#zSAA2j*K(7X68Kh#v!S`Y@WK!M#kK(kv5^{#ABh@s{G_z z`B>ai2n;dag^QPPBmK$%y^E{8I&aNhz5VDVUm~tBnVpjlnpOb_D#&I$AmVmhAB&BN zdD(E51Uz$gK$%Uw-t7RAp>nIqJC}T(1(PYOsFXva64*ZkeuBUQ99l}<4s825&*PIr zSJ~rovq1?2w1#DY`>>YdS3~H^S%$bBk}fB(yMXd7Ph7N|JY4r6wX$+Qx1<{?nVR%B zBxGfK+S?DG>m~Eu=^bSlWf={V`<;PBB|S|lyjS;YPZfPCpQ^puyONf|-Ohx&R3RyP z{fJxD)(QTE6k+2}`jSx+oqe?L5wSuaXkGRSBZ$#yX}X5~Xrvl(&?&K3@#{iQcofJc z0Cug&JMH)}g*sjL38DC=!G3P)PK%CDf)`;Vi5i-tUbVPlXZ@ROU^@P)xn;&%iV3;e z!QK%6k!aARDe3r--aa&nuHKHzlSLGr{C>M}Hh>d==Cmf+Z}Xw>Z796zA^ z(AtNZ^1aPyBe`K0HO*EDey5)JSZqTMOXUp#1c*4%yD}hk1o6?F{TvRwGfe4!M zzeznob4uljm}T@R^p-1_@s`uj#2`mqX7r?6CsK7;jgzlbgk4`TTjr?k(&LHrv2%(l zxWS_R@Yf*xuX7R+3eTGHUn5b&Qa23WCg2U|e^xfUWke(!-dXvB+o`jtEA%kSq@#8% zNXxgZ+4zxkCUlB$C z{IrYXIzR{vhdcBcR{?krBf*FZ>A9pIf=mEImW%6~1Tjo^xV126)rZ9C5(a9VtO#(rkAOdOfhYhVpsI<8k5H6?h6D10a;I+OBuN7o;Jxsa+V;YP>2S@cz0sdi= zxyquPTtsrirxW}VRZ1V_^xXxX)xbEyc~4qC};lA1obDWX7hqw{N-BKC_6g z;uWlQDHFVIT}^p&!M69p?Yna(yseRAJX30+vER6e$|G5Shz5!@E3vYS61etsG~3YV zF;p-RUv|XXS<)&e`s{D+XjJnn!$dPew$b=DR`WVNXN3Hni_D)j$Dhpk>#m*S9kscg zzc=izO~|O&C_)Hh{@0Y(f=LS47EUZr<9+%8El}ml)nkSHX4DPj z0I!GKQky@We5p!69<3H*2=$e(>vP{TiCOr1J=+Xinh5G_MGn@-!%B@<^#<_XmwoJP z{1(+xWfkkoM4j&XzWL&iuU5S-G#1}P$q2=E3=%1RB@n6`%VKk2NL z)V|W(;VoJFF#ZvWbX`mFw#_0Gek>iD50PD>y1X2@;~%z1lj0WG_AM7UDwgyJ&wjgZ z?X*ZNxOMbQUO95mn=STg$enbB8bjs%GX{TpH0cU|&IQG`f+=_xaZr#a@C_O%DK(YpDTq zVkB?ew46F{ro!L71AbYGY+6P}&GBshS2;)pGMwhqp1S0@cvFirMv(OgskD4Or%W5la4ov>~Bok&73r?#(`0CVnOtITz1Z!YJcW^E*2F^IvCjG{Z?&heY3`Tzapdz)!T17 zwo_2B?^>LZOS(p=OvZ}Q+paxD-lydVgS9Mf`ZhL!8%KI7U;jN75|m2% zjXV-VLXHDNA<@#{=xB6u^O_2k0UhU9Icsv6Nt%>!EJ2%9QPLkCb%)KcA#=yB;adrW%W?_CFEY>Sw3k3`d8vStC78LdCw5@QB=7i9(_z=vd zP>@^$U!$M1Y$!|&f$+U@ivvzw2=j3EKcK9Plbr_L6;QFFrMg)V#_#l+H%u(`@J9!f z8MdI~8b`IcfB$||Ls-ewT(GzT;i(114Ie0!}*;hH2Wd23=L`{0wHLsPA;*UAeBfe5qT^Piu#5{OK^~z<-_IWxI|2sgvXmB`U%i~Y*aRxHT&8^p z1mxVnRbn!d-gK#h6C>SJC06bpHT4W|`kW#91Q?2%3Y_Vx0F{QskBK-kGp4Yin0e;K z+$9tCF3`+tU)kBY9bs=EOJKNQ$>uS0@Tr@n-S%RKhNL?Ye=~m0?4!ODa(0%Y+P-3x z1h0f6%i#NYe+oimPN&DTc!ZeTLSDq$WMFw!Uaj}A@$7<+O8$j&uR=JKB(ewd6MELB zhraoa3^j!a8em|Qe`tJ`pfQQgV>#^U-Wrs+RgM@UaUTacJHPwFk)(!GV@ZMYuj3U& z6wmMO*jNP06SA^hj!uf=dcg8%u-C<@aIq}%Vf|#)7_xGR#L~sNg;y9&?kOB9DIzIe zd9)MxFlsKZ=!)dF_#aXYf2PZ1j1_2{Loq<&5s{G$X|>u`xOn7c-2_M`JmAbQb8{1Gip3 z95qUWyja+nG4QGw6{81K2lejiDQ&rWga5EV}mBdF?JJI&4WZTRB{dfLuBlwgN} zzwXjImf~5FUJY~2hkWoAJt9-BWWqbQ(@qvll2N6(BE*t?AO9$?ZX&dU#`Ry=^4n7H?yK3we^F8F1K(~zl zFL;=v_%Cisxb2xc_kk!m{QK9}pWF3ckA8-He?9!Ub^P`4&$I8ZM}Ov>e?7tz^8VwF z{d{clg;@yqBPT*)?ZA9shomL;jMr&5cjOr5wcn@Eb{Bu{Oyo2g<^&9^toPy2_*N0* zk>&5v@cY!Zj{+4z(b_Yke@>?bF02dV-_eR1F8U; z@C+WF^@r4qjO{fc2-Y|`I5@y7ft-@EAjXaW5AV}2l{47@TToNKk|Vz#U)&dSuW77D z%2Y$aOx-Buj+COMB42s~ecTa&vD|f*_8T@>ZLSBAKg>NiOFF(;cU)bLoPSN>S2g`x zYfA`X+U>h)>1U>^(L}-LEc;T$&j2_Dxs!?gl_v0fKWhV{aQ>1V9l3U?esgmmTlZE= zEaG%#Lfen)XUHvU-5%fthf(W^h2dAwlR<^VNc5yzjm6kdkcC%5o@V*9+;5sBBcYnzkNGzF9ru_2oW)+`otR}-)RC=a z2`r00U$EJhQaXhAU*93QQtArsV_glJ;SQO(j%(bipTYe?)}6_*uO6OpQHD`aoK;Z-2c4n|M`aSe}372ee8dZ=07j{ zbJP86`2O?V{^w=?^Ctc4vj2IL{`qeI^RoZH-}}r$i)j2U7J9*n|btmv5~?$%%;6PHnW$O!Nq?UGZFiKuO)gi{;^vodd`gb`z0Tt z_Z1ey8cb;>{J~1l63NcYnPVyr=jtyoCl<*!b?; zzHRqlx6WMk1T}H;Ew}&N;Y_0Es}DAJ6}YEfK`FQ(my|w8VHuhnj`O*1HYH)vSAJAz15Oj&6GLVBaXpX47N0 z*|2-_=!Zd)lDuVBk1ab5vlu>8O>=kSJ|p~}s*={bATnc99PMFntH_sk#ll&`@v%`(nSo-7nu)$`l6b&ut$#14m6l{$2Ej<)BnRhpHUbyW{f#ub@%>^8ry z)D=FT8yMT)94164SQccd zdpw-x=>!TEe2bzBo>%A|VoKZuHXKxS`nDG>cb>#w?%^#-{vBB8?>F2s?b=pXup95l zUTO7kcVZl;&Mw5uYp;`piAbu}KXIS$e(tQ?{emJmFIi79yUI(I4r_ zjcga_$htGNoRC~DP$r8?J02KPH@iG6&_V7n5z7W*zpdS@s9I@M>yUC)sOknn*?Xwk z&}hd_NmR54>)etgE1&U}AeL(b?Ssi(j>bOUoE3I*+!!rt1t1V6;)|~8tFrvI!vmi~fzK&$ zIB=P2x>(CpT5;u}%^~kbPd)M|W?09K@7_I+#)+A{qR!EfoJR#HF8$S;B+{;i(=oj% z6EV9dBzC9(%L0~9H_xM~sPj&Evr|gRuB{DvqV^ivbjI9{mHV}0UoK_Z8M*B*2?$3- z>uio*CJK3yz4BU|%@SR-Qbs~4IG<@Li`vxSzn1Y_C1#G#qi27!L{P_Rt~4v0 z6}4FFB)Fd{5S%*wX1Eu`l-lxZ8}Gi*=<^pv?kZ|L~8x z-V)rJqv>spvQO4ETG1gq8O|;xU78icoD9|>7V%#E_<}cOSxXM75#>Mg0D^;>2SeEXrueczH?EYLHZpq{|r;QpO@Q8 zYoDy&{~U1bWNrTN^~UN$S~P!eFA4A7N^YPdUvR8C z++CMfQ?hOUHZ#tuIyoV_Fh_Fc)yG3}8IdP2DY8>`SRQL3NuMEq&6g!7W>xP^!SpzJ zBt2Y>=$tndNZK1{IL(yMP)(*88Tgs4E%C9%D38&P%tOx6WrB$UBKxVLD55A4Ks4$RTspH-5KVFLw zO#05_8t#9Cm^etxwy(#Ik%snu1m<|hBJl6~={4XP;5V%El8=Y~r6Jwb)yI3DlLE($ zIoBrbg3xOrmgJ73-`G%zf|%_B5QV-R6evPNUSzkuCH(OV0a8;`XU4H=9cAuDQDfd; zEs~TdIu6J4>BC(zTLtW5*CN_+_0l=v1fJ5Im+A{4qHYgXF1Oia*FF!*KPnV4vLgrx ziBTzN@|D&U`uL?%b3N~6ox;0l9l5>f%aO{R6_mGUh@fsj$Um`c==jM}^SE;P?Ko@B zRzp4ZyD`*oq)J-vstSydomP9#Ba!1_f-c{<;?vaol_Pny+_bFcI+wIG0YL?tma2>K zm{$*-$isA_{p@a@mXtLBL6c zK!k$Rxb65m!<>`t!CKVB_M&r>pSD{=;w>_zGy;x1hZeQCPd!bRb8{!{X|cZYMSIH* z{+7-*)334^q&=RK>*?!dH>ZVgnDge7iHJ_;D3z7tMwRE3+S=v{W8UG%TfXv!Zypi` ztUg5CsmPfgQ$DFMd7ji1aJc+_BQP-NvE?W+1!+FZr`}(G@Jzoz%fJEk_&INN$U`+z z{T%J0OI6NiL#5+vEecX{-oy>d%OGp=7cOR_3oHd4oJQiv+}vgL#+Uo6mnX~3$Eh!h*C+V4(NWyk*Kf=b8oU|52@9|Y@ zZvQZHeb$QT>sN?WSn(Jobtk=WCdqAgF7W+$j%LYj281jXt`#!yiCk7ANo14QJIWK@ z%$wc`b)8#|4~)(`w0XV~73-^8sl`eFU7W#|IyD|C0}o_9x*Wu0CAqHX&&(rx*WN#} zsyT|&OqRSh5T0$S!xg1IV>2kfRh{(c*saifsLV3bG}Z|D>x40$`IyLfnlc*?bzQ7s zT#iaX-pIQW%O)#RHwaNO&##|s7xteM+#KnLQFS=uoMfX`t>-Y@y{4Q-F=!oA_PBgB zn*;~p>J^)~cSVv6qR1V-P21t2VHZ)M_#&}xwK6&>qm&dguyCqar%U)a+st3AZFg;Y zMn5`#-{!i& zb~>)+tz4?wd>?cQhVnFOe~hB3-bKWGh|nl@D;sh_?dVDrZTD^9 zW;&hoZiv=?U+#F^8gc(Km7Yer|Lh5edP8}Fcn_-DWJw~=!BX2pOY4m(nPv1!{6ksi zIh~D@m=Xc<5L`San$&&Ed3}khuUa{Mc*S|6Nw#U~(=yk}yc<8t#m78H_)X7alNTt} zNjEk&)Q8m4)wJPshn2qG85@#S*29&$(9dj^K&Zl8rjbbYsCw6=lh;cZaEQi2B2rEF@ebN(> zP{kjztbp}U5?x$&b#9HFHrtbF8^a&d3(CP zxv51pwBTrST{GX)wKbRMa4#S~RlxB_=89##@e8cLc#UJNZl|G@OwvIk6IMo6l7A*5 z+;#{_&%h!nBSFr4m>jL+i79uzbJa&^yxP8YVb`Wta|CTz)@~W?FoWE~9vm{A`!W8I z-6I2kEg#~Z44s!{g_)Hi&$iK)WJKd0Q_jX_d6e;+TJkpH8vPO2nxn@0I#+-H;h8G; zqY;vf6W7^A8}&Smc!$w%B-#f~J1LoY_^LXOwhp2vYmJU3wODg>lJxT{4PN`drk+Zu za@JT0)LhdvFyfR(azOgCQ9pO+{w%i@w~vip;YDsz%L*hVp?ImO*V0#>Q4TMV5{OHS z=d*u`oK(Y73}%!vKEs;6_8&X`o#>-=r6R_WB*Aki972OzK$i-(zghpUy;$;~;XjT>C8 z8OdDr{5wmhCp?xHnNf2zLnB}JDjWuf%9%(KBiW*!@8)l9 z4%Ij%c(e!fKDjvo*(V&j*fFBLwUQQ`EHk+v|gul^|!XftlGJd_XTUt_7%@6QiL7v z?w@{rT!>`pP&s;usSB;&*=imci6PT@f$sK6v8vqYe$Qi2aWjnl@r3ixlCUrSt;(Kv zR#lj=4mO?wML)-0KiqsQ-4pQGIcQs?{`>U8!7$&f6`j1jhYs_c1T|_c2AlSdL=Z5Q zDlxy&X*;j?GMYyZm^7v`pq*B$oyU~B;?i>uZN{l(Wdx2R!dbZ&?Dg>fz8nssdws@7 zqPuE8j(W88u;Z%gV`*eDiWW}Cg4*xh-W$;oQITBINZaKPGkyt=Mjl-G*Q@`&6dt)s zWef5DeE74Z@YfUnLV^AXC;h*HYyJr*c};dDczad4qU-CrP}>O5st9iD#ZWg ze;$T?drq(PUw;Q26s1y#WBgwph&`i$0k6`l|Mu7ycS#dy|C`H(-KGt{WfT72-Ibbp z!T((LpP~DId5}fdH@3E_D3~OSKp>D7I(^sudfmN+{y*+Kpr*E#5c;FM95#^oJWV|D ziIKLpc733i*Xfr9^MC4QfCcqAmPsi@I_r`U&D%--TIZd!Z!=_FAfYx)^xfL)&_TgPpV019>70oC3jo}ULWSgBd-1_ z$`yKlJ$ZR~3A(n|kesFWxV2by>6zM?ILEo4C>T%%EoW}qW7tE|GlFU#jE}}`4c0PdY6L7j~<1wL3U4@ zkn$&R>-aVBu(up*cInM&;0>tUXV{*QInQtB=WBxzn!m^L1)X-f&`TG=aC-EJ%2t~hgi5ik+gSq zu3KNX%aZe{`aLz3-e~mqiK9r@Mr6@7UM+_?684j&7Jhr;pb=(SR7EGsZ{Z?W(5y+y zaXIg4gwm2@-JAqG6+`&5TGMqe$8ax@lq2km&Rur?u-hv*fPu>(j(J`FL=@Ns*qJI$U2O6=z6zvMmB{E*5se>CGy(w*HLiwyOQ}_rr@$wrh)v zU1+(f$M2UurpepP{(J2wspbCNPEGqg*%aGLx&NBd-3BDhcg)2g(Ca-icPL zh;?}=e>AGv-XpV`pc-M53Z8<_zpMz)Tq7lWadU+Zq`JJ?Hormikj5*Vf0+ZH&PjmJ z-<#CDH83jG%F6Xby!$Nl@$XhtcgIjzi4$1LYomp0xu8x*&e&_OYU<|p zl5vDFSPx~0cFtpZBoVghrgUQM2}?W!z(kvywD>oGmud1Uu(Kd-TK)a|;Gci~sgiH= z5I)&ejlVD3*iFJ1F1PZHsllOhbLR2#+qLuXzJaHE!ZY!ops&i-bcoiv`ZEVBIl)2@ zbIBl#b;|4i{VWEI2^?vt z!nXS@jc9+914cHdOIO%-mydVO-yFknMxZPr16uBZ$ZhjD!)B! z{do=d>HOKw%Wu2h0xvyVgx2_{h zY(km3f%`G$_~x^Zr{2&cZ7k9-^JV4^4(c{r^?ttPm*`vEQVrH)5+`Z{%?I??N-VgW zeLE?T%T6C|@sd?Q5YpMmXB|ite2CBk;wD987JuCUMB_;VtJB-_UF00FqD7KXGwKEeLu4| zF-uf|3~}B=Ud-9 z7kXL!Q0z?Pptnco$Q&;-moU972|=m83bfftRr)klz+UKLmo@%d>*bm-o?|sIP82ep z!yg}e_Ar9rAp~S9#$W8u+mVVlXUZdLNbIguPe~@|8e}M(t!iA>e1ZsG$@N|)kv&^Y zcAP9VUOM9yhk0M0A*rMU{@ImMK_*t)pZ}0b|Bwf)f%cX*He$HH!OSoEt9GC%(s>4V zm9?=h6I~qqEC>HEb?v5ohgLrM1I2`rLES;oT>7DoFssS>>o4>|1c6?-@vIoT1NmGK z1YXQ65YEtF#1h1y15Tl#rYZe|LmFkUaK%(NYv|{Y{O2v^^)5>ZL52!>@_wEe#cM-P zVUG(cCfb<{>pfw`(^>bWvx-(@hl|8`f16SHma}1JLcf$Ms|9z{IO9qy^#M0mfhn^F zx6h_-{oJ)vW_}d#QcSFH^U*KmUO$|wnO^wJSj$lx9u+yX40zTQ`hmYUmh51ujB8-) z$G7f^9Xj5gnrQ`ENy0SIXGInpXuH;$g$Q+2^ioG{CPSjvybn@IgAu|^&IZfanzrP4 zxt;?|fuKX;^0b*K#>{t!yv#a<7*hktNrvz3O80 zTMQc6j~7c?qca(;o+`$h*}-GO zD7k!MacRS~tfO?;^xsp08|q2hvP<2K+|iYsyPFLWc*H^}AaJ$9b|dvg!R4gov>8n? zlXSgsbG48VUN%8=8apXU_6FMxXI{QGr42Fk(aRTn%eEEdUMVc^uK(x|Mkd^35y|TN zMbNm4>vGuDW@X745sPEAyBQ-@^u~KB+|uk;Me8PBZY+@>OJuq5`D$YgJq%moVm170 zdg&xj|9)~&Pe<)b-|fjCWMo{`!GgiD%l&>y;u#uOPCU8ZR&d;I#oh-UX^l$}OdV8Y z;+2wx7G8JY9~OpToeJ%(nh#z(+`q*yuAKJTzj`)n(U8t|Z5UbaC0MQ=o0(4VNM4jv9& zt2m~STu)lhf0q-Ea7ty`Te@2rp2y|LDW2LY1TR{P^=Mq^mnqKxIA?&(7GNS#t~jKZ z00g=HYQm?MwXH$JZ)*{=z5^9HHX`c}w3$JP8ib5D zmOstK7@qi{o9pHRZ?2XQrKC+8g)t$CF`P7-7DE02xS-N_q$feH##}Bn)wig+&bAxB zAKK|GwKkNlBLDg>L{pd(cfjVjJ%7zTH~e?<-_VQLK*w{=*qWqF4%q%f#HnRJ1nCC2Q$j!9*2&D?K^C!H zy{#~IbxJgdvUg*Z5a>Mzi#vArmGR;C-kJE&oaO8yaDvRcJ}Oy!CcF75nUL8@im-B8 zs0CxiBm_tIvUt5ARy#&oDL=Suy*a(~lK;@yjE`o-8s(jxkP_RP$+PFs zRKw#DF-$5&-t0*H+++Uc`ZQ8(F^a1#4YVF9Q|#Dx_Y!E~QfuP3nFl?jBS4D?0k_XO zQe_R4dgkj46$O=>H~aB{@K+{|vXz6q`w&^M7VcR!lo;y_u6e=tF?$@Wi zGXP;rt^P5XF0B7ZQZf>Kb3WC&{&M8S>EO|sOCCSHH|0p|wL|OGNiEYO;afFaOdO*6mu^=Rh{^$2t%7??Qgf&$FWR z0|Ef*6nUr!%s-X?4RFH`tSXH#muV(W{hJ>nSv=uw`@j}!Wd)NzB@YbTP-T01baL__ z0)YK{kuI^EaZ*;J$kRD5bBzD>E zplH}G;JqEEJlQTP12XlS#aSJv0OxQXK>xF~TBpxAx5{H0k{k!8t3f<^3TLZbre1TY z2XZKuxb4l&{!In=eL+D%yjt!PBIM1Eb0Cw{dV1@nEym&dkJ_iD0Q=j1+#uO&NLPP- zzD<+NqpvqHIr%`SVKu4C#Ru)Tz*OcpB8?fFL__~e9dP) z%LVDaWV_7vm^9{tH7|ycb(~I&CF?6lulhN>Z^;t}=~?~$_L2`t)YOWFKcOvIlFnwB zOJHxnBpd>0L3|X13A~GPR6sTWPxRu!-y3KcfGYS)-(Q@z-mtt)>cClfum6?wfPm>(Qs~jm*de~}PpZxqY zfn3dI2e)>GnSylxO+QA0^AahBo3=ElS#N_Mdt(SP2j_w2|2l=6t zq{aa)$3L9IA&<}OPF>|Xzd8qRqJZ_%{(#4x!uWM0p0TlEYK%^0zo*c#vK?HNQku)b z_^AY|*vVe#+z^$q*CId(`Wnbl@LLo6xJ1k%s~4|hgc2JRQ&*|Ah|v8tTG-f0KZ2;K~d|rHc-(?bb^p<*^jj} z%_=Pd0IObw;hy8N>id}_Q<)@3?Yb$2qXH_50kteLELsVrfXJ(PzF2t4WnS?WyATNj z7yafBbCnldbx|swuiNbgQWNE-Tr5u$bu3=*HXV+<+ffy3k&uv}ghx5Cd3t%xSVpp> zjpgc=NwS;lNX$6UTo&ex-8lX50!LX{}#3<2V z10n`n2JXj?uga+xzPZ+;0CdZz*h~G?V*3Lve+M0N<}IHy*4l-Di<%J~$(l>Jm0=X} zX@vFkB%ZIYugWt4llD;!o%czaqpf3h$Xc&< zoRJ>GF#mONPk^ISUdHZ3Q+yCa%*-$`M;I`r?9c|YPxzlQ?o z0V*@x!t9pcoRd4Cj=-Nu;*V9uS{IC+N=e+!e~rqId-vd&bE!Q~Sg9;lYNXzw0pSfG8_I=t%&MUwoH5e%+l}pOb0O zOgj;qgC?`9+Q`)EJ%ME?u>Oe@IG?1k(d|}Z;;cz6P24D`qOO23dIKrK?pzXwE^Ycym!%F!@26_2x!kKY;XuZK2y2*-Q3d-N zlIDR9aVtp`u*r$GJR<}&R0hp#@8#%MCMHbGZh@FiwvIogB_+m#4-+Aeq{#b?Iv?th z6G6lwRRH_8>sq@%Dn8>Sr6RtxU^xFC<27COk{4KWnfZeKpHxl6_}T{g^R7^!&X(MN zBvc4~HU!R#6=6D;b=uygQ^n8;R)M3ZQ`mhMSs_+M3%{3A$dMQ*vzv zRPejoe)5zw&VRlX<651XnzvL_`S(3oIRp!KcBqO~R&hoW#jSTb2OMSrP+*q_|A$p1 z^Y!2FV+H?c8pPJat`ZNh0bo8G;O3Kl4YTPX5@Z?s+@70JO3{Qj)eU0i}VQlT~ z8L1W5mbnnQN1i>bpyL()LN*-$qYMjwY0f>=;&ww7*hT2M06q!(=uO&}JcfpK;q;zzWB%xEHJ#PC)$0x13JH ziZGa~SZDuEtgIKY_=`8ZR?zsp&w3^Z0Zp2u>KD>&LA1T=E3ewYCx??IO~v!E(vt$=Ar?N;F90|m(8R?u{}FFMpHs9@Y6hsr zu&@84ix`lHE9N3=;nEKAJ4q=m&mlpXs7N>y?T?gQIt3nDzRN||4%ocwjH~U!9psUD zf!7IW66Py_Y2UeqeH&j&5jO`aSI=!u)3O^0Xcfu7Ncz2;cScC^m}FtZd;q8=w8w-GgPKPxUC>^&%0 zcXzgytA66@PlG37`1Gdl6Px!s$b8bzE*5TDzyOS|{H&c$n6)vc$@bIV#U#e7%46)GFq&Fxn2v#s^3=G`^A#Y z@7jV8fWBG9s^0?#bgM9&aVq~sy!MRFicZ`pnxuuySDbgad~dE!BOzaB#b0{9hP)7) zS=2FUaI=L!Kh!oqPr3qVGx-8m_89&{@0NGJ5PtT>4`(ocsl^+Bkk{{So1HdR2=dH; z-OB%&q!ErtW-F|)psK<0DyQmsnvSxR)7fqrbeFVetDh%NZlg())yKwShBj9)Gc7GG z_RW#EglMiH#W#5UZ+q~ zpxIa|FP$H6hhB}2kJBhD0IaGLjom9x09YjpFMM+fpqfY)V5Uw0$VtHm1GFH*+FmYB z6m|o*AhVRDW*>0k#Y*Hop!;7^c4Vh}_EQY?D$OsK>7}P4Ww{s5M!YDcCZ7k>Bs+4k z0eW(2@b`X;Nb9M2|HEMp;`Bq3b=#R?1mcg2i4uj!UlcG|L5NN&#o3mVpXK5CuMkn^ zfb`6?b92>t0|HuyrkQc~ytTgK%X)5EjJDXh|<0uDc$`^o6 zc5fhtLbsu!$Vad098hzjr3DZEVLA|&y|ty4<2>M*P8x&4Phe})?(G+Mf?EXwj$72SfIjr) zHntr-Ou`PZQBZVIoXkU{JGS+@i~!2RH|9IPrMOU+vqL_M}9 zIC}Gd7KPWl7pNe+Q#0Oi_OOyOr^m3Fri&!akR5Ubp&ohb$j1>9p|qQMqQWcDdmEMl$(GLG2!zacM>imI)n2~*onUrj&o%68Q#Y;2TSs|NOIMJ6{hXJ_YSFxt<2Qo?uZ zYYAZv(3P%)`~v`PQ!D^O{IsXRvJu2K3s9@kx>*uyFQyE38@J24W*gka(^4D%!w8}@ z2OwlMLI55Q0MC&G_twK4^e4G_uqBhElMZ0pQ1Zo31NTBxlI`{squA2ItDPpGg#z}% zcY}uj_6%5r=jP__8H2%B2?tjI9HaE)4(Pz{Y4)aR{EaElOT$skR#??KKC4 zY2)%7v^%ctdc$*;3qV#B{Ol}c2$sU`tWxXNY!^ld>k2-smL zGc@x82qxLWifpXg=I8X{CZa>EGx#v{<8z`708H{ymhJ*}lw05RM}B|~kRlVn4+a2} zY_r0H#6+e_ru^&I{*zgE{fiAv#e1)ulNh583oCwdWri9Z_e-P$k4w%^(chCi1OP$0 zSI+>ju|WR)wuy;}BfvN-#`R~n z+=Uq5_kH^4EImFaJcrC4M3(kkcF?yZ9J;Gmdqp@ZxY( zi-~jdal#=S@oOgHT+42`D_RvHl=*@&A;RxJ+g}f(*m;6$s>3H6Z|*Ge+KE!*>JUM- z2UC(wOBAXj+%Z(fpi0hu%C5M(Hkhy9zXLonNn40y%0gSc>e8Z)<^8BK$2hMEYn7l) z)sGk!?T7-v@0rCuV3@#R_*3~yKk!=?R2?|+PwIw5mt~!7xc>(}8(hUqCOFa|% zbW=~`3NV0FOA_WDFxiyY^6NW5v2aiog|=zRw%PINm7TX-xR^f;xzc%%1xVjBfG48k zw_|Uf^^5NEcX^x@=I~>F4iPONg3C=bwCkk%+J_=oeG|F&Y+<0sc5Mg z`@OtH2A+hfZQtd;*f4hYTrCnQO1TK+l{6Ci z111!4fShM*SFUvlIqc6YQvaYgF{p~^OMCb$cp6+EZVR9boyo=#WWyqDxwksJJ#0=> zis~(q{|`(=Kk6fjXXpi6|F!+r0~QQ>WoD+Vg&EET>&*^?QM|*w;*j`+XNN6(dpSmT zjp}&YP3OR;hRU4=K7!I45Goonw5hTLI5|YnO07Sw5es{Ico@QwxqeO}g?frtN6+as z|CU+*W>|lZ5b!etj!$MX|G&@v?SH!%)UlZD-#+=*k-%q#g@0Mp|IOE5c>i*43vC`r zNFY}GlYg|dnEhb?_v8O{VqOMphJ<%^?Z5o?FA&Eo_?O!7uS5PpcK=-aAt^!MKjiU$ zKSk6BmH*p^_@B!HBk(_i{I7NJKPB~_E8_pC3;gHL|CfLLUzHSAn(Ep}c*6DK_g^P1 zydT|d^;sz7e{BswKZp`j#jRQi@|JS~;xzHXmo&b-CW*?c0jY@sdc?AAb+ni;&!zU%#xFBpiq}R)LLi zRgT)~E(b681U1d^#PqK=7*#n0C~i+p@j1He_N?zzDEJ)M{Eq%>G`>7(ghF?^>CFW^ zM0;pS6Mne(`uVA@o=to;{83qHpp5tT09t+d{+(=EebnddN4Le_*ZueA&it8%h374F z`jWk^u)2D@v9VF(&8dUz(<8;;0hOqOVAp;r9=rnHTmcV8-Y{OaQLRT3|0v)8cCHsP zKxU7dVq{}uqXGb-;R~!v1J1W5C7foBs`8%?yq_}lnhvE>kXp7kbsv6w0=Ob!p!-lp zT)s=X&!HCbwbtvA0co=jj%07~6kR=sC_pkNCnxu40AsJL?&nWi`PPyWP`=~U&6ouo z3lW?e*3w3))Lip_l(n4y>37i2Lxi|{_H?n7S5OGKag*fU9UKr>S_tD2PO)@gPk#FH zG-U^H&*SBM| ztSDIS-OcY%H|I&#o`FBO+j6m6`}>v2v^QsBRMyY(hw~KQwge`n1h*~m@lAc!QYYc? zx5vlF5{`&RGe8Q+5xP@b&1YB~rhsKGVK{}MlrnulxX7_7Q6!`m5%c~yqq~%E+W?Xt z2pEbS^~ac%__}Bso(T48AmT7YC-{dAR$UUyZFQIyGima6WpIYPyKV*QlE4R#O8)2> z#<;>FST|3h*+QSERtaYjoBHwtPQ_;955(>gqH92^s-5+v-)eIo)9K&kvEL6v82dDf zJJ&A}LIEXb2OCFP`TiU}`rC>LDnYx3sLrx8Qq=`dt`G;Qud`bdA0V#)AqENu7|D-s z-yZtML3}%z<}ExtJR}f%0T+PT?SR$%9Dz_8>+uB{pcD&qsioV961&wkG)zCx{dm_w z7p3ojqrl`SpXbJL1B~R%v$7?H1%NE5P6O-D7Hcq1b*IsN4pz6QA=wEM(wG4}ln4b$ z%Z{);Mo)6b)?ta6w~={wLY-=@x<8Cc03smqPPkKzO@ERFeIY&QULIVkMsg+N#$E8e zydr4x*JlZUin3eRWEr{|{rvM~!b%N?*lqB~oA};_EVtlOLG{-Ki_nlY*O-P$f3yJb~~Z(Q%D{ z1WY~0lofsmg5|Qz?^Hb=#GAhYk`2!*q%j4tqj(jvqcOo=qK!D$Lem_d38dSNtSCQJ zhLuHJwt035Yd~%9m0;8uVSsu~MiPWk+}V=gnOZ`?%m3V7t^nBW9+PR-zNReuw)WB> zwQAy(v44Uw{ItoW;_+G5DaAp|DV1Z;{E7l>4F85-hV&qXfsNxp8R)19zw^N5+=xHi z6mnPX&bq!h9hXC^SwlyCu~yVwrCXDL)1Y?&@FE*55G6MA1A- z%#4?8JYh_EE#ZS0RF%xB-~i*I)HOj;FARi>Bgn54}VS_9tSPmyue#DR4-^U>QL zflhv;G}r+FDvaEj@1@>#+2WCh$#R^t@mNM-pcsGeakeT`k%+q>VhX07nV+-4Gmn-^ z_grBfNS$rP#9g>jwD7kqC4&V@LRi@bF^q&=9LD9LRv!D^^hDP2t~Y?AC@ZIk3w{lR z5|x4kc2>Z7*W1S$U=I6@iyGQ)#UZ2%$5174Nvh4Xe;3a(gJGA{d%zht!KEj z-+%16ZyhMy_cO_4vA6u}+s9nw#mZ1kSBo$$$4P}F909==nIi+esZq= zLBHkLC)vt~PWqNTf-GtGVldG3smNGI%Q`V8Az z4`HRx5V=br6!e!NpfRWQN=M?oW7Wv~a+CcxYtgLf6!4ftE%oswR)K1A4r;l<#zF<2 zv|Jtx?!*UPT35(xG95AXECXVg6ISTgyt-D2+PAW=HIbugwNvQYVk-UfR;}H-kL9KE zMqu9`cW^{|e*&8n++_YBt-@jp5NTgl;9;^>Ws6889w_|3|L3g~M2p zAaa!}5U4J~GsT{~VJ)|$mcsDgUF3cWX^*vNR;U$c;{%R3X8;|t(_h+GOq3eva~EQ9 z<3M(o5PATFG1N1r&fAC-EC38+nqeOVgk7%9GiYRhP)*PNrHbp>G%SD)#f;cr&vK@8 z49Ok59P$2?y`w*Gg3Sr?4_rI!ysMksUFH%kiU2**`?>XPs0#0fMJwp9cv@yed|W;_ z>3VOsz163kfF57gh0A@m6W0%ObB(^~Xxc7OIR0wTT*q($*jF|b9a?8X1FX2|2KiQ> zJg6OdSOID|LjXypQ%eQ4UlWND#G@&aTSGJqJ@+uH+Dy!C|bJUXOq zIe;82f`7e;QhMfg2^gEqw_N0(Km-b;zKQ%HKYn|9qEPN~uaiS5-mhTj;1+v+x*Mxo zA4lk|Kl$+5&71DJR9NI!e4Gd!^p;+ETi}mhD-zsSy|>)<4%$g68wTrlda8kwG6(27 zV<$iYGGD+w2k@95+RU&0!JsM?;M%fBKEdIkEx(7-NpTYzxkqjj@<)9n(Q1CeIHA8L z*j>1Vsac07OI9}yT#|qSJnf~=T7+y{xSHI;ZjfGVkR4B1^Rfx>PYTL!KZ-ffHWAfQ zk{ykxAvkV@DO`lnHfBTZhCl8#mmd_#Z^qOR?dU2=DZgt$U_8qGOy9DFe3Oby4Qzr- zr*HeUs*v>Vaa6nVy;@V#nsR6eNF!@OoR#PvLB?B-d=LquDol4$)GHJ|NI2>%5lj_dGlE#*T7FBHmQCut6k<`= z?H)$$UGQawvRHqM=Xld<>%t1EiJFx*mxLsRM&u&txPPj-XIl^N@RvrduxcF>S%85>^gd(uOIlxAJ*1%JUC7=q%QX-M;mTO$E`q*sZZ?Er$tD0=A0J}>Wk zuCQ`GzwRHWqk3|{oUNU6n5#tj+>ZGxM1DXSdT_1ec^>w_V~d7Dotvj2eJ5y%Om8df z6u%u;fFa+snd+Hv4F@>Bw!|snWsT&H$}0;S7Bv6)?e?u2o`aawu_pdabPWkO&WjhE zzR)M}Aov3`N&Z!Z9mBy~+GAlx<(_fp%+lq|udg4ZTwN)F>s_ODq=Bqihxa156ApSK zBJ`DKEA?7i){@hjEpxz)g-r<#BYTrMjr8uC<4N_3Y$vA zMcgep&b2kOKG`1LUMRVS-NPrZq7Jymrk!%UX5a2i-9UM#$`_FA_A&*TX=k4h~E z%ygH7D$%bGJRdWgEtZpu5hhkiE0nxYA)LQ@!!`}M)CgRcTsV|Q)8(eNR&q+W%0*=fHV@yi&*dFi zD?wXT5=3VHUQHv}$0otha)=l&=@EhVyMXD#Gr@tIIl+O}p&NM)yVPA!HqW0Mh4~i< zgF_`&Z(8=kTeKIJyw7>hANP*-`0HJ`IG%$VcK%2vmQ4|mtX{^K$f(R3OUZt(d@gfN zbWVAkN6JPIY}LsD`X&~fmUUwR5O+kdPtK~kY9EO?s!#q>b`^K$iJur{qGSs^em|zP zt+)_!nU7YdzhB7asz0)X2xt-ZUq&2p51`1(8DS}@hkQJTmO^!MMMALt<3h%``nXd; zs!P4vRDWC+#aS}xr>(1q-J>;`S+?m&@@3ichimS}n`BULy8*f!`$Lq7lL?gklipbD zJEoB$CqCg`@qjmMpY?d@p9Q4HX6v851C{B|Jrl}J_gu`BN|#uav|YYg%a7@ykw38- zoU1KdsVsaG_{Wt*?f68|4;iAV;6XV=kQbjD3`rLp5c%dHK5?*+#_-yRo3=jqfv{!jl!phF=VNnYF)hfIc{T$ zF#O2t9;`d#!vKT%r$O)aT!?mVU@{P+J1cn(# z4$X0-o0c8!s=b0jR3nNMT?K7Kdey2U4e3VKn!fzl^wf|r5&yVH#P)GJ)4(Lz3+MbU zP@*Z)sXsOkhjMrB80${^n61hn4fOp9``l5?W&PqVlv9Tm)&sCZ1G8&b!-TFusPfEf zljYAd!+)4P99XlSX>E5H@U*K$p+&aHnP~Eez_HSQ&<*DTu9sy1t0J+ocJABo2Jkr% z+Aoi(IM1qNRAGbItaaXOW4kHuEGt0W^e~|KN2c|O&u#st<;;j?ig#4+aaviy+1mx? zd-KK2-NS9us@`8SkJC%`hPZ141V)AkdgKoc@JCCwN^0U^vJDEVeq*nOvc_3+-;>=0 z@nr6I>1{ln?VJfgfANbexdJ;y`FKnr-)bVFw%sUN;t|e!ir)ZQ_TDqQ zbM^%TvsL0#i`ifF8?RF+jFlSvk+cKd;(OUCy+~;(BI6~nnDjd$7m6};et2~|&Yt92vEx_q_hvm@9y(dB`df(YQSoGPPdNjMdWYjP($$B(w1cl=d3<-mC!r3u z7c1%w*AwTC4(VUZ7np-`8COXp5_mE@ue*>L1J|FZygQ&a7vsqdqmi?A1@f4zlM~Uw zoCN(KQ9gj73~a}BI2rfC)nD{hpMdufAK_@w9TuP z8JagGgWILRQ)^HjL;))!Yyvuy=)aEkSdHT0D2g*B^k&ALDiOTO=>+w=t3%jERzBvw zh;f%nuRZYLQ$Vsp`0|o1W?kgdze6ksv}O*aZB@_45&Oi}Mh}1uY1= zp3Zg&F?MP#J;WCadSuTok&IMgR>o%zofpq4wBe|@Eyjy3gR{SV+PBVE+Sx$6VBO*C&&sf<$5I-kZ}8{AI*F_>}7G`FNdaO5MD? z?D(krN}@uyYq0iMh5*lPZc>#*h#J28?R@o7?o+M`DsRh*LbfHny?!7+%K#zA7Yr7+ z$x(K>Kk75~T(QaDh)=_ge4yjTCo^B*3P7Y(xK%bPYaj7{h#Ef)q7UxieLX?lBjXXV zxRyym&aFhbay29lBmX|-&0+d}O#LJi=Ko-O@;IDRq8|Mz`o%-fO95d$2*o*$WA7m3 zI@BtXmMeF zeped<#<!E{{ijJpn|Df|CQKbqnFBL#6!N4fS#$9!)U(LHhN;~RqJN8g z6R$?`io`b8p2IpJvUEg4OSN`iHFGnvMz;NJU(y2bN}T1fgmpT(%#m@(N#>VjS+Phi zSwDl_Rv`095E{H~6*h+UX1%pv4@+-3`uxmGfOn7fulMpo#d<#o+`8B(!cW#%I@|2+ zv&ki4R7+rA>0iox_DNrADa?fhK_WfyGcnlwY~VHFT~GjV2dB}AJlaQ}cx07%V4Lv1 zW0-?RoI$|q+$mr--mVxjDwx}loRI7t-xW|=^kr5(y9V?>!q2n>Y1b+V?8in&sdapu z!kYRx2LYcHX#})P#!KY-5>JYq_vM3=@t^%Nms3i+CO85!|6-8Drtnm+XzF#@R?zEK(F2BAZib+W z&|)oP_6+9uU!f=q2xs0~CWz=(rjiI%5I2S{2mdPgl*a9@Jo`QN?c^!^-P;@OQYu95 zS6s9yITz>9_>)zI4WT~k>j&<*E71Yn?wpZ{KR4Lty*9j3qLBr;-jqE&=s(_5uijqE z4;+*95q6u4_h02)c_^E4+xo-2!nWzp*+#a&3f}bc+{aUQo;S$)*dTg$d3a1Uv9-LG5y2#lowRY96Iy;EJ z*I9qGK{cc++8fLouN#&VPR^b|c@eWeWCRkG$tsuqMedY<;m?!VFw~~E(an+diFNdh| z`K{TgkF-qERBy9Zi~f+ecQ6G7J{VImWU`-a`fPM!&4^dS;xXbEal?6Cvw(F2O=XuwVJHIPMW6b6>RSp-Jh~;A(kg(C>i1uIq~)?46RT~7Q4UT z&2zslfe+wIk!4-pU6i(Zc(OF$7<49mQVy>g0ZqKg!pBtg>c`(7=v1kB-Ne~uD(!NZ zB*ynyUCQoWtbluGd3{M6scMUbLp1f5>IPq~caA0=jGdCUmbMU`{qi5gravyH>`&Y ztn9@CqjJM9*P7d!@_7>5S(T?$U@Dr6a~<+$lr!`>q&N6tOn%{Bw*%;ax7MCfr9>i2 z;>KQ&QB)+4(N=tK;E^Fj^B;kZ&I`GdHg_J`o4%6Es)l|xM-JfSrg{mx-`V&v)ZV)O zxST{r_E-bpi(F(CMD_H0-3@T{4RZ)1 zf-Q@>p~I_&Uxxm)m~BzBQy-acvh3I6H6Uf@6zx7rWGa*&Z#hF9*e(ihou!&q&0F%t z&~2JS{CcDmxQ`UeA|d%s706MoM6$m7=M=T<=e7qM0;UlH+Y zyOQUn^2@s5+)ntuu`mQRV14iH%vlyQuY)43rM?QQ)H+Mdn;<)&&dIUxKC&t6tuKsY z1f|eJe`ZL$=vbbdY;Jse0@5wzfY&#)iHi$mpg%diWjjwJdZe+Vzsd^!cuD}K45X=r z%;Zf-o)Ec1F(1B~tOslsVJhUlvMKnTD;(Z$(w8pIki9B%FtLv>^?8Vt>5oKwySM#7 z)|bv-(+H(yLoP!FrpSqq;_Kl$?r9RWPH2gCI9PqXA=R{!cm{DrDQrPb@y|(m#htw4 zT}^waJOvJ-uj88vburAw?X&mLcSb-%xN9pceNw8gm0ouUE6EX5;anu2a$4x$7a!9~ zXoVOq7u2T)+hUImQb@Z!OS4#!(ZK~lMm zpP0KqqBk5*wKqXWUG<^q1Ybv}&G41>mOEKNfPoWN{4`ukwFYQ8^!M+;qkE-mANGIv#fKcZ)QN(hPY*IP6!>CAaLl}@xVj9~Ebj{bfWB0Z8ID>1Bs37zyT#y%ct;{}* z?W}Lo@S=HPI%)aO#)U=YL~eTryX&8me2^D@&aBDnlmg?qCui;UE{d@Cm9Xpc)q}lTuDV^$iqoFSwlk27Ls*If&Ra~2< zr6*neB)lC`rHRU4m8R_=`nLQT)r^!%g0qLCd=1Qtz=&JW>~32c}aM5V=R89d#Xm@I7T|* zvG(cXNbPjUl7!|djQo7tYa`tWg&c^qNT*kZ2B>GL<25k%JVXo42j;Rwxyu>l>~AS= z>0EMh7O@*L#xoR`)$L!~SkYyMI%$}z%ooy+-7usx#4;31ff=XzUUP&!A@XG&VV>X2 z4JMRl15QnW#Py|%)3KpHr#%Rd_O^N0TR6CWHxI0q*vK}Y1hP5;+ZW$DhkS;qJ?dw#qX)ZZmNp zSf~1sl?p3sRl>2kFpLKj?Fin zCa6QG*K554MbfoQ$6?+?)NfU94g>lZAUxT-MRi5L;dmw=q&0fT&`#$?ATm%(XAT-7 z*~V(!5?)&X^Yi?3l>oUSmm^>kIYz+9xh z1ZV|B=7pg~Kv9fn52F|5nug|qPUO%9yLAF>AHc}1FAwG2#1WE!W-&Ay4r-xMiLwff z#{v9{+tAVKU`tKWg>Ko{o1$v=tPB&?DK)c#1rF!2aQ}3PBTDnqupiyWiQPk{;zUvM z1H0yMDrT5#pA(&$Wvdub?;EGPD7j1ara(TTT2Wt)6Z{jaiQLXfHA&l%J6VYr>@$^L zi)0_>CsWt=UVL16h)J|6}hGE;2O3aad`ZNuvQ;o5sY>{(tPfWmsEH|ELQT zcbDQ$i$l@i-r}WDC=?CS;_mJc+}%r|I5ZS3PS9Y*-HQd6AU)~x{NH!)eeLUfJm1b2 zuE0vdteG`yX3g(6_l=>MsNjSr#SfK=e%!ivx+Tb5D%ChM(|X_DjL9@G*y9^>gW+TB z!nfiTB-}632gqx^S#dcv5x5zCsG1XlKeO+9sDoKWcaFAmic<=s`lmg05rAKGM`@e9 zfKz+m<3!Xu{{A-ld&-(4lwH4QZJKxD{r*i~|c42TLY2*$FAZ2iKGwc2xH!BymY=RgOt+|9eCGhy%`x5y9TzT`9KtsAL}txHN2 z+xLV#JL0$m*nJ%EIj13LrFo2aQn=S)^UG>t??hhAURzG!ANF4+zy7FF7y2lgPiu%n zFLsU?auS$G>S%x9H>C1w7ATDK@2&(=g$tOiowd(X&2Nr2n|f+V`)U5U0$NG{ToOBn zXmBqaXFk3SnS|Zw9H|_HcogOC4?wt2_J$ND-0KzZq_@JX`*`E< zpv!oc8#Dv>mOvx81mm3LQ}Ee-G-#rwf&vke2)aRbAGqKfxGg$)f%B8f5Y&8zbUbp8 zbszrJwbn^Z@E9Tpd}D4U$qNqLo`Bi zlPo)bfRoLPF6d;1C#5HKCanD?`8y^2qT4wow6dhez06jL=^NO^mT@HDxNtbJPmPeSu(s9g;IlCN?weRqb_&=~Bn~ zZkFdU=sn`uA97$s)_ZF!hQ8G;5 zR377(lwTzXpt5&-$wa%Dn#RM+88D&)iIQ>$<$X5mll8JA!_?E{E^kuy^Ec830V{~}V@L z90?q$xRq}g;$@8N+p3MiQOL$s)8}}2vp|-_1%*yE(CK$Nh>vmMfX|+ z`*O<^9XNx}V5GyUb&fN1+s5sIUop@IcQIi4ZY<68UCkcygK`+VA2q=!i|L-yF#SdB zJuD5A)#%P0p<@WDz~H7#tOG!WzBhlv74b224{U#W44UJ0u+U>c;WO9;9ZL{1OGXRv z5z``a8=6>e78r2ww+BiR%uQ7w8=>>ufe{SckqJ5doa(PUe`_i`;_1#mfXxSof$D1k3=OH6Lb00l(Q@Wz~yLiMr z`*`qfG?Gtx*N`Y?hEEE@vlAQnds=k0K4WSOZ}ZgBjz1pRJJ=ztQx;J8(@WTn-nBD` zSQ4{swwe0M-sKbLfEZlwT!Q>KlCIZzlz{R5?btmCJh*Xm>cD~o+Uu&hyu)1E&2a|V zbqV*^040=3P$z0R${q6%iLE8b4b!1g6C0T4U9$>2%yVxSvJp!WNDvu<07V$$Pf{eM zz25um``P)HxOtQI>I4ofDi{R}9vt8t_NJ(irx>1?H6+6n7oyw|p}Xi|wPqm$wdkXP zfwBHsx3$s{-)5o7$HYC9&Sz-Ce;tf z@f7hM$ z#Q7|@I&aVS1^0(g_q8<+(yYsI=TWzi;k+Iw?qPmK^wasM8dDLs<6kM@NdA3$MD5(( z1X~v#(lm1=HIim{kKt#%_YncmHoTljF_LY{tvK%tn;_S+9#@huO($XhtQL-ty^54= z1&R0sEa0=_5WB69p?D+nJCR}(yCRZ|v@pDF7K>E=%?qa{!L96TIVC>yuYWj}dj+wk zuWLAO9XPe`r|&VK-2~^6Tha9Ev~O_nw}y9c;O}Qvce1?kkF4R?0!RzP&PEt_h}GaQ zknbk`54u59P1lbhVg8X8+Tx`75*jadnuvIDQ$HJPQGR}4;LsK+r2ut& zZH(M9!erLEl^#3|)lwr1hRG)S!G=2=J#(>Z!n<~NV$OpT<>%QPBiDB}KJYC6uo9Pz zWQv#=RAG%8e}7$aRQDOTj7)JT^gD+Llw?dQb+|hxcPh`-kNPFS)3)URzXUZeMdt<5 zbKHkXzY6O&0huP|eH%BQ^C`m9DR`93-L9D8sc}714GVtsPlgr8F$INe8w#AeTva!8 z(4Ph_#&;$f)m~b{4x7*hC&*VFwJ|eUHu}f+w8Nj3Q@mO9%0eBOFP6$gJwKlBde;4W zaE8P^GPzGPb^mi0#}M+QL)YDHp}LJuO{_~O(H8P|4*lN^H&Yb){9!$yx5__@AD4ez zRmVLTR}2V1w{~`)I%(VJBZ;Gnhi3+>7d>9rRih#bOk<$(#$4hQe2ul4Ci zNUuA2_I%TK+#1rh_}&?O3};5~C9+ISE10388g^P1Aa9Yr`t1^Pcz5M}0%RAOyFPDK z+kKvjv#cG*KYnL4_p{eVX*J;_=3>S^)frfRD?m|kd>-Y=jgA(9JHeaP1#Czg(txwO zD;3;GC8{;iJGI})K52GXn4ZU%eEh`x2fsymO`WbJ4gC?jBzp)yz^nOuxvKKg&a`6n z`_R@%=x2!^jN;>u_Z*Y9@D{aHcuPfL$3zFjWgv|7F(haKc(?JbVrV!>ZEI!EK9)(3l6|8c>EI@(y^Zfa;>(q-+q2fD#*?BL@#)Ai-`@=O=I3~sb=uoH;MkNv;JD8+fm?t)=ci#q5`tD*K;?OKq zFF2Xtb))Dm4CHiKv{!c{2z<{p__4fa_OiuLQz7+bA(?-&>HCmTQF6l+hJ~*`krA0% z?}ZIhT{y8$g6DbX#nwd_w+=y9rx)220kG zZGspi4njRqTr2z{SGyYvEpFvF-8#?UJcZ+@pNf?yck|x`!A!%E`rxxLyVDl7ZQQvp>WL(%18-rIXLNaM zF<@7LJ~@WDd7*f3p#j?1hUI`_`;~Dw+Od&QM>wu!Z@{*GJ_&7tUA{JTWfl6FDvw!!sBCVWWC}SgXWYU=_o6{sw2%bf}=1xTmV~L>->24%v zdho)k$9`r;q}xM_iW_W=NgiTH)MWQMC?x--mk@SHI=$W)$$IxlLi8UuCwk*AbTrW} z>BB@ls0_%pRX;B5C%tFi4GI{jeO#~WQvrS>P1PH>+$3a;wN}>OszZwJmmP?uDTu^4(4N*pwy6kPbkmt4UKVt(2MgiI&n?U-Mes(HS~9*g!%u9V)Tm>I!I zkb;cFQE>CR!>LmmCSM~NXL8hD%1+h$?wZ4K{*)U#Hx+u-SH=sodPQc?A8S6gCKu#x zuw!dz>zz&-UoxjYgX3fK8kBQz^4f)b`F%(edse_B)A*qD1Sy0Suh+qo=nsMeVsr?Z z<6xL!r)0)7P+&}`OUUM%KLZnxUC}SqUws3n**M-_QjvD48CcN5N$oZG#J}N-LGLk! zpIc0YzS_ru6suXplc{h-i%v@dUi$as<>V{Iz}M;W7nn_c5Ma}C=K3k}rcm0ACF8-F z&Pgq@bT=tWAT>4sQK@(&#WXA$wgpVO(mc!)OB|vBq7*Z=8HUgb0I3n%qMst=IoHRP z$yuY=hC1T>8*GbgA8R9vql*sC-Wlq_`2MaCqrnPm#ofFu9MMD_$}^y*d8|Ax>OtOX z!Bjtxe1VY)I@K^Bwu=GCXn}Uu?@Jrn-ArYnjSRC!tUA2P9;?hnv=@|yGuuVcOIxF5MX01#e7e&m0b@#&CW5*0CC}%d(74=QNVMMIFoG= z#>hnn3TYVOf=r;SF(Y6C%X{w@fa!gNV>cnTJVf}bVv@wGAc+XGBlu#H(cAId;Q|eL z$gtqqO|M5^jeI`ijhM(UbFrFW5+Z*h0B$)J+`j>IGZeT=mA{i@-Defm zS9g8Xt1C2dqT;va{Cy{$&{`2mVq9dQzMapd0L}4!`~KFv@TE4ikKp9tOHDoNKE{5{ zBobu5kNa3Y=R99g`G$)yZHS#3u4o6d+Kil9+(2)yjZ}F7ndC`Br*R}R4|3nk}wka zPT<#ucOo~04-T;0@q;&D%!{WcFvwnN4G;%+08jcgb{9dMK)}}2F+)DpeRc~)ejHTN zH*w2;bEhPLG6zHrPv8~4bdK=rBQJKCmV93(Bgu~u^C(l$9f1m`^{PArSZp_)@ z+ZNL|8kq;4xy@k39IeyQe7&N&Z|g<7imtdh0Ub1dz% zwQ)%1hsAilkYaZ;-Q621#hSr_$)U9FH{O0XP*Ih(pvyqZYR~!I*lu!$hKNqTJ%vsT zR+uct{sH7u_L||YHx7XNJ>O9K7873*p9J&9F?^1{V&T|gOytFeY83Q4D&^WEoy%ZB<=DA}?>{3rIWYELg)-@Rb6Z_@=<3 z%1aUvf!35leE&%z^{AzHGWzNsq~x7=Lhp~=d>Z+C0TCI1dF+=Dd|eN;Tl6L`cUa>& zy`RRf2v#$iIN{Okw`ctamlOn<%4^YVNax|jo$HYTXZS$=5a^zuhCk6u*Y3X*+0!-` z{~O2naz&<{7!;slJgFXpxl3zY8(S+evrcZ`50PF#51H=@lco|Ei};0w39>n`Lp|Uh zq#+?iMG^M{Sm%N;pNFN?5+bK^n|zEePH0dRev=y!#IU`yo6?BsBT_}UuI6z6(l@n-xB6Kk;|R*oN#O!I9e-mBrL9?g7@VHTLBd(~Bx$zmu)FLxEMT zd@+KZgdmqis=LJT#BEU+ylrH%1LfDgdjpud`6Rz6@av^Z0jj((Ur}UtRE>O#|JAnhAT0$-^hZ%$uL4D61AB|C*phbHUfjN z&IFC1d<|2QL56b43tLhk6O6~r^+-J45`{dE)!TRN9pPovvzRVIAoq=`$VTMTFaaDB z{-)9*v2kDD4+>=PP^{$I?xZC>r!p96)V8v-0gB)>OvENtpKNbB=96Ji#nO8@o{bNa zA`JqfkC7**own=vV!|~gl#JTaX4i044hR6lg199;NY<1&IW|J+{xfY}}{^u(qb3 z{nVdG#an!yN4wDXxX*ma8hHkC2oH^y3VBSaN%+A7X-D&TagMgoO@p}u?0lAkd7mH^ zdU9aUx?kH8Z@*@MA_mDt-(%KkiF6#xKF)G}+PJk&qHl=pgu;M^xz+GBUb>i zWY)dlNnJ_F!b;-D8FuOYB2b&!&gRqKT{fZB^1H7t0|u!4qpUj+8{~Q^t>}uTLWMFj zia&m}-6gLV3=VkhAz-ITZasm{HG6?8(LN|3w&NXWekk}e)^7X5Wj6xq%{ouXwO)ot zDYEs65q&G`hV!CtH2h2ij)lXyoE3?S$X?7*Y^+9cAJ1jVN~I!rIK~M|M9VT&V<7n< za@_j|%VvG~-By3-0Tpbtx-8qm%#X>{3pQB;QujP^RbSPdj{z|cyt=mg5+EPgrw2R< z4kti$O%x)?p+v;}EkT0inKV_1CF7P5dXfTy3yV?RqLkBB3kT9iOzI%S6$252?q^j^ zUr54H;Lk5$G_hPz(pSND3XYzJBnAnONg9qD9iZxHysmrZG}=SNKwiNs_oi&by!S_S zwDAs@%~IwMVx=?>RMWqlFU=XPj7SP|MEyw8vC#ZMv%J7uwa8IturoCDo~Pa#6Laf> zU7Q*ct}tE$t*@uVK57$Qw66{OVi>%1b^e%hVb{$+$j1zyiZ;lHg%KU5@}&7E_F8)v zy^a-=Z_{gatiq!g`9`@>70-kB#@gui1bG>Qp4N5j(!lMR$=6Xz4zNk%auCeePsx{D|(fVqi z-ozj!J%nhtdU>yan+kuYlxBvXpBh4@iIkH2H567i*zGTtO67}r2g!7!&AAE1AfKKc zP2%s&G?9tCfxYb()Z)Fw0}5Kit&NHiKB#fwNl|LD?X(e=tNOfsaT-ttV_fL7Ut>PGkZ1GJ)rt58qxjp3zOEb~mSA_^tbg|4 z5hy862qOUgT#B4TBa_LSUaR0d$nZisNY8u@_XPLPjiM1L2l*A^)hi}hRt(@-gz}Hh z%fCPEBnszOZ4-cvx!XYZi)o2B&$#-`&f@!4)r~W0)57-yE-5aF4=@a5Xc_i?{6WYt zNH?hxWiMZw*bLKbdwtk9jOUQ?pn2PTIKnlV<&(2AiOGG2<&uh=D*OH|=ImuP2GLuN z@%DW`Rb*5iSxfwo6b3O;6`I2KeL`Ws2&R5Xzi%q*ibm|?4l(tEC9a^g6&2r5~?>rVST|>;WMz8H+5vf|Q`O-5*t>wb%VVvoboQ&=f z_2a-ePP!%n`@<}*JL$)@XAnxjj373Bj7S8=-0muB@RucHVoDg~RjN~}!mzq@QG1gR zRPlbROCH~umQ?=zRFdvx$JgXAlBh0x5Eo(zq$JEohS^e1wlv|a>auP7soT5YZqyoG z9h{WM|8m-iq44r;AmkmiCPso~UwB%9c9<{T1LU3y0pa9QrjqQ>L7Wc~#ZRl2B&5#= zpLKmwhNi};m2l+`{jO>pe?ET@Vy&O3?yT)AGuhs+M-!R zSX*?hQse~60*ZuYQ+a$}T5KRVig1Rl(AKS$ZO-@3ms3`v4c_l3YfcotIC$}Tvsn~& z>{Bt`tQNH25`1eVGFI1NeexmIR`cta{h{UngGKV*z^NJ6 z+0$t?m-n6@V$&gx#q2$&`&edFyl;r^?>(bPPl;d^2uF=1t+K3E?#Jj_+8Hg7xvUaFV3eR2aWy`t3?a zw7YZ=veV)a8-Svvf>t6W;tt#)pU7W0(ZIzT;`(VJx~pmXpC;{)A*O3Sl(ZO+80Ew_ z@}1`*44mEst>clBA@M^u+F5jHD`(8~cPf}iUDt{kvVj-G<#5>57>TMfoF5ab8258@0YUV1;kQhj3 z78E+3N%aL-3y}GyfJ^4wOX3MXEnLS)4E^Gw-%8S zX)Mm~MWz)BeR3rTZ7{NQfxV$t|~KD~&(=(ZDWJdDMJXOK^d0 zmfRZmW~nO6I_Rs&HolL~D@6V_YnN1Mfm!o}hv@Hm?|pehP6E;Kp8du|zEQ$cAAh@R z%NJ<3)}N+n8!P0zU$0icITF&)j&BX}c$!sX>TFB^{jgph#(h2+f2JHt*HQKhhpym} z`E|j|to;*i&}(pT8F!-L<@*8VEwr|@>r<|pb!4F#z~H$?kGAH|o9fU0XJP_FgAD-W z`r!Jrx4%(SkN`aP?@{}O&8X*thdBOrNtegk`omV9S~Pn5O3wR zlB*=QWLfx`R zCM{j-g<8-BsD83rnoALUq`ZrPVLy^Aj0t(o>9B1#U|gN6?K|J9F3Pe_*)B&<}bFoQ2zJOB1&u z9f!wx0U^wb&PmRPN;JBJ#q(yzUlxY*td)GON2@NgIX|d0J#VQgqayv@Dv0yA&wy) z1;C|4ZgONW9OGB4xiM#IJlae>C=%8Y9=DHdo*K&!6;ya;C>bBxZ*P>Kk9sLOAmE?b zsYnkTy^!?pCAntleM}N@u=VxOT%*GJiRtsQ`?CbStLuDQ>Vn|q7aT}Qdp`Zo;-8(4P`m+s3;d#a1DWzyY7O?Gj|Mh4GgaWqfzOo< z(1OYLR0SX`_;Z|BR2M8KE`bbNX|1wgEfGldK94S98$sxq{D8?eMJtM{YGQ8ch^P3b zh&Z~dNE2)4XJD3f-H!O>{r>nXqgZEEs<&tZg85W{OB{0)8|4~U>0V5f+HF*fn_s0dR|*3y&%TN!)0O7p0~J5)?gQd9J1 zwqW#70l7NHp15^RQa)0hFauI!uo{H%!C9d&^%RAJtn-%;%7UN{gC7~+TVulQg8^(# zy?H5=LE)G{o^O{5mZ69MN-u{J&<7}hVNp5NI0`~#>--8>!$+r5Arz+)5){)_Jh`2% z&R?J@Nx^!>rYeZ05p!;qj{r{uhT!>_xSFpOmyz-B8G=NeuI3#Mq3Sy+GF<%k9rH1sSwbJhuOEtt(J4 z$cVNI`5Gjv=oeeW8EF2A`4ghEWLF>Y+e)|0WI@xgej;3vSq*X?*sxht&T5_c!UWPT zQ)qL5i_46m%xPighb~Rjr14Xxwznm;_v9}hdOX)|fpJg}@@boH3wtSdU7m(}e{?6; zQXnbH&==-&c)}U~@U8lD)9zvxa{&7!uK`E&co!fsV5rz+n>-#?-_Wr>l}-k(_jMY$ zlhY>oR-gCfiWisH8q-F3;I@WuRJo+t)B@h)G3N*ojSS5S!X#(FwdS;h<6g7+C)yHE z#4?j9Th)WDt`%R{Xy1k;k3i?H=8asb+#=1b~!=m*BUE})?4hH+K zr}jBU<4AA^j3_U_lZEoT6ZJw_8O#jN4DxtfZR=0Dd~XFmDL+9^n7LvYKFPSr8W>D3 zeTuHR+VIr2$^KNI{Uw*&ioC4@G25ho89YIkd4lCw8sB_Zsga0w1dBCu(Q$J@Fzv#o z!0%t&V+E+M-KC4-g#6S$9Vr$~3cyb*m7dRiD3CF8`=!vKl|4_FeeW%Tf6*S=x!<>rEhUnZ!;@;k`tH&h~T z;bNeWn4>ILT&UG-v$L?7^4HP89CMK+0gqTC_rb>Gm_q_QMGXgh5=p( z8I7ZwQPC|SXyBmqtd49#g#nUaXDF(yrN!@}6+uR0IR85SFY;xNB-WOX?Jn=&kz*LK zn84X$@DR%UoEd+MkBUtKYgKNJ@msG`h{dBgYMn2-+!M5eERnJAmQn8`35xz56_hWl z|AbaFJ+qYAf>7AdMOYSW$^4B|Af<}DgqDUnZLKP|e3YxoR7h$82^0T?uQ`9LP`%1$ zKd#iC$+#5i`{bvv0Hs|}y%1W(Cy4pM*?bl-K_POGU&abwU@U6%O6l4fD4Zqe+{6bS z_Mg<{(z6`YHeJB{UPpO`Qd4D6vwAdKplXtLI00=&wq z^xLD1tXE)rg#w0jzFJmX2Prp$sE!mpGFWgp z!PE=C68nc@eG>ELv*+E8-iR!A*K122A}BxjZFXA5t9VEG+M_ZlAv)8h_1Tll?j>#$ z%BQx(qzHM7C*bv}RcAZn4}AKZ2fKchpER=dAp1?ys2m0a&W6tLC^?d=uRQu^Tz$B- zR~2esobKN}K|_Wrej@2d(5$%W9;g@kT@N5ypJ$UpMQWq1ONsGonm1pFwZXo`vKR76 zWPJYvp*RkhOMKSpv8>pS3Xm)lh0+V;3TCMKz>+8V;z*~Oqf0w_I(anS4o~ag7ptAF zdb$Wozn@|2+l<$^Xpz{wwo{$cKUEHmucJfwUmH@UsKkP_R_xWS*n zV4Sb70sw5`pt+Pq;odJ$b2*JS%K`0Qzb<|-GY{vMo*>BdW5gl<2Ao!x*=ho|rM^RM zYUv4!cjS%T82;mIuGE}_$e2GvBB=qs{mUy1mB%tfihO%sDkAVavdpns51WG|rC$wR z&yac}ZP?zZn{_#L9vTqB91i+$6xN%bHhJ99cN=jwn)}QjwVe9G5JJH{HHIrd2q4Ld z8|&382Ys*K{L1C&m2rw+Dowl%m7p3Q+Mk^?x9hr(@FbAl=d=45-I;P^vkS;go-cf$ za{#2^hS<5!*BOy`N360uDq!;G%kCC87k*>Nm^AciW*Zs!T5V97$L??FO%6(yq|1xV z(@~LOF)$98FmA$eeU^V43GV%q+&=#vq3Pm;!fw@x| zm-tl@=2+=Y(J|pa#GB4eoqPV@qiJtEJw5fE>JS9MA#_^S)JlikLQ$Ll z5@7##E+zs2ir8mmUeR-Qd8AO#xD%l#jmRZJa7W)5APro<1U9ftCtMmaz7fQ)7y1tn zGfIxhQ0Jd7dH3>GxPQMGX#qRZ-YO?M+paeP&&-w>4ga5`QEwRN5)2XUzo1Q9TiZqi zceTR!pLg~BFy9)8L!6+3Z$Bp@gsl^WGPSg1`&U!^KcrQDo}_9qIEM^a&ITbXR^@5w z69)i{TRQT`7_J4$;e7=x}3 z4Tl^R(TLjf{h1WTUPas{oy&iTpSsomoIT}xiQDy1Fv0<|B#S{?O8HY8fuSZtS+Mvk z%3VaDJ#DAIs81vPl^!7c#xH%jvXu3?BBZJiT5{}W9jq-J>Wf5qeC_Z5aIK@9`->H0 z<-Q>3u^Zj9xdXM!K!fOEB50tD9M?D|w;{)f|DcC}+a56e>zd+! zNl1BL#_K_#SV`@94gKL_q zv#l$v!Z}c)y^O$C&p+>})mKJj+GV;}_W&Cs*vgo{X^H!`g;p<6XT)OeM7MrQEg?w#Rg5#5&S-xeUoE2LwmuxGT!$D!mv_8m>filhf@Sovtowd?{*+lIJ9a`p<+0sfuv zv2vN^3yo`G|8u|?S54~+3v-x)?IAyJ_;FpFuvVOtA7f`f)bA~~$ z-5Az84(=6haOsYLEo|W(qHg#de(!&49Gtsc+_HV2*2*DAnyWm=)gX33#sJ7h+=F`d z+wZMx3ubI|sh$CyvHJxcBoWSGAke8x;9q3w>h?OPhWh^>%V`#ct%olKt7h z&Sz9@XS<`%FWia3z8Vo@#X1_X8w%?FY8r1=&@Jy*Yhy_jj9v{VZ^S|nsI`1HbE>{u zr+vS!;&j&zqik-vd9@e=rZa3mD|<_!7!}f3WSe63O*yM_va^T-11?Wf5?C(va)rnc z#WYVLhIzW60M7F`$6@DWCzkBE5J^HQe))V-m{~<=#b7dVrki!%MUQI`k!;ek^L4p^ zt@$Zs>260&n8Lm(f~42s&+U42QJV@_~+K5zUi5$l7w5Z%t_+kpVbeDM5fZ5{jrbabvb{eb7fPa-!Vy+Z^pA6fP037Gb8=-X$W)V zk=)b8dEB0MH}VT8*<-1(>$_MB4uNoqY0rhtlg2!quh#z#hW|$)vBMEHntQp>em-;| zlzbZD*TZeTCGf-C=JsrT?d~JHPM=wYe3C%givp*W(Ny2S*SLZ*;u(7{-Ej!oxOP@; z6s=isaHbS$DJlh7-U7qN0OyXP9W5b40Bn9@!W>tit<(sW(kfHh%i7r2MRE|=_(r}rYw=F!NM>65MCrd}`0vC@VF=N9iYY22#987jJqhD} z{rd)!TNa;4mMvczv^L;M3b^Z^+%h#I{n}=3{N)A?OI$#)Yy8MLz4p7IY!MUeI<8c7 z54E`(Oj=_Xt~zdvO?ofRj*gR~{bPaSO*&)q8zQglxGE;M9|nevsEzTj8hEr1oZ7V= z4vA7I4V+67a(dm93B~{hPB9mxep!ZjJ351R!$lZirh(2oBImUo#rvU-tS@bVKza-LIi+H}$Ik2KGvz z(l==<94Y$O0|RPMzN*_nvvlUGIA!K0PQy$uB8QBF#t@0mHAQhP#MC9S&@zWZxvM38 zjfEhR76}LZ1X|9wUk=X*3&oZ_KZ9L$xUq-cTMa6uEBmPNr;qUbr+oiy?BdfI(v55~ zc@vWY1a&<8kBE@a!aR#!ldYb5{^zTEdh@IM_MXaY_W4%FT&Y(AMPFvKjXgoXj_Ygt zD{ZT+&r)VRcGkEiTVKHLEn^#o*{>^8oj-`JHCK+?9pGC{dy3fRT3sKdSyiiYr$;%8 zS#{fvemSzy)9u)4oGr708e5XXur`JnPk7A8WAVn%sX6tJ5d(s*jccG7y!UIQZ{$YP z$BM)*PhN)$IZ0S}|<<&1o{uY_7WY;%^{Glb^Gn>rP0?GKDU^MY6HCC{#%3iPWM zt%Of#0-jg08+x{n&ALh0k1WyiH%9rrVasqUC7WJW^hwlGmX~L{Ncmb~@{4S`>V?hM zn&wAq*e74;@|cyd#&>neYLCHljN{cb0z*#|XrZ{M*Ga(jc?)mj3%r!$e)W+fY3LJF zuc>xOtje|YN_1Ib>h7(!yumxvZ+g`YwzVCz4hVF-VWU+XLUBJ5FS>~dKwvoSc1N=i zGuu|7lGNV_J8s$IU#>nJ4i7PrPErXgKq&2I|Dv@P5hg&3>2l5HzYbtw%VAPZLqrQ% zjZ1u6yO;U4{91&`4A!In#yh^58eKAfQ+VM$prHt!w zzOZ%NZupwKch)Y`JetDc)l!{TENN|loiL0cR(-*2M9hCBUH?98LA5!xVcWdXA3AT` z_+?O!3kFutfrlK6dOGCk>Y917SA8#oA~dSKi;GNPtI;Yjo7KhcucaRQ=kGGi-&G)% z4=b*g=0O9rp|lGmj*YssnhT5Z{j)jyO)tOIzjk-Ex7yMWu6L;EC+Ps!T(mf;S+6N^ zhZAqb?=G?}+3t>ebX9fO=}o&CuGG(-d^k&7X+GCJjK0CAnbXp7#28;4F_!Xl{8n9A zKR734A=2U2Tn#f{#$=2cLb$<>1OMC?AY{bufAzDbwjF;#J<_gw(8LL+L4udQdU;n0Gd<3%vjKxvk+mBU)7ZI%J@7GJ&)zzW)W7!9p z_CmGeh;C3HrpYkCEL4x4^Y$mhd~%$SPBr_gnXNeDk#@Yi_m731J;|XJM!{}rYc*F= z)Dpag72LY@+7|Ya*H8xpcy9aLt~RR;72u*VjcYjFA~m0VQ|0BASZ!eV(H3KLbsB&5 z^V&L&zsrjG{aUQ&V(T~_EB8-AG9m`*)Jm}MH-tSyx(qv_jAm?XY@=~!B;&7Fy;&1qb|8m|sG*~9rqBtbTYOp6Uwr;XA;id{#kyeSLAJBIg&D7v z#(_GaDX_};mxb-z)d%~JT%sIHOZUQ>boMO=J!p8d(<_W-mm*Fm?A7PBYAlwhvr;Dm%=DNbw0ZXTi zofmheM#8_;8tvITUy4eY*mN{*L;1k3`4@}n`vry$&%YkjGx1{UYT!bu*~hUWHY8W7 z!A?^W0JA+2L;I@56aA+k_rd#6;9A29k;nW)#*)1%tkE!I)i&jj9UWtr47$PxS+7Dh z->Q?2J}*NEO47Lu%n`coOvyhF7qbX?3PNnQ0XuG9TSbT>fC$s_Gn}EAp?|#fr4LUx zKc!6_Hx)V%&+DPwAGrRyiD@Me$-^5h_55vZBY>b+dhZ=|r>*qI^l+*?+VZ%FV0Z<1 z;$P~AKJShbbl3lyw#wGk4gYh)9XPp3J#v3H9FnaRD+Cp`&9@Xb<7{kYDff2&__KOJ zVz8>bdQI>5p};piElcmjx>aKw{Gs$&DZ}QPIV&htyB2po-{DET;rqFCsIL#n>|9RW zr|A)^ms%idb3L73rg%ar@=kX0V=UiPUoDh&s?RQV4Ey-DRehzbWr5qt zt=QTAHlQN693U|yFTm3N%|{(I_TzCIO}N?ni+W{&%`e?w;Faw=uvae*xV0p3l2G-a zd{z@|&kk)ih?@@80F*dqt5@0TAr^BK(M>jSc-#3*Z5`(8x<42i9-j@;HzTa;-Cs2F zp8NTgnA!dn`F_uFXdUXj8*_}fhs#a=HU7)&4!6QTRP$=D!gv_5)n{gN-%1aCuKe7y z2CXtN|0X_*KVPbI$c{!$YM5eCC&d0s9br48oKAhG!>EOe!OBTxU>U9b+KB^w`$c)K z`CoC%|HIyUel-!cQNJoEQUnD>q>40=4uW(91XP-$)X)ha5PI*uH|f170@6tWK?p@k z=m8N43BC8wdp*N*-giB3`3ufk$4@#Rm|@15`@Z(Iul-Z3;HHV8Nu-GZ0Lx1O0(AgC zWacFgds9=>A;93o0qJE-NC4^BzLy8kb6c%I`giD-p_1|s#V_4MQ4(Vnc7wjdGG{{c z5ie_lav=Pbpi#Sf_cTS!6nUakNI%4F;ImgFCe{p?RoGaHO9z{L9mIL9n%c#^U)?FF zexYS{Pm{{Fi&JT=z~;)talJM*cM&sGHwD~FIjy|0QuZtzi7rI0!*8IkqOj)H`)yT& z&+KiEf75;N+D9|Cbm)ggAIRi0Z>I}5W^CBPz;|-?3aL6hM4pMPld3*-T;JS;R&ew~ z>oy&JTpXQb;r;ohOz4oHa%jU8`#)jO*3xaBMP_AX->YxQ+EyJp1jtPwn!d&#pkgvV z-%rXr2Y1s%`?>=X7S24)zyeS_f%H;jY+KtK(t%;`t)^F4zkx>2y^Za5iaKlU)2Nyo z&XWzU*9;!XiL4FjMb&;&SJw+%N>mCOCU?A_}3xH47wNFAb( z8hM$c)X)%S?TJQ@AeM8{m^z##ZZxer&2WvxZ8f>4w!p|(pfXZdvzkZ3Yjiv@bv&5i z9sfpuSPrnP^CD^v{A|iIDCslTk-2q`^|oM{IyvYsSZ46aYNY#hMQ(ohU_Pu=r=MD7 z;syBdWGgYt*8FVjD~?EFue!p>PFvDD*md7EZ1SC93;vsywx(s8v~OtbK@I4Wt(k+N zpmX$|(cO>qpgjODd=J4c-EkfMBw{&04{GwNodmqbhd|;z7uEx~i|*B8(P)6P00y|s z)A=)>1+mvyTOMn{XFf>qkks~Xg5ZjiE&r?WUdFWo1jZ|^39N~Z&tMz8{qLV1-VI6U z4L>VUDqk*b(M3<()`A;@%EoJ28yJ5%|MY!v=hOH@!M3pmj{Y_FAC(M(oxCkwlx2(? zGO0%?5Hu`sX4Kebpb|bX@U7v^C+Au`w2K-f#JE)_Y~=H;uSgA$pJ@#KctVADw41R` zX$NdxV-~Me>*Sa4mQ@*7B*=5zdU-*e5O;&mJfaF(lzHcDeOOyp zSv^bjr!5&W^|NjYO4y=P%^jVB*ewr5Uis7x;q~GLrURh zC)xet%?uHFgM$Dfk;owHDF}A^0XEZ`j;guKcwQp=+j*1KFuOOvb8S1|Upw|0tFdwe znnDzgI!^X6ssm^99y;}5aFH3Myc&-DDQrXYFckcpLP|#%m zmfDD;A&Q=3x%bf|vnb*lwDdJsKir7Lw`it++SYSSfVS-=Ed%QbV`#Ib+GsCN-^Mu)AdT7(< za@Dc-Av4;7Z5ZuQ3T`%>C1%s)ECG}@X+zf_66R&Ij=w7t+*2q*ditHQ^Mcg5*i>NZ ztbnHBMxsJGVFaW5gd^hW@{H*0K9cfmW6=N7*}>2bSo~-0-N{fb+G883SlpPr2MqD2u<#bl6?lnTAw_d zNcpoCV()!`LJGtghkHT+GE$T^aV;~~5h{pR`=QBb;^9;+0LbgS zxAUegwXU*e1aA}E4ue+>Yt>c}BhxlSe2I|0xC_kqkR?)mS^%5%Sn`<2+oGLvU3FiV z0R*z2I#UKdN7bbEjXR3hMPL)aa<02(!-1nwd=cu~*B}`zCn1P}ZhyCrkHYPF^T5g8 za=6Xcml5S~Y$<&>&)Wb_QrZ)rJl{hoz^tA`0Bo@kn@XdWDc<^pLq>@9 zuaD-IFdthIQ`1DwtIf%3?ERDL;g*K_tDFJEcOm z6T$w(G_9ywm^dS1ER(x);@3AcyUI^Q$#4zLrx;#BgxjHQ&1N&=>kJVHUTaya`ZLFh zYRw{a2D|BjtXTD6KNjwx0X-^1jFsNW8mdkL3jS(D?#T7ic|Z(&;CeA`m38J7Wpex* zQHLWU_H*>(zMbT5<1p{wdr^};x6pe`zdCXauO@&Gts-mStzHzi@W)LU7=pSP(TcL} zEGjArB!dy6bA1nSttAn%;VcQihqeF~^{me=U9qFmvPzO=0@*@sL(jqs0DDEM$U5+Q zv}x1z@S4L*V?*=vx<_Z=F&m2TIdRGoG=KkVi*EY3b4IdhE{dz|qGwb72~hnfp>)AbtL$SIxkcz5~>L8HRIfg_C%h# z^QxTne!aAe+6w+MTahep<16Y6bwg`t^T4jh3Ron~@&}H{x#xy{R2Snrt+|mhukt1q zJLHC*Wo>PH-&Gc9>m9pR^_JjN%fzW^IpI;aLcfB{TQChb3-|k?t-3syUue5ARHv9oYhR>0fXNRq^&#|4(b1sYuv>Lb zk)7F<&r;^skJN~a8cl5K!lLsb0`MeT3v1RM%Jpd=eRd97@1qAD#U{q$Qp&U9ESM5V zb;$NZ32|J8BnWypdJ&MbvvYcP7h^ll17ABDW*|upApWuh%oOi3qM+e9tCD9M@Ya(R z1jFGo*;?+64mXzV6l2|uUL4$#D4ZqkO^{|iliG*gRylS00{uKQ=qKF|kyHsbew)sD zq(@CBOIg7N4FF6p#L20Gl=s(f02aa*;_Q%__~@}jI^>tA!bz4T4#1~}V>2cBj%Iaw zzgq8n(fvDW6N#XXhL4yVO@AFS5H?BF1cbMp0~_vU69b*W>lx#8i_Pp%cfdt(w=w0aRO@T$oeF^jvz^C`S@EM|@C%gueGCYUgTy+`L| zTbz?s-t5jU(xngdF~;PaI`e?jORu*?va zP`-}77oGQYu$l?yN!Y?6k+{u(V0L?P_*{hX@)Jb$Jcd60UblPp-cG!~BzGzpx_BLr zA7sI~ML;2G{Mf)H!55ffq*$)6h*XXCjcK9se&YQYG>l*Uj9_;abc3Lq@3Ycz!0o61 zC?9@q@bFOHvE_vjKqBnNY~WQF76v;p`au2aHl=_ldVX)?gPa3*N4Yq6b$L}T z4fU5qW(2ZInD7tG0p2p&8AL;Yu&9!D6VTB}(rTg;-o zAuZ%iAq$0P7L7N<-Rh=1s-&7`J-xx`PlbMj%$;@t+`8TlT9gsJB+9>a+Gotn=KwGm z^>uZHPpR@T=YQttAWjG~eJy?I;ZLoRol4^&bA}t-0DubqcO6hS78wa)ey78E#>uzbsHH5+8MSFvG^rvM}?6h=pAgjz+i8@_!UixcL zu*e-Q7~OkQA`-|HJ(az~up#EYv_r=+1pw^jZoDAna=c;Do)e694rlW7aJWy&9X*_& zQq3LJvBYvrO?Usy0Wf&9;v$;DeWMt9ZmGo;(q|(9!SdiMp=+Gp4o33N}%Gjm~={k>;fDdoa@4+0o3> z$NkRtZXC+8$1`4X_w9DZCO{@;_Ei6eVJ+kFdoMT*%$9)@zSw}ugp)s(Ta{N1lq04n z@wNnhXk#0g{5#iLO%odoCd1WUSBGo2uu5i?!lfLl)4uNqf?F+F_!qnJJyGU2uja;P zUW+wA^T;{VtqxGWbqrkLwMXUm-uZUZWI=2aHQnC(`s=H;RFs^^3p78)jD#RxH`mRT`@Xg@tbE5n;z)S`=AF;>?f0-y|!d! zhWhzkWwb{!)82dhkvD5(Su=4{HG$M6%T{N?KH=q{2uJIAL% z)eHAip}wrt)Jx6Oal26fkqgbvNp1HYQ1QHg9sD^5i7hfX+5Hlr5llgJ*UKm$=E~^* zRnR4G_EXx@Td%G~KrKrSI>vz!Rt}sq4+vMZSr{B-c9eY?=P+fqe)$M?@zBCb-i|5l z)w|FE{&GQzgKk&F&qVS{vtP8W?6z9|3Qiobo;SJf(VuM_a$rvfVh_`bt7i@TwBI!=k2!V;c0iJK*#Rg0v@-E;s(D` z-(ZQ&S=_R3)E-jo;76<~k8^|WuJR8vaC#;rnFSTn8R ztttI5uC6DwP8z&!lMBy?l^Fkb8VdZkT>q+oc-8Fr_y_ul#j*(A94#ya(H#%QOd;JO zK7ESV=?EFKxE8&`U+-iYHV%(@OH?!$P0^OF2d_D=|2^B-sZ}5U7uF*Jx5{J?-@1YH zM#*DvWjA=4qs(o-n-#)^Pg>pjQJ95vjyxYh!UD$*q8R8r`>TvlD)#|vZd+=x;WE!j5bOg+xJ;I!vchT1o4V*Dz3)Xsrjdrx z=&^B1YzAE((}`5a&#_D{ZI|(KoGWI68+iBQDx0Z6Q-?n*w!B&`UTzo<(*gYI15&^i zqS^h7u2$Ic72YCgZE39cu&ezDc#%Ddz76b&J`^J$kt63ms}f%<`gfJ;hPDex7VkA+f#jRqNqgK&_d_%#T2~rWou*`Kp;qo^&MZJ*okg`_(^4hcFUa1R>8JZ(HSV5uq=zAn-%8p6fmJQ(4gd0`Z2(Fj3 zzj8qQnhp6`CXbmZobF-Jp*maY&qs=(v^-SeqUYD2-~W)<_jMwVP_0 z#aAKw$Gm*MyLia{%gBY^2r3L9(-y?>=T+S2qELJ$Mxs@BHRrIicPhv>V zdu(G+{h}+ihMTU&%W0>R%|xOfDDd0ubta*_-sl!S*>-*w#!)KX_at75M($4h1*H-Wh?d2(5kXIP7TN7xX^S zT@ll$ZtWpoAeCu?JkC90$=ZMIRCG)!$DZfGWH=qctYHov(^F=hOI?9b==ycseQIN% zzMk6RsBfoFnVqUgt$VvW?#X>A8!b4&$2MwSNOkFprci~|l{&srB06}5Wh{zad%Pyh z7GgFUjd0vE?Jw1-u$3|~${PArP_e2HE|Z|vRcH0kirDGg594&3tF*rd0$tAb_~Yhc z`ND9bF1d(Yx2%8TkoYPP*tUtmBFCZ+q>Xb+LLfK~sB8hxOX%}VU>-iKB7>eV8XsXB zu1-15lT{HpcpsGXM)n$Q6)d%aV849plW?wz(55`lzs7$7;4*eB1nh^B$%wA#5di0! z4;76A3P#%im!I?^D!lh-V%RtT_>B_DD42sfD1ZTi-Sa;tu=#a%hwCx+8!I;PBMAP2 z8iJl7ZN-4YRX&P>;8k6eba`;>L|RsYg4Ru#83_bkS@{c(@J@oLe$>Ev{(##DyB^w- zA=s;*Qh}TeM)wF1OA|{{wpzoLh)SEtiVcsy4fA+wF#)>_jaNfc@bPiTR0!@6$-xU( zpi6@wgsEDmBW3o6gw;bsWVkUtCFY@c0W*#)J(+hmVW#~We{bLb0vRvZLp4kmXvhtQ zUcqhe{^%`A-&g^gF9BPgFMvL?kw2*GxT^MstOsBh3qlg!xn%=N3>HA*s)tr^!)L>u zDgK!6d^YX* z>Y*L3>apxyVShlf?zgfT6xJ5Q%F6Yz8odao;#xSVr9v-l*dsRI!4F3)4wCv2QoS*c z=++r74$#Qh(4&FQFpeThNP#&HXks@kwH z9vI8`#V)6T!0G-Up0T|~<*9p#$~Vj-X(I2_&e{%N2rnc-%%d{^t-oijjAJY_uDF70 z${H;^Y#ZJa4pQ3k8vi%ha`4e$gmB#E)X_xY0$9PV@J$z;7MrhVZ?68;iKl+DCG+>v zsQl7^oZyF#vUs9NU;SRD<+zfe+xJ?RI$WVT#l5)DGc9RTu5k=Dt4?C#vU#NilNB*8 zFwSH}ht%7sS5+or$g7uRc_i4gOkv~MUcDuvw@flCLL2>5_g6PB9e3Emm0eoGPD+k~ z1N+>=1rPchQ4U83Co=MP*`b8_rk1mWD2tA%3ER3!IsTGhs)YGNoF$V4ATrpZq8^#_ zy?49#eFvPtj<6B$Vq2bz35lh9MeehS^TS#XM~-C#cd9Z*D-X*`8Jj8MRj9K~l}A4p z8)EfH<{0qQTWkMsM{(`UT+tv0MVr-zN!vkCKitrG48Ijg8)eEJp#K}A-_$TpOIrr% zB%?o*OC}&*j{_=Oqq1wUY$WTk*{-+U9-|1-%6vWZsBbJpacil-)`xmTu_;1kwMtn+dG7#RHXT|B+MGIXdP~>GEjIPnFvvOtRdLl zmJ->N<-)WDp$!$0*DtKw6kxWH4|v|J4Ak=ZU?)^j$Ka|1Q!~fYLuI2=4W0bRiXJs~ zFc^i|k3p0??G^@_r;f>?Ftc&Ri_DK8=V-|%^{;33uv6!v*lD4n!DyDI?mGL$y%6c7Z%dCMEZdhoJM63;w_K_`?iR`1FvnqW$5xqkIP*;CC1k~_0K*+el zUT3Jq^*rq8MX=DfOVP&|YlS+Y_3Pg75%y%b7sw*pS>#0(OL_9mEU2bV{A@&zN3=#> z3i!O74^ImTes#VvjzO;M7(cgbIF`&h-lQ1&$LGfZK4AWmxuF1RyIujUVScfyXL2Aav63o5&58!fNl^M|{2Kf^`Y~tQAuoCZj zp7iQJhq;bHBbu*5Riw%hKE?-36|ZCw0qJP#i4nl61@?`!8@FHTAy|g7Eg5k6+c|QX zb|Q2lSyrQ-nB*nuYrj}<9&m^fhS@A-y4O7fBi)O3cTT>6n2Z7SotgVF)^iQf>JVaX zTed-TbTxL(bB~>@aJ!Umf!Epk|L|Sb%&YTwW?~~TI(|ZNj={Kx0AokQ>XKBp!{+E$x&1FDq0wvlgb6A;uwCPGJ!vZ<_R$0lJze8O_NZ*`n)wM-lO z?4V|5I##=(V1JZsr2H-hWY5q|)3-wyzx#^(9gHZ!gqmYTO#=Ur-XHkx17JnAJ&HJ0 z`g}0aZj3y++Q;m2(U0~>JYr^nRhehpfO4iUXke&DxG(3p^8iyf$5y8MD|n=T8sjBC z4tNXX$}&Y!Ub#l#9aT_J49X!QV?>R=EYBEIKg2y{i{VF`3b_faTfMR|Dzs*huR$E% z_IBCKZm5w+x%&}fs$~nJU#hM0wbiLvy;;jj z(pJ^&s4jg1zWW2U*@0nwn=&Z?rPGz{IoJ`K^L7EEXMd4Li$G0q3P}Ol)Su_-7DT5N zgw`ZFfYEdm2H>Sj1T#^OC!ayNmcnJuO>mhH<|^na+)tFX>h^M5r()`A_0ZWB71nDm z>!8|+IXd{(n-{SA5cE5X9J*6m^l6WUklU+u6h^;fjZVI%7G>KGw2UO`3<3SGq~hJ* zyfvLz*MnLe06PZA+UyuKG}lAvZZeywn__#MNU@c>4PMt=8MH;}rylpnRI<&EMG3fD zcjGRWg+{UXzRkMI?#+MPosI5`EN0Lc{1o9MkfAh+6Vq0 zwrb}yhly+RhS9~EHeO=-B(7%f>+h(k z-m(-B(d~I+4j7B>-dVYB134JM?qAGO_}^_UA!72`jv#xNU1qnjOV`C&_O@Qh1@(pV z?SYPpdY#c3-+JSGShsBCc9pxPf2!;X=u+cuVl4Ea7$rxIJ3g%qeXbdo$Cf7U8}@gW zX!S?;O!9CoY#|cV(rs$X)o(fyJb806OO79M7o>YpjSE9rXbN8>^fxx%%~Va3a+^tg z^1kjQ9U?0Z&1Pf~Y3oHNJ`j@Ir$&+f>fI_$;uyu|dJBiAB!666(-CW4)Eh1u!Ezai z;b^n4YVIC|J;{IEYbNti_TiL5-^1T)bBSRv4s&dK`4Ussd^J;cePdg7r8=%y!Ebz1 z4D_jf!6^*!xXwk$YMRfM2YD-$#pm+#XAO=%VPJvXQWBzX&ZAG0Bb)E7H)u&`<$L&! zw`*i@8sg4v)<{M@CCUqWM&83Q%7Y*s*8-W@%KxJ2Tsp0c#bjwCj(pN?*?zlf^cn2O z$LRNc-r&BFV{K1O6=fs#^F5vo$9KtGIyyWwHG@9iT`7ns7h%Vlh*?}+9MvgAQ{#X{ zEhXe^7#(E2qK^EKnN$F}cRiFPv6ODM0krl=M&~5`bOJnAzJ=dWVkZ>^dW)Uax7kD( z4q44-^fx1U&H#;AM)WyUM(kBgG+ONwY(ymmkyc(+Vg*G-FoH=t&vP zZ8DAT5iwdH@JakBr3EsQUU<$iE7w>h@^ZN*^)E4DwqhW;R#34sJ<~RQcxqa|mJHzg zvKO%e!854PrR)8rbp53^JkSkZxXA79)XYnUD9Xc*c?J`SzSLC1Xb$Y9h+Pu9=6GA^ z1+FsvnND5hD|!j%R9IKk-_}i*gOMc2`$>!zX!47umYJ~T0pKqsL8euk^@NP!Optv& zuFk|jPYTKgw^MPwRwRizvB?+I_R+GR*-eE*tXwp)s0JPMs zViG?00I;17)hG%w}V;@P>OeV3R1&R80p{ zP3_vP`>uMfdo5fVJG;s3R0BsL2WQRCu!Ydm)9SbIv!OGdDOkzB_z#!=RQa>6)~-d) z29(8?StPM@zg}u)g;zIVe1rUzgJ*bWYL46<7t$IwMr@G7wf^(yJXzsgOe|X8rZF4Q zS+1^~wsSwM$1SpWByg1m<5VJB8B!qNd&v#`l zR*O2T?J>48R>X~rH4>lcJ{x*`>&vLC6cZ&8iYnMFDCFno?Nhuo@YI}Ux!R2+)We+O2alrZwM`}qz%Em^=hS&4pSCVHkf0IHY*33PFTookD=oo2Zz>qc zu|#U@4#O45i?QFt*5ON(Nd1L;l`9{YTUKYx@`EA7BlQfgpjUtaeJsuF_eZhRl6`Qm zLPp$M^;q-O+Kf(XX^;UhL9*n7;Fz`C&-JH&z$N#`#ZjH&hqvv+_np*8_XUjsm+7jl zv4?&zSqq$S&N^Bgp2Frlfbj|Q*gxB-nw?#aihXqaE6PBhS&<>z2fX1qoHg|@JB+Xs zCc1mwG(V+QlMuvj`w!lF^L5R2)Zp;|igAzO%?&z=to>`PKd@3ie&(-x^Ip!ZM0Tnu z{}tfE3}w)$R;G|S->yayOXS=*`n3V;3u+H^mIfMN0(vUs#U(S^vNF{BliJD)IhP8kP0 zzRcjQRnTG3$QHC}gd02HmBtIL>|(qt3!@&i+-db-rOr-;o`i=P7@BGdr=|<^n0`Xk zb@ZO0bwY5X4AOP0$V}mZm+Lriq-Oj+-vD@-@}rXj5caI1bR~{!4ymnkA8)9Y60x+K z%)g;apV2Kk-Sj3xBVbQ}af?_M2G4W@j0}o^YumDKjIlb_K)HRB^}5}nBZQ*0Db|%o zC*Qvt@ymK$*Jjce55!rxb3OPTb2qve=qAQ=T46pISi-X`3FV2AyFIRhV{`ZTLT=zv zbKQ{sBL#@A{TxW1E;76v`l`{Tm}lxZ2=zo>F5-JYYy|!o@cKxzjxaxdez z+2^X}N&EiBbf|TVD#7vrXWS^zD~uu3?BJqVFp49)YgE1#Izr<_i~%9-Ys+~O-8A?P1N7ONo?8*w4sz(1nD>m_>G2; zt*Lb~V7dk)vS`5*pt~ddDY)XDi0+pykbP66oz1###SL8na$9r>=EJ11P*%}x5Y?IE zP#D``f7oNW0EoAGF|dlv8rw8mtOu7@)J@uXt=fTVEJ;nE4#^Spa*SYqKqt zXJVXK_{d}?1JrZe?oN|PShmY>hiChh`C|APR4;iQzD6mU=0r)>cQP}c<-mRP{x--N zwkAZPrb)K^rP@~9A>Y*H(nmH4FIX~E>O=4&mTo^9x^f5JK&e_mmafB3Wo?)Ge_sh1$n8t`L}tDbbimxjXM%YBo- z8Ljew@>gn@6Q6^?sb_B5d)JYXS|FNCPQRtPLb}mqNL~i*rhj@yw(JQB zIS@^BTUpyg##XE7YT7ejLz#!}3Vp`|uyBQf9nX_WP zy}l=359QQd=sD4kcNWY2ZM2~&J#R?3?!>g2);nd0fZ(2jlJJg09AKP%j)Y>*sf0{B2x zO=Xq;(#s%IfazA~CYn?WXgG+J_8!GW1@!ZN&6fR2(*w5DvJVw(dngfKr_>(ov3+NKl+n8a+4e67YXet5jdaF*n;~ zt9qVmSI{s$yexh9uWKF~g6)vIYcNknCVLCPKDulO{FJWKI8Gcyb))mkmAkLY$?oFp z1Qs zmhcLkKq+FWCdtUAHc6aE1VeonRf?ufqCU~E_00i6&}&{ou+Fd?f%%K+gBU=2ste{3 zanA+rcox;$UO-QHtD&l{8SQ{jyv!Xn09Z^Qxw=OXNSrVTiow6sSa`gJAR zqCJ#E-Bfz>9Ob;#3nuHncWvsPXp}??ZUX1fNl~rLdueQgIC9akQAa}1w|4v4j>aY2 zM92IbHtXBRMr324WH9L!{)J=Noo7#zAyPmjgDh4$MDwd(IaAuI7mf95whtqJ)&T#W zt+HUCW4L1mZ*;tU?UUOqLgTK!eMv*?p6@wC?re$CnrNUJ{8rm8O~rh(dGES)K?mArl?lCNw==E^a!V)IX^^F#3sM>>ujVeCX~%JPxn`-GaloZ4gYt!z7-gZOf|HjnB|buFe=h&=8LlIG~- zzy_QfcbRO>{sb1QuaAm+&1@zrKN(3~&zbWLka9@%}e^;Xz3b!<_iuWJ#32vJ9=U*7|!aVicB zc-p$!&|do^BWuu}z=a(vH~~MLx-CZ*FrSbI*=Ik67+6~5yaRldk~A-^ZA`T()89Lk zv|AEp>?Xy1KKvq$V2@@xiKJ{Yfo>9F=PzHO;B9PbidK+;vTJ5EP8mk`z+2|O7A^6n<0|X zf#rV`Ks+DquWY~PKnr8rU7}Ewh_@KaFB|%$J+Qz;59-HvzztgN-?S`vQf{E4y|z+s zr6jQMLLM{lPvQAQ1Y<>UKVG{2PIFP@LcdOUq2FJh&Af|WE+$Z@pwaJ-B_`BntM#xZ zXAK^&=kA>vx+rWI5C0(GsGSL5rHj{E`cIk$FzrdhxuM}SAht{>Q~W=YG?+u4^Yy-X zEi$SCm3!F4L_JHJ(N=2O-ZPfjE~O;5B$>DB^fz|F5XF2#9OYQ`<+-u6ths#9H@M)` z-ugWbl}0kb8gk@a=q!`&&&ouXoO9Ual9NkRkVSd>koBNTf$;FfUR2z`Y;KCwLf^?y zZ#|@E;k$OSgjq>53R^6bWqR?oU;KZL`F6a8sJbPxM*q(om5AMf(to$_7s!AAt;GJ` zCEk=@@2H1bE9K~&0(-(kcDf7na)G9O{nu`RK11FvinPxrj=0S<|Gl`;``_O%7JR8$ z`0^!@)e5i1u_0|f16 z^S?Yc1~YrJC?}>{C7sObS2e=ZmbAj25n^Mu6HA;Ns9*9~-eeL>UHp!7ilT-c7MNt7 zghJw)o|X-fnljYd6N_vz74u%jXlK?tZ`GUk7VKp&|2x&Ins(NyJoGRZvp#SG-}vvJ zVNzn4kk$p;BTc00$lHdu>WTd$aXrMEp^{vK?FSxF(Ndyp6*YgnN&O|WRM3NIZ#LAw zJvvBz{u#-7NJ}3n$ex|%yZC9!FR(AABIA?iqvXall2Y_coSq$2(w1`*oZ@X9tgW4v zp*>4|EZkI7VHtDHi*mlfsU?YE!zXU_$?Y2NLGM8}7kkk8UQ&~h{Y!!Afh0P{kG*gS{832U z@OsEWQBm>W=;*?rBJ1W$R=$ZJsmfJD8+DB(7}XMqZ{||FV-Zd3Iiq4q8sjhHX1?}i zrKlz;4xcghc-jqH%h`S)m8`B@|RkcadUTpiOu{Cb|`_K4Fg>C3aDDUJ2ie>s2t z+IiZ_%B71hySge{7c=Sxuh}sUSxJ>WQhsAS`OvsCszFDna$Rd%{LTEyIYZu3)rh8I z5G0tm#`XE1A%!6BfYZ5ms;zTW`8Sh|a$=v{?0uGfcSnri^LzfE+fgIdO}lsEcHZ#5 zO8wDiCGZ7-v3-rI3H^b&@467E2O7%A79jodQU>2xk5RoroA&s_my>rLnNQ+X1>?uM(0Df5%{ovIjK0DF?tSmn*?{;)JOf;mul9LsI{JPXGBEEeSE~ z|2XvJIcxW=|NU70x35o0|Mx=yVRHZDTK;?d|NmkCy%#tBKX%V3|MSlJakI-%r)(vh z#oU?G6>qs9`q_D~#AbhkWPbdLioSwuPCC3$&onZfQhJp6197vx{XX$y%Ukz2eow1? z!0RNjkUuYEMa|OZSyzh=&!g#nV$T}$o?_kv!~DFO&kC$Z$9JM*ZOEVBg<4da z$(QS*b&_nL4R62N@)J$(QRDH}n!kM??9#1deHd$g_zM)uqg8MAdE$_6RX@eZ!7X~J z>0|>;sfD@x0X0is{Swzw^|uQda!`C(gnzVmzUnghuwH#WPKgbX)Sl_OtCg$KMqS*D zUv*KmsWpmqh@mxM`WxG!w7+NIE^_=4R@pU&?2ta{xOt#7SNbDTsnjn{-xWj|-%)Em zJb#*mY5~>S-VzFx5&z!GG+jjCom=kuDFC+Kup=pqu2Vnh^)nce~eRH)EXYBS{2) zw883xR1~B6CI}+GN9$m89>gWF^gfIpS?tvHb6YDl{k4Y76aJJ0t1BmJP*2YHbhq2} z(~TsoYO%J(A+_<|QQ9;0xoVGJry|tG>Pq6A=#k`!Et;31f`~&6giy2Z@M;XT*{)xT zpP{v5Ot0@F;Wba*lYEQ*?R{%!EumPD*i^15=yQdh^b_e9W!%#od;wO2M=3NbpM0)1 zuYV&6{{^sBM=8rE<|mpnI9KY~4+OVqV-KvKyM@dPx4!Kk9-6hlGf4i1mISqS^LIV@ z2`(4=r(PZzwm?yptcc$#@VQc|HC4T=y!r42?E5}s@Lz!Y9MLaS?4no`Vc-sY|J=ABBPgi6{rs8uXJcGcNsP?Z@R;TNDN z``72a;n~ws0v5CouzCJ9?M&>z2jiR*J!kYcbgLyNdLO)~G3boIr);GU{v#Bu;vG=< zHkealS@OM+6YP-d!SXua&~(bVcG&)xrC*oP;;g_SF+Jm}8*kmgCdwb5B*!q?JBT|T@F>-qb{z~Rt?J4zQ36;Df6PYOq8GF>=i$O zsQ!C3H{JnzwoI<3RIJWD^_HlT4;dOx!yG|*V`FscJ7=qBCj;K*f35!}y&^54-$*GD z+^hLK=eO)PwqRxyOIX_DY8|cJ_@3V|ZtALXF3;AxXw+Ezroz!an!th%@6C zgCIXw{#W;%iQOD(HM;+v`Y8i3?91!WBBdW1Y@axvEUGtTWD)0$&$z}g;ikjN*4c4$=HhXo z3~1+`&3=1Y{@H4`cu zc1OQ^WJmfAmp4#~WEzHa|1amvANcxIf+{6_d`6o^_S-Gb$5Wrv?h^hm=J&Vy`#nfScY6CbZ@7eD!keR7gL?xd+V#_ zH+wae_<^lCJh5DRPJ`9<(MMv;QOetxNgo+`#_wBw>Y$|#IfcBkw$v=2dyb0ADSIA| zFBGi^3~nX82)5KKs@|A9k5=*O{b5}#|H}HduEZ2Y?yem&_^qog)>2H zBsK2O{f-0X&W^g77-@lAauQB{?>M>Ww0c6^ac+*CF3PM{?8V}XG~H2>ciw7+mF!8M z_N2^8Q@}!1t%K)Z);3FWIlTR<-;ub#V<0Vjqfa}=7kk*VH(V(LD(XqqO>X2RI#NzB z?1@*0-b~6$65LEro6p>5ud;EfSc#;|$QIEqOAC8NWmKf#^scJ;VdOC_eT<`*g9aFZu6}ZbwutS*RNrFaz00qG7!ZBRhQKrU;?nK{qIJ^O09E z8zgLmcI~63$G0#uB^Pd(*YZ-e|A=lo8+Ss(%C zpZLo^JpK7ra?NfvlkyHD<fZS_9WOD4ICR8mm2|{!xNNd2vf1!xYi6*y zxO<)=wFF|3fahD>;$7?&EkX9Dv}xdq#y0u~2ccS3D&c*XH2!~;3pYpp{$b|)_pFvL z8F8U9=G=1D9=2YtzxUn>^WJJD;GwlL`>@?*WKA9Y=$F(Y^NYfl9C4Z$*Vv{xA?Ygm zao)Z?Wk2l~j@}1#%@7du#%_1Q&s>nqf;d}N76C17R9UTXzU%s!Fj8Ven(OS;)GlLc zDqUP$j+R07m${lmlL6dW0dq|v3acGJb_*PR5!Wp>RHO2??k;&q1)UVxksb#^@R^#c3G}e{GD;^saMk*1`CA}6uAaiK!1#D72oO~6q5f|AtpIF#pt7W;gEB|Fp?Xx!>RM@-P zGEbG?Jd>Z~T>s~H!SzV`K;>wY+V_(4z<-a_?)4IJU_hpt1PEW{k(8+>ZLlMMCJgKm zg?)~4dfw>fCzivV4&Uuk8@+Jlaeh~InXvrBz+G9MC@HU(XL5HbkL~|q?>xNO{NMlI zML*SQ-=%ol9aN3bVbs<|?GZCET53k95qorLYZn!J6GTWu5}Rt9DoV_RSglR$O^Dy^ zH_rF-NBnw@)1GpU*L~l)U$5(WUeD`sb*e+%mXVrqzs8R~;#Z8to!%w_v#!0S5^mgq z4=d$A`j9BNGOGGK%g-%CNeO&Ue0O0fmcBRp!FN@oU;ifIg=>|8TI~QSV|y0n{es^P zoNIG_nA}?#w;@;WnkF=O^hA(v=)OnV%Uqi>=SGd_VKM?RnZ2jNfM!P6t*}C;r3x{R ze`YcXbsnT?rEsQ_!ap1J{2qNhJ!(5OoqCl)+uk84OQ?}U)jVTKkAgp9>5 zzG`%ZQap52E+f(8zcV;4VS@=o((F8NGfJdOoUr_Ks%!U_MUbv^iWA76_dTFw zESh1785$Aw982qc<5PsJ?VU5;J1dm3t#XU>{=Q8~ndQb@Pb$%qzo+G`@lO4gW45;r zw6ghb?dSdd3EG$EmS?xMtgUMUw5uo>SF>Pc+>G9Huc>_EJp%q7FHFt%kFL`FhUeDm z_ID`_>j4;E%Im+g`1wJy+!bZ(J|Z<5`K-zSsQ$q$tWoEAGK+$@Rr0awJC6kU)Pk;4 zta}KiRHQ$=3kAFl_8+8vZk)K}Lt(z}|T3StAJA<|8dx8p~` z{&pKfJS9uC6t}4!29Wb~u76^)jykXIi%Q#dUi@q3kPZP5#BB3zG#`=80S@% z=)flUx6`MDgCJ2CoksjXeY+z>G1=TN#HrF{%lwBN7$1-Vli4mjurAhX=K1syc(9Mx znOLR_;@vJ4`+)bF{32a*dkWpLJmipkF2p8iNXkNyf*e{s_(XK)rC2#5GXE7&H)Cl! zbZivcDeluV`=P8C_klCan(-mKXSqd-P)T2pF|-{d8VKs2-#Wkz`##&XLMUK++o~%1 z4k&%V<3zm^Zd+~eZr%t?mc&3=4-+079ySX14Q&_<1a}=ZYR9*7dZ|_(iH9z%Ve90f z-xeh;?6BiXThnzut&Mz783(Cu!Or`Vr<3_l)WV15Q~q`HLW#cX%26LjSgQe)uKgi$ z7z!wXPebZ_UCk!S4a3%xDnNk!qnKVJ%k6AlH@TYkLCCv0rC~~Rze=5PkH?caqtM&~ z0DY_zU%I`#g}!yggkB`$duQ^Gf79Z!o7#>&qT%n(z|LNHihAPW;<<7at8$CclEI(O zat9qb?Nu+9Usg2?sjgpIoc^3w`3>GXa&JoOY$4pg=A9K5R(rt0^K>{o+Zq*`cR<|h z&D)YzG%xp=?z9D|D@j?+7O@YWS$M_%b)?#}-|VeTuujIQlMGcfJO78#XTOo$t}jIL z1c$Y3oTqu6@%8O$XD@2n9MpO{M!#v{l^^udT<;%~HSBEh6XYF5A&quwbY$B^PeBHo z43_=|RutS_Zk27`x&rc0*Mc%u%vBsR6@3QBalsHLS6f*8#fyTJ3T9{p#ISDrWkwLh z2?kq{RtoJw=AIWjFb$bw)mRp=JxugdrEM> zw^E0@AMr~DDYxmJ5b^LHQZFS(w5*K?`ZSJvtW;^t*CeBOzYiICQJWzo&R9&St@`t4vv`<6$Q(aDlfF1E`s zc{M}9zqM{`q7I#u?nUh_gcQZP+pmshjoFLFTW+|+mu^t-mOg$yDKmu5o}Rz9OLN1M z=vEZ$e05!bum6!+=;5HBg}~hBdt7`? zip+J54uQ`7#cakKo`$cg6kr8m23RK;xmpAQ{cxCx_RC=N1;-bmjBq*Sf<$ZLvrQ&r zg?d~*tA^`F5!fCcF;|W%E``nkb8l%do7*4rKO=H}3YbLyBq3zczZ?uur8YIWlh+ zJH$6LqdbN_PgPuj9->S4D5_ga=8VIjiEX#W!zpr0Zn0I>cZZ#z?DX_g3yT-(+;H1O zzSw;+bUW?vXV~)G1=pjdkF2cr9)e)~O=)JPGo}sII0W^dRnzTn?a$N{RB*r%zW*c1yHF zT1SsNF?b9wUc8yq1m}$&H+g#tGz0VW^uLos3Np`f4hR@TL_sp0;*0Ecf=4KxU_HKQ znA&HkGj|UHM3{ynbi`uws&^w;|v(o39Vs2 zV5|eBOAGc^^lVNzbI-$udxy4!gnIM<;IbKs_WXVOdViNq+}SJY_R05)cK^OzVA8_} zevSIOZT19D6A&d!=_$X21-k!ashdm;0ue+IsJyKuRikLgdh=~?(RX@LPnh_>NDkw` z^D>{q-3$8bZK5`H&t`wx_tP<7!xljy-lYw-#ceCY((K^Br?y&}W`_R&c#lVJo`$4^ z2dW1~%|Pp0?*vJ|;@e{0qsv)-kc^p5Po+CI182KF*3~~+nE%W0oZJ{tud{g6^L>F$ zruTpX76bJNWz&^z?XasA*qn~96Tbrzr#Q(d-mM!Lb-EjUuRJK;Y~5;5jV$`@=i-J) z=QH1@hQhSmcPsT5J6~;eTo4?Pq*`O;sw`Z{Ur$Ofa+j^7oK6c12QS`foO>eUeJ-C{ z3zE6hm%}t2XN>Jw|8_bp3lh>J`E&cD_W9s~++e3@IZ#s-vn>*bGK(T0itLS}FE52f zvx6x3Rw+uuTz>Rsq#=NjcDP#}ZjW)L<61H~9Xd_BZL6m)OczAg}hLq0jX&1IP zE&br%ftmUtnGe}Pk0Zag(XWNgy{bD}u#@#(k&)g1rMeCoPQuM}=dy+~Z%}8oF_8ams|27Qi5N%uMY?h z73U3JM!e^#`$3I7`~d%}C`}nr-^BP`QUlIu{%AR^k8&W2%3W{0ON*h_P+Cy`SU<{T zB4Dj%@_qhyNcf8+3Pa~6IVgLZU8q;m+^#sO-okD6tF6WT|J;M>AJsW?fy0k>!tKKM zi^I|3yC1?|K0t;(uSUxsvko`IndGCMqXWZAlUV>8TXaJ!u4evftZ0qe`mY;72Wzcc z7560$i9cy3+g@vK|As(6n za>)8D-`k5GguF^+gTVQ@AFBcVVbZ&Vi(Ozt)q(OGa(sP6*l@K*FR|9O59P)6ye|n3 z=9adeMI3Y#)H7{#t2c(Kw=K{BU;Y z41_C($*jrPzWdMW$Xv(F%&WMIB-#7_TIlK;egA%rot^gQirx1|=Q^`(7Lnf7U*uO% zguu~czr(5e=KiJ6O|htF_4Qj?!!^jnc9UaN}!8&aro-l z@IS0U5a(i553ek^_Qjw+@ zcx%fx$=+P|geLpr8+>(#XD350MggeM^~tpt z-tI#adRM6krK?L#o{N{Zz3iASSQUPeJ{72rd*Z&oK|t3t@3d_eliS~SK)IUV{=Pzj zbh)j+#AyXH2q#mvv7{v6D@ER=s$6w$!hkV?kL#NH^SOpzQ`lFzMmjJiO%z0Zm~j$V z9=x25{X(5#eRlIRCWa?C0 zB(9)V<*~m`Uk_G}n4VM_x3}sbA|Yc-CT!}4aF6QF$Ry4AFpro?LUDIwd$)`4Hy`aB z)onurLKsWc^rOS(quJ~YyQ3{TkDrEgi%?*zowe^YeUKZ1Lv6jL$pc}a2;V?=mb!p2 zYqaFs4kA}d`0@eaKCdE8@wxR2s^ zQC`riBm{E7PrLU|zGvs(1R9K5Sw3=WK>pbQxP9#`epG9p*zJ{Z>@hO{Xb1@_D#JF> zSc>HH`;;Cm?NM$rsG3@|{qoZr0DaUaD~pogn)MlpcLO6WU%I@W2Rhujc&>2sUHB4ejD&A+fWCA|wB4 ze=3{TXL0jruBVry`wfe}QphcIakhZ(4axEweW<1jA5?hUkxt}PBa*PrLKWuMw^C5n4s8(Pt06)4=cYaq-F_z1+m6dX3Phw~nPS zSOG50R7#B~Vg+p`kd?%iYL7d}_#4vrZXG{*v+y;Z@V~_8f@R1M*cyuTY2G9&`6ib# zL=1yK)Ar$CUF!PXrApaqZknn7y74@(p*P<77KU;j`$_Xg)Y8bzGFw-g7`F5YD8;&H zo8L|pTL2CV&(Rb*NPfSvS6jAy+SHbY;PXhK){dAZ40PvR=m;{Q3k2G9Byu^A>WOL` zJ|)lNYP?pmr({!0CDbX}uAZHxsdueDwovCj9%kM5nrL#e(N++6u zS?LQqS{i4c_Kf_al_kG(NT8=?k7|#-LI>hqbxp6@jDP@JBlLB*d;5 zPG$`Up51AM^RaRuR$@T?C(FJtA%bPqsc>>u&&?m{ARcRJb#7yKs-M3_uCs0BA2LbC zXqX+VA_UupO|{g^hLB~ZE{R67pWtdTY7M(UY|kLvwX*VC)p+lyTIxt_uqsQeN*!b` znY8pdQp<=?;)OvnUA1v-mSAA#Ft*nhkz=7vGwzVwxBtZ8oT?_mW*Y9qP%nE}7<&7>6|80QPIo6@z8NZsN_ZQ4;Pelms2-Ei96hTiEM1e&cQwo{R` z=G3y}d|1v~`ATob_GLkpe-U77$aM^~e%5ttL)VGWj@kB9swaEM`)El#kmHHg z1^EFnzzXm=wOMo-c>Lv@1w6T4z z;h`O~FrVRvUTWv>_nRzBei>QWEX3$gGIDLXNt4d~RQ54l?VrBue0FyN*~F)mKzm)LAA#I#F7e5%%Y$J7KnUOb#dMbS4&nP9 znf&S%P@4irc-;IM=$FIZ?c0`P6*aCGBUjE>zI6^#Sw>1GUZj)p%wJn{YW=@``=>!` z{r2*Vk-FtNy1|e1G$#&i+%zbT5N2NX6ox~QD&=eXCYk_@G(!mhcN+ePmI>eMuvxn{ z{C?{#?W!^Vk2Dzy-oYOD$yRd&g_hpMG;of1hr!B{Iyv^|3LuX$R<)KsTdr>PGon!{ z+qwDloR=$DTM3E)pWe^(VE>Y>cK(sCdVoe{ldGLhuwGCU?K4yEBScT?j_=P90K_ z;f1+bW71xpmR-Vq;*ZgO<9^M&6N2vG&MJE%xG^B$-kWqbhx*L@UD(rp`3LgJ{Yw7J zBQfz-W`epJAYX}#=fAouUDibrN*_x7sXWn<_!Ja?hg*r2m|+M}it-U3W5@8NAo%0i zI6>ugkMAf0T<&&$w6ymFG%im2`~t?_-L0@tlt3$K?|0EZ&k8akT+XT;+$aYRXgWbo zz_lCB^GN@$!I(7>jI+(xZf#j-Xg(=R8u)0$Dy`@jNweF8u*`z`|A6caSrb}CS%Z@2 zR?OVV7fBbFb+bSGy++zzHrdGB18UZvi9_C54MD%SK@Ky2BF*$Io%4W8zy?@rWVp>g zo}lv=74R3u%GCQQ+Mz^b9N{iBxOF@yuoT_k zxZ9*DrRX>Ov24zv4HwO$VCeQ#%h^cGU-T?>P*x;Eo?TMFz~F;br%$G2B=PoE_?D@; zxZLB7=7sB#5B#g-(66@SOOJ{3~0 zv3(#@!eyhoF7k`JN-*~T^R|0}V49pBSp~P$b5@|&;0;KT$(|-A%}{qI9Fl}O#?$gY zbsYxWV64v}TKS}4Z15<3wfwCtiS;97By*v#(>5*imnaSLB$o;x(}Q}VZ9n5~4A4H6mES7R=lnF+*9*Ru9<=)yA~DxMv8a=jur2ph={Apy zM{nL+_PK;`x65d8%r?aL+%r&b5q7TF?L5v}NP(qc?VFZ9K;Eh7pg%kgWE$)$ zgdvkA0PI_zx(h&{ynX@-G@@@;|%!G1ba>>2{401?V#1j|Dcs!8B^a?16_-sNDiAL;S|H8$zt$OgsY4)xVS-#_AG z_kj1?$-#--a#R|mBG3?zu)~;NqJPyLlGZo}_ z+b8rgF84`v{1lrByINL!QFX;*>94s>%^xY7+NpG!j|kTl112ajzCg)V?|dZFX{<_Zfv z5(6lS<{5|A*@U(?t(!m~VGa3|ik@-H!uaXp;9?y`hP(DDKZU9JV!CtRjqL&-wmI2 z2*ieDX*E6Aa*{;!H1Fe`mBc^8acEs^J0Ec+z1fKQ>kG%*B+h(T1~`d`!0HUIw^#3o zWxGb4=?#;SQ!E$wkn4AjSn3?q){dixL6wMRw4kyr+F<>s&mRS`*Xg234%EgcO6v{y z>0*=H0QQ2pdnZi9r0KoBV?0*?I7NZKZ?rsJU&spz(%@m8`9H>4q69Al z+_5YjmQHb-MIhm$ffk=bR;m`hJdjy@Lwd#YvOo+df1M-A@>O4T&Y2-%dVp4SrMq?d zS$QmOmpc1!zYN%0KyJR0OS9qiqFjepz1NKV|c~&JSTFPrTIgo~lf6I5;aH z>U7lPmp%$Y`CS8lW)hay4ta~srO9e1r=P8*0cv7W5vqA{aZ#n`j%!;5WyobMSO3su z2P#%b^5M1{y1R|-l(nbpgk5AACCihF*k|xHRb^$mo?#mqHW7mK1N^_86J(&Xac*xm zhYE~gfLWZI0~j71yysD9re2I=Is0~Skh|-!cKl_qU?!)slbD|+%{Sv{P59`q#3`%k ztNizs5(H0|MZv1C=&~^xEhi(wYMbBPdyQF4hZ0SeWOTaR?*U4Rame`K*VE0-7C;Je z(9(oUyC%gd$orYvFGU~%wzvG=hEM%C%drEWqQ|Dp?6ZY`&w*{_5h7)KzSsoMNL;XR z;#2pBS$>w=TO-04CJR zPQ){x(o?G5C<1jUHrn9gRrB4S_PwT3u4@p92eMo+2qs0Gf*%J_teZk=%a+|jKVbog zoQ*w(l;&4;UE?_K4*f{XcGs>XhDGxxg@Xn8FQi4uf!91xmiM-Nh?equ)gzZvYG6;o zZMQ2^=63)w)FwtXfzX1Upn*se{mnvrCKGY0U=_*Km%Ut&x`%LuMo2c7N8L0mYK1rB z9*k-OP_$J*<9~|T|+M5L1}1S0}GD`wqtZh`w=H|`HDx%Oy;u3ah*P!QE0jS zE;QGCapOy~dIfw~b98uNK@OBICn+lpTtvQAmD2}Vl}v7!CWo6V!K(G6oRQ=UW&Hit;LRP*uyB;n8RH|3^x%UND>zsep=F#2USjJq6%v`%Lmb5}fnfC2Y}5yc-LPxq*O zVOsXhZNRC#Z)M3doDsR??69Pbs6-*F5;Eo6`%YP$zp0ym7GMCP-bgG5VO|cnTH|k?Kbcw`LAf_J(Sr+9B-S%Q}A{%#bQR`dn>#J*DSPi-S zXdkrLomvdP3EI)fmlYr>>5)|~!19DmSvz$C> z`e09=Eu!%C>l&b}?v)&}STLCAP`*z_o5@EIEqc|Gj}G&9Ei`M3#GazUuv5X#^KBDp z=AVPpP#X2RAxjrzOm)A2*EFKJ2|490|EHAYs(CS11>1#UfsA?Koa8`e&VBh)hu_Jw z=S2Dv_oA7$(`HLsla7HQ-j)8_QQgIUSju_@NvSqC`TAN(g>6uzeVFy7rQnCHnhbny zXvJ6vO>%3br+h(Ju=`+JQTo#XDUM-nl;%2Iib%=dymm#yiIV1m%R>m!WaCrp!fK{rH4cv=4lg)4>3mf~cfv=;>A*Q~XDi%D?+;%yd@J zVA{BB&$l|72w+Cf{JosL7>~O7n}=;V2a)uWC-9*QqJU-Wp{-U5Yxn`^Nwtc)htl6c z=4jONP+oUp@;XEaseZTcE5?JRu8wPH6~ob}C;pMG%IYa?rX3pa`igs^=Rk3;MN?V` z?sn0|+#=9PqGeOzU)3om(Rp{s9IGSk>$mMy0gD0Wt8P^d#w>SoKJl0Eny6g%uljtZ z@l{>A(#YWroUy1$8$?5}DqpQQC#(*jS^(cZW2Ku)80?N3AH3QoiEZfJvVb%fZAsEX z&D#bh9`FOhL7dR-7*YlIrECPnst$0}*|-BVFci9m_Ek^!Bf&~fZ7tGpuCzGY`wmLg zLmN|TuMd0M`ELEVd<<6rb~#~qDGmiE+jky&CF<6G@^2Lb1)GX|kelRv|JSsN;Nyaa z+-~2>EvL{l*OhYIVepmFDsUdD)uHom3n$LWcd|-n^D->ISEaNFI+h=89bp+xRW%up z^P-m0sf%igivL!57ULOV;@_l{O4PRl@83`D-d>W2T0N9B$Ja1BP3;_mFhhO!xB-`e z92)gf!zSwitNl0LC;^k-r1bOs!b1h`Na=Zs>mTLLbFaT)JNrF~;YFIblk#$8sQ>RW zf2`KXp#~5kjRPg4c`fz*1m>3Aky$u%HXN9H3b|U1pqq#OJ#Tm4_;u?k5Wk=+_@T!z za2N$GBZBFluSIyywG;S93&4IUjVm`<4CcTqx||kJ{Gw0he64 za;v@-hkA|0qvnH1dwIFGwWx0q9@rX&WT*g}4UvNmP{o4!&GdhlFWW*R#$IJK^;R#0 zmvd@5?JVDCz6EVyLKxel^4ECt{WCuQR+n=9P`R8Tx@aJE)!G?7K)gGkFFluFPc+NI zGbXBgN3L`y7PYlpGanTby==(-Y)v-U{3*=PW1uPY@)L(91IQ>kaKpX(*C3vAD`Xkn zSyq4MiD!Gq;D6dFM)B!y1Q%jO%Jh8S@!a~`+Alm>R^w^ra?xcHrwrH?3ABekh?l#8 zfN!qk?_k2I>a5}{$NNULWewbk3%0)+hnnqv!Tz*_m{&M#EK{XTlU)lH*q|pCuPJXf}nbe|Lo zAE&L0CID#!`S^%m4x|6U15L@UcV>rxVW9TJ%hAt4e)yKSQZ$yx1Q=1Z1|*;%xDO!# zAzjN*>qC#weqSr9yf}QUi9 z9XANE5(k)8MS)KIrto-8;r&>MbUg*}?B~vkNr$M6@4e*5*+G_3n)l%)s|ean&mNM= zjy4by15z2nqq46z@fqjkQlHuemf80BcpdqF@Acn|fD{Ex?cUXsi`#!D+@kCkGq;*o zf|Q2&afPs+ofNb0Mmdp1yOzg=jqfkko=k6S^jaEMK#S^T4D`63s|*2WopVPfBD>uQ z@9VfW-z<;Et%f||{NCy;F@$}4gCAeBBo+H}pKIp^gcjBm7q@J>GG~csO8d=Wct2FQo9kdt`bk(kgogHnFC@iaJm$|cetT+*ZVifXJ}$WmQNUgyE))+M{w|K8^1?Q z%a$nQWbW(NC#htYb0yp`+8-T$Q`g7}ZW!clxo8&?7^vnO`WZ<7GIaw8KOkiow8t6Q7n4}-}wlZ_a0&*b?k~e0b^>WfP3w1 zn7GoX7&$mmH~NM{fk`VzV6^ln&o$?9;)_gPH-n$436pELjLu?K$rV{QlzeaJKZ(xh zA6ayDxdkZ5BSRr76qT1(7uZf%VO&FV7(1dVD~pu^SM58~zM@-*tj=Yfr1Z8Lz&3di za45~41m3LN2)MJG$k;5all0PkJ0PlS75&=fw%k7v$Fkt&=3nI?J#RV3Y9qwI1W3>B z>NLc<;S_SWFwvd zLt1ZP$E;5Py$RZnADF89nRzq!a*l>Tu&fW}OEZAmC9$lc&SO-m9GHy662|?Q@4P(d zFGW+8Ih1pl28>GLsAlI+b8W*Qufkf=M8_bnTv~GA9f{9@5j_fZTb8+Q4;FxZ+n6d( zkHMcYqhFCDjvhPoJOslT)!}p{umYS`NUx~xifxcZ{!V8KINZ1of9FJu`eF{Eas<#Kl;#>~-&fdP zYfW@aTEbW#jTRQ`yWySFl1Oc zH{tun`3Mz|<=~V@ZNNz~OKjU$oOf^1lQREzQR60xG-T67tN;wXdXhg*xM!O=bpmOv zInhW{-F0!~yHj*nwylw;2U^|gu-U1HRyba~AWXSbJ(A{ZvzHip-jzH>g}8ptcy)); z=DaoyxKq@4>>wZVNf2|wY=lfm9{oS~E>gd5lKI{M`X}TRhV+gbN~`2nhN!p+hO7jV zgEzBQLRt|wA?~h%iSqaRm`lscegk1rNJf9L+VsRj{;#fp)|pIX&j9^EW#hYaqIr*Y zpWHQ(PfC1sOzh9J$W@J`M?FC$) zK_BhbFB{zKJcan`B!&~0SsI5!wMIGz?@ySC5#|b$AU3l_fVmpT6@%i3W_^vy3@Teh z9KePJYgUefRWl7;X732^V&tkS{1V!-Tg32x2L;!;sKln=&vP*gQ$y6+>5CWDi_1fI zBo;1F>-G@OJ#?#W!`q_~%ME>_E0Xm{V2G{r!qANj-;MXfc>mQ`GXy_+lqipj{tlZ$ zMqAYfh52IWa&H_{)x(@Kcg*U*>F|U3W~)RAFg04;_b`!L9nxG#N=HtmN6CRA2NGRD zNPKGd#ND#nFqR;xF@VOw&40{9^Y2(3ZyqNFP!wF&a<(`j?t9HgjAm(b{1zmV=2_ZclCouDR@|D5;u&wyuz%|wIuBJCi;Rd;=>Gr!zwKMSkq_@ zX@l+{U_;H!0+i)f-OWsTvtJc9xBblnxpI}E!wAgMzC{f*ioHwVpsgCPA<2YaSLZWh z5M+{_lO3v6uuRXeYl=QMja*-U=_g#bI^ojhxQ?_&HmEC!jB_~cs3vm5h&nL4tdNnW z8=EW0X1YS#gt~^{mw$bpeRZnZCO9xk>Uqy!v#4$8O^8)**yklp{jz#niat(Z03Km$+BtowZJH+3ju`5Hx~qTUf{ zTRX#QLv&eGp0V;V?D^?1yxACA4TG&12r3G}vU?lbxy}G#19#}S5Pf)_!}%mR=l-l_ z^3V(%KMB~3rZpc!%!K#>52h#_@30X6iQC2MVVT(`?&1@Ach#RR4#(pihw-D%eQFvY z3DP+%%4uaR&*ukh$_v&2Bc;EY8~jB9;vM8uO3)$zPMrsZaeTOkV_mWS*9+Z_2 zpEBU@bWMIQ^;O?&4EN3&`hn%kc8CL4ko)G$!a&*RI_Hqu@PCZ?_tLs(&Svo@ePJ{9 zWWwau-ZWf^P-gb}LU==Y{FRb#pDC36@$dVd&qLX|JbD@wa%?E4EmLOmKP_O2Fzz}X zFYJh)f>G0oR#gUL?O=(@g`mOKAienV5Avoy;e7CLE&Ch$dlkz3en+SYA4377aFMZY z?7Rs_n`F<=0FeriU9ffd`kQftb_}KMjNS{}D4-_G@yI|j9TjxlMb|`?=_-eeoui_M z%?Al%K04k=?%agmVTS{5*}}xqjxeL8n1;08MznZ1pWl*-{#oZ%*g5t zTDaYIZQ#qiWc&g_YB?6@I>6o z{9!RIhEKyGZ7Zr{pz?Rp|NSim4Mv|WId63roE7TJZW$H8p3C<#Y#tlR7rO|b9yD!1 zVb#!7Os%%?;V&(n?17Vgg>T%WSU$>&wgI%W173_;9qL+MMh$JJe)GQ4*br%Udh|NOR-&l?!D<^}{m6%Y)SM;9xNZ-LBJtecEewk|HxKmEqUQCF*E7Jmkd zn!hq#@zH88Qa*=~-nXM557oJLt99vTSvn zcVh-u4%BYYOETou!@oJ4MHhm8HK8Wsk>1AoAAYxG!hdhuzz&j7!!VlUciQ>Dc&QIT z%^^m?rSn2ZfFGcUqW`~pBV~<%z$i`l;Llmu=#}GZ)Mx}+JS0dn=B588I;albrf|2%&bCT@W#ayzzY~czNxIx)?VFE#C#o&O zQRZ!Z8Qj0zlyyp8kM(n# zuOL)7ssuJ3ul@i2DLi9v@b105;`6Jj17FPNpCS{JLc=yDk_1c;jGx)iw#Sh{df!&j zbsxgahO?AGHQQXbssv*v7F-MvFh%Z;ZJ+HFW3LS903HcE)-lv6u-d}1_XU%Jyzv@- zQ06Gbuf(84>-uHUij8qljAv2yY;VPI%ut3aY%@B<;2ivSvV%?c8w950dm$%vf(cM*H+VCH756Pn9!z<0P z5VZSU?WTKw23o?nh%e+4J#^Z{L5o9a=B9tvN!%}_MZm7@q-TxS4Rx4GQAMg%2kV07 z%?}w?zk7!k-XUT1J$26YqB^Q`qP5)n(=Q~)th32O>tS8NeM{df%@5k`z|&~5&AEsM z)cHM^|H52i}ew)JFgGydRm!;{MtNX|0#3PHgSQQ! ze?!|%i@YTO-LV4Qj}vdGfCs`JQR;hXwu3l{gF$Mmm$Zm+#o%++B6w}$N@qo+b9Kq^r`&%Lic+JxKWE3fdW2km3@`qgwNH_}g9`}d z%VAAbX0QFE^O`fqaf@XsJSpY3ubtc8Luw8-)V51@bdfGau9YF1na4CQZ^+3%_e`u^N8cM!knp{my+hBLj zPphSB2wEIoy4}Pbt5gtSGaRyzE5Rf1f%n!7*Q8aZ+e*)cEdC<{j+d=B|E!H-_yT5G zB@R#B0B9Y6=8llLAE#h61$%FKPxrzy%SXAg!rkmZJ+5<=?5KHs)j-3uxKptzqRLL0 z&$N>ZU%BX>UMo#?5VL3 zju&DdZ>nV7Q7EiHDOwwv-5$gxO1p2^l>*6W;Ef@X- zQi|Kg9vtb09?$YeBXPe>Dk!anLiL zm+vXktgMM2AAvz{$3-7-mt2v#VnUy$qGz#332!d|KjXB8xkm`%KC1$3qTbeM$6ZE! z@>7xff6RWUsQlMUbo|f%kKp;Q8}k22L;rO%fR9EVMB)GZN57bQf>D061#WcsI3Adu z3S`5-=W?-MRCzUd>OpC#6&q{u)-~S9cnRc3?JzGge=LJ9juair$7dbxYb2OQgeaVL zdD^rhX@EH=>x3ENFwaf1ReIdDGgX2Vu|ICx+OZt678onB2;n1eSS&tR|0nW4U z+sAI|*{wa*+gSs zy`U$4zY+Y{e|x3>Z$hKa?pl6!wevIN@^F>@x$vMB^>%u~p&=bD$^#5M*ZJ5g3wXYi zw$sA@?w(@*0b?tjWO0@pQM9C^PL%M#ZPqE7%D_e0oUTW>1jJ8-VM=C~1XGI`J02EN z2_=@pw+~esj$9j`twj(#e#SfmU|+nU2M=O>2{U@12=Rj0j||B?AzJsXcK_c$vEt)F zV(PZp$d~LdD7D)HrB#7CTAmXHO(B8H+16xTHF=_Y-fXFfh11fsIwZBNwV`3Dtx0~| zPMm!H%4VGfmo2skbB#kiKlG6y65lu*cVU5A&oEsXvezN1zhY4Tdd^l*Xej@2LKd?A zEce{nTe|iq(*3g^;$A*}rK7zYB|M@FJm`P1ikKg~qb4zAqZ6&986Bn@y)BLM;l(Oo z_ueUZqUyQxCq&h2Rq+XDU+|H!?b-Ji@4eMeHXd%ua};`gN9}=h-(eW-2Io;{(@fir zBjkhKGyZj~;9i^+uJz?Xx|HbMo!+nnkocki<`NLEi2Q zWA4N02NL9diaRiL)sy&QAJP_%ZzpqnJ`b%pX#FXZmlYNpABY>4AvC6Cr-)_|zQVb8 z(z6>#i#Y?e(A!&*)t}^Kd&L6t7ozV8 z@Q#6AW=5t!N;oWyl3;tjyxW|+see~a;d(e5Bdv@%F=&`Xj>)MK`aAVbrFm+}xw+bl zywJZb#VC^=m)A)Hc})0JW*K|xz(G684;?b;k>}cnQgp)|oyPo#7QU!f6X(L!7hg>u zBG%gXBxL*;MYe_!V&}O14h^T}vRvo;w>~lFGq5Z}FZh(enEBnhtaA(#Z2__WS*->r z;p%Yrfs%p4ssvFcHY?_@*)#Q4tdBS7TN^@4j3W3uN6lt%yJ~#6#+hIZwsF?6_5pNC z4qD>`?Cs5*dx68-IeOa2BGY>y>DW5&_S(j8s2UkRc!YXl`WqFf@=b%kwgG1S-)Lqf z?&5o3W0z4%I~==d*kEthmnS)~VLZ299+H>tt;%kP5!XK^Rc(LmTsd8!>T z@RXcxz%~R8ZwJ@%m|VkmmyX|qm#TD_+KEEsk_%ExXEq{pd~SXVn$~`?ebo_Pe3n|Fsw+Nx(?)T-N*gd%NDTAg-+T#{TKP9II?cG?t?ry?ABC z771&UDOsog5K(FV)d2G3yZOp&mbQVmMcq{$l{-`k?wdmI6gR|{+Bk!obq*_=P_4|2 z(lPfuxHf8v8`2mk(VD9^-b1%pKln@+tQ;G2Ek@Ugul~;xUd_J;qTHgO$Op+f*U{U) zLtFX%@8b2eiU*_Kf_3BCt&?9mWfDqLQ-4Be8+TPza7r!}?bykc9HRtTPbWv5b8Yu# z18>0L6y}tQSM9f?UpKR7PgN&sIg;ZnCglRayLbsWBSMJ$dn>$SEpw`1NHW@RFNXT} zd|iy>C3SA^>hb68f)z(?tZp4&9nIynz0Vti(QFZ;Z8)#8{sb zvVBi5(DRe>5F`n$ZJzo4`i6 zT~Z1J!GTSxETMHdW!ztHJ*iC!lwwo1stqgpGpMWB!i%uMWG zhH{ia(;en&VcpT{)lE~uRuqd7nt_z+nyaWYB&Fss@d|TMPuHMHhH7HFy~F}7R4mqp zZ-}bj+*u-{B>L*i73T6C<#WEN4ikrH{$9)!`2yy0E4PNdX zNt~eBL?zmSBUB3Xu=DnD*2EOl3PVREMD=j9dul7V7qB)!YQAW5B~Wr_o}~bWC}Z6c zC~o&l+!MbNh01z2D|}$IgR^mavK%w{b1+>0^_MQYm#D5(pGtY5VN|`J>TTDw+H%#p zke()L976|9lcp03Sqw<3^fc&t@Baef^;C z{A0KEv8lKp(F+6dS?xY|ReffP0L;IC!$I|xxwNt$e^2XNxP;!z=c$1nrKnZxwuE}r zq7btZ_x+nRg~N@)L?)J_g%z)g9yGL;_iFWLJajY4bMtrXcj<5q#PD(&H$F5;xF_Zi zYnZs%x7?9=KUv{#puOu8Y=6V>1cyl3mfCExHC^5ZX1J(T^9XWiBHk+#E5y$@{K^TS zH0s}3$tX#&3;t_&CafiJ9WwiCJP3LjZs6_z}eu`bT6gZ(N=Y;+`PK*%HO^VNDZtaQx3MR;!S1{6>5 zOhNkorjFYlXzf$~7klsh&Su#Ead+vUI?STzunBDywRPCDwpgt#F>1sf)m9a?EB2m2 zL=byaNn@{&*lKTTml)5L`+Gdceg6y3aXfypIgcyXd0yxF`Mlq+cZdvX@^i=5P3*R7 z6)H6YFkZ5-LFnW_|_Nt>mY;14#t-XD3ILSBiuYon(8$GSFem zlR4_pENX0=oV0a327U`kF1kVN?RiO}j(=YZFyK!QfoKcAB}pG3r(k$;5()U9!2c1& zqJMVNB@QFuT`0X>rll^Z(_4o_59&!+v4wHEr}_0uZj6PezYU6yN_KHg72j_`=VN?D zyt)9sjo*d5>tAvs^9DavEWiZdvu}??@3>9pXy+PGR;#KC#*2BT&F7ugzPKCbQ{6s& z#Bcxn@SWO&IIjtypq4WR02Xs{I)a*cO)FkW9L?(khRRXFFrdZFP@RU@gvakRL?0`7 zLKV+XnIqX#2Dp(TBiVrAb#)NC1Q{-|_HjQKuCv}{WscxJ|Lp+a6jsWyOKaH_wzXT= zqu9Ol57)il0NaTA_whf~JpTT9$%voySwoIhJ7+8c!p_-lpd- zQ~N+Bl%ce=^kx&;v~k>RE0aSu@9P^F7|2`ncu563BKWN$3doEXMrae@K;kB(wlwq_ zK^jjaL^5DO4RC$zAqUm*8!_3XGs=6*NjZRNBWKY~kU3l=Cx_YpXT zQ4>dF-y*&vkx+AQP!^C~9)2j#5FUC2YSNu*sEBp34`cVF_;j+-tR#5t2Y`c^WEnVc ze9X+m#0~|UFRczElXdc&dK|!?C&42DUwx7dc<)?C2$dU1lGyvT)|bBvt_%XQ_0`cX z*l6~yyXzqzAj|vQbb6vGLc=bN?k>sKFfCucZwiF$1vg}-%T&H>o;uAuxWxvjZ|At$ zxoB=odQSTbew%3YtzNq)1sHuyLnZ;7MG+yA%o_q4mPy$Ig;NJr)wQH!5@{bugQ*wQ zlX&R?h=B!}h?hD(yeLr>tZkzhM0~7rKf?dWPtP|j3LWk!$Fvl`q%I#Tm%isc&&JCT zFZ+D??9aQ4R)-m9jjx~@IwvFV4IUDp_HP>wzbUXCM;P~p;$o}oWN%r9j^~;AW5!!m za<%BorYf!4zK0f4bi|FUMmZKbtPGodHSco24)u>`)IkXE&e6u|B58j~uvxZtWL$2s z3SP!0DAjMNH&rP{sa#7}tH1YYu!tr1F-zW?a##1J)zS`*h0xG}xbbv1_67up?IKD; z+-3Y|wMSposM-`xboVI^v!9$_@=7nrQ%%tnh*45fjBKO3>7#S&5gy8|>3X6;b+7v1 zR3T?u276kVe3=zI=90xwg~ZRqs52wtdb>=Bi*H8z6lOXKTG4M$w~me7t>z1`iBOr-cCuf(o0AmJVI!=S#~GbWa~=sO>dsrm=jXmhD_$fI%)TJ z1k3({P~a#`-z@NSAB?sL7ImH~0Ynlyz6a|rPYWguA|h4C)3HAAvSf?xd<;2VD`=E`mSuFo2vFBfiZfFv369|FI+sT&+ZakSCh@?ca931;E57Wn-5R2 zB3QnfgxHAe;51h2w6o+YJZ?)ZTJ*?o*sgSoqX=^$O-LmRIpMc2?hKN}bVyswRX`6A zAzxYOpZ@7!Ox8)?t)LXJ4iNTJOF|B05lT||FgF4Z-SyST4bL?m<=wq!+pKOC7LrqS`Ao z?dH$wBXP+$IIrIOMxi!sSfRRV!a=;a{Hyf}5WMp<@6%t`Z(@YV6Z0UqJZfIa0`5SD zsY^WyJa~VUMX~+5$f?}9JXH`4%_}!vESds zJ9 zqk4Gpg&#UagYc}Zhs5{d5)yDs)4P^Srv&Fyee7pLDl^9))&SfOh%kSaP(lJa=`FD3 zra9KF#9ww@CM$1fq5p;-slT^y)h*o%eWlHt-*h`zJ;qF?mcTaMXz6$Djnt-u@M+A< z9KA){FQ7;_N8g{}-1?k;)rO$wI#dg?t)-v#qdrNjBdv3snxSp9# z!b#)d65#gwF|?$2pqH@{t2#~c+rrRR#~jg?>~NXsEnQ$J2jMV~xgg`S^%Q%$B0=^`e?tfRT6b84~Vzv+BCOHR(VTUx%@7S-QM$|zDE z4*~-#Yhp2=N-Pxe?of4~ix8{xS_7;dp6CBj9iRbAfAW_9maia#--@dF>a6fC;0D!K zjA9!mQ~SuoKWywl1CWY{+dQKZtdVQpm2A#|tr2RO1VLXbAZ1l%s$VdmPl@+pl5Jg;acl`^*Ry+WS9kp7)0Lw{7Hrzr z(W6iM8rwMAxwh1JJU(PR($^D}(8t{W=^i0M!r_vG%1HHv)vG=T{~-5DXTK7r>#FLe z9af`L8*RxvN&d3-_ULiL67grxRM*$`SZPC3+hYF0) zO(rk38^g*t8+xO_`OTnHiMmG3iWJFV{4?V;QRv&`yfiA<%&&^d#=xk}5tk^Mru~mx z?%TiI+{aRf>wG=MchWves6=CKE2LNqO0a^oDpsW#l#H&;FC>_g2`8qd!u_9KspeuL zU!}0&KZ#m~mWZlwYh{{bB@w|4kaK=DimxCikNIHv&7KBd8Fg5Bvu{$( z-#RfE7f_noVT@S!;LiOWvBXUWMk@e^)13YZ3Q7UPk{09Ul+>^`y>Ibrh2J+O5hG2e zlG1+OU~NaNc7o8c$v>=YtrU^;593X10B}dV)4Dj;GRv-vs>`Zz z_1S>uvcq$Oq_xjCm5nD8hQdn{_`!YM$a6(oVP z%6+n!4(o`>HCX#nId5c)!Uizh_HcIx_U8auB0vp;4X834VyiY%DXG|{&G`3aO;-en z#{MvD<~S)D_YGD9R?Ne8R{1$Qqtbmh#ib8MECrK@a5RSj%Ln_k1VX8MRWpP6SWk@+ zZ}wZFHw4#82uUuGex3=OU4H|@>2U`aT>HlLR0S6!OgT}K8ry*+JNr(u8qE6@vJ zRDV$|Xstxe_tfX5cNSMiezj`K?B*A(@P;byj$6Ggr-JruJRyeNM0Czuk>CwqBc&{@ zh4Z2+U^|BOBSj{h?6E}LuGvyn59&=m*F)(G^j40ltP>a@J@-6&oi??NYvg^e-LB!Q zSo~8)ZLu*F8%aS9Iw>C+m=#^Ct{54dRrb|H-|MpIBWLDGJDsLhsqqDgG`@)HS$6sJ z^P*=4Hig0VKlC3i%!@v@iWkl+gL$Qa1G5^y;&gYo%J#A-2thbjb2JuB#M8I{K$#a? zdw9+Npwdj;dPGVuXhCdZhK{S9CRZ)gRcA4}3+ebpE+xv>|P9 zTQa3s2h`E+^K)8%%fN9!bN{Q$0I~3?YXKmp1$Z@E_r>A2{Rj&h`SGA^Z6wbmf56}E1c;P;Wx_7j|US> zVvF?V(SM#|V^tlkvh_4EMK9onkf21^oqWSb#iwU$=I6(6TuWedV?(U^h^71#C)c## z^8@Ge#ZRx-bSv8oRNFD{`eMN$At9z^63?E^@(qLg?O4AO*r=W%EeG?b)nNC>cFCvD zH6R5#OEn$SDGN7*2CZbAA7#{Y7_IG9E*XA=K7IwdPEJqWESfn3EM;f_d)J_h`$e#< z*8OOoqwFZ{G2N!o%gegUJ49KWj^HpMxXn60MJQX+eD)7>8s`ZtGw%t97kN*LGuJL@ zV56?ZU6%cqe9~TcGVq=l#57%PoaP)*t-xNZI6&RUv4j(RmDLf8HR$8FURyBM>@ZN! z6G9*y1auymp6xFr8`ei#?@rAH?5&dMP1>%8tKR|DU0mU3lSyr8z0~Esq>`o@NAJ(2 zFM_sz=Bp83HMJ-qxXaf1UAe0^_9;GDY?$`PL*@GW+>Oh*^$;^F`v|_eMVlL_73DRa z<)-fSIZM*P+nyv^eFNe=D*PyJgXoKE69 z*!s!43#n1Sb7I5qP1 zz-*)U?qcn~XY|m~W_Um3GcWS;;H+Ty=?*$5ar&50J>f={vW;U=ge*IHKZl<=SZ{`D zu;MIP3ze=^hp`%=5^B(5GwnubiwlIl~3 zj=FAQDc$?@fYx+`%zoJ;P3crWDK_$<+S`$p5@ebs=UdP~(2tP%#}Xm4{ikO1<^{FK zqW;#zPAk9Bi50%K<7*kQUvEX4_e!`V+p2EtE*QJ6|J_!Rm1EjF#0?SI4Ky_k)6!bL z>)q%AEk?n*eJLSkYv4njK=;1yC2Yop0R0+m?Dm97=c)kW#XZ;13OGP}xWptW8Ke*; z0?IFEl681u19^~-4g@_USo|i(%5$O^v`>D|3a8Ap60A?ZGw6Vu$?(`E8)>v*pUq5V z(<}Z5R{lkVbHEM9fFGS>I0pw7VVeP&Wix`Fsysk9+#6|*52!lBZ*DpBT8l{w+<6}R9xOxbEDQr+cP7CPNAdHVK7b*9;b#{*u_+9|$c2)fvLp(O7 zR8Z^Hc1{T0^0KyFhbzUH!~)C%vezI*cSnOE48cVHxOBuyzQf{Q;YDCMW9Y1H9JijYeN;!Nl-exB* zsp*d4^iB)FbmPC;VqS+y`D8rGidJB2)STQp3WPNMk41j!+uq$&u$%}? zsGHisQKBUD2GslL(;gW6cNFIgh5n|}+mR^pQT7%woF0nZ2va^NEm_S4=W$!)pPR*q z?rlY1^-vATi1`| tbJOG+?8?K;B}dxpm7C3OR7@hD);IEu5xr5h(gIE(W$!s|}1 z{N-ydcQx^jld1MM|9shnRpvfke94374i6v3Qza?|z)P!2_7YR!ahS$)8CEvT{NJ4} z-Qh}!Ev|*hFr+>4r4qg5X4t(Z$-P!Qg98Dwn`&P?vP|_x7w& zqW=bGU#9V|aC3n-7>g;Ph$3AOgh)db$8^as8x zc?oqbX;tP7n#M~A&N&;^Xv~J;1mtNx_3z4&Q48zv5d7$w;jawjD4hd zq|^~Jb@@VG)4^O05TcN!w|4`hlvQPAYa@|@&COG!^i;a6spNMxQ;p_E@iMK>qfMxX zr&3Q(e8!Gzwm7J`vgY*u28$oqKSsLybxdnIu%CYcxLy}a27uEqooX8l+{fJGxbc?f zPU-PYGdXFcecrL@UIDJudrOhnzYrj#oAh206`UI%vsD8y5 z;?tckO9R-lU#~}LtRgs97sEw>`jFx&nK$L)a7=qr=e6PAh0s8iF?59ZTS?3XHOl{7q?nF;QdCLY>8g-U05cQ*`YU zvsi0`zf+aFDySl_wNK@#%w?@6KqhXfkkiBQ6CgOVvSZ7e=O(;^w> zjY9I&p%wx!Fn41`IhFZd4ogT8ON{0uWF1-IUeKsfQCD;>*qCt1f{FoTM4$=KdFd$O zJ5hAQh})4bu~JTt-{H!M?srW^o;+>4vnAbnr;+ESI&h_ScGeh&-}PB9Ilo?|Pic>XR6M$$h<;&Lo1-~Ed+Rzv&v zEn+i%RxgLzNhQY6^*E+!W9Qe#4idcH9+3Gr32XkT( zwQOf>`b%*-Yt5 z>{*$?S^q`eA-;(F@zsC)j!x@i)8cq%M7>Q_^OiG>r)ZXfT<5t&P<3WU^YqZs*&p+`vF_N z({7RLo`Emp_CVBfN*G#?8d^-lU~iK}efx+qV}5x7(y_&3^V z+NBz}yFvrDz7y@Av%TeD!v|%xGM5|1ts6eK_*9}djLyY}3OuN|8wW1|x6^U_hGTy2 z0yY2IwINmXpMj#wM%?+ZD`$W$<#WKv9DDs0JQ@D#88q%YO)?|iNQ$CpsFG2wR7YnH ze6m=3p%xKVdEr^3b__*omFB^OiH7vPZkpdthhWXd`nvn$7tRga3Sy7kXH#kb=y9YW zl|uwYx3dpEy3WaKRljR);2Zj7mqWS&SAUU;m!XtWA#Q9)(T# zBg_XGI_nTLv6jM4)xB=x{DTd>)*Tw{F*%mTiJtHu_tf=c)iuwPVX+Md!8>ASf8N|N zYPxu1ly3ZexZm{{0Zf^98oy3@$J;N81vObyShyo0<0={wArL zLZ>UP9db5@8)HV?)i<<>u1AWZ&lWg4As?R1IJqr-9U|CFzc2FqIQ~jn!k(Zfh;TEW zmS+COX7$aKji7uq-?CJBG~xkZ#3l}VFq8cIpYj-2+U>Tsm1q-<1kTDw#RaO$frl{# zeolmc$THZW#4D0ISq+;^5KEkrwR3@Uegls6;R6l~YAMLJ*+yXYj+gJ7doRR0F#$eO zQB{_|cH`Bf@&Y#9zsHgQWBu%J;742>ina#Eo<1c!uRRvgLFXfh7V2w&m_4C66+I0& z5`icC_}S;fsmG4!q=9~|6Wy7NyI2n=y_3H$MbbPx;D*BaZSR^%8q9Vo45&*_BCc7D ztx2-QT#Y*KL30{?*!=RL__;6UWC|I}iN9q1OzJ-Ir<_Te=}Sy~OX9F(B{IuN><-?i z2{78qxw8*j?tbIQ1_ye@dF*Yx-Q6~HlPA)cR-9-XT<3WhyEO0);0nH&1kk$2WRfeR zfYHwvE_D%ARieZWyDsp91h!=(Esy2?EZSz{zcxDGM#61pmEQOU@Re2csulmS%wa=n zuaV94bsskXcVU6AlmX77sL1iyBZ^gWam+g2R~rxi!8bf=PlBXj^eNiM>>ZO6A3#}a z5qwp@;UJEV>XB8`1^o!ep%m>{>k~s=bzAe?Ua_Xvp+N!OAP{Abac)e=CZWC6vrBfW zW7_X*p)@Q?J%|bDSIaFq?4NGgn)Y`T7Vo4*tvmqX1kTHuXts8^-YgU|8!M$y`t5|u zyV`V!wkM@Nul9chK7GbJ5qtloy-viHS36=8kL0;^gG}6CK5MVMn`k7-$)|T2&)*fG zc`lqtI^HYVOBSrYOv+(q)3C#K!j-3GJI^{L(E*yK>Z%wY!f+V(qvUCir_l%7lvh2&3w8lau*-6D; z{l)HwMHC4=%LD={>WpoQJuA(}eLVFRCNA#(Hlx+|9xlqC0#Yb8J@D#cwH$B5F>C?< z-ZQF#@3Mz;f;xu64h;uO0BSzg66mtJxg=m?xzpTZ0fWDJ?MRn}vM~@uT=P6$0P0eL zbtVYeq4PO$V;%xi80#GXx3mQgT&6cLnb}kYsP38E7{8}am)Z>RWA8|CmG3=t(BwTs z{APur@Y`b9kJ)?x)Y$0iQm=sn@nHUve%6bj=YTV^inn2vj`yy?`k#L<8!qJE5aOVC ztu2-OUF0)>&UlCa7oZ;g5=6L(QNmT-fo6B3Z6;v4Fpn#f>xsjI_m|z{Ege17R3kSc z*57_ItjGk8?H?5^a#o{m7K#i3Jv`IR!wAJ{y}6qIx~Ue5GJqmY%6Ux%DF<2jZEi zw2vcmw;Q)3oZW+#Hmavf4S@J3!6ZU{f*OSr!#D69=;J3F-bwjmm8+!;AE&&R(n|4z zRgOW$0J5i-sI3Y!RxGB7AybHrmu6Z+_5slT5Jf4WCE30a(c2Z8Bd(WckK~u8hiz7= z37Ji;rk>5`DJY2S;ZsC>rcD8+7>6vI!R+6Q*eJGG*>~n#{`~eOL0jihpMdzU7lBzP zF?X@IH}z)QABsH_Mtxs+S-_{MJQ&6tct1StQC&K{cGSb&am_{PUf9hY*2k!Cwi*x} z|(#CvE!BhmIZrx%Z zQ1Wx{bOgQ0Lv^nlA4QCnt4NZ2VW!=-!ru%P)ASTE_I&LAdv6Wwalq#OB2uSswstAq zw-;3JGN)i*O`uT$X;jp775yBmOkgN5nk~l05gyv<*^t5Pha@r+gP3IRl1lxqa-mm- z5}ScwQgS#Ib?f9eKT;vKK%Qn{g9z~5KH2G>SZ%(wCz#Xn zNd0lfwZv0^pEq;07>qIQmJCXQS)+yfaU9s$gV{}`vZV$A>C-7cDpBS zXE7E2{WVGXi{!J5M@GfQ-P$wT<^LF_%z(*>>d zzu%D@<7^Q8U~e#Z0AuK8TtDegZh(?PZrM-&c}dauQDemnNwMK(0%$g1kqnr=Vc`%l zh@z~rT4Jrh=-%-f%JT+_Fb(jW0T*&EUXjha4Qr&|hNIjZnf|cu8P4fkzad)vegE9( zCZr>qfePGh8+A@*Q>;~9F#*IFhWJ_CwcD5%&*Il19pwxtFh<|Ev~~e*3}kejw$ooP zznBac0P1{Av-GGBr_n%_ki7tlVJHTd7(u49vB_&hl&4D-b{P1^Gy+&^ZZHaKJ;)^R zJ4efoWC)z#hvqGM-UOnqIya8`b5ny1XNx+xu99+{F$RtZ2x4dEq>RV5hgPGi)a^3^hDfGP%s2SNE?)@}cG^}80$<3o=Kp+}5> zs^=Ks5}O*t4_|uD5^R41jfhErw?ULE7~GktM5oE(tuWawA7cH)7JMGU8je^kW4P%w zQr3cO1s-Ns@?jcH3m|8gpgfoZ_<=V7y|2|!TYI8zJMIf;J~PQ6gAW(WV2R*AhX>Wo z{)6S%t3&4heleOTBGC^<6oQ)0Pq#cTIwC@=vAJ~fV90DGA-F5;zOh$%>qzWqtU8si z$Hu%ysVb^i5$9_qaVycD`*K~4bhP`@BKi;UWGBN}Z2Fe#j(a+y+ zK2CWUEQZrwsn=myf&CyYeFpV(KWr%W6Op_G_ z`&wJ&0NkT%zWsPE>ImbF&~ujzX0Hxa=TqDmw?JjBA~aNOdTt@0aEh2bztu%JRQ>U` z*#?u3-_GTxyl(yKI?Wjrz)Abzle@#ZP=6@(tXAEA`i6tj;7p8VX>63gbLEvWzxSR8 zV>oQ3z?_0 z17FuE&5!}UdA#Y_JkHseZ*v2!@g|(Y@!&2?xBb%;&^ge!ALGmbzbZw}k=Y+>Je4qT zFnH}ACJ6r9qMp20^pG`vw2^T-nvrIQg6WQZ)Kr~69l^;g#yUGv_5f0V&vQ1$yl~8R z6KT_JLqo5v5dip_+;kv)Vd9DTFzh?#`%mcEizyZ(*oIsTbxdI<92C}JazHB5w zMy9m^G?k|h`89r6gw~Mt9Y9PKIbUGE1&mI=?f2)hAeUhLK5}ebK);elZ>0U$3~5fZ zumYCw!a$r2X7ZnkNSb?*U%0fV(=eIrzf7REMB6+m1cah`8m)`cX{G<2vW*Mo#I&(956eEPXTbqw4B>m|bOOV`{4W zHe60Sr~(Yg9GD4Dy9e}-$9^h>*9r($P|7m6feZ3DtHBL++v(Ua2GS@f{wJhQ_0(ZI z3k2{qL6)-PAJtSHFoykv_vmaa3;~g5_zZTi?Gs@L0dqbG=XdlD*8!bXyqVBtDTzQJ z_>enM*e?fuVvQU9(Z@*P3 zFBF)2n5ylw#Jj4-QzBqa)$7&uf%t3Yk-r}^f4{}QiKD0dGQ(I2M_m5EgC4mI3tz!mfWlALZMNZhA2C-9i@PD8`E@Qo1NBxI3eqnb`PpwHuuuk^ zkx3F;)L0)wHNbaznvQj>q7J9md0I4?!AE0NVm??E69&+$sv7oP^2gqxOD0u9MRbIV ze+UyQNB*Iv4`nzv|D{g_Ldu2cBWR#i%2{)P3E>Jq?g7zVJITgChRTY_N;9D_E47km`ItCi!4~Tq!#1Z6wq+QBu^`B`N5{2s;C%Ysa?Vp zs%U!2p*yPHdh8bnLiwC`h8t)M#EdL=hlw;F7n)Tp0$1oUJ7W3!c3~W4IfIr_rq#;? zy$_hXA@KPlGOG;`uA->8fMPN*UpW)UTz?DRq54_!NJFJ4Zoozv!ROFlxuHRgP5m@LLrh`w#fXk9po6~&FCIYUL(o>7!S2Hm*yLqR^l;{44Thr-65%It%0MM%h2Y&P!!b_MooZd~ZQyE*nQlg$TJFHexG2ld7 zZGTx*SQ%SSdq|}vQ1r$eOdl0`@&#y2dS345aUf(3%p;?Lgs*2*S2ui>9h)W-A+-k#aYh+gljR+Z z)kYHlR=ea~)Z}2Evyi!fYDwtM?__Zq|?!n?S= z=P?g;uDTmdOKYRkWee48TGAKH%Vfh-7n#4WWQ%&`4RD6njqEo{&fSxaohIJ|TttM_ zvY|31c)m!xGzL58M0bpYk9$;c>yzkXV7_Kdha%%DEVCj8&H3;X(?&viGn7 zbQK}JkEeM~8Qw(>0rOuJ&Tw%_;QXmgK}og;JsBqVw(|L?3v8JF0}dGqsZ)whYtK)t z?34^vYYj^Jq5Wk4ON9wvh85hN%IuaxSS@&dNouD-|D?eLpixYtPLd z0cr418C5tf*kdeq>g?4tj__2!fDZxoL+h-fJhbFNesukvJZf|K|Hh|3N&Q|;&js@? z_AZ=fIl1HQ?qJ5OPiJur=sRbSUKT4(Oh*aRsTLKb>cem4tFxF;M(9kRnYi&QX={7! z#eT`+M!QzT^X7G2-TfWC7yBwQ{Q+p9+B#h?(rK(G7jZyvX?t7MZyHfebazzW9ySP# zYL*yv;8iBzm3cSPoJiNnBl^F$M7CAImkc}xJ01U2KI8RnAoTLqoob)e@TJ~Z)a?3E z(E)poGtXFw`te{xdEY%R3aZM)441qixi5DV$EB+LO~8?V-~FI`do9z$rkpxn20R*< zRpB6xfACp*cm?WHG>jfkzF8aA^_HjN^4K-UQ%8CeWEvOV}5bKg4Kj_vx9;4Q~ITiLyIZd z&S!t#Gk2aHclZZ3S?BLca{hNLnE}xc!au2t+{jDU6?3unv&k^;ArPQnBh4GRHA^Lo z8$WArgS_|mnY(M%ox>ELwC?UMP5SImD&_Q?t(PD>>M*kea5{hPn9%NyqmVRxFTZa+ zrK#nj)&7KI=W(GJ_Oad$bPQF`U+AZ2*%)TFYz9~NHQMC&XpAULY+*CI+cmFZ^FJQP zOfA3yI`iXMu&XuqhKA3uukMo#c6jn>-+i^GtgS z+K9{UVpgraLJn;R2qE?T$X6>wD%&DvT=Cnc(f|JY3lMJIR!2)_Uh7NiJ8H?MHA)mfz0YNkN zru;??g8%ZxT67IuEy7WKrIT6F#h4zxx+U2!*N`9mi3+YfiE+B|(Pst&Q%M%ysK2>b z`H#}a?Z;nQd1;~bU?8G>l4|6 zL#>{C7jV;z;4zMUHIiXP0oEtq=f~eUd1+J!6@Qg$kmRzFM zRP$*y1JamVNY3S5=D?*+m4H`1_~%DF1}p`yNmL@H2Uuw4T=bgATgIi<6dCiGa#mEj zjky>o&|Z11;eFCx`tHBWEWf`;My@(<=X3@q62s$yzC;l6ohmY4RsUw=3* z{LMd~{*mC3T9U_##f97U#*~^Wq=s&L^aa9SU(!{1QnT^rOXhB#Ps;YRs|3z_NO+IGyG$JtHZ zPkHIC6Y7}cUhhb$W>d9OiIFi27cO{@8YIMe(cGorqI@o=D5KSf&S$(y1HE+NqkWJe z?E>B2B^57S`ckg!|21%v@15tsP5Ymv_P;k$zm`%o#eY8~eq02lyJ2(!4@Y)ggrNFSavEqP7Mc3G$o37eut)1+p`J8))EL z52m+kyLG|W`ER}@t*U*^R#WBB(I!E6rx5Ppz%5gdnm{OFAr`_mQX8OYR}>CR-|N zwo@-MD%0Pe{We0%z1l~XgaQ_-CvM)_#9=6B)SLb6Zlg!ey;8hVyH_p2V23~}t?^?~ zVjXXLj&r5*?RCj^mrJWd6=Ip^P0~LZ!9AMCY+zJ8N9P7 z7@hn|xcu6?2hU1C{wx5RWqyF&o^a}W`$OtSiT(Bs+JSDiAAbDY{oGzPJd303qo#RzWJt9CVXaFJF6VzqnMGS6TtQx(qS~$#ID>2vPl6=nI)Qz$?BOpg6Jd;{Trrp(5rudpn9sg467Fj3&=i;Pg&5Jr56B2> z%nVuiF_w(M8(k4W2m8&dhx|1&$=L#`Ng|9t-4f!>rqpwNhuO30^@C z`S%(;?nnK5TfT-9;sO#V5N7b=hnk-YbUtb2jf2B2pAN4EpSjB-uzx!f-zCmrbZ+yF zax~xUinnCd(Gx1@$vE(RV*10Qfq5Z?`oI4((?cm*{&W8OfAV=?FM16xCga_I;`OHp zn}DMTcu8CqpH-7J_h~9GYt^9bi`oN+H6d8Nx2=1I(@7_HDkD5s3ggIV272Mi!o0D^ zz>UxR=+mCK8y?W!_peDO>FZ*%%}GO7gfzT9Vxdt+nA+}dfqP}A%NKr36z0BD+$j@Q zs`y3x*mTk<+l~K@iRT)?LrFFNyssCS60HBIWTJ9CI4SW?igZ@_JMKkq6iNb`SN&Tv zem5;PbfqjF#h#+>5;~>>c03};SO-k4VQ6kFjc)Ryv#0eQB z!GX=yOhyy_^z_z$N2!&e6z%wKZue#sH=D-WhX{IWmf(l^|gT zfiOb8y8>Ss|8OBY)YagM2I$Z5qYzY)YgLv4wZJp#ia)RgxSA1v?WeMQF_ge%7D|7o zBx^n|@DATj9!kTsX`ey=ZB;{&_bFWXVnxlC`2H^6KHo(0ugK}PFC)KX{kw(_j>RAU zcUT{NP-A#`k5wsxQ6*e z!cOh!(f0+vM%!_HzQ*Rgy%8yv#DfOjb+`PnBnsKuCrOm)HZz(z9GyG-ecQdBSG%^8 z(^dADEXK6Qz-#93aYDYY954qyK5VA{9fe#TunlKI(R9%1sE6=zp^J{=x{01N8c%Hr z#r?xE&8sf?Jyu={*5N(y2!n;+^TpC&2UqwOX;VMUq5gS1VvcI;XQfYt+HjRX*>CFs zQtH8#=HqMKDFZ9sI^t7F{A)H~OC*h81;!dOE{GEWJ5ZfSBoAcn!Tvjh3tA;w1AU1v z1>W<;DAic@a`e;{5MMhnZYRmA(;6#C{#Cv-t*729mmc!=a|Dm)y)j{y)*gEX z6Bv)_gr(~!J95X4Pmt>A!jHmmu?T~#vI4Dkod;SYzKT6&wnw5Sn_u$?3GdS`3YA0? zb3bIN544p%3Jr3Jy4Gj|Al-4C4@hB99vh-b_LqE82gitCQiq66#8ut7&f?#qlSUW!DjgFv87+rHvSpp(72wuV1B+ASWu zMUs;7`&TA;%hc2q;^>I{C;HZu0SI?QYCl+RTB--yY3)Ov=yytHs^JYDKq*!f{cQcBASVJLk6X6=??%p0}Vr}g?c z8J(2R>P|`T9%R;J^xHY;=4@ZTd?D!SdzW~uJA*S>Cxl+t7eX&Kc<<6F`QJc1@MV_* zXsZ_Jd+5dQp(2V4iV8ppF4K1cn>+=`a1sq^v2DrkdGGYHLw$k(`nym=UqcpP;l@j` zG2DeRFhjr6?ZpOGe>=)i`8NOrxA635e@sY!wNQW7x0gs)n5*?5mq3for&E4I^-bh4 zP#GXYy<}>q%rV-@pDKKZToR=@y~lmhc`e3GrGT({^RT}N1M!^+ zA9g<$7tGwdc1^^ch-5w+M(&V&sm3(klXO<3`+`Yi(6_``|tr@x*51v$>3ziG+ipua^cJDsb?X@rUPV%{&pu9jKK_PI2J~NJFY` zG4jyiL)DiCKLg8^@)FSW)lUE9@)DtW zjGZ#>2t4BP)kX}2j|{q2dA1xin9eZNK+tiYYM367oBtU~oL6el)MPu0RG7v6M)iAI zUf&V>T`XU|yzNK~t}CK49oDy!95;%yY>e(r_APQUIl2U-pPQ(+Z~+MuCG5^e!JFfx z#IF{QA(UTW1HUR@r(yh+4Q?^2@JY!Ub1~asr;an=Inn>rWhxg)imm|RLm z?3G0to!)1$Ka|$Cuz@`qg|7VxDopqH&^kSJ!Bk(vcsLfr1sppi?$NGDVS;@s%N*0- z9wwPunMP|-CvQk!(_KD;)NQ@8deaYmU?QN{z=qE}oBt1cZxt0+^KSiyBtSxN2reNc zxVu{j?(Xi5yAy(Y2*EA5b>r^tE{(gpyM2rQ+4~)5?Dy=ebNk(74ARKzTC1z-sb|jl z6TR4Jv)LIv>BbmKUl4i6`H-HTz)P-%KknquCfr(A*{BBcqCpVUU zwEe1%i^Eg6#->5j<)BvcF2T_PGsH|Ufu$XNf`eTF%x;72wq-XC_OYpU7Bln)|pR`0m$>mWNtV!0+kDL zTu`%CTY%&r4tu$dmS*j5EjM;d(8`f+Wzf`V=5(R?A}8HdIM03UUCZOwuInSP)4BXH z4P`Ybu`vL02YyjkqJ;8vbtRb&s_)-X5Obe|H&?9Y&83C1`bpPY15oy{{vs`~o7qji z^|E(O!=-39cKK^L(f8#A*^^nKQS}mR@W=#mK-R&2WeO`OjtkI6L*t^O(X5u67pt}b zf1}Iw;cSIy`u)PTmQ%*_@$>z2;W+YsrRUYG>EbEJapO4^Q6rX;vt41K+AhO$p~W@q zST%uGB5j$2~g(1#)C%>Tpn}gioFWptZ(blMNtaOFU|41)<`aW&cn{&@2Bi% zS@+xrh#PtU3Uw7`#0F17KrZSw57zpyWMq9J=ZJ1u67TirgKcf7#;q@`hol2RYn%eeZ=IIsTF;7gR`Y0mWn6q-rAB*=EuV(x@V%a?uo ztW)ntlVj0M(|jE6V&1N&wi(tYotW?Yxl6W$6w754SL)hBgce9uJ3s_Q#&)E&T^60L z%bB$MSYgp5KJJUNUcu#@M)h`ke`GO}wuyT&c%TO25uxL77Qw|eUWC+BUC4vCiD&lb zu{HcQ>ont=`$n{=)@I58eaphv+_}F}MV9Bly=X|7Sc6zNYIp-j*JDHM%P)Z`6IRpy z9r{kr&MKbw1uzA1!JyPUR$~8<(07A-&L0g#)4i2^kw(M--6XA6;mUZd1kdvy&2Ds~ zk0E9k(H=3f7S{6Tv)C3pCjf?|f-6oAQ5J!X-1JijVlOdQihlIp$w?Cana?&Gz2Q&w z3_J(_35p0$<>fZQfZtWKk@^q$(6#su{<~4d2Uo#qd2>G(_^hBwqO=&hI)CEnw$%u{ zNJ1yVcxVO?Z}Aq1${_1Z;~T`{Lrp!-S?eeXY~zo)4l50yWs8hNZ0E<=kldiPy=4fW zu6!O%Rt1+_33kYcbD|pu+%`Q!m2dRi#g!$!4$6A82HnQKWABbj(mQ#DVcEQ3tM^{m z6`Dn8AV3eL>nL9TB3Y^gQaxPKziz7l4KY4xgCV#m)^GX|eCPSE@nZn}UVmU5L}8;2 zkTZOd2Fb*)l^KD}mt8dHCp`he5SLNe)?kYAYgqdVZRgsy_@_~l)C70ZE~;(~Fs?-m zyXTigIqnX?lM{ZJ^wA!}|LUr1l35C@?g}=q6HNnb1&hatH{M!7qSdvoEV!Ui5%JXcOr+HIrTi_dpk=urUIbr*mVYhhuLREezFQg)eVLpnv~;a&KK?b4xH zZ!+!$Q*{Y24Qh^DA8va1p;M~5+PA`RC2YIM0o!a5Hri!Yw9}PMo2Xt}W$XA=RKaO$ z_tzBFF7cC4I(p0L#FC73FPjAik)zwXIo&h&09DA;4hBkXfw;tSj8=iC`E`UxZ}KmR z_$$37iAc^Z6Z(S32~zz$6WS0YaeQl;r^b_qg8`mv$i_$*ojfTenVr*UVYmBBQk;dg zOmomkGPd(a<0zuA0+7m;h5hVr+oCvR^|+6+ypj#{^_pIyF2w1fU#8<;TOg^IS05MN z31hG!3FD$O>}`Kd7tAe$P8>IZt9uOgkfR7D7Cnggnw4cwg|+7IuXg?%O<5qZHr!vM z5RX4;2g%SdgXOIb7jr(QN=_P0aBcE32c%WB2bD~YZ#Wwjb!k5&l`nr#>Rws->wP<* zyO+oRSb*<(18BV#oUrCTiS6@LhL*FTo)s1q+n;8C9h)<4K^m_d7B);x!@3735{ssG zgWVOLsVFNEc-+!+>?kI=PQF(6p3VtZbo*NkN^u14(~SmE|V4rkA; z9-Sp2%jm9(u|bxE)!s#jlk@ZYaBg$erXy*GaYJ2P){x&Lg~~+>&6#Mop;q&MS3P{_ zd|c%+x&|h11D92Sd}XR?uZo8;G}!Io>632&;v>P;_lHJFt`~{Ja?`NBn)7q_I^upPc0Iv_~=T>@-t^I zHi$T#&8fh?_9X4^S?kWqn*S&nZf3V~03J9v@R7R@N>dhME|Or}>j2y$bGD8}$SA~$ zfOnr>$EixE{LI3Nt6myE%F1D2riFjmE?vX`07#X|wfJn|J5G%QGDmYoqt^*(G;|Gs zsBt0u(+h3wX$9p;0Ej|^K0V$8>Te%i{=2a#Eku`>q|_bWZOI zbJnH8lA;Bjrt+GM$O6LMH*?jrB34#bPEnecK+pXVRAyok_$Nk&OZ>(DAln(TyI+%j z=nWY9t+oLMlvQu{+Lq7bw2#w#<)e^csMRtD7KlzObC|tpqAOd(Tz5tQ?=(=ZEBSEYqEY zt-Vl?mSzOL9jxd~f<5O|MY>Wm%F7HPft_c*wwhzQhf9a1we>8H2q?Ry;rrJy(n3AQ zfZE}F%xdlz5$LE8-JZHNI+mz@rtba#kx%EDTLfS~L2rS#vn@LfD!%H*d3ab2X+q)0lgEIZFnj zZ!}(yr^)$vd7|y6)j-SW@$}hEyJD)+0s^?5%}z}DrFw2pXn9D z$V|R(^OXnWj7#T>s8{VpV$`HQhUVZ?wTwr}8%J7~IR!B17?~Ev?B(K@)pGxq<4FV0 z>GPu?cd{@M^w+Km6?H+cxCWXoEu&Nlhg4Xhe6VyW&sP{zMlL8ol0w`U?&?K_!XA~s zZLG_Byq*SAI(1Q3Kp5SSRU*XA%E1xfmH`<^ew`bO_TZ zZ}~~`pjR3xw^CM@5|*AG1J$gP`r!7S-MU+Vq`+M#7` zcktqn*0%5aO1CxN=vE;qq3RGV&7bS9twfv`6mnSVSx~1-yTkR&!(derF+^)n`fuf{u+M(nk+U=GL z(qZDtGD>OEnzx>Fld*nd`c{YY1=w^AO0+%jhDU@vJJyr{`pSfIx0LcHr+90nak?bH zR04Jf`Evq;Q_uV!$1vnQ$|g4Hdn^+%qMX}il5u`1R-CKBZ8&~?oHY1q&g$)S$=5CS zFaV)Uorw)cib)T{GTb4~YPQ@`z1)5{YiuL(@^SdEKz>9jXm4S{fyfM$+pxE!SyKqQ zyYN`LrqeQe+ER4T0bE2P>%6xcF=_ynF66yJ17r2=uuJoV8P6G@rXK6WecrNp>gK62 z>_J`t!XU}m`fgI9Z-8ka9!m!tg0b+ARTu$VM1o;cQ+4p6yz?c-jo(FyCBZ_B4_{hQuyL`)!$~f9x&Y+x!c?sQzS8Nk%-Llc`)7bfqaG1O?{$5R-585bX=p5(7L;Cdjn*tdMEN^@46u|` zE5}&}))%4s`Q&uVA6$*3xKruyJ~K&~Cj<}s(g9}nbX)%c#;u@B5bt3Bcff8k_bXQ>4W4gi z1n{g_4^~Mn46@inWbsu=t0w{&7Tu@Bge^6M5@`S} zjW| zjv9{H_!VVe!rIu~f0HR$bOBKV$=TA8z8W#>Zp-&eL47gg_(KC~+kkb*1DC9@4(h2IqLCVxf4k&y-am1+6NP} zX>!+GC);K;d!BmehTlPO_~;rAb6|hy!7*z|7c#k&DO?G5Gv^2NA~T|RC}yTwr=gZP zX9aZQk!?P-`!jDyix^ujYjLOl9V}U#o24Fi^{+=@8Z(QlG|GV*;m~*j>V7>Y zEMmahb?(4M0Y}*hE!GCT4g;Tj6TE#{AG;Us01e^DTXD)AwbVFYaX5P1AK51jS972; z0R4-B_%Ju!Y%;e2V(H~#_|adDE0^;r2PSSdon=qqrW_qje^V1d6^>awI(YpKpo|@&S2)>B+C?BB}?s2H{}oqk?j^+YK{jVDaRXLQfaHa9f^By5%}39L5Cr>zg0l z&MR!7o|TQ)q-KprWET%-ar!WlMHziGF1Tvd=!-Qz@MC@+aLnsqAOgBL#w@;rd&_f$ zrV+a+Q&p+{F3a44WqY)Vx`}y4heY&G7`@$OLgCKPEcB>jJV)?g7Nh;@@bTo1hK1d2 zsQgQu>BWqqa@5e!kydY814Mh@;?u2D^7N6NsS9iAw(9&@nqoCe~ zbS7=3?>l7kPB9SfBH=tL)ecYOnxw+p+NhA2s>9atm=0F1!WvOppkFE}G?2QN7+^?Ht3V(`}E9dlr&)f`pq^K({-gXyPU1%XQ zAx487%Rdn`uwKX4ElixVxPKN!jkq?n=%7rP_iVn!bo=Y#S8zfq%=x!ki+P`5(&G&W z(Ox?(zK=Q8!Oh zLEfRVs!YT3?VCrt$te$1qFmNPL5TXUe54nouH>5YLX;aV@>0*<_Pq%!B(Ueqz~}g! zj8ie#-gfap(k^5y$;nUS9Qi`zZrn_oK8>>xhF%hcAm0S1-Yz9c$IXcj$3$66(Ow&Y zPqCEJVy+aSDKQKdHnE#4sVkddNKfFhnKLoLT_!{LD!pJlY1i6&ks%Y6k}ja(!B4bA{)GwbV1X&d*LKIp~_Who^pWi2iNVd7zj#5b_x zz$vQrh#nbMRYtzr_j~|&72l!8tR#GWB(PIQF7Gmor=}HYH2Mj|%9e4Olq^?sCv@@f z0RIl+leFCYXTi;2Q@wnGDr_PL-Lxjbi%hoDY+p_Pm@qyjC9HzB2k2&hRVkS&s2Vbj z`-FQ}ZtH_X*h89MavrX6#iV>WV=1cHNGfabH5uP)!&oKTIt*62VzAcoLKcsCTD(lm zMI+R1<2z#$cB|Qd&*_}Zly~!muzT6nihByZ|aLr`3;(Mc?IRyIQOIM0AZ#bmu!eauJq8Tf5~ zjl`%8&Xp87({hF4H|g_rR@5}c=}|}r9Fab!x-dSkoCajSt?w^I1{PT}B#j^KbDBq{ zvV4q~UU)}66MUrE0++2eB>XO#_ygAD`b-%Go6TNFr8!Ir2ikWV+3+-{nBc@;LwB8u z@0!N4wpL3UJRoBUia#aC7)uGgGv98z$uk)ZPc$cw78!Y9&R?d8BqbQcc&UODYBTLfaEp>W5U6a5VtP%ocnSk zjn`w)d(wZ>dm-LVevh@A>HQEGh4$OyaHJ58c$^n z#o*6OKHfs0<}-=sU(kbH=gQo#5cRirS%h1wsC&C2qx>)!``CC8N>E$a01PrIu?C;= ze4~}fZUqDhlh0%hZLrulb|P&6#JL&mrB@>j`!|+a6_3$vH2}LFuY@^QJVpl3g907* zRgTyO$Ul>X^IiXsuU$kv9O!%_ITB`nH*wSHvJv0=W@zK-TTZ9U(<99KE)vfsj-Ii{Ve{9(GVi2Wy8hW95tT&5m2tw;CC zRG0VeK2DmSJAQxk;fU_aUr0X}4o_(!Fm)JAGCXgwRY?AUkkA3X&o0Y76?ItT2wXs$ z=NRLRlVZI_=PonnFK-nQ;Nno_!vKom8wRZVB}BMJws=tEd7Co`oaeko^dFOei%dB z)NnMZBkFYoS@)+~I_12&q(!l&KGyDz^9DI328_*rs|{dP;Wls(vl;))#iXm=H0Sok zqLA^HCsC*8t^S!CRHqtWfQN${1R>fg?AyVjz`@M2)sQcw7sWH2^z?IsTRSAmCzB`r z!Q&mBeM%zQL5?BO3qd2CToYqSGQXm~Bx{NaDbl|IPqt~v#I!gh%Ho--UqTD`Hk971 zHJ1IPB}N8EUeKpMy!Av`P(E=(GyZ}uvXisDlHP)OiLDjcoXd@xB?vuhWwt~38L#tU zdC+aAY2VqurV*@2DvV}sb#8dMM|Loe-Tm}P!ouRp;8wmYW@9lDL#8fIlX>+@sEml^ zhODjpZ2DYiW1y`$s}^+cbrV$aOdvV8jq*VQoz9`|XjFtIz4YC-G(Vw>Wu2&?BuO_# z_$8x>_~GR2tT{`TBFE2Xrlr1{FNVP~mN9c<;!BQ|WJuYOiE$c7D{X!zmjmSKp7vs( zaYRW-AK&vC{quMy!Yvo|@LAP#(~%QUxGPI!S(ihN?q#afMQyk=nAP*P3Rx35lEAEq z0ut*qRe&@s-MVm=>!Z~yGmf)N zG?)jbxqsPGZ`JLWw0N7{JKFMK+V?#woXB@7{EF0)=|Vb)f>R4MQHlPF*r*`344gWV zVf^V~9seXLKiJdDIh1~p`+oX6i6T$Dn^;#lCMP6^-A+mJW5eA!oiF)J@Xpg>DXIR= zHjTee9|9te9lrr#$R2hZt7_Ki9{$+#j92ira~r!&v>TsyCPrDu{VklJTbT$=Ja6P@ zP8IKM-uvp?!HfZ~B$HQ5uTah2HaZCmX#J3^Nfj&ny~u-cas%V@%|O$-Ba5eu*^B<` z>5j2YsS;Fx&cW@5VTg_m?%z70gpWOA1ZM5G%)^~!zA~1(3jqm)J!kJfl$AOmM?D;QZJqBu1Q(2c0<;_X5`Dc$Zj>~PY*;rh&U+h%SUm=fI|;tjeOOs3J>9CT!hKWJvia&)zVVA1zu z5{&n(Zg`R2x#FWmUR&(C%VQ-N^>s>;87ipW(a_^PA_dRMpMMh6Z4&Pf@BA#XJbC;2 zgpre3C;MZ&Kk7%{`f%~U@ZB*?iN&57vMPeARe(ZK=5nl4QTT<`oC?zSMW*{z0a^ho z?z3jOQHXeP<3agAxP0tf^r4+kPp^anWespZr+NaUzYi%Hv|(Iq{?1tQu=23Z` z?cc@~3on!UbhcJRy=-z3AhSET5LR*p5ZP~PVg1p!1NmYLp1C!v=Wo$YSU#g4e;b5u zyUJ5Sa0kJxP2^Q%1558n3MW6^r(HL~``k^WpL7sEjlSbXAcI514SoQYS>G3k35~S4 zz9^&H^`cAiCnCS-g}_)hf*S&)n(HMGdh6y}6UC_@gI}>~xUaNoZ8Q4Bvfpi-ku1c; z+Ea*78YEhY>$@JzFdEJnpRm*^pylVK$W$k>ly0C;jiP0=hgBId$2SnIrk^29Z{g`OM_EBW^Pg_ zflK$BKDjBEVPgU9WV^iihjFhqr;r~v4$FT%B`le*l?6WO2QtjlGRbtsVFJiFE#^{Zy1zdCroy5h^Q=SM`Nv9Q7g$e(LPpr^EO9rt*P=cT6h33BYF zA%cCzhto;vS*NIbO|)uIZ`S&bpp)@aT~d>vvOH5-6V}uK@uBUcL-)@?rH`F{I}ykw z7e{zS?v@Ty%)jR{W*qMNPYF-du;^0ku;`M?=HB&76V9LBJeii2T>qLic^s48T0YNB z_cf1*kv5)n3exS&x=-sG^PMar;P|ulU}{}4lWrh0?0OrO<9Ls-+WPnF8)xv&9dPiz z^o30Up6Q(!l7y8Dkg9@d`w^vPxSy2E4QrB zxBN8XOZhEylbmlCVpVktKI8_T(DO~DT+f6cV`N`Qrz0&Nz~fi@gN$#+l5;>w3>(9_kO;T^}uS*sb}G0b6)*^&VJAh?Kgh zTp>mQq`;A12Q%H%&;v zo%yU*S-kk37^7%&`c!=g^2iX*EORO@co`hX?3zt`-NcAk5$pP7lJo>ai7{CkF9op4 zP{ub(MCvo90JaP^$>Cj!GMrrx_du*r|J(O3%qo045kb+41NN3%X-@#t!YHZ4#2lUY zTjp=H@6dJ2^JBLqFz>=r-On_8HJFEuFglzwr{9L7rCUk;b7ICPF;w4~!k${-t?;!JH` zbza5om2pGdvyoj9kHvUf?MFvK&yOw4QI3w!H_1nX*0&eB8EzCywUUa-RgH)xJ;_+- z3Q1O$#eEzW>z!NpK7YL4;d`%GXD+BjiR2!FX$(ioJp!#O5)GMeJ#McvAVW4pU1al3 zRF~ZIgeJ=|&$wd%9w>cR=6k(w18*0i6rbCU&k(1yi^jK8I?H|cPgC+6=5BNsggT84 zdaIBP&7j&!mpZAyeTAqI$m$|3BX?kYq!nY7qwu;skH^jTa|-^%eFh+(#YK#FKz zPDq~L7c1%wtRQO+>Gvt(?b!vf%4W03)X$|5fRpEyuR(pS-x^)Q9NgzsAjwH)(T8u- zXlK^Q(%F1yWzzxND6fZ>=j&%Fff&5lqO26>IrERnqKwXZpN$t`}j(0_j z_6K%+E@VTDqW*c9uSPJY#I>Ru1}BtxR=`0Y1YY&^mzuo|&L@cx1jeo$WX%H=bB`cLp<6 z4xh>l#QoqaeydPXnw{p^wO0lzGBnwJ#Pf;?=ZxE$rfkcZnK(xTPMq1^Ct=`YWk9Us z3Wx?I_BS+f`dmeZ!BoJi&KY~!50I)LKy5H3rxjgf zqySp7>mlqGkcij;8wu5(y)Wt*x4nPCVI^qcwlo4Qc&P*6=+4T{hs<7qdVEL1fyyxM zA?+SG{BA1`=NQS>ODlASXfWpz*vnN@B4Gd_21((UFADeVb*nDcZs2z!(R3Hlo!zRH9dHR|E6G7ZA7s6yMhWJE5N9^;C0Uma{;0neT(Cg2M!5i?R^TW?{>urngnOHx}GAlks^dFg`Q$PY5^j}rusnEp&! z2HL1nv7byd$5{p>N~X14QfC99O(apMPzfq~=?eo@=KlTz8rxXI4Xd6h%S zuHMV^Ek@`!%oIG4YpW7*W)syg`MOK@Q5Z`XJWlFN4 z=~kv-gcmbkrm}9gDQi)odGx1RCbAZLIRZ&UgYCTb?1NXs{JPTG&c|7?-H zT$faZ$Vv_NGJW1Dc_g)gX8S}5{ylfR+L&RQ7Kx>p2#=ogj(4$}=^ z(%m|s5X~V8QW<4JxVHs_xSpOs6nA)C?38W3U;%7mW3NvEc|4uA#cu}lU&eoblW80c zSmj^eFkez%QeM(HeJ;93#nT4P(|>%q&jmU{j@8@M1k^n}dsSd5$%uhwj6Pl~lLDEm z&DIt2_;sTeYrWP#FdA^;->uNNo!_1o7k8q^v!NdI`SuRe20IZjDjP`W%&d!|*`eF< z`iVE`loY^y5jIJ{-1aq|Fa4G(E*mAM_rOaOc&N0-E?uBTh}l0shHy}gNp zZ8SuT2LXk~KT{tAyfD>7Jm$J~zPb8jxPx&0$;9IB6}iyj%v{|E!VC;9FQLg-lRsJF z6^OZ}bZ{FyfnzEWbLnpQ0#@_igg7`1r{DJ!i&MnCL}OL{>yXm(LgMg#@mKss z@yT^I@+AaH6Mlv1G87A*;^sb!>d9o!w7VE92M^I@rmOx_JD$iscA$b-qo~TwGOcK{ zE0@i)FU}{-rvxn5yil{DwBl8biA*R@VDB)bqcV513U{UCVCDOzVHw;9et8%+esa$A z*zmYcTkXEhj+n|^W4G?9yk~#tMSD41ym}tgG7dTjE22Z2#d>>vHZ$rlT-8lgwyMUy z7L05$WbGJ)l7LY0pdEZ>KGZ7?nXOvhk;Zx;5xtYKkZw+n2ojw{~dL+mH75r`_i zkZqrEyyo^2M6tjje<%fCwyER9v?4W`fSa()O#x;y<}JRywyRSHZ$xyFHw(%^6S3FW z>$smZ)4rg3WU?wqXsJ!4;@r1TV5NJU`6WRTaB!DfR+pk z|8gkv2jCR2*CF)12o+ujf>-(l3^S-*CYiwg|9$8b5Ji`&zPtL4u{iN+4D{nfk3p{1 zux+-~WaRB@a#c4x`c5nSpu76hgVi8vUd(71Z|Y@62Hcv)O2P9l!m;I-aZausYoHSV z2qzeV{5cD1^!ckQW(G-YkqVQ(f(A1$%X^=_bz;$nCGL|x;|fQo_ws_-tmk@1xTRae zFnd%QVZ{a-=Vm^{P$IlK_w0N&h?}P#llP~WnXUX1>Qrk!#(LAf%}>85M^?C3!p8iO z63;yRajL{S0N|%4NQuagg0cDr<(6{df{xX#u)@a`BVk)5t*q@ddCPt=DjoIrT3MeL zU?djL%R9YN#Kau5^p(~Q8?#TT5sx5~0vBjF=wJ8CRWc~TOh#ko+?juruLO}?2Zl|k zE@5a9I@jyRyD3LY;%*-(=gC4p$xQt|Pg3@OS_t>D)Q>MSv0IZ;>hUmSNi5D>i>#e- zpc7_m>MP`Vk&R@8pbNbt@kbSUCqFr}^`cd^5D5Uj0{$x#p@7PdM&Eg}YFYN-NHWyhjMKSaM<}L(07O@sl(eNqVA<3%G1(Qd!bkBreK%<2tVpt;_)ib&KQsA;hb&#Cd?d?w0~#h|q`2!F6%2`}GQ0=16n`6^PCn!55R)$FA+~5B*OV@5$q?maa!Lj3>c(!{6 z{7LhUn)|EzhdL7r)6z=IvQmeIRxh-nQ5< z7C`bf!cq_;ZcnItY`6Y?!e_OZTr!`HYKe)bnw(h(xm%m(1xyAJ$0p{8TYz zJKZ?V+;{bIzUN0pb>nmWgA{Y_9_j{w!=Ox12_GL%3>AqizSbuz0)MMUsIJ^Dx5`0u z-DLXpk+|p%9M+W(ZW*N5-2s`bs~X^_rmA-j4OPyayUV&BQMzS+_MSLSzNPmhnR0ZP zZBZ#9{byMI8KqcJxY?v0I)~)Voe~_Zjxt{l$)Ym;+!^+m?_`U0RM~8cy{FkVo7vSe z^}F+U%viGu+A+6{Z@@~Xq@vRvM{p3W16}K@Vm<`ibqYxb66`CvZ_ZA{wgq#=LSU++ zngv6A>gxjuLc=;LNL*1mo(J`Ze_aDkNAD-i363l3hF;}u@Xw(zXP6!aqHwmlWGRt3 z;>DErMXdpu%vH?pJXzNg#-78|&YV}hE_Dad^K-B&=CsaDeUr|+YjpFe)XpC(w+oYO z<>?M4C394}4(gsAl!O-WPN_w!$71a-oFffwx#KiyO|kcJ7FDr`o0^hcTXmHsV zK$5LnI**|g^Sb?42U^45inpg^%vZQL)7EI_Q|Y^oN=A*R!i1ojW+6)x);5c~3`5G} zfA^Mxb&&#Zl&t>PU#LW~f!NdO3g;uWyb;6&?IuKu=cn=Nm;UuI34I~;vy6zDy^BjX z{#>OzMK$VgH@*?y%r8%~pq{b#%Z(dX`HUo<+WV$~^D@nEM59j0x6&Sr$yt9owq6#d z(^T$kXXl@lILp}eQ-6w}=gycwJ~ac?F#ep6%EcX4;aJs+UB=b)KC zqW#Z9^UsG2hx&$!_m#ZXo=R%Ooq5b^nUOeJCi)GQ)EhGPsE|Hlby}unt56|rUK%O; zDOK8~MKX95%AmM;H~)GMd?9Hpp2;U86GwA6P=-eH5&GR@I5HE?lo1ddCtRNQfdCdr;& z?TysoSoxerOGF6=+eJ)iplk|l2alk*zFD`2p+&K*gm&4^b$*Q{3hhO&44-Qa4UvC& zs}jePys<<-QLDnHgX)>-h39oW!Q-T823n+$#60Llge*k-;{Wo1cwuA)FYa1WYv>e@KofukDUQ;GGj&*gv5rSib% zlltFJ;D23*1p=0TWzF*L3x5AD(BG zp0Q|hL%vkSP3l^Us`Snhx2Q%@V1JvwJ781e#8Hs+vLZV2!JQIPr3lSKCMp0Hi~t;z z>s6u1vBT!gI}Z+(5mg$34qrY%&`Sa9OcU6t zGM?6yI_2|^))Y&=q>ss{p-!sq6gyFD>$BhP?f%xB!6=akAC|Xl%jE=p5+Ensvg@jqrj7WHe?((hR5;PSsf3yDpIYN_FFG3*ck8WL9y>;3 z->~tbNBC;ih;_Ue%R|Th80TSGg7Cv=#T{`M*amh>DSsO&Wv5ue-`nh$#7h3g2 z7}+LiFNr33|Ie2vRdbHOT0(Xd5`T)tCXsjYbL|Mm)hQI)PKuUdPu7?(6wkYmxtdfpD~w%d1AcxbRC z+PsFDRi#y#ynm?{x?l6l;zz(iI*QX0~n_wUsuoY&|V;WT0mgHefi0=2W? zrA!!i+^O5rZ&NDOEbVI5MP-zs%c+>d`hp)Eo+ItW;Rf2uGMkMDhnpZ+qIr{(hwdZm z;)M|}C%uM*f*9p&$?2H+L-kwEW3quxH8&fjejZJl13Z5C*bbuY$EetIV0rx?ON;^d zlixvYSL*wA>DbYW4U5Bakp1eC#GJH!$&LD;AI+g#IaOt6)x7h<^lfGL3KRDC&Z)Ax z4`npPk`g_}>rivSKHiM~& zw-;xRiXL-pI|QV+cOj!ZRVdqVzamVM1UzaD=Pu(&9xrqNBj%XrWBM@HE2HfkS;JC2%qQVG%L*c2x z(AaOpbo4maSVx1-S<$RP)OHa@d~s_d+A=eA63Foej85Ty3#XLrOz84Msy;eYr}%c+rmJqoLGp4wd$di@`Q)R zzecC?Mg(paFZblGY_m)HQH|YdGE&_6B6U{42} z%pHEd%UO^T<1?8}=`o8+#LFT*W>yJUn!UY_@3}HZ8Fzk4w-4HQ&doYI?i)1hyFM`D zr{j)dvoHFZa-T4Mt=#92*w9~+{9vaF>veNgH!RRRi(D5;>lF2`!6Fg8WJdsZIb=5`5^l<*XG{IU(Sd>Hf1S|Q&3=`mC>7!i4Z@torxE>XT5B^6qrD4#eNIN^`rUQ4?^Mv zr&9JP6tgs>w@JQojy$Y zw2O;Qy?OEx-A^lBe*iXZQ-LPFc^RL2g;Omh-(rCnJBKw>)@isry)*KGh%VSrSTTf9 zWPSp)O)qD?U5-PG?UBBK<7_>^(Htj$p(3UA^J(Xm4oCfa#%*u-Pdku~gRR{J^ps%I zN5YxeD(qF)w}$Blmt8?N@&~doiN$MkZYcjB6=F;8r)1yto~U&IN)j}^-<8A)lAGT! zyX>3#s1nY{{Oe%iLMGKWH+czGRubPJmGFe6rv2=G%wt*>ZRsR@c4=ZR^6o>iz@qwg z$Hb`r%-FXbu1fkM!D`HEdKat_DwaabE+?)TvAAj~Q^aAJa>6NTX*E?TUW^2HI8-E< zGSpF?4?A;6miN4<>#Pa=ZLymE9@&+yEsWxpBYx@}eDPJiAg*}rX?*40+x9%P&C z!z^@~)>byZ6G89>4yimR|Gj4KV-V2TJ54hs6e`Ybc`z&weK;2Cb zk3!T5B*2Ee^f);@Zx{fvPb8q_AyUTGWA6B>kv^{Uuuv>zcAGX-@OG@b7 z@1+`Nt3cRKfLjQNDLH8$JwMn7pzy?efaw~mX+)!Er}smNz@oWn$HYwdP8#9P{e*V# z!QAUkgAgkX4SAP4w|xF*g`3=A;hyIQQiJ(zob97_{KRxNMHgXi-efSe%)C3sTvT_AOy?qIovSTR?sjdfbf z4^+~G#cVpvV%H^McieQn2Bh1g1LWKEzd1QKKIgaWoTl*Kr$}O)}0U zpRHL6Zdb^KbM#5lDU0-^v!Rx6-BH^4ZV*T79h6rbOx0|;P_;cv?Ib>2ed;!lca+w;Us+L{X zFTpFI0h#swQ{4Ecf%O*Pl~PlbBK|c0b&kzHigK!|LE|xPk^1K!9I=x%>8_o|Oq~^` zlqGqvQIPajX30?(t6-hKytcU)ep^yY6fxb@7A)RSGjE9t?AOK?=TSKhE#JnaAPjV2 zW35ktqb=l3J(Q+;(bTMI=)OfZQhjFEl&LoW@9H>A!SjEzYJm^Ff^kNCCj%3=oWjsY z0q(cca84|j%?ISm7XNkec1Cnr94yIzu(fKpLrvsRr><=4 zyhfF_i{s*lo?qrR={-Tl7+7mRaZL>zdYlb^7>}mCLBj&-un3bzPHlmQ{m|fJB*~^v45J*V8U+ zJE*#8;*U+=H}EIDq)|AF*DpK<9#!O+1DBS2ZH(*(z+>o_o105QSPP_}bgt9!)ohAW zU;-wR`O`wxrv4qvc7a2H5hnpPrNwBx(71_D3GIc(qa7ax`aGetXx+PCJREqC?f#}t zyunUISRUjIc1itVx~X3J;2T3c?w|jKh@ZjjEBL)6Op;F48-Wf?y}Q|v&cUOm5M>FC z?T#czs?iGi4C&-t^6FVPU7_?)#y2f7AA+pj?(rn>HVlJh+N0*2oMOe0Pd}|#34d9N zGUT0SK;_owvkJ^y#0gHzZ*}c-)w4dA0;ko#2BaPtkYZyokizCd>4^l5WwKw;Rq=O+ zzwftYGy}38d&-`A2Rc+((1d~=LlRzC#3w+s2ELUOpzXrzIA9*(F|6DI>E3G$CNO5v zXq-beZCFpcN&t020wD2_Yjgnex`Rb9#9?yAlYkH(X1hV=VKJ~s_j)XJFlyy{iICpy zZt%fEsH+S1g9CQvY9aopLk}dF@c*#)mR)fzZM1d>!97TDLLj(na6*va!Cf17cM0wg zAXww>?(TGOcZcBa4rj67ckeIH`3dJ6Fc_oPs;*V5>b~c^<{Z+k$0?&G?8{K2QSDGi zPvPT_1o)1DkF+!qTjD0tV36#g)b5|a!j4OO%z&RwH{=^h^cT9)d_=okZ~U8oZYOmN zUHl{h{+y;i)UhZ-WzoG;&*Ut_*U~0T*hxawK4UPR{xcuSmdE#r?_ivS#|n^k%!ECg zWbH%kxqeUHg<3zN5RF>5W$%amKc|H{t zb}Yx#f5bPygE#nfs*rw`c|XL!Vp3>ewHhId90F|60pQtuV|!XODl0Bo6zCdzmOv z<>Lm+XfNQazwAWd5&LEl^frOA%UzeOdo_m;l_R0CXRR)dZLkr~x^jZAq^K4V$Ekk! za^Wz~w87*0&ILGCgCe)O^@KbL;$>BXLBOz{cU(|BoQphQr?BWT$4jgJjOUZyMWieu zObGpZ!y0N8KYX>sT`1TXJI8qQY}a~XxX3VGgua#8+`RY>q4Con0K*XhG^hztP*8UF z_L#8^li;~r&kYpB>#(LZ#OyA27?E6MBTwZCQG)mLXx<6^1C3A_|hpyulI6}|D39*lM{xMaR z<6(P~(D2Bxw30VkT23Z`TV|j6qPs&zgPaH-(}9VIkWjAUfz3gBjx3;?IQtv*_0P?Lj@Kf3AO(Gfe0cbdn!xPt0V(?Quc5Qyyl{$5H% zZU09f`)lf_0(!v|A&=7#xd=tF9%JjJ{39TVpclWIi~eD5he`-E;K;4APommcu=S2? zaHHoh#?H6V5~n5ac_O<|Q9f2##*Sw__YO+us(scAE&4<(Z8F^E7lQ4CpWg*;g}u(% z5?oyuwy^JW70mf?od$==Jl5t~vE7R3G)uhpr#~*L2X_LDqAis!N2Jb*bqcTRs z&s4yUH?0^`P8BiZapX%|v2`mWg(|}oXb~i0X@6G4^ts0ng_2y#0dL_lX5T=6dW;I(9S zG$(Jy4G3I>|}LiRHXDPkdQ7Sk%#i~fkUqd3iW#zqfQ z6~-nm(q2_oZ-30by>w0~nZw+J*}sKp-}#&7XjuU^0*89%L82vc5@p&kEOR;SwokxP zS{lsFsZ7%LFzaZJ)^Q<#O9WkrV9=edHUV1QM%{Ml8e|4fJd-8L` z%B-D1k8Tt-en4|??O*+Q-GoE9%fnK`)*oWS8F@(poM=oFRacd<{46S^#{%&3SZ6JU zdxH;-t@eNey_;;<8T8eff-GMEm;LtIt8FSy|IRgFTB8sn9Z1nD(Q2OAZ3HCNkFQ4c zI3*nb@rJeskp;B9q9k@9-_0cRKOOm@@tZhMI=(PZO>Qb$%b@lpM#t1S6W;}73^W+rKUp)sta`*Q6TF33A;ex1z2((bK=~8@)yYDCF|RACdH_>}wh(vQUAf%#lsi0G)|;l1KGY+rvkR=Y zlc>AJ3AnI!q_o%%9m^DjP-@oy7+v~5=w_lV${zNa;{dwzey6~O`@}LyQem@(_ki+x z(~B*OC4SdLx)16Oe=}mrL~0->Fvm5%QhJ}W%dDJ;h=`)Df2RQEH3UeZC&>1PvYzLG z#;O?`B_?;_=k}Y{6Fd}2OXm@;oi)I5UL9g;7x#W&heB9>@%#)33nTi+y_C$>U$sFG z`C2OOce2qNcD9b@J=Y^xh=Hd7_>iTp>lUq8)$Na$8gIvf_zmvy@hGK5)vLc;3V5Jd z^wDL9%>A%en~?qiQ2X>9}z*m-8jX%lHOPQc*V9y{48k9CLdXQ^b!mzLULjl;<41lqt8G#Tk2g>SLC!W73vGX zkXeSG{1$|Y7cDmaCu0|QRawx?we3k;o014ZFMNnFq*Am0I;5X-*d4C-p3 zc>&s&$6lSs06fm#vsXbPC@VME@MHW}naG#&=l$~VQz^LKqmGWB2yNOPXT5o?9z}55 z4#ZVS^r7RPIFlO85$I%#m2a=$OTJ)28L6$fQy#8ZDN^nkk$!NOTvw&0w7opZM%Ff! z%}TE3xh>?Xm&37$9BO~7!@N+lbTmlG2cvPBJM9uY#Sd2{Q-@5nB`l^z(FkrbwdA9V?5GEcW3xyjw?Xt8FcML zQi73XSA#H{D?QU&8n``YjQa8h*f!`b+TQYgP2o6;P+jrjn;~kfH4)PaH;c*Tn804} zDxzt~W$M9+LH!YWXK!DE(&koO@@Huq@Ae)^pzBS7IzALDZ7VU!eKzzrF^ou&p%bqt z633OMD*UzTXmbK;+7mRs*yU&Nz!>+v!nb`VQSd=^trG2tDYI7wan5yiNE|pE>MMj- z!n0R!bts8dT4a_?EHbf2SlK1l^!NRgkEFr5Grx(~69BHVSjf3Hx3=b-_Aya><%&dY z4JHtLqsL@&7ILZ$2Pv5qD!l;96K-}1YZ`>ad&xvIGGQSWN{Zs=#Hj?)-D`~D zqm;BHQGXkk5!kiSfD$_EFx_WjzS%q}|9TSNmdpzvtqzI{AfVjM=1zzrQ5U^vivWD{t;& zPZEUSnc-^*YC*=v`QipS$C5MPsiY|*w#11`ZoRH|*$Ac*hFw|Eiy13_?U#-TR&N9E zp7>5&qe9{)s0NiN)ue*%k6yFy#v8(!&mD0{HU@qJ*=%^%hx2}`Psh%;08~T(^k>UO zbuB1Q4XjegUigjEV(#Z_B%6_UowOg_&AROu^;rB%_Hx&VkR*BYfA|jK`Qd7j{*Xc3 zZTk8p-}INq9SV%t`-kmh>pou?q#Snpo?}Udx4NA?=ES_i^uZ*2Y`-&-=Eg9RSv*5% z$T)so4ra{caMih63z@q?7q;ITBG)iG`Y_8aGg-_}JIb5Sz+tM}clk@03{&|&I{`Ql zn>=K*Vet2K9<2f4+C7da+^b@Nj~=ZsgbpC>5$I0?%*h@NTzC2L~bFgUgFB~|A% z>+Q(MRr_er2_?G{>*7#1fC?X@e$}fP!HdNmm}>ai)Tr|m4+diwHIp)|zQ5I?ErN_x zjGU?%yL3MXY$q9~nbNGV{Jam-dF(RKO0yfF?rV|UWavFoGfoX?ze{dsR?A^qXTiM# zY{_}-e^^Y!<%Tr!@W=Mp8ozT{c!{4G_?c zZ?b54Hu6vNdiR9(r1yhYIr6eE>TR(#&YXK$bClU<%WA9pY8n&8;RyZuZnOe(7;bH-`>4+}FIaA=J2r(4>6rEGpOJ`TXa}r222$|H z_&Ws@$H3mPICKS&x>CY0H zI@>rxjl;orKTIBaIW~6WQ*RA;l(p@*jR*sna`oPq0fyJ>8{$4S1?7wtji6r33n`^} zB*12qTt4O0f6AqNlNo5>tIy%WsLw){P-?)gM#0Jw65|6Y_dGH;nnni$(PvxO3RiKR z-^}Jj!f^10zk3dLPz@JKJ?C7LmFP#>k6avzr4q=Ao;tPGH$I$S!#AHQKW%(i4bHZZrj;EcE81)la~ySLB#^V9p5_>+W1 zH&S`AJHyI^OLpFMG4hE;r*$jQ2xFt0z*3~Yb@A*tvqZSCXkm!{InTxl2*r7ki(PR_ z1d$F^zf{s0VF>tzObA7AnZ}UNmuj=IyA2n8cE9$oSP#%namAq>ickdS`rTKt*1!Qa za(FTKwX0iZt_I{u0%dTHIliH326omD^|#UuE;D8hfla4f5Lm!o2r``mwj}b#fDkVVkdCu>4fII$iM>3Zym+ZDC2VHQ7|^k+dGnu5#U{?s z#{T)v8=Lphr4u_C?UMBI{Gy^8Ovc;?&-PY9`Ar-5+U<=0OwO0R70v?o#fZ#!Y{ODO zFs{k0pl&bKIVnzNp%D8)dRQA7*uM1L@3;d;4T_qY-=n_5e)=jdBtlwR@V#zpJ|ALz z!$|kLYc~dD@b|v(a^@7S>;>X?&Dre0 zfMwY!I%tU?Rs$Oh55+jeXPGl$TZrY7VCCJbC+ZOLSi8%4VJp zzODkZ?S}Act%G$V38Xtsiuhd_G3$rpJ2RFNiNO*%W3M@WzoNuutj!3A?YSl;X$37Jcm95D%ll9xi_DFkJ9Bu_Zp_o_i&IQj!>Lv&|M^GNSNhiaXFnuAXGMN z%?jS6<$P8z?UDbi#p9Fa88RR+)S>CbYEext-cm8Hk^5z%Yu{M;UK4vobbIPex%2Ib zm$&|WkJ6LM1Y-%Apslq1Y{4F>X~DC;J^# zm-Wu2?WBSW*fHfnZX*rJ52ICUQj;JuG=+I;hPsBf3um7C)77`il{T)47h9az@%# zyUfP!cU*uL5PQ)H%GEZ?h>i29vs&gJ`gky;#gey*NQtLRmNw%AxS&T84IYjk=(B>* z%+h-1e6jWN(-4YXQ4hOEq4?Y}(?5RltU%+3mg0j>bnjh@NwgHqq0HnGQ|v>ZMzP*I z!u0qCHPlDJz-hXkl;3Q#`vZ4)xU(wavys>sHa}C18Ny`4EvJ#pMWYFVl$fy#qmbV; zZ@`}fQEzCOB*58_oVV%ID!ZZja`qeMv%b?3xemo9doi2rs`lNwp zI-9H@|f(_zu_5PSYJVR$$+(E;;cBJY-?zwL$)as((9ux|!ut}Ob_bRatfI%Nyc z04RuXQ62Qbg%A2N7l0dEmk9NSh=9f*5gF;>hdD(;*_kTw1&>Y`YN;TFKdv*Z8oqdv zbRr_d!&m11LorSp4OlvAT!a7u7@`Cc+oA&|zjJ`w)WDp!V$+Qxx;B1zUsvBctVDw4 zi&ak;OUAAC6yzJdtzyh2^E`rB7rD0ig^EQ1#yHh=&Cl|@^9@ZzcS*1$X$m6Z=yb74 z@+JjV1Lv|sZ1HA+>!a6Hsb)kTXB%ARPP)*EwHI=;fP0-)?GH9dwY)&YO^<&H zM-Jgvwa(j;K4d$!mug5{Pe(u!m>?XZ5{aN@r--tNP3yN=o|FlHED{l=R8bFaTO~=8 zMt32{2}-$NR(svb`?5H?qQC6#^BUp3xBJVKU|%=BuuoJ(r@^q_YKa>>ZqUv6d5A2vTdfo?gZqC?-K5I z4dt13w=G&Avw`;&TF1R&e^L9R@6}LjIrqW_$=j>%R zU0J+S;H5P6*Z^nTRRa;VzGoAgH z<7)ygSQw`TU|3QS2-VRZPVfCO;+gvT&8pUkRj(`&O8egm`cQln>GfuYtu^w4)6Qle zw0>joJ})%~5F7CeA2GEk6Y&BpMEIK7dVQHe#9e95pE{d&SnP|S!K*Mo!TmkE*qKa6NA@KI^OMV7XzL9bUvpGB86)gw6($c+Dy5=cxoMSIgy=JVU3-Q z$<6TeCwJy^nNV}Bd7)P3S8vP-mMEsUMS^*36F=2_GvQU|KNqGoHItNSln| zJ}q*PdL7z~2XT1drEl@8XaNVYurl{SBVp=^hUY-Z1V5|*RM{AXG!{gL&~IgdxAu}iFSpYcihm~ znvp=V?-&~huXZ%Uee#L>Iu^t*PWUqgBXN0{@a*^TDvV0S6+`)M**do9 zVl&n1+&K@4Wj}SybFU_v9gz{xu$#$|-|hr-4wy`dRKI)mC0$#8Zl@YRWprI z0^v;ptSTV%KuR$ujnGtn%Wr!+jInKwoDDcjUnH;gyf*&4oI)>hLItX{#LTNkfj6-2 zxIWNJQBovc&D7FTDpAUe^kB5Bd_5|p_pEZtpjwrfr*^y!;Ab)46*bDxS zukZqNM^G@`*p}>)FhY4?9}*q=y#Vqo_9Sfj&iU`5B>?{LLE9y>kVaDPd$jnvs9ZcM zARU~nHJ`=*DmmWh_2fooLLGd8{p+>)sT7_vAjsCtf7$_^$n98E_#@fsIfYJkNA7)5 z*^m*3eSCn6$(ziGQPP&J&n^^Ffz~s;7pF3*rYua-Nc<$c0G2G31M{qG)5x76b}yB? zJJDFuXY+{XZt>JO&^l><$K$@g&am*iEpjd}we4}qnk9|zhJt+2dXr)t@;^=?FjdD$ zs&YuZ1?N!^Yg+X*j{Xol-ryUPsDVgSd*lr9+UbCpJPp?dyyV!~RIu?y>zvK$mh^F|@`D1klQdVUstYV&C+O8sWE=V+qg z_q4ee!sn9!5|HH1NQ&seb#T#BQ;AY2yE9^8ut7u0rn&Y7K4wm~TwH(jl%{6gIh??) z5A$f5T6N#9D88aB*A`Yb(rae`bLtVGb(`0aUXj$|_(ih~+BN9sIQFIIHyv=hCaWD9leQ3ZoF)SJwF%sInS97HB;FvfCP*zWbv? zKAgzJDYXH4riB*MXqFExiUU&BWbyDx_nZc^K={H!_nxbw*$EoLp=9>=(`Y*s5EEmu zG8F`ZeCoq>zchJAzqF=Gw(9yn1X4}WHFVKmO7>CDvMkLHmYpXxU1PPP1kGm_g^+4f#PIRFkI4`r> zR{WBxWhlP=_H(nQ&0{a=`Mt(6<*G6EH{EwW!kBc|T-Ic`AUTdX;7=KQ)TQIvR-|Qj z4FxTPnBYs~6JO9c(Q)Tw5QnbH4O9#0?trP-6(49N_}b^C1{$MUcAWXhC=^J&t~^a% z*a>i%KktF=L5LWM=ahlKgvCI{XYc379Rcg`Vk}!^D|yXvHc8uB;4BAd1yJz5nUd$O zUjv{Trn0tsGfd5#_1}XUujp%|`N8fWw9Qw(1A-CD$AJtozxbC+*%yNzngpu5S4QoE zE(rj6z+>00dwPX1Q&34jGq4JmH|^7CdfjcgjzYsQ?D#;0ljQoGJ5wbAYou9OS3s&wAFA6= zEeowG^Y-5&VbZXkt#GVHGkW(9i-{R``4Me%cF7=dLOBO9)C@*9gNnS`hz25Y?=@G{ z@nLtiSxWjLp{(b?yZyHFxbnn- z!l_?uL9eU^R`E!gs&yb0NxC9N{RCk9;_zQ)qT$hRzeB=P{D=6hVbuupitjOZpp9kt zr@vkrAE>GPka-thUM&qvsumptCF$krv6JeIUrqbcHkl~-v@ggv$ghSF{34IWGS|OG z{m`EwF%LPHjgWI_CX!-a>GKp%BlGBHU>e|{3V zl=(<*#}Lx{Q3zQD-mj%+xay_PLRuAhX$W);eTuQ{MhnogP(`O)+ouooY;11QYgNUx zh~=|gIpSV)+JtOAgLdyjuRgv%fQ0ucnUuFf5xb1zt@tf3%VvOd;VgDns6wIJyMsTg z$o*B3d?cZzTL{Tj0l2pwXY(f;%lS+GFKxG&@V%d0Y))ci9~>ExsMHPfYXV@NWNVK8M8eT!=hXDp z3Yz5hP1`GCWsVZ_9|ymFOnAsP5~vKoG5{UQe%tTn+cKvy=0imZ9&DNy_npF01kkbq zp#U_~N|~XM=jMG)%LU`QW$K&aOpMs)tHEFe^XEMofX&45F{@oKOUR|ABJYQ}%sV43 zWb=Ejkewqc3kr3sCwlZ_j$R)+e1jb=n4YeRs5baR_bwB8=DO26dbWC(N>_UUnUvtJ z%}OTQEVN=7Yau38?NYqR8&bjpc6EEThvN0x$6dse?zH24n;P%p5LZMwWJ0YZKy{4F zXGQE`_z}NrHm$uE*Wl&CHwx@4h<2o54)Ed&(6g#kor)Ye2i`RsiEd_o3zE7f7a^~v zOLyC+=Dl6>6U||E`Ex{d=yW)zM{|DajQHbt5Rvz_?-W#*>0%K7Ie|HIFK#e~PQB)j zB8+}6G1vg;x9Do;5G}09wbbTfOGxZ`tO{dygpa4N0#oLUl;dVard+%?r?dtoMG<={eB8;f~$? z4x$k_k(XqNo=}tXzmMjQC+m`^nYREZiP}1 z!a07fC411#CE6FT8m*+LA3aDEPg+VZx7V=(NIl;9viuOQn1o`s6F#1^+|)^mMPrSn znZod76j;}nt=RORCqB)mi_pOkYpc3VL`{Xd88 zNhI3!hg~{39p8gTbbj8e#S!;^>D90fugYe5lN8*)#gN**up+3><7N0qH}`FPTz8dj z>Xmv1Up+oth_(Bj7WE6x`N`J}*OmLmQ1Q0aE5bdVz@4bJ;2(51G`u)1r|SGJB|Vir zM^ySw{@Fw3bWh_(k8Xqfgu7c$D#4d*aQHw6pnqGXECcIuy8GlTDT6`>X|fsrx-}sn?BsI-A#o(B8($kISa%XFtHI%VxvTwgW(W z0JME=RYP&}GzAfeylr(}iyb6KHF2r+@R8HWz$=|!O}Mp5kTDPZRsom8-io<6=Fs{6 z-44!?B|~T?dy)yBbSC?qyOetMgle&M0e)$J9AO$?3o&$MS;|dqqOa+lo|^Urmw*)n zC_8wCBtnl1?9Nj123NO}&tE1!gA=(-FIqi2^v&l$FF=8WS}Ow8 zH^7JNAkSn+Vzm=2{5)ha2yp3>_xWXBMtViN>C$)JfAko}$QvQCdzQ3?NC>m_aa(eK ziWy4bnlzB0(CN^$3rLFHi>FysCvB<-aN+HS+D^1i^GMyBcm~kUr?314E-gt zDBv!cU0=`^n_?%dd`B-iFQpm~NoCI7t;thsRx*>L)Z>$vG#I^;fweO)-8_*S;qZyuL+;j?4VoU4mOo-j?^*Irs5F zo+v#AHznL|i$G&Go{DjKeFbYaJEE;%NLVQN(KZI{E@P(oazZjTX~+J(QLGmM(hLVVFEmjqC!;3e19?xkj6yV$x6Ab3S>(0#C~%tJb#lj za{IJbv;C%YhMPo45f7XF&wGgKfFKDgs_FYDAdE8Vbu+CPZaA%E%)>7VOHGt*Vdst& z=8<#2xO^~w?O2ytAZ_ddfHKivR4d#m{p%e1^I;!I-ci|jEzRF8AB7VA>)PoH`O1Np zZx^MI$sQ}G)Q~bs!;y(qE=zktlf8u!6vYO?>15(@_zvQ!5OBbCJLU~sx3J@Nsd>nbMe&J+w%i(9ZONl-m_Fy zMgD8Tk}H^zs>cuh|9=f0kXM3Ld0xUYStQ_rN=*I7>qY&0DgW83!>w!jATB*cSCuF_x}2@_@h`OM z`3#~l_euLa^dJi#eV$b}M@s3c0EeRy4}*v+wK7Ec(WJQRyNT2t3s7;Ivwi8>^&__V z_Juj6C*SDVqZf(iq1Ap`lWg!GXI?9JhLy(RxZ;c!Nb~`AR&)9Pe15P2U@d14erPhI z{6Hh~T>nT`$WX$}r^z#D>R>T$>NMJH-dtzgNMmCyKX?RkWK{PUp|Yq+-R}%| zDV^)X+)$<&obXl&l=1o$THGB=m#%2t2>~ln?c>V73j@U9kowsWm`A#|9h)T(O;FrsV8PF zYc8rJayZy=;0CW6O4!JT*|N^epr~(z4jQk(D;}wC$>WTRjVeRKwib8C8dF~9Tztyc z&ef@6lU2=1tX9XXy(WcYPfPXuX=U|Gk<$ZB)~2KDyOz}&P9p4W`H)F>sehlE|E@vU z2^eNj=;d~trUkasK-16M5?b!6o4?*-&nc#>XW^Fl6#`98U06m*mFIIT?E^uDZUZgO zq$=WE$brY#wUR&9tLJ7!ImyuHx5?90XnYpO|GM!uKIay3*x@OZVLLA?9ni0~V41m> z^90=r;Y?qr5i?#e2+vp2xq#KzQn?jk84>$_a|+6%*gkv+8P%zEuOxTf~(a3R7v) z^D4w?mEIQDlHhSLaq;=}XGY&dtng1*lRJW>!h2tEO@3%r4=Fw~hEvhRw%Y&-j;6Q7 zQFL#!;9Zmq)UnXaHQzCW)%&|-YI5G_DPeG#&j0Odo>qJol@Sj(6bS`cLfY1QRo7chqyvWy)V^_bR0d7M$cg*vgrHV`|?nK1X79bLzsT~1IO+{Q&SSC@emVf;Cb3i zp}8O|;Qxu9b$NrgCq*hz$W9-nqOJf;J>cW?HO+<_u*)x*`mp71{#~m7$DI5B;1K^U zO#hFB@$c;Tf7p+IM*?7+yi$Aqn`X3uphZ-sw;#G6n!_3`2v%Vp7s5N@>%7Cn$$n} zL4+5>9mDV&@br_d%!awha;_D|$WHg-AVXQ_ijfv!48HZ4w&e-y1yvlm`~&^zaF+j) zhZZOleCYp))E|T)9f$t;&X4e$!7Rt6fSdL3h_$X067N@U;Gc_-iw)l%2KM={l)MGB z2%=M{Dz8AEcZ)pTxWRkP1f;@F*A65-DcgHs8d3=#A~A>2$b}g&D|p=$^$+dmKt1;Q zZmXP`65jw|pC(Nj+CPGcaVZ9>0)R19Rm~4?j5uW`rQ)LZZGMMj0a{{#pMLaTT_n&u zGDZ4nI_s>?*kG8p_>BMZ{X7Ke^Tn^yA=kGEoHPoH%KyPBrL9~?^lKq(QZLxpp@ z*|LWU)fDH-H%!^(ZK8QG{AC@rMP%Bv;^Z7~T0Kmpc0+s9(zGXQefPM7W5}DnSC*-` zS#Y_NVMab}o5yqgcc?GP29tDh^^9rSf|{pdjxpv_F-4qthTT&T)#`bs0Hu_3f%`rfPSHq)&0_XM35A*#tM*lxU zGti@;nJjZQX~P^u`Pd#+(uAlz?3eH9haI?QQw1Ml>MA5WhA7<~L6O5#X3YGGarb^| z)DYD(S~?`<^>4&c>B;tdM#WvTfpHI=s)hoPyAd(GZRVq=c|K*l#!aAlyScoj6Vv~u?|++;+7RTbEQ-o%ZpD;) z1Ji5TnpNc1$VcjS?NGf|>RQiyRS;b%Q6GaL4;Q;t!rJAW;Zi9)Yf=@y#a$C4gR*H< zJ^CTrOMF(;d#z2YAWiYuEUoqE-2HZ5l|-ePYB zLXukIYeMxy$y^-IioQc^sUm2c_t8~*6SNd=qIBz(B5644VdE}kc%kzF!Mp@(uuT6P z??jbH^nZr{1P$;Q;?3&CaL|esSGwL-vhW@_A?(R*N-gvc*t_o7>EP|%51KwI$8)d} zD%QEyg)wmk44bBfg(R4voL5C3WF6!llcndCzE?w_pQZnOG_}AL4xyR4)tE=B`>lMk z0a7WUFQ(Y3<_*6(`(K|vItb?V^EEAerhT>QmL&~k`i<_TqO=}!vyb+fwsVfke@@R# z-k-3{97(S#XI{~l7FFjME|lV)Jn7fy#bwsN*FNH6w`}BvrQK1HFdQGAk@MQD)VxlA zaizW1shfDtr8{{j;I)ji>g$_nBwEZa%sW#Y{r=y=_TPYnivWNS%5V-`EM*Ui{CKlENxi?c75$2FN?~%AwKXffmyYhN5v?)PM9b=wVPedYbuAp`&i0D* zwb8}Z`UZE!p4-m+h)3;n7n%zaOL1*95?}Ws3pIC~4hd2rfocoH*{o#$a|QYqq<)8A zI%&@1l>_dnV7B%tHLxdBoN1VqL){_)XkF`ZkT-#AQ?J+crCVZS~+nGSt$o0#^X|8MU9w->@) zd|lg_uPgTV^`_yVqTqrd07Rl26(u9SB23p6Z(fw6*r2M_+C(D??Q|L{{zLF3l#|2d z$O?DICLCQ_6g)Z+Rp>G~bL1sb;RjG;;LVm@G6sS1;_LuZdu3vTNss6fKbKCtVdst{ z?>R}kl3lXv09iRjx-uT^yZpsIUpVbSw5To4cF1dK4VPo1yKaX=o0h3T`kfq4%8NVI zG)&S>a_>`Qb{*Z!qsCqMpZS5|8EWm(Dh+n6ZIGVD^cRZyO+=SR`1}2}%9h}HW4sn`M-b?=IdWyIiRDz zzthsv>SN;6>+(NOjic!^GZE_EDi8D?w*z3*b5EY|?T>HoN!k`4HEETj<>`ddP2W*R z)U?57I1<0wn78LEbnZTn)go2I4tY8rb<|7?PO^0nyt$8j^N{}b9`%Do%y9RNa#foP z)yytS9i{j1gdlgeov|^NM*U@WIU|QbFv>gLMAmxL$^6;IHmeeOu2_~j1yFp}r_m%B zAjTpVkP~CkKjWRM5?=~OuGzc{0u}P0h{So`T}uc6vL09FoW(Vh^}pHBT@BlfAnrdW zmSA18XxmANtZum}*|>_`9tMZ}buFxvY~J8MVCIf|g>Oi!2eRg+gkIk(I|R7{0$U?q zM;pGTEn7zCz9Y60a19~K^GCpE;&Qf2>vFz!@rA>Na9XNzdwh5Yk+hGs&XNp2 zBCENXfRB$axc4?`G$=2R;$m%d%57`y_H5G#89*WU2ZaRw#G9=IL70q3QZjcWnBj8T z+gHO$2~o+=;WKJ$u_GcP40*g%Ts$lA@z)EBIZ2+6Ox`(JqaE55Opq0SEfLPjE%#!= zt0wp^AtY|G0sSZyE=`_HiX%a8S#<5Jd|MYLya68+bb!#djE~Pdebt8Px?a1#b~Dvk zcMNJ{RKx4ipRGmfve(vG6G%)R>f)=1C^YnPr4#|xt ztPA;Y3WLck{i$>hzwIb1`isy6m>ntX?w0o|&jkLY8Zc~=uLJ@3C3FBRb>IP|;6GwA z{JordpHlM8fiL_Bfj0p=YGAm zxcbboe{gX2st5Uel>T&mb+z6Tf(aiWv^{4!V7R*VKE}%InH^|3v$bqX@7|Amz*wv& zXakak&fD5yT8J;7oN*tdlhhKP|(v7y@Gr`(0)&8!V`{jFfG67h*il8#$NDFbZMyhk<3-(bp4kSKr;TZ6s z)yE#bjLQgX*U=8ol}|9t8oQqWc@k<5h6R+`+ssU1yWEe#Is~{?*iFc{7==0XxPy?zYr1)CKj@paajM_2;fyHw;GXBAc#ld+R`3I{>Ux_D< z$wgH~vPa|&!DS$~%^!%V#RSgRzsJ?5l0InKKxqTX!JxbIEm8OQZ`Q94!!AazGo;5o zS#OqYMLQsoW%JcuKU1y~6&M&8vu6oQJ3q_leJ6RiSdV7EGt#TEa*m_<8vU@x$=ITu zO-}%%Py#$4Jy*|QA|C%|N)lm{WlW$sO3T-^@CiWX576kIBW9RV91gd?Lly9rS9N_$ zp*9KTFA(2ko}+Yn`;hkL9<`r58K&*Z=>%~-H^EI#<;2JM6le2Bqv5iuPCi{rPTxZr zeG*@$b1G2b$B8*-@ozx<3$h-q-VGs-iQ_v3nb~j|ah8jw=Hux#kG6Pa?7;Mp`lX`B z`KsH0J+RQ^KG3AI)OpiB8}yn8YttW z9JZD_OImS@rRoJFNr^F^UXtOeKENNYDB7|`b3TizD#*f7l)h2l=~}r&S{rL3FWrMv z-|hn2qK>h3W4)^aWG(I_&~9iF=1t?^W&nHN>y@HuZZ^!GP;*v{%^Y~9b|q>oW2qXM zVeQM@n#QDVpE?d^>vvo0{tZN6o|t}}JBGBS8CSO7z4Ucu;nivj#)xs*Q(n7`7dD(vd+LCBL6%aDM^AO4>!y-d zTRTtfvA9mzNJ){$QrJpR)GiPBx!Qdqv3B8l{yw^U#AN2Y`3}uxE-eXcYZ~b|9{#|g z$)Pwl{mb$gR_8d(NmuNKOk6E4zP}}9-hl$&12f`leBT_9NTR^(WPP&GdBmGI?!vvW zZ?vhaL*aKgXA`yMUQVCP#WAj?)N~lCM>yIZG*PR$K+Pa?0Ay!eiD~y;h-q_p7k-Bb zQUVr;&XVoDyiX2(jKPH{n9>;egPiYq>fc!K_0d*LF_p)sfmDWQmiGVO#PXSBINR2S<$Z6vA3^A5Ir}h z_*&&lPy1k_!9RBlgp~3rj#D;zT1gW9d6Tc;8T>%Z=QgDXyU~6a)bLka z3CLQjN;Oumz_V#h+1iUZ6$=Ha>N#6!5b{_?jy?K@(2?RLfHQRuO(@(>?)v=&q z1hBPNcs@8i-a-WW0NDv2<{}Remn$uzV#aGGgm03XB{&r^Sc#SPp8<`uy%-78_jxlp;Kz6yjlKSN2Lf~3}N{4_mRFn0CKu;v0Fra1u?;N)A1KN09V4yYLE$U6a zb9W)4Q;sHrO_)jqf=+rXzEQph!g?K!w<@-EP}~R0-|#bPnhq=FbAH18JyRl5+IV-% zha2pe$;E^nrcn+QH0&$4dOYDFZc-Q-0i_B0vNsA}#%?}QOf%w7fW_eIl<(2~aqFjC zpG;8LHk14aPQz4=IlRxyQrt0C?Dq+VLO+iZ%?ESQvz{I+Sao5-rFAFFKE2^DN3+)S zK(W$v`5bxatgABH_Byicvc1SvShiS!B==)M;U@YVWH1CU3jmZrq2=Z21mgX2cOF`J6 zMiRd~tXz+0Kx6;FbOvFz2?tUWVMVBgsc}-@kn8O56QX$=3t;6eaZFDn5h6j?yru|6 zFyHPMmvej_{Gj83AsJ7{ENP`27QuSiH3_eMO9LQdm?eLy(jT4H)Mcj!&a*v)b9}{u zypL{g%xbAa&TlXsvHw+iPPCkoC$-yuURYVLIQnhdlaSyV2rdcI5Zr^i zHSX?>ySuv+AXpP1!QI`R;O-WJyL$+y_|Dn;KJ4c^?s>TVLPK{`HL7}4{nuJ^{-*YB zkLla*ig1e?5b9$(jcp!s54A5QSvn7nr|lTABr)I1$AShEpHf-aVSLq-q(d8&@tgKg z7~{V^pHSxhx-|mBfwePGvsAwbX=C!asPkCUJ6*=VitMip|SzTV<+f(-eo=T%Wq?|sy+8oe7dFRFZ6Kuod z-um}L>e04dw=L^@xr`RYd4C@l2KY_c7Rz;8WR$i~{hqzB1dUz3cicsFFxe=fUtEs^ zLX!SeX$FA1a>*SOHIq6MG2_iPrewzw?zw1^lIEbOUHyCPCErQ;KJ4+E=RwikE%1%` zh;{lBKkxetu&6BipL?<74JNb2fIybJuph4C!sJI4zSp#X`I(f-Nzg|M!hpp>Om5Hq z%fd3Cz=q5S{`ONmt#PE`#d=5E8g66=tJ?yjwr`O>z^D}3VeMh?mMVQn zVBr#hX(Ap$i$n|FYU8>xE!V?1NG=SyQ47pz-Lnbi^=|LgFD}-yRog;Iq`$Y{Ln0Ma zcV~qDQ3hi7qJ>;Nr}q&C9_+un!Diq1-@BP^TGE-fi2~4Q8cF@yb(K@_U(>5K-MHVO zZ`BPvH?gfbZz92sC=Uncdw(P~lv<kRBfa)byB~ZaWx4_+FnpXmF#^OG`D8nv^Ac+ktj!~LV!4As( zQqM=@f2|As(e$4I;fa43iRVu|o%vEth+e^YQj)c1*9{;%3yKh#x{@jb^GS_Llr{N1 z`?8{0idZhbByiz*ak+x5UsT(7anEr9KsD_^ADC0~KSUn2%c z&C&D4Fk=Nn+2X{T)7+wPV*c=-vGkSXKx@@T!~pQ@3Mpf!mGcSC>wP!jz-W-L8Vwy3 z{LZe(JZCP8Zf`(ec@+aHPt#ZwZJdTWDF2brs&NHY@oeZ}bYN5D!GLJk{?qT%RApgzvEOGK_zAe(ObhTzet zVy;^rnjyASlh;IfR;=UTooaIB{5v3DlU;z6pQtOD{%Mc& zmsiVL_^=LjUlTvq?7iA+Vrwd8WO6;Co06zY4Rb!7&ne37#|`tN11rhM3cD68()uR{ zzTWnW(hTbFm`D|JI800e&3TPWJ^1B`t;V{=L5UtAmVP^&nzkthZh$Snu~{S1OWjRN z%C?HY296xn4>J8;cZ<*t?InV|?vjyxI9`Fsma`c@?#QdZ6(>gG{7-yLzR}TgN*mf! z)hlJx@b`Y1+>IoY(THR@aUW*cRkN|k2JxFHW##dD>d<>IciCSMC z;(=oNLq;(_(AEG|N^Twl^+wq9pYdn5*^oP)I%ah&!vyMEvu+Anj4B(mA{onxf-K)9 za}CSA>%;kUW+wlk-idgHtZF}~Q&A8Xnyo~}$oE3!uEMF_=2-G(JKR=fQ#@ts)&}@? z%}Wfkw|TH$w0x}&p-CDy2`Kc(Ca_fqzsg_(v1qv(nPIm%N2|PUgMVEsdVvy{)6?5_ zNGKDJ7N~w1l9|Gw{zWXjt=|xJCnc+Tb*bgGs`Cxun0-g1n??|Tj4*d>3v1w11UMeb zd=zDo>9)RtAKknfEcm6c&U|#RmcSjtj)S@QNDG`w3%0jUB0%{|V`9O>&UKp~;^6#ti9a zDg#64UD)a<>Od}LK($6cBrHtSk;AU}B^=PlX3l1_Z}RCzYz@Da-q5dqcaAl%kyV4? zs?SLF=&I`JzKLEF7=hXg4`I3aHO}8r#6Y`ZHR|KlBckOrl^Z=849N6RS|JQdw9VI>>4Ew(bIbGvJrROxtF21K|O?f&# zB!F^-8OaDop?M!RYn}$wpENOb*yhit&rbs6lECuld0u7Akb`0wG7&#sgRXY{qtH0- zLu`O%(#Y4`MhX;vfT!i~2mo+aRLCE?(0%=1S_LBAaY70N9$fXnrMw3eb!jH>m^PT3 zJJEVjTp~W&S2NCU^d+YAc(bJMnkNUiLLdZ4uMWT=7r%LGY^E z8yvr}Kw9POr2dPe-~LD(eEE(R&HJCj?rp7JG7aH}6BlyYR?&IZ%!&u)G6)2%4)NIN@9vaHMXMK{tut!kK-sk=Oh$-_f? zO)*2G?K(VFuhyP;rZ`x7A2LrKKv((*9aWM>!D(0 zP7Z&sSnVgHYwUM#9x);_*g9~9nb#3*mw$##&7Qk_*89BkTS?6ehwS}WG3ks93Q26K zUe7O*l0v0Q-29)wksxwWpXKG9&-7O6F}_bw?F2# z8u5CGxNPgCr|C-&nem32zW19{&K9X{?a7Yes%vlDprKTg9PSB9)3vly2fM3Nb*Jl# z_FOHRx849?35-%fzHY*-&&|qTF_%M$kHh+S>cOp7Ae0)^AXO8e>j)YF2DV-I{2!B1 z7SnjSS04#t(v3$%;CncqqCqt%`FM{b=G??F?SqB4bV)f4lRZK!9Vkv5Oil@^jCO(vDBFotEj+Ta}O+W<)I?;M%97sR>vJ$7L_0iA) zP#d8~nMkoZ2+S2GKmcng&af(@=7gENeD?>h%3FlYg{%oEKom$H*PVf)pZX9GKLJrC ziqmkK)j;Xmy2D<9f6Xg~RYP{q7?MF~9@utVzibbXJ<>{L;4Z!)RqJFY^|q@~?%1WTogfe)^lTj1+IB;-4A2XiD_@+z;z>2#GV4f$<7kfgr;e zjl9X^*9rLPg8}`<3+R1xDa=iqu{_cC`I08CRH${>v*fbX*qKDEsBOVX5#~d033L`P zFB&M>R_|P|{+^iOxo^eo-0t0so{eh<=Fhj4Ny05Uvril)&^z*0tIzk)t}=iZ_T!>a zvldXT?-(%5Lv1_^#XJqm{!&{r$Qqd~d>)l4XfaZ{4`ij6&9H5;mf)VE_PF4p^%|VU zd}{7$tw?Y+c)$4Y9iB=~bo7Ekj8a`i;TyylV`M?$7V9QsSEE!$gLmjC9gh($h3)lgp9O5gS*cW&~Av? zbqq$_KzNPTOL^?Zl3$ine@U~N4(ev z(jKRLu1`Dcy0uah_&;wM<(oOA?lVcOZjlwa@w{^u6LY0FM(Ut&>=f!x2AyAoI@-K$ zp{l~ExspNjCGh8F2QmzH9^-tscp2a}u~;}^#vR_lzI?Q?oWiM@G7mN-Uxmmf7PAG(&Bt0UP8{`xg7(C0m%~1%3q|7aN`zk zk|@>m9WxaiF5W5_LU%gOwnVx4=R_?X5P!j!^tp<8PUy`?Mww;C0CTFqmquMbM4P$I z@ZA`+`L#BW+r~!Qc<1T0;b>`142};lqT-xL*GQ5?VCHwoVRxDYFc)-JJ*onQgqpQs zOJBw>xo~bb#-meM_y<*))GPF2(pb$1fW<~ikpM)Pm@U5@a6hv|WJGIDMGq$_;LXd- z0S2AK5`${leoZI9s`nEx?8GF3G}StQWcP+V#5*7vccrq4x6zJN%{?;lS0z0@HY$UMB(11!^F66L_9O5JCjGpqsbD$*iN zKuRuN}rh)=rxN(+|kUyFV^o+{s0%{}lyj3wx5EBx+xa2<$X zDP)srJ&L^opt8se->L`-fPo%vtaW$PhB{LnaFD)v(zt$Guu>Z~X4&auRo|=~ls=!T zqF)$D$_c@!v-*;U;nce&N!?1_O^viFm_sdFh$5$?prmu&wTpk16OjD-v>Ta`Z84z~ zZuo$|bVtNtAFcoiGw3VY$kJ8<1$Km-m^zX&9G!=E@Gyj1Ix{zLVDLbUh_vKw)hN(% zd;bEPmbG^tg|ds-a4|_fymW;?%3mv=f)xaXFot1Z$PvJzLMjNx8A^G0zElD;we_+cd@b+BGc@H^t3 zJ0)i8NUdG@`~9PhstNC9hq_g2$jVQvKAJnxizk98kgy7NLhx|H)$PE>xyIRJ016 zh)SVnbtTI(TM1|M*4Q%dx@|{Wo6Ta~x<%uC^>mDL!*2cbo==I+0InV?>pCo5?D@=U zeIGG|!SA`TR5GIhZPI-v)p*p2B#znT91`AF?6NZrpAwy2wHjtlm%Lzl_E&F6+I-9X zvgVDM9I?HXuv|k%O9v{K&uf`wPY$Iz{o)R_`&{LSrQpG^(s$AseZ64I;VsJ143iJ| zcR9&UfvJPE&Sz$30t6b1WA!%6(H=94VHM08`xII)1p3~8IxZGr(lRgfGxuGdbqksi zPy^pP0=o=LzEYyYP8f0*%7KH<_M*?k8korta31?TFO~@YS7Vs3o6c8siA)w(eBO7J zh|%1a{lBP#ve9@?7=3r9%{9FQq$2EYyx*v0hD_AN4PVJz}7_jYrd(AmxG^jN_8C+Dm6HClc

    U+uD+WZ4|opBwwNC{FmP9v!@h`CM_I>N2a5W` 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 Date: Sun, 26 Jul 2026 08:37:06 -0700 Subject: [PATCH 13/15] Restore categorical bar build performance --- python/xy/marks.py | 42 +++++++++++++++++---------- python/xy/pyplot/_axes.py | 45 +++++++++++++++++++++++++++++ python/xy/pyplot/_mplfig.py | 17 +++++++---- tests/pyplot/test_perf_guardrail.py | 30 +++++++++++++++++++ 4 files changed, 113 insertions(+), 21 deletions(-) diff --git a/python/xy/marks.py b/python/xy/marks.py index 60363ff6..d4a46092 100644 --- a/python/xy/marks.py +++ b/python/xy/marks.py @@ -656,29 +656,39 @@ def _bar_like( raise ValueError(f"{kind} orientation must be 'vertical' or 'horizontal'") category_axis = "x" if orientation == "vertical" else "y" pos, category_labels = self._axis_positions_with_labels(x, category_axis) - try: - raw_width_array = np.asarray(width) - except (TypeError, ValueError) as exc: - raise ValueError(f"{kind} width must be scalar or contain numeric values") from exc - if np.issubdtype(raw_width_array.dtype, np.bool_): - raise ValueError(f"{kind} width must be scalar or contain numeric values") - try: - width_array = np.asarray(width, dtype=np.float64) - except (TypeError, ValueError) as exc: - raise ValueError(f"{kind} width must be scalar or contain numeric values") from exc - if width_array.ndim == 0: - width_values: float | np.ndarray = self._positive_scalar( - float(width_array), f"{kind} width" - ) + if np.isscalar(width): + # Scalar widths are overwhelmingly the common path. Preserve the + # established scalar validator (including bool rejection) without + # allocating two temporary NumPy arrays for every bar chart. + try: + width_values: float | np.ndarray = self._positive_scalar(width, f"{kind} width") + except ValueError as exc: + if isinstance(width, (str, bytes)): + raise ValueError(f"{kind} width must be scalar or contain numeric values") from exc + raise + elif isinstance(width, np.ndarray) and width.ndim == 0: + if np.issubdtype(width.dtype, np.bool_): + raise ValueError(f"{kind} width must be scalar or contain numeric values") + width_values = self._positive_scalar(width.item(), f"{kind} width") else: + try: + raw_width_array = np.asarray(width) + except (TypeError, ValueError) as exc: + raise ValueError(f"{kind} width must be scalar or contain numeric values") from exc + if np.issubdtype(raw_width_array.dtype, np.bool_): + raise ValueError(f"{kind} width must be scalar or contain numeric values") + try: + width_array = raw_width_array.astype(np.float64, copy=False) + except (TypeError, ValueError) as exc: + raise ValueError(f"{kind} width must be scalar or contain numeric values") from exc try: width_values = np.broadcast_to(width_array, (len(pos),)).astype(np.float64, copy=False) except ValueError: raise ValueError( f"{kind} width must be scalar or broadcast to the {len(pos)} bars" ) from None - if not np.isfinite(width_values).all() or np.any(width_values <= 0.0): - raise ValueError(f"{kind} width values must be finite and positive") + if not np.isfinite(width_values).all() or np.any(width_values <= 0.0): + raise ValueError(f"{kind} width values must be finite and positive") vals = self._bar_value_matrix(y, len(pos), kind) n_series, n_items = vals.shape if mode == "normalized": diff --git a/python/xy/pyplot/_axes.py b/python/xy/pyplot/_axes.py index d17b06c5..38033da6 100644 --- a/python/xy/pyplot/_axes.py +++ b/python/xy/pyplot/_axes.py @@ -3418,6 +3418,51 @@ def _axis_is_dataless(self, axis: str) -> bool: prefix probe answers real data immediately; only all-non-finite prefixes fall through to a full scan. """ + host = self._y2_of or self + y_axis = "y2" if self._y2_of is not None else "y" + # Bars are a frequent build-path boundary case: `_iter_entry_arrays` + # expands their centers, widths, bases, and endpoints before its first + # yield. Dataless detection only needs one real coordinate, so answer + # the ordinary bar case from the compact entry and leave pathological + # all-non-finite inputs to the exact fallback below. + for entry in host._entries: + if axis == "y" and entry.get("y_axis", "y") != y_axis: + continue + if entry.get("kind") != "bar": + continue + kwargs = entry.get("kwargs", {}) + orientation = kwargs.get("orientation", "vertical") + category_axis = "x" if orientation == "vertical" else "y" + if axis == category_axis: + centers = np.asarray(entry.get("x", ())).reshape(-1) + if not centers.size: + continue + if centers.dtype.kind in {"U", "S", "O", "b"}: + return False + try: + numeric = np.asarray(unit_converted_values(centers), dtype=np.float64).reshape( + -1 + ) + except (TypeError, ValueError): + return False + if np.isfinite(numeric).any(): + return False + continue + values = np.asarray(entry.get("y", ())).reshape(-1) + if not values.size: + continue + base = np.asarray(kwargs.get("base", 0.0), dtype=np.float64) + if base.ndim == 0: + if np.isfinite(base).item(): + return False + continue + try: + bases = np.broadcast_to(base, values.shape).reshape(-1) + numeric_values = np.asarray(values, dtype=np.float64) + except (TypeError, ValueError): + continue + if np.isfinite(bases).any() or np.isfinite(bases + numeric_values).any(): + return False for array, needs_filter in self._iter_entry_arrays(axis): if not needs_filter: if array.size: diff --git a/python/xy/pyplot/_mplfig.py b/python/xy/pyplot/_mplfig.py index 0a5f183d..6cba62c9 100644 --- a/python/xy/pyplot/_mplfig.py +++ b/python/xy/pyplot/_mplfig.py @@ -848,6 +848,11 @@ def _axes_rect(self, ax: Axes) -> Optional[tuple[float, float, float, float]]: if not self._subplot_adjust: return _DEFAULT_AXES_RECT return _GridSpec(self, 1, 1, **self._subplot_adjust).cell_rect((0, 1), (0, 1)) + if len(self._axes) == 1 and self._nrows == self._ncols == 1 and not self._subplot_adjust: + # The overwhelmingly common single-subplot case is exactly the + # Matplotlib default frame. Avoid rebuilding a one-cell GridSpec + # every time layout asks for the axes rectangle. + return _DEFAULT_AXES_RECT # A uniform grid (adjusted or default SubplotParams): the panel # resolves to its gridspec cell rectangle under the frame and spacing. index = ax._subplot_index @@ -1421,6 +1426,11 @@ def _parse_subplot_args(args: tuple) -> tuple[int, int, int]: def make_axes_grid(fig: Figure, nrows: int, ncols: int, squeeze: bool = True) -> Any: """The plt.subplots() return contract: Axes, 1-D, or 2-D ndarray.""" fig._ensure_grid(nrows, ncols) + if squeeze and nrows == ncols == 1: + # Avoid allocating and populating an object ndarray for the dominant + # plt.subplots() case whose public return value is a bare Axes. + fig._current_ax = fig._axes[0] + return fig._axes[0] axes = np.empty((nrows, ncols), dtype=object) for r in range(nrows): for c in range(ncols): @@ -1428,11 +1438,8 @@ def make_axes_grid(fig: Figure, nrows: int, ncols: int, squeeze: bool = True) -> # Matplotlib's subplots() constructs axes in row-major order and leaves # the final one active for subsequent stateful ``plt.*`` calls. fig._current_ax = axes[-1, -1] - if squeeze: - if nrows == ncols == 1: - return axes[0, 0] - if nrows == 1 or ncols == 1: - return axes.ravel() + if squeeze and (nrows == 1 or ncols == 1): + return axes.ravel() return axes diff --git a/tests/pyplot/test_perf_guardrail.py b/tests/pyplot/test_perf_guardrail.py index b248bc31..f254ff72 100644 --- a/tests/pyplot/test_perf_guardrail.py +++ b/tests/pyplot/test_perf_guardrail.py @@ -76,3 +76,33 @@ def test_theme_and_axis_components_are_shared() -> None: if themes1 and themes2: # mpl theme active (default) assert themes1[0] is themes2[0], "theme component must be cached, not rebuilt" assert _axes._component_cache, "component cache unexpectedly empty" + + +@pytest.mark.parametrize( + ("method", "axis"), + [("bar", "x"), ("bar", "y"), ("barh", "x"), ("barh", "y")], +) +def test_bar_dataless_probe_avoids_materializing_geometry( + monkeypatch: pytest.MonkeyPatch, + method: str, + axis: str, +) -> None: + """Ordinary bars answer the empty-axis question from their compact entry.""" + plt.close("all") + _fig, ax = plt.subplots() + getattr(ax, method)(["a", "b"], [1.0, 2.0]) + + def unexpected_scan(_axis: str): + raise AssertionError("ordinary bar dataless probe materialized full geometry") + + monkeypatch.setattr(ax, "_iter_entry_arrays", unexpected_scan) + assert not ax._axis_is_dataless(axis) + + +def test_all_nonfinite_bar_remains_dataless() -> None: + plt.close("all") + _fig, ax = plt.subplots() + ax.bar([np.nan], [np.nan], bottom=np.nan) + + assert ax._axis_is_dataless("x") + assert ax._axis_is_dataless("y") From 71c5f3312fe7b09f0e534813c72e990a58d55918 Mon Sep 17 00:00:00 2001 From: Alek Date: Sun, 26 Jul 2026 12:30:52 -0700 Subject: [PATCH 14/15] Remove PR evidence assets from the tree The consolidation comparison sheets and their provenance manifest were committed only as review evidence. The PR description links them by pinned raw URL at c196c12, so the images stay reachable without carrying 430 KB of PNGs into the merge. --- .../annotation-basic.png | Bin 199205 -> 0 bytes .../bar-label-demo.png | Bin 114238 -> 0 bytes .../horizontal-barchart-legend.png | Bin 118266 -> 0 bytes .../provenance.json | 52 ------------------ 4 files changed, 52 deletions(-) delete mode 100644 pr-assets/matplotlib-gallery-consolidation/annotation-basic.png delete mode 100644 pr-assets/matplotlib-gallery-consolidation/bar-label-demo.png delete mode 100644 pr-assets/matplotlib-gallery-consolidation/horizontal-barchart-legend.png delete mode 100644 pr-assets/matplotlib-gallery-consolidation/provenance.json diff --git a/pr-assets/matplotlib-gallery-consolidation/annotation-basic.png b/pr-assets/matplotlib-gallery-consolidation/annotation-basic.png deleted file mode 100644 index 34c15bb13c298d53a70805a29554fff313ea0891..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199205 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 EFXXSwz5oCK diff --git a/pr-assets/matplotlib-gallery-consolidation/bar-label-demo.png b/pr-assets/matplotlib-gallery-consolidation/bar-label-demo.png deleted file mode 100644 index 132a84975c6964d32a7540eee29fbbe63371f7e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114238 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

    vTwnfnH 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 diff --git a/pr-assets/matplotlib-gallery-consolidation/horizontal-barchart-legend.png b/pr-assets/matplotlib-gallery-consolidation/horizontal-barchart-legend.png deleted file mode 100644 index 7dd31a001255d3ebd6660adb1a0144d292d00c02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 118266 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

    9#du3fFs#k~ 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%0APgLn9qky7FawB7*h&fd(vF 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 ITf!{B@~o9)nv;PGTn)YQ8>s81seED`_Xg{ zLgS=ljj)BcTn{#8y3}%$&-)t5M5M;{@K~yojQH~pdN_bBp-D*CWF3q9LXP|N zv{7!~Fg)476WPG32@Iq>sMw**l^2XhiO(-<72Eoptph6e<%^8>YabK$*)qU?36Ud_9aI0PEn#(uMskBup4To&6dM^GX_1M`F$* zvg~cq%F8^lH06vOXVu_LGI#u{vHk173wKpcM&%G1FFYhE;VUWotpxH4R{pQu*0hi{ zk;jl^c8vTElv88mG-xVcB6>-}CiRq2h>F)Ypoo22;EsqveEc#!>sA0}yXNz(Pka_i z*~utQB8|>h^L!*$i{wV;3F~}*oE<8!lzOU7W3CRpCpTEEOktA8=fKo?Qt|P%h8d4M z4PvuEL_4ye4j0iIEFkskf$;vc|6y%zE0}Jfe$X}M0{U9!Wnhw^^5CQh$3EnDv}P;a z8VX~97!v*ykYwKlmq|=a3{E~Ui-X(N9(I|qvv-8Y2ciMaatoFqoadMy8*JS3^@A2N zkj?`>(>`>RfQBlG|0gkI7&~A%5&a*}_K&mAZXi{mZWgKv5~YyITZDI|j?v*YB_s+` zGp|@XD@%1*WD#y&iUsSK`tt^H!F%q?lun-S)hkA2NM!p^sMlhkZbgP+`eOQ`ri9pg zp2*RvnClL13K%4`R}8+IrY1u1<&(3HNyjF9BU8A2lQ)122i(lx$W|T*X&79TgBWu708teBKVtX$VIvNFBpjvp_gxVW zNTA)~g#&{dtdVex~R0ev#(w|@gL)aWYw{+0sjRGF}IFNG{YbT3_Ncpuj@ z7<XASW4ab14YG<9v$5ZSR1obEY{ zkz?@?CtjV6O%Qr^twv6kAUK#>hWabD?ic;8XTxvsjmo@g>cXBTG*eTPEHy=M9aeX@ zg-eN(ye`=Ie1R2qM}sZBQ_c5shUCv%gO8~Oljg;ZXvc5ri~OOI7?q>JA2EZvH^BC; zP_Aket!B6La>>)|=%!}c@LSF^AL*T2jIs?SEk6hEbVkG^hj0aEzo_KbkJ6sXCrbEI zmhzX9@NZ#fdd2~o<%NwLnw_{Gcm*0kAlwdAQQ+HQU|~6he?bSUkdVYgMG@Y(!4F#y z@Iu0n1rqNugw>FS0&6cDO%3UE<`7$j2Hxvk?PP)PbUQ%vpKv5Ox{HBPpdg_#2!;1df%@zA(6{ERo5gwUpWaX%ntbQjjQtmrR*U?pg`O=9Z_ElJo{vOYBOlF(FjDKaaekf>6Yw4U;P~!%1JB-96v_+WpgF z|K^r3b^}$&w>6c^m+L!;u4ZJ|r#vO(N-+=NaZ%@buk5fWDgP$lD_F3&$0-x%S?v_j zDDFI%!0cV_8B4@=PjIlMzIynJf!<}*M0_OmeW|{AhptXUNCoo!RqLsT4Wdu1oe%V) zsXztz=i{Go?%xNz99Xr!r3mi9u5D;}2f_l-9c6$c`1$$4k_zgQ6ZD)SEq%6X<9!p- z7wAHuQWL%K-gaNOlh(}(6Zr4nzmt3{4%h?*s zSF_5cE5GMGlvNVCzA8jfFKLH>T=0T>KC-+$x~N*djKmzQCXG z0&BQ7mekDUy_wM>Lf}Y9u{gf998S zRDa!vo=1?z3zg7d5k^45O>Q6hI@N=AhgRWrI&cmOaZj}4g7e^92q|biT;UESL(Ba0 zrx%G-VIC)C(OYQLcJM|df*}hm+F9Sdx8P!;zx*mTM#@d<&uKgm9p(yLse$K)WLFK< zC5Yys)cbe=p=d17z{**LfIk@vwPA0P~rB(Wbm1V+(80_=TiluOOc3=|qrv=#q2uvXxI=w`CJ{2+!51eX*39t72EH#&a&;y> zisrAO`S%bNyLv<&r}gS~x*_X`S>=7~%Jrul2`ndWC}2>BKIHc;9^XK1UGhsGTJEmn zJeJd_>3e?acEk7J?&Yyn0nt#ZOAB(h7RsARNQP`mznLLd^i0IF6VL0B-PNNo?7nni zV680uW%siEgKH&`b2itnc+sBImuO_h)vOmu`}q7B8^e%iND?uvQDrXLTJ^8Q{(co@ z@y(I%FD~aAni#D<$79(Px?XcYIf<>Fc5>~_B)^-2H-WU+B#!OyNUE*)rq7wXNSQ#q z&+bF-Huvg+B<5trK+z=CM?}P3%QWIb@2^Sh{pI)gN7}1m%(vIc;&tdoY&BWmJb$3Z zdeJdB0fU<8XF;TdQogR$=#uLP>veF!Us-U;^>SBI#YmPDOPNTodj_3e%ASp3MC>f7$~-=d1QX z{BN5~30L3mGD7H75;!Mz@?EgNC8c5T2WcMf$Jy;4wQVXdF5}SsHIM&wxBmCF`PXOu z`ECC7ng6LH`PZlZ!;Aizp8oZs-;I$fe;yeh_aJs6BoWf+N{jgt-(7KP8UkVzyF{o@ z>%fO#9AsFDPKRk2=9wtMAeU7kIf{x++{Et-=EL`;c;}o>pL9vmu&oUJ`N98w^u%^p zQ$98r6cqeYiVwsXPPg!zkQbpnNPdGzKNo&^9?20^Do|v5?Gmnw8}~&sfnw`PpVpe9 zcBQnsUMtO-H+E2|K)y4mgs!415b=!qGfMt`Yn4WD&{(HZzx>dmrF{>FEaoa-a5TYW zbQnY5rFri3s7h-hNup^~bKy3g)*JQ~>J}V@Urs5VKLu1*ZmnMJ9o^3S^4g%KUeaf%esSeSMrYHOo1HH?vIRG)pO}yeb;W9OA8D&~Tu zqY+m=9rqwM)sF@ABk7;BT?UWC%lMScqN{HX$X)Keq_86)b+xj_#*!WP(E2V`@JV=NOs2LvJ2<^&wfpt#v406a<-ni<$qrW^gGi(Fx`aklF%)HC!(vjBg8m zcW?8rikNs<-uvs#ub*v(#ryMmLxJl__DxS#XFmP%iX<7QMTf>~(d`vi%4HXL_ zxEllgbT%>0EXM|He`sW>nh#CQE3Aj=_@=h+A_SjJrBtm~JBK>`N58$Q?H>1T8Qisr8oX=x3=2@RVA01j7Kj~{-Q zro0820!q1sSqNM|yB?X21so%-H>U6Tc}whyPNO}>6l)&`yORzl7`az`oIBn(10B6x zI0{8}dE4rWn4?< zkc(->T0yaHqP?yO1JfWlxU+CVyhH=8=G^`mFK&H|fY&tBau#-d=}6+aXV1243wqxqzFz zg$^bK{zy?-nU_2q08}@?O#!0t7&cr03gi^Ra{(}!Zd`N}0CxfF`b9UuhtRMn{q;TRsRTc>_BCJ_VQTW`!B^K*r!gU zgv0UNtM{b_wKyanoLUn-_pts<@I~h(4UOf|sdz|Gx1K& zL&j{@wbAhl%`$$cD(#xql^il@Jv0kCQHy;HymX19h#=aamx8*LE~PWC%+=ar-s zJU7{z%Q9E#);3Wy5*v%F@R$%i4q*C9JR0U!ve(r8%$uKMkstS^ai~P%t zH%uYNC8dC0!eBw@wyAb(z(B#Pis<|Mm1fZ z*8B*?%9D=I1Mwho$mkF^?F7$SUpt}uvh+!)9* znVXwadd+qRLYG-s)*$Q`9fA*`Ixi_j4OCUp`L!&7(n8QTq!j@s>%PMt_xUpjfgv`A zhl=VE;60$gK3#;7xBzn+@ETASN=Zh>2hm0#XgA!a=iuaodo%;$gb0W)H7a`tGgq9h zb$$h0xkbU9UsZA-E#Q`po$tAAXj&kW?V)y-t!5XPTl}l)Y43C57SlO8)0dgYC%_7 zb-Tl_I#^flw?G+|+ba0i))@FqwnpUjXW;A_qj@tWVp;y zUSY=!AiJQ-WzHZ>$E07o4G|Sba3z3sT}a!6kQ=C%f$N>d?;uq=)D1uZ=+I$aj`dzc zhr2-fB+%rO-dlipLy#svBpzvL{Qz45pTnF2`tS;=r1`n2z`!Q~+yafUsUYuw{05Po zel?|BP6mb$l!5!=y#@nA4^$93YXjnZgyBnp=xf3k^#nNmAeU9I+7>k1?}4j>ya049 zD(GJz@%=6}^{;yTav1R7_b34b2m*qT{V?Q#MI4-!D9|a7l(qjQJz3a-WrU0|ZkgY; z5tST0@h`T=(;Q=ZPM~Zki6j|~59Z(vr0(#hmwFoj5NtA+&cEiuL1AtKW)OKT0nw;EXHDkK_}TFg(@ zzG6GNKLWhPxy}p5W~Nq3A%UbF;A4vD? zKY!K!&V9#HQWf}S1MRpQ#sJ1cz8Emp5IqXHF#r}kVpD(kunQ<@;P!#Wh727L+CzW> zELdpg0XlgW2x$N^y)&Rx1h_I<5HE3aJ3*l+Eb}}G3YC-XfR=)WoLcs5zfCk*$qdkZ z$hCsb?EEzrA;FUM5osmMb$P)%QpnIxk5jXb%A|TIubhY>_3Sj(hYl#3$+V60(xbes z>+}`non$#UlUlyWq%h4eo`$T+;h55YqYF?!z`fRaADIzI%473E*?};sb--TvA*U5< zE9S({BaRm|&D1yCC7sIMR);kXkTL6Y1;2mPBHx|Ou2`en1e#-O85x8%=txwEap;&J z91lo(?nTT-FbYhg7Zu>-;bIgP6o5Cy(zHgeBr_9nHVKvYx4{GmVplHj(_SBY2L*Vo4fNcfIus&z=eKE0*=(#u%?;2zs3j;$1<<*O= zH*L`FSD-qdv5{HVZ%85R`6vKkzI5r*K14s~(|rXd6JEOkC|%l~IJ)H<^2EFaG7hbZ ztd&p5FX|bS^Hf|dE#FFp1%Wa1D2~2MEmS7>@Tz9IdolKgiJKpTy3o9EP z2}>D%wq)G+O`|#_%XYr?zP9P>JJyyyDmXV(tTndwW5RW!7ET1Gi!cpI}PZlk0Cf_)M(x6uA`#VEPPiazO zO*nB77U8>EFD9s71hh+KEo@ns^^Rj5OmyipMZZW>(gYyDs`Ej$5|@XDN6Cp#W=-%H zDy+C_wfx-xvrJi2DOQ(sBb76!h!sA%60`IP@+Wv_OWTS4Ay*Jkjd(D(9WkSWw|aA2 zg9IQ=FeF~%lT%?yry)||1O5$+mR(6dpgvuk02WLUAm2lUoPl*myTSHmVbw%O)|$ce z1Gz=<)QjNd07V`2t>6+uflVru{XyO>h&eq}__~2q26@yGcs7Ytfr5g#*j<=SV9SX# z;Yos?gXxGt^qoR0%LBS26B9?EtLk8D9-Y~rNe7YH-tcXsqN3)D>OQeA}KOY=-yGvkM9Q>q_`CHftcB?|eR={OW7XS3rKa5_~S06`*bV zBwcK^lw$XFyfxNT>#x#jLK?r92#}V3zmv}UISHgdcyy4MH@Fu@KX`e-vYRgM&qR8e za0je;uwKGe1(0Lzq)xPt6RKMv7_S%L{?NuCn6IE%2sqYm?|v8P_t@CjfSa&&k%UC@ z25^F|u6%?5Orw<-+}9fio^yhr8?8wOA0Taqy^#@mUYvv_7&;jeBdXxY3JgO3a~Y4& zHG7Q*At8NED{I2eA01pHl6!jDY+tbCHxyoK8aEP58KB$W?eAf z+Rc4SfYpu+++%QkuLPd`e&z)mjYRPdlsN<#U%t))WqW5lPzrA)a0)q?bo2))SE4fM zAY=|756|F(XHC=8{^;bXGcc}e!xe3!zmVaYhF(rEf;CN)TTC8y$a|l>WMU;`I&WTg zHdP&77z3>&?cWG>mfkDQzhcDQJK!^_a{8F{5Nm1X*n3o{M*PsQ?&6hRT6MQA{tQaC z^gtde!+V5S3rt9ps7~vF8D(066K{{bTLzM`BDTlEoDRC~GE{dmFxecDQHV>K7Z^yJ z{SdXJOrmeo%S)ax7g`y%Tp(4~Ybh^5g=G3YBOJf>wkHWQa^itZqto2+X*Gc{x%heF zgXgJ2B4agssr*}A{0^mi^$ss%0y`v}=_anp$DHGj$!g4@|7zZhgDV$ISnSS|x`yq>$JZbDy?o){@qsrf=bj!<*I6U$0txr;>kB&->Vs5S z^H(!(HCP3A8PYqeB%_Wq;@85T$8uj8VCr1m$kVTROhkeg-TPY!NB*(xE206!+H1YD z#By8fW}Mec^U2g5wxMxsyr~&cbXQ2PV}}lrTI(g(EggvOrHs{{^~bK?p3HPfY9{6N z-m&#j4_XRH zTl^CS4J!>OB*$THc=#|5HHK#LOurFCjat_g!wwKmhcRCFj-dtXtJ{aFXVQqMkQc#* z6FzG95e^{jiFtsQ2?;ta^@HRJqLkgCW@aFlqYmh$(A^Q(LY@yZv7McMEpArugO8A% zDB6?u%GKgW#pNU1>v!Xnk8D6 z0I#|V2SeW@R~F@xZPvQ;L*oO(p{?5DG08e1{e<)P+{8BLN%dMElsI`4^&@HSRf?1M zZH|T`2P>J6+Q0f$BFedJoRS&m`UgD*EyxF*BS#%sJC35#&)cJH@ZzOT+qP%U*{VF) zJeY}SlscddUu?C`f|VC~K;ev+f9$b1-4Y6$1;}D0QM_(jH~zfQaCf2*W=I}FSp|i# z&`==Lw%|mP3y2GRfanC0wn4B;xCm!IXiEZ}xdXIsJ_p?1r5@l zDcfqJ0-ZKHNEc;{CSu6-?2kJ|hXjJCz0Ho{`H>Sv8(SDdX?F=VJ^kW27R9-*-^yK{ z^-V>ZGgsXjE*p@sG-__%(0;fzue-?8aLhelD41Nj-Ye==z?2qaEjo63J@UB8zw^6u z4-0$jsCpbK=7n=>b>fQRvASK!yXfCaxs@_j67&s9@d5Lvuz;wgIGg`)DaL8 zwlu=Mui>hBN#DqBU1;#eC)UdJ|5x2tM@5~6;j(t3fC3_j64D?DilhsJbax2SIdn*~ zC@mn;NGRRiHA^cgjSL~(AxI7|_nlpL@7?`l&$;*9bI-Z_fy~JKnE8HRyzlcq@ALf9 zW%VUlB%d&d`rOuP z^7f@uKBnwhD}j&3w|1y|)rnMY=Dx2qS#}UTUg~3ApqFQ7otzP@EiE^p{uKwGdo?xu zsn-kER;j=o$<1X>8vwombPWzcU<6!Bd4!vQ&a-E&P&tPlS$Ba+SVNEjuuy@g3*;O) zmxo55%fKhu`2G@To0tD+wi~zH1LX=3pZwX>0KF1mh6Gv`8L6rJ$0sl+7dP^Y_bP?} z?lCej=zRaU0ImhO8mxWjWCY=eEUY}FhA9At!8*omjp#LK9dQ666o~Z$8SXbTKxoeimzy$VP?kaNOxw?Bx(}M^4>Wyp>1D zq2;Sg%FKEV6L5RhT1>7IdcJY(A3!<6c_aX@@0yPgP6Y&5ff-V;3rZA#||!J$8H{BRgc$A4crXhJ>F z*j$ALhs=95iD+nyg4}cx=xbjjx(_W3pUc-k@Evn}0t8B4T3QhVEPUt$IfPX$74zUD zq&*M^!tvR=2Si93I=Te_iL_ynyScgDy05BS=?_J9T@j2|4=mA%~b8 z_a@;ui=GxkNQl3GkJOgB`0b#D^J|0zU*TB#+RwvuQu*%7?n@^ZUF+@nz72m;vig@! z7N|G+2%71UJN<)CXk90EMRcr=We~&`I(@7~JN~;Fd7nCL-se-l(_kAZ+RsSt(ukQQ z^b_^=9$q;vF9R9pC=hTQpdG@sZUVSw048{bf^I}sMhF?#G91-`2r8Jj2^@xj{_(c$4Dd4) z8DyoTYJu&ute0Nhj@{s^s9P+qx8DS$)C{Fr^G%5sje7^?ML`TF046Q&!tux_OLyE#pDx>eIk z8DYJi*)i$wY;q^c5L>DN6nzbZk-f6Cl=prccbOsK!L|t=u~mzU4~6D*Y;QM7WR-HN zw#l$ZwNPCc%*N$Tbg!q{=9AS!6gE^!aNI`jM;t;y_#rWr#$AE zTaJ|-wmx__Hn=hCrf{A9Mp(j}bID^j2lZ$>)-~IZlmtpg z)})#_v^QQ;kcpa^+N30Y;}#vXwL@H24Y1v$^Fjikyfs@T2Mn(`RB2)OW+7&RjdM`gwYi3@K?<`py!Vlgv$^}pe!Or=O6VguvC{9n zE~~u7JYMcW5q?;wuRma`Jw9f~58lucrHV3q&c5C{J)G!1GobGjbs#-x;+ez|p-3#j z{Sl6oy!hg`q(@(N&tuB7X$YeRqOy%W!zOj3C}{P}`HeeN4X1>J)f?;XLTqDdx%Oy` zGXFBmSlOU)6}fcDc`{jSnS+$X>X@rQW%0^^EWaSbVPt^~g%B7hLZ=8fRO7%WaR&ra ztn7CRP(bdE_Sh_Ntu8gYQ6^346wj?&t=4oH=hpeabee|~b7~5aJ+>QwnO&qpJUT*t>_?AO5YJoBB zN|PLFc=dur00(02iIEMbQxf)2ERaw>IU$=}sg;fRuJB;}eGSRd^9bz67`>Ex74~0U zeM?OaT5irn%k~cZcKrV0GX~+cV?M{yd^J+F00jw=q`qW_v<$Dw4b4z8P(9e3YPxt9 z-a#q>EqzRSY+|C!7dU_JUfuB~maxR)hr``=Rd5Af>ySs7aS>U&OMq9^p_32mdaP~iRpdr*o-7nSqxEmd0dZ{CJ zWB5Z}F-?(=gauRLnL4|$2ulKXM1((ex@z2=tZB`_a)(~oV%G$d_ivRi`0SMD{g$lf z+7rAN!ik)3H(5_V=ITse=cqMhPaxE~)EwigK>f+B_*^6n=-!dQ;Ds6>Me~DA7rnClcXL+@GRx$Es97Tub0P4XJvD*tYhW+^s?_ z`rP5!{q60>s5B|X*eH&DN=4HTc62fA;{(G2E$D8!D1~Q6TA}#j8Lev4h|(b$4XK6Q z&l&rj1|6GalB6RX^%c{i=RVva&vR$BDk!C{NprN0jq0$zYC4YHVqM@25-$?LFmF_S z&4?fNFp1|KLRQLJ*){r5^hoW}aOWoDh-gn^{!m0U*=+CVNKvG2ZfQ}@9sN+o%Ekt9 zsIM+;cxq9~z!C?Gaj;On*O+6N zSe>S6hg;(xaF)*2Z2FSV?FJfcrkq@5f+*yfrT}$$m5FAl|HtNwl8pq}&TMrD=5JP&=k?}VtE4WMD9U4S+>8ugc0W32v8~7HCSCCZFzr1xX*m$vU!%{5@ zb-#j7a20Ww>V*2(X4qy#zSAA2j*K(7X68Kh#v!S`Y@WK!M#kK(kv5^{#ABh@s{G_z z`B>ai2n;dag^QPPBmK$%y^E{8I&aNhz5VDVUm~tBnVpjlnpOb_D#&I$AmVmhAB&BN zdD(E51Uz$gK$%Uw-t7RAp>nIqJC}T(1(PYOsFXva64*ZkeuBUQ99l}<4s825&*PIr zSJ~rovq1?2w1#DY`>>YdS3~H^S%$bBk}fB(yMXd7Ph7N|JY4r6wX$+Qx1<{?nVR%B zBxGfK+S?DG>m~Eu=^bSlWf={V`<;PBB|S|lyjS;YPZfPCpQ^puyONf|-Ohx&R3RyP z{fJxD)(QTE6k+2}`jSx+oqe?L5wSuaXkGRSBZ$#yX}X5~Xrvl(&?&K3@#{iQcofJc z0Cug&JMH)}g*sjL38DC=!G3P)PK%CDf)`;Vi5i-tUbVPlXZ@ROU^@P)xn;&%iV3;e z!QK%6k!aARDe3r--aa&nuHKHzlSLGr{C>M}Hh>d==Cmf+Z}Xw>Z796zA^ z(AtNZ^1aPyBe`K0HO*EDey5)JSZqTMOXUp#1c*4%yD}hk1o6?F{TvRwGfe4!M zzeznob4uljm}T@R^p-1_@s`uj#2`mqX7r?6CsK7;jgzlbgk4`TTjr?k(&LHrv2%(l zxWS_R@Yf*xuX7R+3eTGHUn5b&Qa23WCg2U|e^xfUWke(!-dXvB+o`jtEA%kSq@#8% zNXxgZ+4zxkCUlB$C z{IrYXIzR{vhdcBcR{?krBf*FZ>A9pIf=mEImW%6~1Tjo^xV126)rZ9C5(a9VtO#(rkAOdOfhYhVpsI<8k5H6?h6D10a;I+OBuN7o;Jxsa+V;YP>2S@cz0sdi= zxyquPTtsrirxW}VRZ1V_^xXxX)xbEyc~4qC};lA1obDWX7hqw{N-BKC_6g z;uWlQDHFVIT}^p&!M69p?Yna(yseRAJX30+vER6e$|G5Shz5!@E3vYS61etsG~3YV zF;p-RUv|XXS<)&e`s{D+XjJnn!$dPew$b=DR`WVNXN3Hni_D)j$Dhpk>#m*S9kscg zzc=izO~|O&C_)Hh{@0Y(f=LS47EUZr<9+%8El}ml)nkSHX4DPj z0I!GKQky@We5p!69<3H*2=$e(>vP{TiCOr1J=+Xinh5G_MGn@-!%B@<^#<_XmwoJP z{1(+xWfkkoM4j&XzWL&iuU5S-G#1}P$q2=E3=%1RB@n6`%VKk2NL z)V|W(;VoJFF#ZvWbX`mFw#_0Gek>iD50PD>y1X2@;~%z1lj0WG_AM7UDwgyJ&wjgZ z?X*ZNxOMbQUO95mn=STg$enbB8bjs%GX{TpH0cU|&IQG`f+=_xaZr#a@C_O%DK(YpDTq zVkB?ew46F{ro!L71AbYGY+6P}&GBshS2;)pGMwhqp1S0@cvFirMv(OgskD4Or%W5la4ov>~Bok&73r?#(`0CVnOtITz1Z!YJcW^E*2F^IvCjG{Z?&heY3`Tzapdz)!T17 zwo_2B?^>LZOS(p=OvZ}Q+paxD-lydVgS9Mf`ZhL!8%KI7U;jN75|m2% zjXV-VLXHDNA<@#{=xB6u^O_2k0UhU9Icsv6Nt%>!EJ2%9QPLkCb%)KcA#=yB;adrW%W?_CFEY>Sw3k3`d8vStC78LdCw5@QB=7i9(_z=vd zP>@^$U!$M1Y$!|&f$+U@ivvzw2=j3EKcK9Plbr_L6;QFFrMg)V#_#l+H%u(`@J9!f z8MdI~8b`IcfB$||Ls-ewT(GzT;i(114Ie0!}*;hH2Wd23=L`{0wHLsPA;*UAeBfe5qT^Piu#5{OK^~z<-_IWxI|2sgvXmB`U%i~Y*aRxHT&8^p z1mxVnRbn!d-gK#h6C>SJC06bpHT4W|`kW#91Q?2%3Y_Vx0F{QskBK-kGp4Yin0e;K z+$9tCF3`+tU)kBY9bs=EOJKNQ$>uS0@Tr@n-S%RKhNL?Ye=~m0?4!ODa(0%Y+P-3x z1h0f6%i#NYe+oimPN&DTc!ZeTLSDq$WMFw!Uaj}A@$7<+O8$j&uR=JKB(ewd6MELB zhraoa3^j!a8em|Qe`tJ`pfQQgV>#^U-Wrs+RgM@UaUTacJHPwFk)(!GV@ZMYuj3U& z6wmMO*jNP06SA^hj!uf=dcg8%u-C<@aIq}%Vf|#)7_xGR#L~sNg;y9&?kOB9DIzIe zd9)MxFlsKZ=!)dF_#aXYf2PZ1j1_2{Loq<&5s{G$X|>u`xOn7c-2_M`JmAbQb8{1Gip3 z95qUWyja+nG4QGw6{81K2lejiDQ&rWga5EV}mBdF?JJI&4WZTRB{dfLuBlwgN} zzwXjImf~5FUJY~2hkWoAJt9-BWWqbQ(@qvll2N6(BE*t?AO9$?ZX&dU#`Ry=^4n7H?yK3we^F8F1K(~zl zFL;=v_%Cisxb2xc_kk!m{QK9}pWF3ckA8-He?9!Ub^P`4&$I8ZM}Ov>e?7tz^8VwF z{d{clg;@yqBPT*)?ZA9shomL;jMr&5cjOr5wcn@Eb{Bu{Oyo2g<^&9^toPy2_*N0* zk>&5v@cY!Zj{+4z(b_Yke@>?bF02dV-_eR1F8U; z@C+WF^@r4qjO{fc2-Y|`I5@y7ft-@EAjXaW5AV}2l{47@TToNKk|Vz#U)&dSuW77D z%2Y$aOx-Buj+COMB42s~ecTa&vD|f*_8T@>ZLSBAKg>NiOFF(;cU)bLoPSN>S2g`x zYfA`X+U>h)>1U>^(L}-LEc;T$&j2_Dxs!?gl_v0fKWhV{aQ>1V9l3U?esgmmTlZE= zEaG%#Lfen)XUHvU-5%fthf(W^h2dAwlR<^VNc5yzjm6kdkcC%5o@V*9+;5sBBcYnzkNGzF9ru_2oW)+`otR}-)RC=a z2`r00U$EJhQaXhAU*93QQtArsV_glJ;SQO(j%(bipTYe?)}6_*uO6OpQHD`aoK;Z-2c4n|M`aSe}372ee8dZ=07j{ zbJP86`2O?V{^w=?^Ctc4vj2IL{`qeI^RoZH-}}r$i)j2U7J9*n|btmv5~?$%%;6PHnW$O!Nq?UGZFiKuO)gi{;^vodd`gb`z0Tt z_Z1ey8cb;>{J~1l63NcYnPVyr=jtyoCl<*!b?; zzHRqlx6WMk1T}H;Ew}&N;Y_0Es}DAJ6}YEfK`FQ(my|w8VHuhnj`O*1HYH)vSAJAz15Oj&6GLVBaXpX47N0 z*|2-_=!Zd)lDuVBk1ab5vlu>8O>=kSJ|p~}s*={bATnc99PMFntH_sk#ll&`@v%`(nSo-7nu)$`l6b&ut$#14m6l{$2Ej<)BnRhpHUbyW{f#ub@%>^8ry z)D=FT8yMT)94164SQccd zdpw-x=>!TEe2bzBo>%A|VoKZuHXKxS`nDG>cb>#w?%^#-{vBB8?>F2s?b=pXup95l zUTO7kcVZl;&Mw5uYp;`piAbu}KXIS$e(tQ?{emJmFIi79yUI(I4r_ zjcga_$htGNoRC~DP$r8?J02KPH@iG6&_V7n5z7W*zpdS@s9I@M>yUC)sOknn*?Xwk z&}hd_NmR54>)etgE1&U}AeL(b?Ssi(j>bOUoE3I*+!!rt1t1V6;)|~8tFrvI!vmi~fzK&$ zIB=P2x>(CpT5;u}%^~kbPd)M|W?09K@7_I+#)+A{qR!EfoJR#HF8$S;B+{;i(=oj% z6EV9dBzC9(%L0~9H_xM~sPj&Evr|gRuB{DvqV^ivbjI9{mHV}0UoK_Z8M*B*2?$3- z>uio*CJK3yz4BU|%@SR-Qbs~4IG<@Li`vxSzn1Y_C1#G#qi27!L{P_Rt~4v0 z6}4FFB)Fd{5S%*wX1Eu`l-lxZ8}Gi*=<^pv?kZ|L~8x z-V)rJqv>spvQO4ETG1gq8O|;xU78icoD9|>7V%#E_<}cOSxXM75#>Mg0D^;>2SeEXrueczH?EYLHZpq{|r;QpO@Q8 zYoDy&{~U1bWNrTN^~UN$S~P!eFA4A7N^YPdUvR8C z++CMfQ?hOUHZ#tuIyoV_Fh_Fc)yG3}8IdP2DY8>`SRQL3NuMEq&6g!7W>xP^!SpzJ zBt2Y>=$tndNZK1{IL(yMP)(*88Tgs4E%C9%D38&P%tOx6WrB$UBKxVLD55A4Ks4$RTspH-5KVFLw zO#05_8t#9Cm^etxwy(#Ik%snu1m<|hBJl6~={4XP;5V%El8=Y~r6Jwb)yI3DlLE($ zIoBrbg3xOrmgJ73-`G%zf|%_B5QV-R6evPNUSzkuCH(OV0a8;`XU4H=9cAuDQDfd; zEs~TdIu6J4>BC(zTLtW5*CN_+_0l=v1fJ5Im+A{4qHYgXF1Oia*FF!*KPnV4vLgrx ziBTzN@|D&U`uL?%b3N~6ox;0l9l5>f%aO{R6_mGUh@fsj$Um`c==jM}^SE;P?Ko@B zRzp4ZyD`*oq)J-vstSydomP9#Ba!1_f-c{<;?vaol_Pny+_bFcI+wIG0YL?tma2>K zm{$*-$isA_{p@a@mXtLBL6c zK!k$Rxb65m!<>`t!CKVB_M&r>pSD{=;w>_zGy;x1hZeQCPd!bRb8{!{X|cZYMSIH* z{+7-*)334^q&=RK>*?!dH>ZVgnDge7iHJ_;D3z7tMwRE3+S=v{W8UG%TfXv!Zypi` ztUg5CsmPfgQ$DFMd7ji1aJc+_BQP-NvE?W+1!+FZr`}(G@Jzoz%fJEk_&INN$U`+z z{T%J0OI6NiL#5+vEecX{-oy>d%OGp=7cOR_3oHd4oJQiv+}vgL#+Uo6mnX~3$Eh!h*C+V4(NWyk*Kf=b8oU|52@9|Y@ zZvQZHeb$QT>sN?WSn(Jobtk=WCdqAgF7W+$j%LYj281jXt`#!yiCk7ANo14QJIWK@ z%$wc`b)8#|4~)(`w0XV~73-^8sl`eFU7W#|IyD|C0}o_9x*Wu0CAqHX&&(rx*WN#} zsyT|&OqRSh5T0$S!xg1IV>2kfRh{(c*saifsLV3bG}Z|D>x40$`IyLfnlc*?bzQ7s zT#iaX-pIQW%O)#RHwaNO&##|s7xteM+#KnLQFS=uoMfX`t>-Y@y{4Q-F=!oA_PBgB zn*;~p>J^)~cSVv6qR1V-P21t2VHZ)M_#&}xwK6&>qm&dguyCqar%U)a+st3AZFg;Y zMn5`#-{!i& zb~>)+tz4?wd>?cQhVnFOe~hB3-bKWGh|nl@D;sh_?dVDrZTD^9 zW;&hoZiv=?U+#F^8gc(Km7Yer|Lh5edP8}Fcn_-DWJw~=!BX2pOY4m(nPv1!{6ksi zIh~D@m=Xc<5L`San$&&Ed3}khuUa{Mc*S|6Nw#U~(=yk}yc<8t#m78H_)X7alNTt} zNjEk&)Q8m4)wJPshn2qG85@#S*29&$(9dj^K&Zl8rjbbYsCw6=lh;cZaEQi2B2rEF@ebN(> zP{kjztbp}U5?x$&b#9HFHrtbF8^a&d3(CP zxv51pwBTrST{GX)wKbRMa4#S~RlxB_=89##@e8cLc#UJNZl|G@OwvIk6IMo6l7A*5 z+;#{_&%h!nBSFr4m>jL+i79uzbJa&^yxP8YVb`Wta|CTz)@~W?FoWE~9vm{A`!W8I z-6I2kEg#~Z44s!{g_)Hi&$iK)WJKd0Q_jX_d6e;+TJkpH8vPO2nxn@0I#+-H;h8G; zqY;vf6W7^A8}&Smc!$w%B-#f~J1LoY_^LXOwhp2vYmJU3wODg>lJxT{4PN`drk+Zu za@JT0)LhdvFyfR(azOgCQ9pO+{w%i@w~vip;YDsz%L*hVp?ImO*V0#>Q4TMV5{OHS z=d*u`oK(Y73}%!vKEs;6_8&X`o#>-=r6R_WB*Aki972OzK$i-(zghpUy;$;~;XjT>C8 z8OdDr{5wmhCp?xHnNf2zLnB}JDjWuf%9%(KBiW*!@8)l9 z4%Ij%c(e!fKDjvo*(V&j*fFBLwUQQ`EHk+v|gul^|!XftlGJd_XTUt_7%@6QiL7v z?w@{rT!>`pP&s;usSB;&*=imci6PT@f$sK6v8vqYe$Qi2aWjnl@r3ixlCUrSt;(Kv zR#lj=4mO?wML)-0KiqsQ-4pQGIcQs?{`>U8!7$&f6`j1jhYs_c1T|_c2AlSdL=Z5Q zDlxy&X*;j?GMYyZm^7v`pq*B$oyU~B;?i>uZN{l(Wdx2R!dbZ&?Dg>fz8nssdws@7 zqPuE8j(W88u;Z%gV`*eDiWW}Cg4*xh-W$;oQITBINZaKPGkyt=Mjl-G*Q@`&6dt)s zWef5DeE74Z@YfUnLV^AXC;h*HYyJr*c};d Date: Sun, 26 Jul 2026 17:18:10 -0700 Subject: [PATCH 15/15] Address gallery stack review findings --- js/src/00_header.ts | 4 +- python/xy/_native.py | 2 +- python/xy/_paint.py | 39 +++++-- python/xy/_svg.py | 19 +++- python/xy/config.py | 4 +- python/xy/marks.py | 3 + python/xy/pyplot/_artists.py | 6 +- python/xy/pyplot/_axes.py | 79 +++++++++---- python/xy/pyplot/_mplfig.py | 4 +- python/xy/pyplot/_plot_types.py | 105 ++++++++++++------ python/xy/pyplot/_rc.py | 2 - python/xy/styling/capabilities.py | 1 + spec/design/wire-protocol.md | 8 +- src/lib.rs | 2 +- src/raster.rs | 6 +- tests/pyplot/test_adversarial_parity_fixes.py | 12 ++ .../test_autoscale_margin_bar_regressions.py | 28 +++++ tests/pyplot/test_axes_charts.py | 22 ++++ tests/pyplot/test_axes_helpers.py | 6 +- tests/pyplot/test_axes_layout.py | 13 +++ .../test_categorical_gallery_regressions.py | 3 +- tests/pyplot/test_color_pipeline_fixes.py | 12 ++ .../test_gallery_layout_api_regressions.py | 14 +++ tests/pyplot/test_p3_option_contracts.py | 30 +++++ tests/pyplot/test_rc_chrome_contracts.py | 25 +++++ tests/test_capability_registry.py | 12 ++ tests/test_plot_families.py | 18 +++ 27 files changed, 392 insertions(+), 87 deletions(-) diff --git a/js/src/00_header.ts b/js/src/00_header.ts index 295c2bb4..e8db899e 100644 --- a/js/src/00_header.ts +++ b/js/src/00_header.ts @@ -27,7 +27,9 @@ // v7: `colormap` may be explicit RGB stops rather than a built-in name, and the // spec may carry a chart `palette`. A v6 client indexes COLORMAP_STOPS with the // stop array, misses, and paints viridis without erroring. -export const PROTOCOL = 7; +// v8: legend/colorbar geometry, extra colormap names, and match-fill strokes +// add wire values an older v7 client would accept but silently misrender. +export const PROTOCOL = 8; // HTTP binary frame v1 (spec/design/wire-protocol.md §7; Python side in // python/xy/_framing.py). The chart spec's PROTOCOL diff --git a/python/xy/_native.py b/python/xy/_native.py index ec7b645b..ea1b2d8b 100644 --- a/python/xy/_native.py +++ b/python/xy/_native.py @@ -24,7 +24,7 @@ from .config import MAX_CONTOUR_WORK, MAX_SCREEN_DIM -ABI_VERSION = 42 +ABI_VERSION = 43 # Rust reports invalid arguments (and, via the ffi_guard panic shield, any # internal panic) by returning `usize::MAX` from size-returning entry points. diff --git a/python/xy/_paint.py b/python/xy/_paint.py index 06f5ba08..8cf910ea 100644 --- a/python/xy/_paint.py +++ b/python/xy/_paint.py @@ -2,6 +2,7 @@ from __future__ import annotations +import math from collections.abc import Callable from typing import Any @@ -34,11 +35,33 @@ def triangle_mesh_boundary(*vertices: np.ndarray) -> np.ndarray | None: # generous relative bucket is still far below meaningful edge spacing. tolerance = max(span * 2e-5, 1e-12) - def vertex_key(point: tuple[float, float]) -> tuple[int, int]: - return (round(point[0] / tolerance), round(point[1] / tolerance)) - - edge_counts: dict[tuple[tuple[int, int], tuple[int, int]], int] = {} - points_by_key: dict[tuple[int, int], tuple[float, float]] = {} + # A single rounded bucket is not a proximity test: two float32-decoded + # copies of one source vertex can straddle its boundary. Search the + # neighboring cells and snap each copy to a stable representative instead. + buckets: dict[tuple[int, int], list[int]] = {} + points_by_key: list[tuple[float, float]] = [] + + def vertex_key(point: tuple[float, float]) -> int: + cell = (math.floor(point[0] / tolerance), math.floor(point[1] / tolerance)) + best: int | None = None + best_distance = math.inf + for dx in (-1, 0, 1): + for dy in (-1, 0, 1): + for candidate in buckets.get((cell[0] + dx, cell[1] + dy), ()): + other = points_by_key[candidate] + delta_x, delta_y = abs(point[0] - other[0]), abs(point[1] - other[1]) + if delta_x <= tolerance and delta_y <= tolerance: + distance = delta_x * delta_x + delta_y * delta_y + if distance < best_distance: + best, best_distance = candidate, distance + if best is not None: + return best + key = len(points_by_key) + points_by_key.append(point) + buckets.setdefault(cell, []).append(key) + return key + + edge_counts: dict[tuple[int, int], int] = {} for index in range(n): points = ( (float(arrays[0][index]), float(arrays[1][index])), @@ -47,14 +70,12 @@ def vertex_key(point: tuple[float, float]) -> tuple[int, int]: ) for start, end in zip(points, points[1:] + points[:1], strict=True): start_key, end_key = vertex_key(start), vertex_key(end) - points_by_key.setdefault(start_key, start) - points_by_key.setdefault(end_key, end) edge = (start_key, end_key) if start_key <= end_key else (end_key, start_key) edge_counts[edge] = edge_counts.get(edge, 0) + 1 boundary = [edge for edge, count in edge_counts.items() if count == 1] if len(boundary) < 3: return None - adjacency: dict[tuple[int, int], list[tuple[int, int]]] = {} + adjacency: dict[int, list[int]] = {} for start, end in boundary: adjacency.setdefault(start, []).append(end) adjacency.setdefault(end, []).append(start) @@ -62,7 +83,7 @@ def vertex_key(point: tuple[float, float]) -> tuple[int, int]: return None first = boundary[0][0] ring = [first] - previous: tuple[int, int] | None = None + previous: int | None = None current = first for _ in range(len(boundary)): neighbors = adjacency[current] diff --git a/python/xy/_svg.py b/python/xy/_svg.py index d02405a6..2d815a48 100644 --- a/python/xy/_svg.py +++ b/python/xy/_svg.py @@ -58,6 +58,11 @@ def escape(data: str, entities: dict[str, str] | None = None) -> str: return data +def _escape_attr(data: Any) -> str: + """Escape arbitrary text for a double-quoted XML attribute.""" + return escape(str(data), {'"': """}) + + def _fill_opacity(style: dict[str, Any], default: float = 1.0) -> float: """CSS whole-mark opacity multiplied by the fill-only channel.""" return float(style.get("opacity", default)) * float(style.get("fill_opacity", 1.0)) @@ -2002,15 +2007,17 @@ def line_attrs(style: dict[str, Any], color: str) -> str: title_family = title_style.get("font-family") title_font_style = title_style.get("font-style") title_font_attrs = ( - f' font-family="{escape(str(title_family))}"' if title_family is not None else "" + f' font-family="{_escape_attr(title_family)}"' if title_family is not None else "" ) + ( - f' font-style="{escape(str(title_font_style))}"' if title_font_style is not None else "" + f' font-style="{_escape_attr(title_font_style)}"' + if title_font_style is not None + else "" ) chrome.append( f'' f"{escape(str(spec['title']))}" ) @@ -2025,13 +2032,13 @@ def append_axis_title(axis: dict[str, Any], *, is_x: bool) -> None: transform = f' transform="rotate({_num(angle)} {_num(x)} {_num(y)})"' if angle else "" family = axis_style.get("label_font_family") font_style = axis_style.get("label_font_style") - font_attrs = (f' font-family="{escape(str(family))}"' if family is not None else "") + ( - f' font-style="{escape(str(font_style))}"' if font_style is not None else "" + font_attrs = (f' font-family="{_escape_attr(family)}"' if family is not None else "") + ( + f' font-style="{_escape_attr(font_style)}"' if font_style is not None else "" ) chrome.append( f'' f"{escape(str(axis['label']))}" ) diff --git a/python/xy/config.py b/python/xy/config.py index 33d47bf4..7f80255b 100644 --- a/python/xy/config.py +++ b/python/xy/config.py @@ -18,7 +18,9 @@ # and the spec may carry a chart `palette`. A v6 client indexes its built-in # table with the stop array, misses, and paints viridis without erroring — the # same silent-misrender case v6 itself was cut for. -PROTOCOL_VERSION = 7 +# v8: legend/colorbar geometry, extra colormap names, and match-fill strokes +# add wire values an older v7 client would accept but silently misrender. +PROTOCOL_VERSION = 8 # Line traces longer than this ship M4-decimated (Tier 1, §5); the canonical # column stays kernel-side for re-decimation on zoom (§28: recompute for the diff --git a/python/xy/marks.py b/python/xy/marks.py index d4a46092..f819660e 100644 --- a/python/xy/marks.py +++ b/python/xy/marks.py @@ -2384,6 +2384,9 @@ def contour( arr, xpos, ypos, corner_mask=bool(corner_mask) ) band = np.searchsorted(edges, dense, side="right") - 1 + # Matplotlib includes the final level in the final filled + # interval; only values strictly above it are outside. + band[np.isfinite(dense) & (dense == edges[-1])] = len(edges) - 2 mids = (edges[:-1] + edges[1:]) * 0.5 inside = np.isfinite(dense) & (band >= 0) & (band < len(edges) - 1) if color_table is None: diff --git a/python/xy/pyplot/_artists.py b/python/xy/pyplot/_artists.py index 53d3649d..84f2a105 100644 --- a/python/xy/pyplot/_artists.py +++ b/python/xy/pyplot/_artists.py @@ -486,6 +486,7 @@ def set_sizes(self, sizes: Any, dpi: Any = 72.0) -> None: del dpi # compat-noop: xy sizes use the owning figure DPI from ._translate import marker_size_to_scatter_size + self._entry["source_sizes"] = np.asarray(sizes, dtype=np.float64).reshape(-1) self._entry["kwargs"]["size"] = marker_size_to_scatter_size( sizes, default=6.0 * self._axes._point_scale(), @@ -1388,7 +1389,7 @@ class Legend: """ def __init__( - self, parent: Any, handles: Any, labels: Any, loc: Any = "best", **kwargs: Any + self, parent: Any, handles: Any, labels: Any, loc: Any = None, **kwargs: Any ) -> None: handles, labels = list(handles), list(labels) if len(handles) != len(labels): @@ -1413,7 +1414,8 @@ def __init__( continue self._pairs.append((entry, label)) self._kwargs = dict(kwargs) - self._kwargs.setdefault("loc", loc) + if loc is not None: + self._kwargs.setdefault("loc", loc) self._attach(parent) def _attach(self, parent: Any) -> None: diff --git a/python/xy/pyplot/_axes.py b/python/xy/pyplot/_axes.py index 38033da6..4c78a171 100644 --- a/python/xy/pyplot/_axes.py +++ b/python/xy/pyplot/_axes.py @@ -3321,16 +3321,7 @@ def numeric_or_categorical(values: Any) -> np.ndarray: kwargs = entry.get("kwargs", {}) orientation = kwargs.get("orientation", "vertical") centers = np.asarray(entry.get("x", ())).reshape(-1) - try: - centers = np.asarray(unit_converted_values(centers), dtype=np.float64).reshape( - -1 - ) - except (TypeError, ValueError): - # The core provisions one categorical bar trace in this - # same first-seen order, so its extent is the ordinal - # range directly. Keep this hot path free of a duplicate - # Python label-map pass. - centers = np.arange(centers.size, dtype=np.float64) + centers = numeric_or_categorical(centers) values = np.asarray(entry.get("y", ()), dtype=np.float64).reshape(-1) bases = np.asarray(kwargs.get("base", 0.0), dtype=np.float64) bases = np.broadcast_to(bases, values.shape).reshape(-1) @@ -3352,6 +3343,10 @@ def numeric_or_categorical(values: Any) -> np.ndarray: except (TypeError, ValueError): continue yield array, True + if entry.get("kind") == "area" and axis == "y": + base = entry.get("kwargs", {}).get("base") + if base is not None: + yield np.asarray(base, dtype=np.float64).reshape(-1), True mpl_extent = entry.get("_mpl_extent", {}).get(axis) if mpl_extent is not None: yield np.asarray(mpl_extent, dtype=np.float64).reshape(-1), True @@ -3375,6 +3370,21 @@ def numeric_or_categorical(values: Any) -> np.ndarray: yield np.asarray(base, dtype=np.float64).reshape(-1), True if factory == "stem" and axis == "y": yield np.asarray(entry.get("kwargs", {}).get("base", 0.0)).reshape(-1), True + if factory == "errorbar": + center = np.asarray( + entry["args"][0 if axis == "x" else 1], dtype=np.float64 + ).reshape(-1) + yield center, True + error = entry.get("kwargs", {}).get("xerr" if axis == "x" else "yerr") + if error is not None: + raw = np.asarray(error, dtype=np.float64) + if raw.ndim >= 2 and raw.shape[0] == 2: + lower = np.broadcast_to(raw[0], center.shape) + upper = np.broadcast_to(raw[1], center.shape) + else: + lower = upper = np.broadcast_to(raw, center.shape) + yield center - lower, True + yield center + upper, True if factory == "contour": z = np.asarray(entry["args"][0]) coordinates = entry.get("kwargs", {}).get(key) @@ -3537,6 +3547,25 @@ def _entry_sticky_edges(self, axis: str) -> np.ndarray: combined = np.concatenate(edges) return combined[np.isfinite(combined)] + def _has_nonzero_bar_baseline(self, axis: str) -> bool: + """Whether the core's zero-only bar anchor cannot represent a base.""" + host = self._y2_of or self + y_axis = "y2" if self._y2_of is not None else "y" + for entry in host._entries: + if axis == "y" and entry.get("y_axis", "y") != y_axis: + continue + if entry.get("kind") != "bar": + continue + orientation = entry.get("kwargs", {}).get("orientation", "vertical") + value_axis = "y" if orientation == "vertical" else "x" + if axis != value_axis: + continue + base = np.asarray(entry.get("kwargs", {}).get("base", 0.0), dtype=np.float64) + finite = base[np.isfinite(base)] + if finite.size and np.any(np.abs(finite) > np.finfo(np.float64).eps): + return True + return False + def _has_fully_sticky_candidate(self, axis: str) -> bool: """Whether an entry can pin both ends of *axis*. @@ -4076,9 +4105,9 @@ def set_axisbelow(self, b: bool) -> None: ) def get_legend(self) -> Any: - """A truthy legend handle when a legend is shown, else None.""" + """Return the current legend artist, or ``None`` when hidden.""" host = self._y2_of or self - return (host._legend_handle or self) if host._legend else None + return host._legend_handle if host._legend else None def get_legend_handles_labels(self) -> tuple[list[Artist], list[str]]: """Handles and labels of the entries that would appear in the legend. @@ -5193,12 +5222,10 @@ def legend(self, *args: Any, **kwargs: Any) -> Any: raise loudly. ``loc="best"`` picks the least occupied corner. """ host = self._y2_of or self - returned: Any = self if len(args) >= 2: handles = list(args[0]) labels = [_plain_text(label) for label in args[1]] legend_artist = Legend(host, handles, labels, **kwargs) - returned = legend_artist host._legend_handle = legend_artist # An explicit handles/labels call defines the primary legend even # when the handles are proxy artists rather than plotted entries. @@ -5223,17 +5250,19 @@ def legend(self, *args: Any, **kwargs: Any) -> Any: for entry, label in zip(eligible, labels, strict=False): entry.setdefault("kwargs", {})["name"] = _plain_text(label) host._legend_artist = None - host._legend_options = self._compose_legend_options(kwargs) host._legend_items = None - host._legend_handle = None + handles, labels = host.get_legend_handles_labels() + host._legend_handle = Legend(host, handles, labels, **kwargs) + host._legend_options = dict(host._legend_handle._options) else: host._legend_artist = None - host._legend_options = self._compose_legend_options(kwargs) host._legend_items = None - host._legend_handle = None + handles, labels = host.get_legend_handles_labels() + host._legend_handle = Legend(host, handles, labels, **kwargs) + host._legend_options = dict(host._legend_handle._options) host._legend = True host._invalidate() - return returned + return host._legend_handle def _compose_legend_options(self, kwargs: dict[str, Any]) -> dict[str, Any]: """Translate legend() keyword styling into the engine's option dict. @@ -6412,7 +6441,11 @@ def _build_chart(self, width: int, height: int) -> Any: if pinned is not None: props["domain"] = pinned else: - props["margin"] = self._effective_margin(axis) + margin = self._effective_margin(axis) + if margin < 0.0 or self._has_nonzero_bar_baseline(axis): + props["domain"] = self._auto_domain(axis) + else: + props["margin"] = margin if "x" in empty_view: x_props["domain"] = (0.0, 1.0) if "y" in empty_view: @@ -6440,7 +6473,11 @@ def _build_chart(self, width: int, height: int) -> Any: if self._twin._axis_is_dataless("y"): y2_props["domain"] = (0.0, 1.0) else: - y2_props["margin"] = self._twin._effective_margin("y") + margin = self._twin._effective_margin("y") + if margin < 0.0 or self._twin._has_nonzero_bar_baseline("y"): + y2_props["domain"] = self._twin._auto_domain("y") + else: + y2_props["margin"] = margin self._apply_tickers("y2", y2_props, auto_tick_counts["y"]) children.append(xy.y_axis(id="y2", side="right", **y2_props)) legend_needs_best = False diff --git a/python/xy/pyplot/_mplfig.py b/python/xy/pyplot/_mplfig.py index 6cba62c9..4d3fd1c6 100644 --- a/python/xy/pyplot/_mplfig.py +++ b/python/xy/pyplot/_mplfig.py @@ -199,7 +199,6 @@ def add_axes(self, rect: Any, **kwargs: Any) -> Axes: ax = Axes(self) self._axes.append(ax) ax._figure_rect = parsed - self._nrows, self._ncols = 1, len(self._axes) self._current_ax = ax if kwargs: ax.set(**kwargs) @@ -459,7 +458,8 @@ def tight_layout(self, **kwargs: Any) -> None: # engine performs from artist extents; the shim uses its deterministic # renderer margins instead of a second text-layout engine. if self._axes and not any( - ax._figure_rect is not None and ax._subplot_spec is None for ax in self._axes + ax._figure_rect is not None and ax._subplot_spec is None and ax._subplot_index is None + for ax in self._axes ): canvas_w, canvas_h = rc_figsize_px(self._figsize, self._dpi) compact = canvas_w / max(1, self._ncols) < 520 diff --git a/python/xy/pyplot/_plot_types.py b/python/xy/pyplot/_plot_types.py index a35352b1..4614326d 100644 --- a/python/xy/pyplot/_plot_types.py +++ b/python/xy/pyplot/_plot_types.py @@ -610,6 +610,10 @@ def _add(self, kind: str, entry: dict[str, Any]) -> dict[str, Any]: ... def _next_color(self) -> str: ... + def _mpl_dash(self, dash: Any, linewidth: Any) -> Any: ... + + def _point_scale(self) -> float: ... + def _entry_extent(self, axis: str) -> tuple[float, float]: ... def _categorical_position(self, axis: str, label: Any) -> float: ... @@ -1814,7 +1818,9 @@ def stem( ) base_color, base_linestyle, _base_marker = parse_fmt(str(basefmt or "C3-")) - base_dash = _dash_segment_pattern("stem", base_linestyle) + base_dash = LINESTYLE_TO_DASH.get(base_linestyle) + if base_dash is not None: + base_dash = self._mpl_dash(base_dash, 1.5) baseline_entry = self._add( "line", { @@ -5122,6 +5128,8 @@ def _barb_field( empty = ~(halves | (nflags > 0) | (nbarbs > 0)) def visible_span(values: np.ndarray) -> float: + if values.size == 0: + return 1.0 span = float(np.ptp(values)) if span > np.finfo(float).eps: return span @@ -5562,6 +5570,14 @@ def streamplot( if np.any(density_xy <= 0): raise ValueError("streamplot density must be positive") max_steps = max(1, min(100_000, int(float(maxlength) * max(u_values.shape) * 8))) + native_fast_path = ( + start_points is None + and integration_direction == "both" + and broken_streamlines + and integration_max_step_scale == 1.0 + and integration_max_error_scale == 1.0 + and density_xy[0] == density_xy[1] + ) if start_points is not None: seeds = np.asarray(start_points, dtype=np.float64) if seeds.ndim != 2 or seeds.shape[1] != 2: @@ -5574,28 +5590,44 @@ def streamplot( ) if not np.all(inside): raise ValueError("streamplot start_points must lie inside the x/y grid") - else: + elif not native_fast_path: seed_x, seed_y = np.meshgrid( np.linspace(x_values[0], x_values[-1], max(2, int(18 * density_xy[0]))), np.linspace(y_values[0], y_values[-1], max(2, int(18 * density_xy[1]))), ) seeds = np.column_stack((seed_x.reshape(-1), seed_y.reshape(-1))) - source_segments = _integrate_streamlines( - x_values, - y_values, - u_values, - v_values, - seeds, - integration_direction, - max_steps, - float(maxlength), - float(minlength), - broken_streamlines=broken_streamlines, - density=(float(density_xy[0]), float(density_xy[1])), - step_scale=integration_max_step_scale, - error_scale=integration_max_error_scale, - skip_occupied_seeds=start_points is None, - ) + if native_fast_path: + from xy import kernels + + kx0, kx1, ky0, ky1 = kernels.streamlines( + x_values, + y_values, + u_values, + v_values, + density=float(density_xy[0]), + max_steps=max_steps, + ) + source_segments = [ + np.asarray(((sx, sy), (ex, ey)), dtype=np.float64) + for sx, ex, sy, ey in zip(kx0, kx1, ky0, ky1, strict=True) + ] + else: + source_segments = _integrate_streamlines( + x_values, + y_values, + u_values, + v_values, + seeds, + integration_direction, + max_steps, + float(maxlength), + float(minlength), + broken_streamlines=broken_streamlines, + density=(float(density_xy[0]), float(density_xy[1])), + step_scale=integration_max_step_scale, + error_scale=integration_max_error_scale, + skip_occupied_seeds=start_points is None, + ) x0_values: list[float] = [] y0_values: list[float] = [] x1_values: list[float] = [] @@ -5696,23 +5728,30 @@ def streamplot( collection = PolyCollection(self, entries[0]) arrow_collection = collection if num_arrows > 0 and len(x0): - arrow_indices_list: list[int] = [] - segment_offset = 0 - for streamline in source_segments: - deltas = np.diff(streamline, axis=0) - lengths = np.hypot( - deltas[:, 0] / max(float(np.ptp(x_values)), np.finfo(float).eps), - deltas[:, 1] / max(float(np.ptp(y_values)), np.finfo(float).eps), + if native_fast_path: + arrow_count = max( + 1, + min(len(x0), num_arrows * int(30 * float(density_xy[0]))), ) - cumulative = np.cumsum(lengths) - if cumulative.size and cumulative[-1] > 0.0: - targets = cumulative[-1] * ( - np.arange(1, num_arrows + 1, dtype=np.float64) / (num_arrows + 1) + arrow_indices = np.unique(np.linspace(0, len(x0) - 1, arrow_count, dtype=np.int64)) + else: + arrow_indices_list: list[int] = [] + segment_offset = 0 + for streamline in source_segments: + deltas = np.diff(streamline, axis=0) + lengths = np.hypot( + deltas[:, 0] / max(float(np.ptp(x_values)), np.finfo(float).eps), + deltas[:, 1] / max(float(np.ptp(y_values)), np.finfo(float).eps), ) - local = np.clip(np.searchsorted(cumulative, targets), 0, len(lengths) - 1) - arrow_indices_list.extend((segment_offset + local).tolist()) - segment_offset += len(lengths) - arrow_indices = np.unique(np.asarray(arrow_indices_list, dtype=np.int64)) + cumulative = np.cumsum(lengths) + if cumulative.size and cumulative[-1] > 0.0: + targets = cumulative[-1] * ( + np.arange(1, num_arrows + 1, dtype=np.float64) / (num_arrows + 1) + ) + local = np.clip(np.searchsorted(cumulative, targets), 0, len(lengths) - 1) + arrow_indices_list.extend((segment_offset + local).tolist()) + segment_offset += len(lengths) + arrow_indices = np.unique(np.asarray(arrow_indices_list, dtype=np.int64)) dx = x1[arrow_indices] - x0[arrow_indices] dy = y1[arrow_indices] - y0[arrow_indices] lengths = np.hypot(dx, dy) diff --git a/python/xy/pyplot/_rc.py b/python/xy/pyplot/_rc.py index 60922f19..7de5017e 100644 --- a/python/xy/pyplot/_rc.py +++ b/python/xy/pyplot/_rc.py @@ -164,8 +164,6 @@ def __setitem__(self, key: str, value: Any) -> None: "ytick.major.size", "xtick.major.width", "ytick.major.width", - "xtick.major.pad", - "ytick.major.pad", }: value = float(value) if value < 0: diff --git a/python/xy/styling/capabilities.py b/python/xy/styling/capabilities.py index 1b4aed19..6e17efc7 100644 --- a/python/xy/styling/capabilities.py +++ b/python/xy/styling/capabilities.py @@ -358,6 +358,7 @@ def axis_style_keys() -> tuple[str, ...]: return tuple( sorted( styles._AXIS_COLOR_PROPERTIES + | styles._AXIS_FONT_PROPERTIES | styles._AXIS_LENGTH_PROPERTIES | styles._AXIS_SIZE_PROPERTIES | styles._AXIS_COMPAT_PROPERTIES diff --git a/spec/design/wire-protocol.md b/spec/design/wire-protocol.md index 97cc664d..4809f966 100644 --- a/spec/design/wire-protocol.md +++ b/spec/design/wire-protocol.md @@ -420,9 +420,9 @@ The reassembled bytes are identical to the source blob, which is what keeps Two independent version constants: -- **Renderer/spec protocol.** `PROTOCOL_VERSION = 7` (`python/xy/config.py`) +- **Renderer/spec protocol.** `PROTOCOL_VERSION = 8` (`python/xy/config.py`) rides every first-paint spec as `spec["protocol"]`; the client's - `PROTOCOL = 7` (`js/src/00_header.ts`) is checked in the `ChartView` + `PROTOCOL = 8` (`js/src/00_header.ts`) is checked in the `ChartView` constructor. A mismatch replaces the chart element with "update the xy package and restart the kernel" and throws. Requests and replies carry no version of their own — the handshake happens once, at first paint, before @@ -436,7 +436,9 @@ Two independent version constants: client would draw both as linear without erroring. v7 widened `colormap` from a built-in name to *either* a name or explicit evenly spaced RGB stops, and added an optional top-level `palette`; a v6 client indexes its built-in - table with the stop array, misses, and silently paints viridis. + table with the stop array, misses, and silently paints viridis. v8 adds + legend/colorbar geometry, named colormaps, and match-fill strokes that an + older v7 client would accept but silently render with its old defaults. - **Transport frame.** `FRAME_MAGIC` `"XYBF"` with `FRAME_VERSION = 1` versions the binary envelope separately, so the transport and the renderer can evolve without coupling. diff --git a/src/lib.rs b/src/lib.rs index 9554250f..65402622 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,7 +82,7 @@ unsafe fn borrowed_byte_spans<'a>( /// ABI version — bumped on any signature change. The Python wrapper checks this /// at load time and refuses a mismatched library loudly (§33 comm-versioning /// rule, applied to the in-process boundary). -pub const ABI_VERSION: u32 = 42; +pub const ABI_VERSION: u32 = 43; const FACTORIZE_CAPACITY_EXCEEDED: usize = usize::MAX - 1; #[no_mangle] diff --git a/src/raster.rs b/src/raster.rs index aa4eeca0..671461da 100644 --- a/src/raster.rs +++ b/src/raster.rs @@ -2011,7 +2011,7 @@ fn paint_points(cv: &mut Canvas, batch: &PointsBatch, threads: usize) { batch.n, |i| { let (cy, rr) = (f32_at(batch.ys, i), f32_at(batch.rs, i)); - let ext = rr + batch.sw + 1.0; + let ext = symbol_extent(rr, batch.sym) + batch.sw + 1.0; Some((cy - ext, cy + ext)) }, |sf, indices| paint_points_band(sf, batch, indices.iter().map(|&i| i as usize)), @@ -3342,7 +3342,9 @@ mod tests { rs[8..12].copy_from_slice(&f32le(f32::NAN)); let batch = PointsBatch { n, - sym: 0, + // Diamonds extend sqrt(2) beyond their nominal radius, so this + // also guards row-band bucketing against clipped tips. + sym: 2, sw: 0.5, stroke: [10, 10, 10, 255], xs: &xs, diff --git a/tests/pyplot/test_adversarial_parity_fixes.py b/tests/pyplot/test_adversarial_parity_fixes.py index c8052a28..529f44de 100644 --- a/tests/pyplot/test_adversarial_parity_fixes.py +++ b/tests/pyplot/test_adversarial_parity_fixes.py @@ -126,6 +126,18 @@ def test_subplots_adjust_overrides_set_position_for_gridspec_axes(): assert np.allclose(ax.get_position().bounds, (0.35, 0.11, 0.25, 0.77)) +def test_add_axes_does_not_reshape_the_subplot_grid() -> None: + fig = plt.figure() + subplot = fig.gca() + absolute = fig.add_axes((0.7, 0.7, 0.2, 0.2)) + + fig.subplots_adjust(left=0.2) + + assert subplot.get_position().bounds == pytest.approx((0.2, 0.11, 0.7, 0.77)) + assert absolute.get_position().bounds == pytest.approx((0.7, 0.7, 0.2, 0.2)) + assert (fig._nrows, fig._ncols) == (1, 1) + + def test_month_locator_bymonth_subset_keeps_rrule_stride(): # rrule's MONTHLY interval strides over *all* months; bymonth filters the # survivors (matplotlib 3.11 reference). diff --git a/tests/pyplot/test_autoscale_margin_bar_regressions.py b/tests/pyplot/test_autoscale_margin_bar_regressions.py index d1188a01..61fcbdc4 100644 --- a/tests/pyplot/test_autoscale_margin_bar_regressions.py +++ b/tests/pyplot/test_autoscale_margin_bar_regressions.py @@ -149,6 +149,34 @@ def test_categorical_bar_domain_covers_every_category() -> None: assert _axis_domain(ax, "x") == pytest.approx((-0.59, 3.59)) +def test_repeated_categorical_bars_share_the_renderers_category_map() -> None: + _fig, ax = plt.subplots() + ax.bar(["same", "same"], [1.0, 2.0]) + + assert ax.get_xlim() == pytest.approx((-0.44, 0.44)) + assert _axis_domain(ax, "x") == pytest.approx(ax.get_xlim()) + + +def test_nonzero_bar_base_stays_sticky_in_the_rendered_domain() -> None: + _fig, ax = plt.subplots() + ax.bar([0.0, 1.0], [1.0, 2.0], bottom=10.0) + + assert ax.get_ylim() == pytest.approx((10.0, 12.1)) + assert _axis_domain(ax, "y") == pytest.approx(ax.get_ylim()) + + +def test_fill_between_and_errorbar_geometry_contribute_to_autoscale() -> None: + _fig, fill_ax = plt.subplots() + fill_ax.fill_between([0.0, 1.0], [2.0, 3.0], [-5.0, -4.0]) + assert fill_ax.get_ylim() == pytest.approx((-5.4, 3.4)) + assert _axis_domain(fill_ax, "y") == pytest.approx(fill_ax.get_ylim()) + + _fig, error_ax = plt.subplots() + error_ax.errorbar([0.0, 1.0], [2.0, 3.0], yerr=[5.0, 6.0]) + assert error_ax.get_ylim() == pytest.approx((-3.6, 9.6)) + assert _axis_domain(error_ax, "y") == pytest.approx(error_ax.get_ylim()) + + def test_default_bar_margin_reserves_visible_headroom_for_edge_labels() -> None: _fig, ax = plt.subplots() bars = ax.bar([0.0, 1.0, 2.0], [1.2, 1.8, 1.4], width=0.55) diff --git a/tests/pyplot/test_axes_charts.py b/tests/pyplot/test_axes_charts.py index 918c75e6..71911f13 100644 --- a/tests/pyplot/test_axes_charts.py +++ b/tests/pyplot/test_axes_charts.py @@ -430,6 +430,28 @@ def test_streamplot_translates_lines_and_arrowheads_to_xy_marks() -> None: assert len(traces[-1].x0.values) > 0 +def test_default_streamplot_uses_the_native_integrator(monkeypatch) -> None: + from xy import kernels + + called = False + native = kernels.streamlines + + def tracked(*args, **kwargs): + nonlocal called + called = True + return native(*args, **kwargs) + + monkeypatch.setattr(kernels, "streamlines", tracked) + _fig, ax = plt.subplots() + x = np.linspace(-1.0, 1.0, 10) + y = np.linspace(-1.0, 1.0, 8) + xx, yy = np.meshgrid(x, y) + + ax.streamplot(x, y, -yy, xx) + + assert called + + def test_artist_set_ydata_rebuilds() -> None: _fig, ax = plt.subplots() (line,) = ax.plot([0, 1, 2], [1, 2, 3]) diff --git a/tests/pyplot/test_axes_helpers.py b/tests/pyplot/test_axes_helpers.py index 4aab7194..25d87bd4 100644 --- a/tests/pyplot/test_axes_helpers.py +++ b/tests/pyplot/test_axes_helpers.py @@ -2,6 +2,7 @@ import pytest import xy.pyplot as plt +from xy.pyplot._artists import Legend from xy.pyplot._rc import rcParams @@ -36,7 +37,7 @@ def test_ticklabel_minor_label_axis_and_legend_helpers(): ax.set_title("title") ax.ticklabel_format(axis="x", style="sci", scilimits=(-2, 3), useOffset=False) ax.minorticks_on() - ax.legend() + legend = ax.legend() assert ax.get_xlabel() == "x label" assert ax.get_ylabel() == "y label" @@ -45,7 +46,8 @@ def test_ticklabel_minor_label_axis_and_legend_helpers(): assert ax.get_yaxis() is ax.yaxis assert ax._axis_props("x")["tick_label_format"]["style"] == "sci" assert ax._axis_props("x")["minor_ticks"] is True - assert ax.get_legend() is ax + assert isinstance(legend, Legend) + assert ax.get_legend() is legend handles, labels = ax.get_legend_handles_labels() assert len(handles) == 1 assert labels == ["series"] diff --git a/tests/pyplot/test_axes_layout.py b/tests/pyplot/test_axes_layout.py index 4e523f2b..7abf7012 100644 --- a/tests/pyplot/test_axes_layout.py +++ b/tests/pyplot/test_axes_layout.py @@ -65,6 +65,19 @@ def test_margins_expand_only_automatic_domains() -> None: assert ax.get_xlim() == (0.0, 1.0) +def test_negative_margins_shrink_the_rendered_domain() -> None: + _fig, ax = plt.subplots() + ax.plot([0.0, 10.0], [100.0, 140.0]) + + ax.margins(x=-0.1, y=-0.25) + + assert ax.get_xlim() == (1.0, 9.0) + assert ax.get_ylim() == (110.0, 130.0) + figure = ax._build_chart(640, 480).figure() + assert figure.x_range() == (1.0, 9.0) + assert figure.y_range() == (110.0, 130.0) + + def test_axis_tight_sets_data_domains_and_equal_expands_to_panel_ratio() -> None: _fig, ax = plt.subplots() ax.plot([0.0, 2.0], [0.0, 1.0]) diff --git a/tests/pyplot/test_categorical_gallery_regressions.py b/tests/pyplot/test_categorical_gallery_regressions.py index 1aab7931..ce7f93f1 100644 --- a/tests/pyplot/test_categorical_gallery_regressions.py +++ b/tests/pyplot/test_categorical_gallery_regressions.py @@ -86,4 +86,5 @@ def test_barh_gallery_width_vector_remains_bar_value_geometry() -> None: bar_trace = ax._build_chart(640, 480).figure().traces[0] np.testing.assert_allclose(bar_trace.x1.values - bar_trace.x0.values, performance) - assert ax.get_xlim() == pytest.approx((0.0, 9.45)) + # Matplotlib includes the x-error geometry in autoscale: max 9.2 plus 5%. + assert ax.get_xlim() == pytest.approx((0.0, 9.66)) diff --git a/tests/pyplot/test_color_pipeline_fixes.py b/tests/pyplot/test_color_pipeline_fixes.py index c0cae0e3..dd530644 100644 --- a/tests/pyplot/test_color_pipeline_fixes.py +++ b/tests/pyplot/test_color_pipeline_fixes.py @@ -264,3 +264,15 @@ def test_contourf_fills_discrete_bands_not_a_smooth_gradient(): expected_ticks[np.abs(expected_ticks) < 1e-12] = 0.0 assert colorbar["ticks"] == pytest.approx(expected_ticks) assert 0.0 in colorbar["ticks"] + + +def test_contourf_includes_samples_equal_to_the_final_level(): + values = np.array([[0.0, 1.0], [1.0, 2.0]]) + _fig, ax = plt.subplots() + ax.contourf(values, levels=[0.0, 1.0, 2.0]) + + heatmap = next( + trace for trace in ax._build_chart(640, 480).figure().traces if trace.kind == "heatmap" + ) + + assert heatmap.grid.values.reshape(heatmap.grid_shape)[-1, -1] == 1.5 diff --git a/tests/pyplot/test_gallery_layout_api_regressions.py b/tests/pyplot/test_gallery_layout_api_regressions.py index d5fb3446..6eef892b 100644 --- a/tests/pyplot/test_gallery_layout_api_regressions.py +++ b/tests/pyplot/test_gallery_layout_api_regressions.py @@ -78,6 +78,20 @@ def test_tight_layout_reserves_subplot_tick_chrome() -> None: assert vertical_gap >= 43 +def test_tight_layout_recomputes_materialized_subplot_rectangles() -> None: + fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(6.4, 4.8)) + + fig.tight_layout() + first = axes[0, 0]._figure_rect + fig.tight_layout(pad=3.0) + second = axes[0, 0]._figure_rect + + assert first is not None and second is not None + assert second != first + assert second[0] > first[0] + assert second[2] < first[2] + + def test_subplots_constrained_layout_reserves_subplot_tick_chrome() -> None: plt.close("all") fig, _axes = plt.subplots(nrows=1, ncols=3, figsize=(8, 4), layout="constrained") diff --git a/tests/pyplot/test_p3_option_contracts.py b/tests/pyplot/test_p3_option_contracts.py index f5a403a5..aaf48ee6 100644 --- a/tests/pyplot/test_p3_option_contracts.py +++ b/tests/pyplot/test_p3_option_contracts.py @@ -327,6 +327,36 @@ def test_barbs_support_increment_flip_size_and_color_controls() -> None: assert triangle_entries[0]["kwargs"]["color"] == "#ff0000" +def test_fully_masked_barbs_return_an_empty_collection() -> None: + _fig, ax = plt.subplots() + masked = np.ma.masked_all(3) + + collection = ax.barbs([0, 1, 2], [0, 1, 2], masked, masked) + + assert collection._entry["factory"] == "segments" + assert len(collection._entry["args"][0]) == 0 + + +def test_stem_dashed_basefmt_builds_a_flat_dash_pattern() -> None: + _fig, ax = plt.subplots() + + container = ax.stem([0.0, 1.0], [1.0, 2.0], basefmt="k--") + ax._build_chart(640, 480) + + dash = container.baseline._entry["kwargs"]["dash"] + assert dash + assert all(np.isscalar(value) for value in dash) + + +def test_path_collection_get_sizes_tracks_set_sizes() -> None: + _fig, ax = plt.subplots() + collection = ax.scatter([0.0, 1.0], [0.0, 1.0], s=[4.0, 9.0]) + + collection.set_sizes([16.0, 25.0]) + + np.testing.assert_array_equal(collection.get_sizes(), [16.0, 25.0]) + + def test_barb_staff_length_is_screen_stable_across_subplot_grids() -> None: def staff_pixels(fig: Any, ax: Any) -> float: ax.barbs([0.0, 4.0], [0.0, 3.0], [50.0, 50.0], [0.0, 0.0]) diff --git a/tests/pyplot/test_rc_chrome_contracts.py b/tests/pyplot/test_rc_chrome_contracts.py index 580cc25f..f61b16aa 100644 --- a/tests/pyplot/test_rc_chrome_contracts.py +++ b/tests/pyplot/test_rc_chrome_contracts.py @@ -1,5 +1,7 @@ from __future__ import annotations +import xml.etree.ElementTree as ET + import pytest import xy.pyplot as plt @@ -90,6 +92,17 @@ def test_rc_fonts_and_axis_strokes_scale_with_figure_dpi() -> None: assert built.axis_options["x"]["style"]["tick_padding"] == pytest.approx(7.0) +def test_rc_tick_padding_accepts_negative_values() -> None: + plt.rcParams["xtick.major.pad"] = -4 + plt.rcParams["ytick.major.pad"] = -2 + + _fig, ax = plt.subplots() + built = ax._build_chart(640, 480).figure() + + assert built.axis_options["x"]["style"]["tick_padding"] == pytest.approx(-4 * ax._point_scale()) + assert built.axis_options["y"]["style"]["tick_padding"] == pytest.approx(-2 * ax._point_scale()) + + def test_spine_controls_and_invalid_cycle_boundaries() -> None: plt.rcParams["axes.spines.left"] = False plt.rcParams["axes.spines.top"] = True @@ -150,6 +163,18 @@ def test_explicit_set_title_weight_still_beats_the_rc_default() -> None: assert built.axis_options["x"]["style"]["label_font_weight"] == "light" +def test_quoted_font_families_remain_well_formed_in_svg() -> None: + _fig, ax = plt.subplots() + ax.set_title("title", fontfamily='"Foo Bar", serif') + ax.set_xlabel("x", fontfamily='"Foo Bar", serif') + ax.set_ylabel("y", fontfamily='"Foo Bar", serif') + + svg = ax._build_chart(640, 480).figure().to_svg() + + ET.fromstring(svg) + assert svg.count('font-family=""Foo Bar", serif"') == 3 + + def test_spine_open_slice_targets_every_side_like_matplotlib() -> None: _fig, ax = plt.subplots() diff --git a/tests/test_capability_registry.py b/tests/test_capability_registry.py index 690ab9ed..88daaee2 100644 --- a/tests/test_capability_registry.py +++ b/tests/test_capability_registry.py @@ -54,6 +54,18 @@ def test_registry_covers_exactly_the_public_dom_slots() -> None: assert tuple(slot.id for slot in caps.CHART_SLOTS) == CHART_DOM_SLOTS +def test_axis_style_registry_covers_the_compiler_vocabulary() -> None: + expected = ( + styles._AXIS_COLOR_PROPERTIES + | styles._AXIS_FONT_PROPERTIES + | styles._AXIS_LENGTH_PROPERTIES + | styles._AXIS_SIZE_PROPERTIES + | styles._AXIS_COMPAT_PROPERTIES + | {"tick_direction", "tick_label_anchor"} + ) + assert set(caps.axis_style_keys()) == expected + + def test_property_kinds_are_derived_not_restated() -> None: # `kinds` reads from styles.py at access time rather than being typed out, # so there is no second list to keep in sync. Guard that it stays that way. diff --git a/tests/test_plot_families.py b/tests/test_plot_families.py index c54a8c15..82e47646 100644 --- a/tests/test_plot_families.py +++ b/tests/test_plot_families.py @@ -144,6 +144,24 @@ def test_triangle_mesh_boundary_rejects_nonfinite_coordinates(nonfinite: float) assert boundary is None +def test_triangle_mesh_boundary_merges_vertices_across_bucket_edges() -> None: + # span=1 gives tolerance=2e-5. These are two encoded copies of the same + # vertex on opposite sides of the old round(... / tolerance) boundary. + lower = 0.9999e-5 + upper = 1.0001e-5 + boundary = _paint.triangle_mesh_boundary( + np.array([lower, upper]), + np.array([lower, upper]), + np.array([1.0, 1.0]), + np.array([0.0, 1.0]), + np.array([1.0, 0.0]), + np.array([1.0, 1.0]), + ) + + assert boundary is not None + assert boundary.shape == (4, 2) + + def test_new_marks_reject_invalid_inputs_without_mutating_figure() -> None: fig = Figure().line([0, 1], [1, 2]) with pytest.raises(ValueError, match="errorbar requires"):

    vTwnfnH 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 literal 114064 zcmc$`bySt@x-X24N~tJ_QWgkGcPa*mgdzfxA|2A5DkUNUDxgv#B_bu#B~B$oT2ev; zq`Uk4rtdy`uf4|ijeXAe{`lrt<6WRI=kwh6bzj%79{sN=NR#iO+e1P^LViW&q7n(o zZhW~lnsh7v&r>z4gJcT{$(4)em7O}qy6l~lTNebU+{;f2SUWCylQNev=h4V&us%Pu z$EQ(g#AeioPT4s2T5MjSM*VhDW|@ck99yg8%6lXi(g&lCcq!#qF3!$%`^i0t*=AIy z?VA3TmTV{SbN=%+mGSG>{{Q@r_{Dh=vVZ;l9uvvVfBpU(70I@L{ho>R9T!A>DfWU*GP3y7>R$*GaZ-;riFN`}ceQ`|A_FWw$?FBL3LN zEC2j3@g}BNv+SmF?WQP$4tFlAo=g~+%WaB&xf#UpNvE@9`q0i(3M(TKp^HTW;;R&t zhlRhEiGOEdwP^fd)Rd+@soT5u;0=q>cU!By<2Ib)n}_he3>M{gpGtn^BH$xDHi zI_!B^Pf_T>{nWSDmdgkgC--Mc#TKo~%exwG#2#lk!j`p}A2;qyvz1xr(_qifFhR?o zyqgJvNs|1_C3Ewp{N|V4E>RoVs()5jos9(K3;dGyWbPm$PqRh46Bdf9EKnPHl5-`FMGCi&T~wkt}ed+PQ^ zcn2pxtLWp#ishvrm301-{F3to#o?*u#zh~gGXEQc5}T%%u3xWuWEmFhnWCDst8n4y zhwN;DA#&G6M*o1of{2^y8UyL2>zUImo(VUbW(zzM2o<-v#OA-R1<<4yO^-ZytKF;G zn09u3W_47M*YWPMk1nm)%fF?!G&uLfUoPKi;8*Mc`mMKjQAE+Uac=wyIY3#TZ)fqo z^JL)V)fU$n2?6W5Tpjl{X~k!w4>J|hdOpV4l8mh~dM>Y}9K692v^gc2zU=emUzaVx z;NVWLSRJX!x7xZbg==i(!T|u17OHqaXWbRADt@OS} z*F#n0>qeiJ*7w@}n)2s0dM3I2E08AI)0gULJjD<>uPx!Ay5)kvyM*<;#K5T5==Rykn$pgLqgg-6QE-I(TO#SJyO3 zgPmw5E898GSeV^7DrR#`#3L_GdMP;MMq1DJqE&|wYqn^Uy6=*1b3cCd1_`@f!kJQ^ z`Rb^i`o!)a$#L(z!U8*IC!b3R-oX;ZaqWt~`|gl3^Jix}ibYE{|2Tbyt^K3@;QPah zLTx|0tV^p-higUBo6H4J9Xk~8z-xVPfb5hI`gNz}o;_F1@4h#l3vjvf&HD@UHnx;^ zu0uA%vG>oDUT6C$sr})Mm|=#OtD1RFh>mBWY=V+~{-T$(f|}?K3CT_VV(p&g++@|X z(C1-_w1PH2rpiKZHskxQX*-Uj#LXOw>eb0J6S^-Yo8JvPYuO}G#4vFDm?-vh5}RmJ zl-HGfxzVrB5nkvz$t)K3PiZFw(sB2z7%E)1KD}BM5|>2EOgONMj#H(lUdZM1Tx4ev zr^ISqd5?#kgUyT0#)u?^7#7dRc8PZ%>g~#*3v%IL<8Zg=W+(VjbWHuEv@FS)`jVV= zyj-Ha?T1_eU4+>5v{ATwp=tkA*-wGgWs|SriHVI#M#W3(L8Ws=0TZ3;X>oC%*#j)e zj)>e_@Bh|3>K%N3+kO#FG3&Lr45#`Q*EEPHJ|;n@TBg`#y<#$~_SN*4+OA!L98T-& zK_yO$HR0jz)91B4dJibp8EjJ(&kYb^J)7#ZoV{o$7xTe-JjlIIuT*oRFTC1=N$ckA zgL{0EOXpXB>&LznJ&kHolcr~gr-a|NJB8p&vDEuBp?sfEOIqO;>nhxosT+LLVyx{kUW^qv_4r6T;g07!V&{slpood){895*j?q%_z=6|+ zMajwjLAe$91MKRe=r$6uO8o^7#TvKRf`XQB+`s&8mVSs)jM`Yst1!&iTTj`#R&d^M z(vg3C=Xz#NnzrF&?ojq-hM743?2ebkI)3BTW9ter@`jS_S(6#xyC;h&B?To&Rt68U zdxo~JrfwK)E6mVNXOtW`Y?kzC?ZIybhcb&;LX2y-y(4;Tg<|yZLBY8$%CM37mBRdc ziwl3Zu&3ja%9Abp+4gf4ZzTx0yio!3I7yGGDpelWQg)NpiA1d*`SLbPL#J2b6q5E1 z^E2_8-X7exr)=JcnECX-qGv=-W<0VpV!2 z-|lM_ucqOopy}F2%Mu-TcHShy)~G^F7mM3&v+Jh#;W7eC+d!$>!nU8< zM=v3+!zvw=;U82tlHs#ENV2d0@RN%Dza;z)-zK5lrlB$V;_bt2ejA*7-$=!ZxeNF_ zA>k1)ANqu2=DQy9yZoEd8I0 zM!O=duk-wXvq+Rh#l-rem9}H4nO>SiaiSQ1l6>skjGZ($fbTtN*?Xmw5l!V?H9l00 zlR-J&5h=XP@o6Q~3>}wRRKmu_*eU$_CI@d^za?MrYD=QvQ0`sL^&bbGt&~@kEVi(x zpK+5|@2GL#^<=-)*!W$~TiIs>({E2btimVx2EJ6+)^1O?JQ`H7exstv_QqgVT`50z zNXgP?+c6gL$yT+ych?_WvUGKIE)tr&C3Y3(sJ|p-OAq_}=MapS#5W&C2#Tc&w0sVg zm8XYWEfz9l>&PERxl$Aei9R_h@j`3kWm1yITuiI;W&3ff%D`OeIrc)RBxJwUAjN`6^?qYrp0h^a4H+o z^j{1LBNL8y$0|!|QaqQw0Rn}#_UL3A(npgMH^ncoW;1<=iE3&$bB;jEoU}xYW#`QD zjqziWI-Gsio}K$NX;Y;r={9=V^l5q!&1%(wAVntcNX3$iq^RP7OqS@qyBBl{|NPum z*y=gm?&>Dt*&Sf1SroaD^d!kIu{Qfi?gFF8#^+hyv)^mlC|$cbx!JbN^na(J-t)CQ zTT<$J-03-y<6iBn@`gPFgHSAEC{i-6JmES?Ni+ za*NASMNNijJySl`&8_2T;N`-*eIpF7h~Vpl_v09`rmv!nUqxrWs&+Gbj}4#N`v%}{ zxp~vc)wO79jaNK!n79S`7IiKq*Q8?4B`7(nC1@q=_xE->wS~wa&TRyesNr{BCzMhg zm0&nWA;|-qxszzshZUR@Qf|r?#_IkJBovxp0 zdT)+1LMFN_0m%1rtYv?S@D9WNFsYszD4}=(t&{<4^OU{QJ7~quJ_r zDP4ta1%wA3JT4hDC&$lrosDZAp*SkCv82~WG2T_VLBmK>y!k7WBV4D{#PwSOyAH=P zrB-;05kD=Nd2CB*+q+?luIPEU*rW7g@7|e-ynpZ^nS^pX5&jd(8p=vk^@qxivm`0J zv|9Vp-bzzi@BEUpM7wviFMD{A(WFc%zi8YdM^jU&Mfa_O$N9|MBJpoqn?Ijgvqw<<9v`r#WU*f?j4u2&U$Ej!AK_^zxzGP%i9|FFr_R?b;2ILoOsyXV znTxeM$)b!64L?{8ZpMV(ymj*eX=ZK~v$y_W|NI2KftZVk2-^dy#;iM0to zQdpkVx=&4{lppMv%+oP#Fq=FXC0shZ7@FA-;v_&^zYC?7Z40X_snw+`FQTF^ksgi~ z3Z_!JspV=(&cMRr_vZKJh?9x2xook`S-umW%DSIW{q7&KGM+34rC9rX)iPg5^wRvE z(V~DRBhDX!dadaazOjpM0*Zm6>{WAg%5vi#&c;|-W2d4G6Qhg`ccF(gSuYph(DKB9o zmYkoEQ0-`SLGM{$_Q{`Kwtw9AFkeh>&DzW5&FpQ=x5>Z8vgoj}++RHw2YZY0&EZx|4O(PQsMf90%m z2jlHKRp+K#D+gpS7Fm>DvfR*KrQ7nDWx`2JT+p7BIjQc1j?5LUnQ2k;Z_+Att6H<8 zAneX3+gETZWy7FEw*DR(K z7mNK_+c!4cInZdkO|RjzF!-{wMfdMq9nY$sy4A7e=Zq@r0*(u0sx&NpT0h&{&DB;3 zmDY;l664EptAY_PUw$Z6N^bUh5`9$IoGZL~JVRFh;?Rayg@n^$GX+bdvjQ#im(I?| z>ub>({Nm}Ws_MRR(qzLu>2=aE95+(%`qpj(5=Lq*M7{ z{F<*ikh+A_kn_v!}6 zJ7=mLCD)2<>&h5a*H2OHk$SMTWqoCRXx|0bHlOK3B1f(23Iz;LX9<1qoE_A02OTE| z3*fmLaDV-`;M&4A@^`mx-BQ2xZOR+V{i!QAVB&t(GeX09grwHWcv6gK)3u(V@$u>T zLB{Wq8%vwnuTBLyI@oAt&a^H{tN^`#{n|cVRl&mXLNFjl$weYMIzq%dSW#lLysAO> zPg9Vi#JlK4qQbCWs^xBHjzyn9Uv}Hki})<7n5C6j%AJ&Bg)8CnmZhcf2?@=B75PTd zuOt@_3vlWTa)e`IKcQHtps-kXs+y@QUC~ZZadj^6%^ceNIAx{g;gMQL2ae-KL~t&K8D*9Hu+El%z2GpF2rLFkc(@;|yD$ zs_u}Fai30&O0AjAit$(vU0zg~Vj$U&e+*IXCds`CHIb#DqY_R8OUYjVp#S+gPyXM8 zy}vvEpMQxj{$164y%Vy=f4zv^_rJa)A^Cq42LI&;{(q1q|KC6T-&M_jzxn@5QS{$` z{omK_-|qc?`t*PQb&~%B3HJZ|UjHvQ>VLY}|7oc<^~5y)k>7`&_EJI#)1_UoE!I{f z)uk<8B9!jylJFzsGuB2$4{t8qp77i2B-u&*_h#-DR@7VC{mXrkkZkAu^!NK;%q>5D zD66Z#Q)VkJDtiC^J=xA}1TLs~_%b2kYjbn+j~{cEJtnTMt|lhQWw)nhW`5h`Z>HF) zCMypN4BWhVlP&aHceex+)4k}8bucGrS(dIZOjj@}UcGwUdua3A zhNu?9s=s!6>#*HUulpP4lbY<84z8c=I?f!Qm*>>*=F(mo4s$azURpA{v`lPOFh8mSjP*gSBaZnI^HNmSFD zgR;)ad4W_kCR-utxVN&h@)`Ay#+`ZAdwd>H-6`_n2zpk0O-q}7MbF-TUc<7O->CLz zf>Qf(Vn&QzxA~x1BO!EhDurUOQbI=D?VoM>JMfA3>QX*9D=#PKEv0K?W8>oDqN#b5 zT;So?J2!6JU3!jq+g&vmc+%urX19NsFnz&I z7S}YqFxkU-C_vDnb7*j|b)dyXC|%M%xGS~0cS>X}pHN22c_u{W&Ye3)>FI~b?}U%( zN;^iHRB%03X5;7P9=5tM^gfRxx1M0=`j(-UkS?Ml_x;j;>-j5Ju4rjR z6&AW)y?WK!nmeY>(a|wCH@DR^`|H=Q2M->cJ0LABEl|M})zZ}6t*xrs`s2rm5E=8k zch8!v#z$bwyMh7%Ia-eTFdCXgM&j@ zSXh7Qjje~MsfX-D@Y$a~fA;m=86wj^GBWb(*QW`oq^8jD@bJ*k?A+X}(gbeie9h>X z7)w)A)4O-0A|h}xrWO_xfBqO67<|=sb~#p4Q?uXyOKWRxW@ct~c5_!(*Z1%5-@SYH z;X`9XLql!tlW1jkcXyl?+*C?RijU9NAIUd<{`|RP>;21dr#Uz*OiZTd=TqOlef$1> z|Fjba2Zy%Ml>jBEJu;|Cu<|85^CARa7n zwt826{WW!U*;a$_^yK8zr%!Y9^Uu%Dj?R2*ZEYQ$cfr!(?H0Z?o7!V*?CrB<6Q0T@ zFfcH*w6q+hfMGy=@F0$^vy)TX&!0{HcMJ>+va_=n78Vo~6euq`$o{Q`B|&S+rC-}L zcl`ZsXl!Bpr}UGfFZoQKqF2}rD_y%5jN4O461Dv!cm8}?ee8v<&Q2a49&MN5ga|>) zCybKO<-%-iY=6GLd=?qmnXV(5th_Rw+f%aG?RqCu=;XpoVyx#@1~}wTk7ie zehXz+O;yjf?ki7BObiaDI&k0sUG)`N*{9V5Dk>@(Ip*yjO`4|rDpKCPL*2>C%OCc= zo~&$C7rj1H&FQ&35Z+bjh@$;iP|$(8>*#o;`vRSzXz6!AYr2jgEt!tT@<7!y7Bf@R zwe|J0XU_%_xKdM7f9Bj>{T;yRvAMqJzPfPob>aepKIq`{!ShmEZ zq@Du%>W+?%>gucMtxfxl$q33fZx(N?j7A9DeOje&*7E*VmSN4t`fByJZx6h@OsM5k znzf6Zte0m7*j3Xyi(MCEFZg}?_AN3h>aMxD(9zoY(bmDbn3%9IbcgV>8Vl8&rAH;) z)RLMmUA{cC>?S31;R1o!3EPcg?zVpz!0JH8ZPoGA%C*q4vdSndTuqdZ=yn-B%g&zi z@F8ijc3rO(1--~eEiEk#3?yeh!O1yU!RV=(dFSgySD|8*$W1jhV>7eSv9V6w&$m!iN=i!Z z?&4jm<$*_n=tWi3)Q0-{;u?%OH1no9ZR=1%SoVfKBicXVIv(h=sw1PL(t&iBD4%MJ z-DPA*4ZVouorI)}>>nJKcZ6>bYWm>O zqi$HWzKWp5k>->O+M*0WM!?>ovi{fai170AzTya?f(7U;)r-1g@LZcVX-bR|wly5@ z$d+86dxrIWecnskbv&D1)L{&zwK&l=J6Ol!4HujvTtibcGAvBM`uD|`at>=t(^`cN z)5~i+_8yWs@iav>-D7>emFMLcDtuvX?t5kB(nR4T*-pX{%OYJfv+BO-GiT4v&dwg8 zqeF%L85=u8MLN`*$-O^R)_!iN0d;y3ePXyV;aG?cEGLjLO>D5|{ar2Rrtfo1520ix*mS74&#+x^Jv4ypTPImMU48`pN0XzqvGD^MQc=-blcMB+O@8U-#wseg4?VW8kDsn4 z`9@L;4zSDI(3NMWtc4=Ic2T0O!q=hG-oMA^&!0b1vBBaD_s`w7u;4fpu$x&uH77PU zHZjq6XC$aQt#7{5^zWtVJ{_lCpZ@;-<`h*%VVf@~mM>rQE1u8~4-az|&nfkkxQEIb z$jZv1At)vDmBjW3kp*KcR0J_HO1LfI?4$lv(zVZ0?-{I#5HxSgNY%(iS3XEh?d|JJ zN9J2zUXD-u_3M}a0hSNpPZ$&p4gdI(ACZ!h!YUiyxnr}sF#i7i8IgoDXqVU;42O-4 z)yb%+sC2Eug)YY)>-^430f(yeKd{8OeZXRTf60qu%fM$`e}CI9v^K-hprvpddv?W7mB>Hp$?;DRsN6&acO(fKc|@^2K9csIPMK6^-wnp6$g z=;-u#dvC{K!l^yLqOi8`(-K=8!KJ%3sNx8IJ5#TsHd2@u=t3d}2l|I8zaPOri1-?u zUCznL0ldO(MDQ3q^70~}C!?End#sL^xUcS)a&vd*<>66?7IQ}JaO;&*NvUgSBq*6+ zWeEg=sD61I_X{jiwpr`U^4f4ylAoX70Vyn5noenn?O-jgOHxu2qdHlcIP%8FYsz1W zZ2#2p^XI&aJ1T3kyLj2HBq6~-MWy8lz3AmYIs;wZOf=1>PoFAEEPFFNMIXO)s~v^P zp;gfT`?nNnNcF(65LRYpW-+lyLhs|lynoh~XR+m@I8Sq7+y{ zWfdcZuIuP1>N(B5YNCD~HMy0*CB_gG<)5IG+;4+{<%EmC*C{EZy#zl_%{(sCAFNo? z@89J(!jBw23?!gHYVGKVDaaSx(#w4l_1N0LX(e@#2#2;pdnL@Atl z)(!yC)+Qt@40I5s0C0d;YkhrvTboQcU=~jK_3PK&BzkUhsolCYk9L=woc#LrYuv%{ z*`OiZ`Z>p+_3JdcK2;hyMN`AHkY{I9I5i+vBJ#JXOf{ik-VPj!Q!dqig zzkQSSDm&*Tj!S@rs~xqrkLG!mK5)+*lL5~yO-)SzSll~G(#55KxHzFVF_leBOmKqn zwT4E-^!b9kym~J_S~8R_Ucf{y#U*3emFJ92nu|AbKfs4en#)5lO0l%Rq*^joIWMNTNQQ0pQuVgZ4_kb_hL{~Q? zIGAa_|IqOUbSfVy>(zz3US-7c(9rk^7=U4TKALNWjNWH zKZ|pOPf$vJUeTAGlha+~+*DR}o|PIP7|5{cdl)}I|MK$k+#??!pBfxaLBT~YN(rif zuc&}Gsi}AUNQep*UWWg~nLc%m{LHn~)a*px#N|4PMO&*q^tF0SGeMQa&CMNqdfxc8 z6cbfjd;66W`&azWG2yKMeq*l%OMV!~oGTz<_9paJ>ht*OzDr4|`TiZS<3m;!=7Iqo z)fIPI9+ z*!f0VBihTSo}qUa6ck`zu|R$0fw?^%8fOkQ?SY$h7xy^#_ThE93v`U2cv7($sj2cw zO;`?aLx4^SKZ3SKU!E}z(7-JsvVw*nEG#S%#c}p*OQ}#1HB<{2_c<gqzb9+Y0F5v=D{C||vc9v^?e`adlqVoC@Uo(; z?8=`AOVn;wRu))TR@Q6)XNj?{uCALAfd0^pAKl&2&z~!6X^l@zc%UIZfBqap=*@qO zM5NaKuKuD-QWH5H-w@~lxITC7QzP(GQ&Y^PlxwWUPm9rIK78Pzp$T_YkgMR5b9Y}y z%iO@2btr+ zgG5DtqJx%~|FKXSX*hhHoSgjd;lmUZ6h|qfW3OozI>@7noSgFV^Kq87O5EB}e*yvv ziu4RM97AJcks%=%&(n{#XF>Qcc@02o(R zR$|3B2PHSJC@9ocR=$3gD-vmmS^>x3+*rr3R7#eUmj|GVj*k9Iye>*hLrRH}a4&fG z?psGkf#YPi*2MMn*1g-eG7?`gKwZ1GZ!cOIA?_kjfz-Kk=d`u8F@XY|?9~DYy@1N8 z7}tt164ut%AQqa%F4;**NhvAprvH(p{NHjUlOz2@oMiL&SC55Y@|HI?&itu~*n0n- z?@_$44UYl>a_{~G)b<4A1<+{}QRF*Q)@zlgnP%#_tn^nsOHoNJuo>91e0*4EkWHoBnh8)R zDca@Tn>Tj|zT}rKUBU_j>YD*Zyx`U=Dk>6*5gKNbJ4r?Q!*sqOP8w)TMN7+lX{t9) zI_Sw!;l`$>8%$JkQ6iz$0~|UfL|BGl1G)j~r&`@u0!?N2jxwzfXwab?;YiV_Xi&A1KNdi`%wsTVS7(oj`FfpBD3x(#;U>qnF zYiw%DQ`?$!jrCPT#PEnW)vMm%KTQze>>0(3-7_zQP=XL@X(Mn*ua)8nEA&zZ-T zTK>!#2Vy_z{qW+kUAz49@`PMnS2-x3hHc!Ty`0pvd;0@yE?`l#q^E?iF!89LI#pg> zosyFi=KEo6Y>deFCQDW)@&}`Bt*nNA=B5L?g1wx5lh`^sJRjehgR4nSuF8{op_FWH zYT9U;4X$|V834Zi?4O#s+hgP7Mm4Vv9zNWz+xVjFwy}vxh|GzQkPvp2_n>1I05p5{ zyyDjLO-((^%|@MT(sT;gWoXDaN9qXo9&zw{Y&tkp!qxDW=H_8LkxVr)-Ot_t?QIw; z>gpVj4uJD<*iL!NoY*fdU4hQ6rl$5hENo+nKnZwj16A z#H3$i#f_oAqc=EGhmvpBOuwCL&2JxgCcbj#UWCV2Khkdgc4im zjvYJDu~aYR(6{eC-Cgqo2=A;sHks9Xy3m-hWXp6sjRGzYabqN zpKS;3g*G=bVhT-9PmjPr$sAu?ybfr_7o+Ppd}Hnyk@!O)z;8>gOJ zfK+j8t*oX%%^Ny9iy&-?WXZ-gV47j6_e&KO7k|BDee2fYt{pWGQHr=iI}t6kUNAVU ze(KT7q^H@~K$jM#rnq={%`7cBarbZEUQ1S%imh)azVdCkh|}ZHAqcycmXoM$?6CjE z-@U!MmX?Zj;U4K{SXrGmmIuYf#3WXRj-#A8cn^TjLf&*yCL;jR=NA?>?edo(!y$oI z2j0y@rKX_)9jC#`6lhO9bzyck&ia~^jJ!N~aVsFXxLoUhS9VE;GZ&f(Ar=$Sir(b+ zikJUHpoN0w7s{Pl{h6*PFJFW6g1HM}joAP0c65Qfp)r1wrMjY zoHeKqP=`WQ#y{&E{#$8(!$!of`XvJPH*on{9}`_+p54`Va(JuVVJXr;&!Kr20Mnv< zeJ2AYb^A_^ZH18ErR*0>*>%QMd93BJDzkW)An#f%;ZT8Ce68x`WM$xCcpE|Svxhdu z&eQ1}VhB>bd2_x&nh}T;9SbjV=pr-yRd!F*!*}&8ziP@iEBBlzI^H*K=S(k>-n{%~ z*scInmqEfUFFszsEkl9W?P<(9@wRT90k({ZCMUv$I1h`T(gX67|=Uz2f&awFUY6 zUvY9;0){cx{t_G<43G_WG@s!!k>*^dx;nwB8ZPJ)2;uN1>On+UnEWu0cZ=|-Zq}mJ zK%r(rwKO>4Jv%!4hJlnXPDNi!9k@1U7$za_lU;Cr5$)~S`#X#B$i~PPrX9!rF8u%g z&;ORbNNgmZ7aena#d>+;$-dG4^Rzx)ge4dJ)N`I4B=Nd7U zDO9wi4cg>W>LmHX2{O(8c&|dTtG{vBZgIBwKb|phGKP1wwzdW-W1kcSgBb0>g9AfD zGJa-AS)%3l_v?dXhRR+N-DOPcRXy-wecN0>k#;)X_2X2$N(#F0N6PbY4fUkE*3S~S z?2hxTm8VHn4a`75O-M?TzId_z326s!{Q&9yCKLn{UU4C3O&2#LYLDw#QUcw29*V(j&S$K z9w|9XMOsGzcnAD(PG*rdzpIQDUv=iJwc0ER1| zaR5@m%oh%wQ3IiE(25D24mqOps5YtImQlvx!0Tw<|45m6#l_;|G(Z%l z*{>7=n7#P~1XPrjxybrZp|G)3;jQ9lF)+ahfmb1>0sy^zTM2UqVd0s9YMXq`zl2y= zNXSYk5|HY_g9i|KVy_KBZRqd+;u~OmOhV*7Br)O%&duHX*Eu?J>K;sU5cw|J^SBKXmxJ^7loT#s=Xps;eM;wlmwjG=yvj*LK|gjcwC z&mMplaFgQVV$6FCe(T7@v@{M$$rKJ}yUZAxeCff!ks&B)XpUCh1p9@O$}lQLXVH{t)5B~QEor*} zyN-xw($Z9tmC^MfpSHKZbYQgSI4y0-9d!dD*VV#%xI#1-0BTxaXkTYJIl)wk{$N&C z-?Wq6alqTOv^201Z2Xxsa%`b=Jr@he+)qHq$yQH=q6j70&hEL)iLo=qD=RA>K77FF z54?;9O59Be54u1U9MDT;XJ=E@1S{&ytIC32&~kmO$6P8qTqfj@{key{LFyMPxnY{d@D8SNwoe z*hn~-b>fSfz(a&-5&b%x=L3^K3DS)2e7c{vQ}{I*Tn$;156OXBpI1_{0oL*%H@8CP z@;}9X&og$TsWRkv6A0Ul8<29j;g9h0W>MIh!Tk6dK;ya8y9-Zlz@Y+~tyl2EhJsT3 z{{1yz@1ZjzN|sGQ!x zkos$1^0Gi)UXW-=zAX}!_U_#XBqel8Hcn2OfUo=Z?SsrtMoG!yd9f6qCt%rK?AICfIsA6PB zu>1x<8MLVw&kbRi&ZuTJHE?Xhg|T)hBvP?cpuwOyRh5;jr%#(08|ML6!n2Eu>%)p- z7?`X`yYPQhA4j(=Ss7tZRVjo<49;rNU34q<8cJDg_B*fbpYPnfym43GDZc{`AX*iW zP?F!hyF+^lIs^g|jJ$@AaeVy<$?54mdDcWZee1SuNeWRb@b>7%U6kP^Ub+OY#PZwo z(|l*X4A`)ZM@OB^J3E+(HjZV<@}I0aiPbL$6x~*alR!~y z^2G!M9AIaF^2P6~M`^>1vuyw1v(eJoiN9Kaas?3g0uFz8l-}Gk6h2PUwp|o_e0)S5 zd$iSZtSxh5VggZ<9`{8pFa=Z>E_U?SuXBQp&`&Vx!Gjc%m4Whvz-CjL>HJVc8iIE_ z=HRDN)6hV_L*5TKt3Np@`q7goP&B-Qf#Sto7sk4aS6fmwWD^=e*r05{VG9ThJm`NB z?GN{}3Z6ASJ`RcH@Vuuswp-%O2^pKh+i)Iy| z3ZVKJUB|fnFMi%BX300|+Omq=+hx>>^>>lpD6h z;bWq_zTu#`{hljr7uM#skx_Vbvc|r<;kw@A#nrJ zWU2kAivPv^)YKP)uAO>zkcI}>LHyXU-*G__A2Ksh^s_TF$1Y#lJG@&!Kmcp#4x<_d z2VBCZa;FNNrtjF;%;5OboK^2191IT*{?*_A5v73tLAjfs?CHVmK69wBpul0n$gghj zYC_|qM~@(NN?*D}&LEbTkT8Hcg7I(b=%^?s$0sO=bU;;A6_l0hY@sNF+4*?{n^3{1 zH6(FSwJ4)ODlZ$YsWcnd^4H-FDA z%O==Bqu8=#3-$|_1FgI#%P6SqHm#sVB+3Wt2{{LnF<3IJs-Xeo5ip#d%O+qWvmttw zjDemJdQp#hSO6GAXg}Cyw$Ksi##mv@4vb0Q2q0tmD_5o$7d=Oklc02BM#Cm`7;9tR z@Bbz)4nKijhkoSp>(hO(FJTdpj`nuUEqhp==g*&~|DFCH*pu=jPz?I?+vbs+905!L z=&D&4^e`anqQ#-T$)vn!EDu&mNk}+d>bhH#H^$bb;NY+TeQ|YhQqtfXH5A+q7bYzO z>v&bKE~W^br8)-BLHW#+mkWQUTVMV|A(%qAdna8$>v5N*l+&_*>vlLdgv&2`k*k3YvmNC*>k3dV3{C1Og~A9xEo$Df}-gLAZp}+E-5AVPtUkZcVS1ok-N*v`}wvFMJd} zGe*~vaxV*vbMP5cF4}1Kg?5CG7=mc%=sH?j97cX5qu-#MK&|NLk#v|stO1QtUcE`z zZ0ux0p#VSscx!r0K)_z+FQ{6i4lt?WVq$b;WMqKwaW2pjh_WWS1SA_@T`Wbec{?P) zvEJVEda8CduxVgH9O1fs4?q(}6=E^4<1tk(%+4evCQfu@UuC71nErCWu0$PiCrrEx z7rd-}o=lA79_|s!sq(ZZ!AC#cch-ro3BK(>z``8+*6W3Rmk2|<5> zgUIDDrUs!CJ_6!lVPS_}8D~}x>+qGHgbV-h;p?iMI4dft>h{0C?8Y6#mYABFYD!W> zbPLP?HT>w}F(0WAY-&V=nURs8N#ltE>%O$J3_*^tp75E@vwu#WI@L%Ufm>2Llk?$& z5-T+>n(v1Q!Ub(@YME-9N=kSV3kEtAsDCnQzj}MQv2_?)7>!HI%Rauo8<0S85Q!59 zW`dlYTwC<9wZbj%y6)|IrI2(ZrCBL?4zq0+#ZhRRoJW4d#_ps0HWC|bILH=a{{7z0 z$j3Sb=3`%k-o9=ceyp05QlA$xedi5g+~3;~YC*on!iC zC4@hQhVT4T^9d@?9T( z8eMqtQLAm%YdZubhEeFzKM@VxW%TO-PEqi#`~x~kP5u{;p?2pKwsvkqYQ)S;)M@G$ zoIoHAgh4*=Iz5i~W_Qsf+_v)Zri6f?Aha^9SHodF;6V^L8cuBp6|kSdugD17ckDoG z`ZG9)$=aaJMCaFMB?Qw2UYOmRplhs0xo)3BG@w1p=pWb7VZ5Wctt}5I7EW5dI9T_S zBZ6spc}uWYh<;jTCi;4^vh0bcpFVwp3qSFcwjugibvP$Xd&LNWRG2?Se(AS)*aL=qI^kChN|HGq!r0gzV! zv^@~;6?P~TS(lkAmgC2c!Bx{vPb!O8UtK)n*kkY9C(^0e@sqF+44R4h26e+76ElOu zcd&MVCD0^5MwzHssUHE|frAEKK2Al7VS?At+kuG{w;xbFQzvjl)YNEG1rLGoM@QoZ z7C>1c^+M~!0m9e#d4v^^8%6pOXA$}s(tikL^je7|?R}G(3sVF34&qyf0{Z&;Ovv-` zanGMq2VUkiu775FCRvp0pWy~|& zE**L=z8aqOYIsIOZ%mX|{g?oJH!h?tTwu4S$-3WewVuR?zD5IjL{*j`}N!N_90YLldvuEvX zZ2>M5UOouaIANzyESn(mH#d17Knsx;;LP@~Lp*L0F$!Uv92|zUcy|`a0!&o(ad?yn z5l>)gZf-b*F`|wfz$+reR{^2$*+%8yED>L5<|}Dyb5N0j0K~m{W4xml&Z=2!8l1fV zs;AGNpV;pYbM4dpZNo>cR+Qq8Gz{AzM$F2}N-O4+@$zN6&t4iHUf$IA?}1p_gg3_Q z`(~GMQNVY#b#(|{1BAmNG(2J|5=A6lPzsQ7f-npiZLXpchSgD4ejX8V#C4B3D=YF5 z7*?46nDNuo)A#~|i=2#XZgDY5w7_}R(As($(vGpS(!0dOKd65w*60;>pU{J^LlMAR z!Ox_>1VV}z|LspCM~+0mPMDjsLyB=~$||R;ymkun8`Dh*fnz@co)M#rv?4-5jB^!-ID+ks@jT_U#e9 z%}8ILo{^C%VmYY(p`jPgo;AT}(9|sQ-1G>%d_j~E5fZco%rz|W5O=+jHh`nughF^$ zHlW`%Rt#R^Bbka@>FGxQdJ{TmdL13#D0U?Y-$qQr)u3Q4$(PXk;^oU7+qX|SiDj!J z0ghbQX97XcvRe~-2P+w-70xvX4_1F{%)H}SeM?Iie6gsg@!{cQm6S`zLLh1$h&R5; z)v;F>b)>5chc)#Yt3J=Izg7mt-o0_vqjn+^F_W;%U<8F#j!cN|8$QLDI30w5GGNhM z=Wb@K;m12+O3Bou+ksOc7owxVlDr`!^APF~BqYq>i^qo3-uY;!)A(Nm7`~JFqFfaA z6~e#5M?uuI(Bcs&yLj;nIy;ana*^<6OwG)&NK0-Wc6NMc-xwAdbX;u*m6Y8Yilzc zI57KpFK32(kW(u0$&`CyXLeklb15z@^+Z$#B+L`E86n|DU(!_$eH}ljbVQR6>J&N; zxmNvVPlhf5f(IBp4IN2Jdiv%_O1jX|C&|gfC~I6k01Es3JOoaqTpW6%+5Z0`t+1y^ig8uWH^G{4=fN9GW+Juo5&gn z+;dr+5Z5aw!|W4TJAu$O6_VptfQA}aFC*BI znmP_OasPn>Cc%$OG7t;ML4!uJs;LhK08)K$5)uz&paJ717a?1~8^)EQQQ#n=2=Vr4 zYYP)y5o`NGkrel%pkKixKpX=k5+4Gkj=4V}TpQ1MgrH#Z^PP#F>{$(miB9LKU*`pW zS8~b0kbtF%413?-XAII>M-e*AK%5ofaB%bnsvlq~rK=N#u*$9@$jrimCkY^jYTUYY zRxRW9)UPr-E(&J+@gT$$4pvqsZ_@2s{V$?9^XOLw|Mi2-!^cx$U4pzel$*hoG&UY8 za-PMF40RC$?+6nh9gcXQjKiVu%W<$12N6%5f&2qU!p_13P8e2u6f^zfrxzEG;YmSg zs8|fn)Xwr=EBLs>FaJr|ZTO=|fC;gX z2M%Po#?GfeEJi;!;CTu1Q9VEeB~?|rdym$C@rT`aEac%@$X35YXGfV`&advm&jQ$p zPJ}VQ{T4)?&Njk0Xv+~Pz0FRod%@`b7mpQ~6^I3vbCX?2(dQQwWDos@1qXPprx2v@ zLt-6~9*ET`j z=PUhQ{k#0Uy;<)l>i2JAPa=obWo_0LmwFt4LzuF$pw=zeltL zC)htQ5CjC!)s8{!%9Y*4If!;4rx({CBqH*muQp#ZEk9qFd#D0YP?so^ssOx6G4xenYnaet zJUqw>L>l@`1haD@yFHu~gDHT7#5AJ3FbF)*H=!5j#>e-AUoK8hJHvj&zb=K0w}jQN zPdG6s36YQS7o-rLMZg6P=i*p9reg;>ds|x@NW+I96qaLk3NSH z4?(gNi7udCarc!u^lGd(dNttV&>1Iqi2)BA%a8s%29|_Y4O<2O&I4O0@|ZXa9C59q z;5W|B%Xm-fJ(u+L`_U3%ZZ6@m5CcO)=$^pi5rkfZBfuH$5U?V~S}-UO27&U6Dd;%X zwvU0Kwp>U`;KgItF%psC&bj-ueCH=8 zF>PeQ@hvIyww+|J<09Ms(BFLvahWJU+1uHz^*>XDJA+3Vkj_W1HPh8S&#Q*#v+$UY zB`5}lOth$D8UP~D#M6^k5o}o^P)dUM#KW$`6Eo^~Fb{to#-Rmd;sW6dkGK@WYJ!Rw zn_%ZE1KJAm8Q#8ozBZh}fL|H+U4qaHt$V9SJ+K=wY zB1OZs^M2F%e9xk->mR0O*7z#5T{|FJ_;BJXjL+y}D;gqX;kAN@wNUNxK}hh_v-#mB z7A`J?#y{*hjw6m2bc@u=b4JmbuER5K2=pPVOS&C?OloSN_zn@JTgl3Z(o3%L$E2k+ zn+C4F0=P6YV-IYB^MyPR^&UJ`=}SQ`yX#5TrrYlATNM=*{VzhemQ8Ic4(0vep!eKxxJ3RI{7?)D=W7`EN%<9XZ5w)q^y_cN42I~aPPf@Yd zVO$+4#B0~6&W5!Z2sPE!5s@fb87xkqQ$Sz9bs)}zq}u@i{#vL492`$-XXEDkhC@NJ z)bN5jrEJJC0y_PeMpDF6V}cCmAAF&`N!C-$1z5ZzcV+h=nCL$ACE2U zDSd(X>0gB5r}Iy_7X3#XezA%M7%11pi_?(971@{cv-Jgqy|G4+)#u0PD@j_YUH}iX zvumDp;G3|EOMJCrqM~SK+mWv#4a|Eas^Gq^TsZuoU$tz$uel)PTZD1`uwkobPb!fT zxik+ALI)HNeTO9*0$w6CRch$awDLw4=^W?ZKM-=@zZ*95UQEod=H>uhr5E{AH0{*a zc!r;e!s%$P3hl!zfIgxHGn$}oMDE4uMO#o0V=FkDX!a}bVR`x8+WPjwbWRqd$b^Pt zAS;b6JEL2{4gjQq^+;)piyJ@a7+x)fQKQUILCz0R(bDQXw5|Z)`isEH8cVrw5Ux;`q8$4~3kx_321gAX@7r#*}n(g%KHgj2U2F^%LfNA&M1Cb05 z<`*Rz%h8ZlKggiMX5ZX@X}Dj{!}ApVGSBp=%8k4>sgiO4RMubf_vYuv1_MC)uNVu^ z^!dJ7I{h-529zBYap1$?@n0dI%oo{~M<&t!5A@QB8CGn(-E)`Vs4_ zK1Eq@9?&@mM~3;x>CCTuxfB3lOnrYVKyUO#O&652tw@YUP>}eXJb6t>TgZ{HoVp(_ z!w=3r_g=iheOdRrbR#djZA`t8UY4CEA@XB=>wlsOpd6g!dP|oI48evC=M5va?|6)O zE@XuP4}(d@HsoDyE+8Xdey5R%C!PwbBEyjReVvGP8|kzE={&!E8!hRD5Q;g1r7Nfu zC$GNr;PmTS>3ak-KmsG8+j0)X|?u_jy&gI67xqE=q(lIw2X|0Y>}d={8L8i z=ce~C7(qcZ;?b(fpQgoMuwv=b*DfAL2>^-9H18roSJ8aZCp zv>iAPZEtdXmz| z==_h06W&(4caOke!y8jJNdj7N{D;9V?>f>>%|mx`fQGud`0yFW+f~MnJ^I!F$AofQ zAFMmgjg7ch#!Z;8)z^Jp#0U-Bi5iXse8t>b`go9W>x!Wea_?n@SZkRa}>hOv8@0Ep`@Sa78N z_PDs{+ErRP_m;9ir%iSn3`jV5@LAODt5(eyO+zHP_sc>2fOO->H~K(RMBTf`X`|=h z5Xp_&(tKD-o1OX zTlwm*w)GPgl?Lv^H;X94V&js@0b@pu!kWN3!wr_rKer7twQVY)y z^WEw6GEG{#7dc%ZW`IGmv$OFEE)WIDK~*G3*NzRIz`)g9SES|8P$~?@-Mi`}3!Q(< z2Y%Hhp?l z?PcmZ)~~>s`@Z7VQax)5e1uJoZfN)JiTY*D*Zz}p)-<`XCTP}y@JEl%-ML7!&(|p> zwb1(sLS;d?^}RoZP1W{2SVVBJ8wRPbUrj%yWFC0uBfH$%niIU4kBT;WP@f)?#`^^Y zExTrr)uom;m_E}mVg~0RdYI7%XdEX@nne7f+xVDN+ap88JlKO!);K=>0|F3@K$tQo z0$SLH+6*0b_4Ieh&R{fIxYrG9;Imh+S_NRjLg1jVQ1&@}diC772f+eayuc?gt}9lo zC>NI-wu=@YKbh|0#XNm9Bphv!ZmRb}7KYxtd$%IzT7TcvrQmA%`exp7$nmyq+x9uZ z0iVWs2`HW5z(8jPSoRXK`<*Z)bZ)xKmK8=>tj52acuFYGSd~tCntzJN=o1ws93WJV zr1oDM)yr?hH-D8WdbKn96R=YF$?!VC{c_J>H)@pf@>JKcQr>il6;AXL-bpOwRP<5FrMR}rKYs}U#3WH(G`4Tb_Vd2XC2LS~Vh%-+oX;HAo44P$ zui#?D=fSdfa$N>c=VNu!I1*K;4eij_v6qKnd2Fi6&B)3UuoUHlAOEcwOF6E_HUKV7 zGg4F>bl**oz2JmET5!*;vja;HDkcOVF!vXf?;#k{(4f1gvH6U^??Yu+ZVg}u$ShqN zhe1^FBh%-{KsneVHna+$C=vT!{0)#sNZLzO-+$|D{Z#b#r7!(B)K%{(^wa%&{yF{p zz7_|+pWi*JB26Gto)xaJ^LmJ`@(O#(`i_AuJL7qIaI*TKz2ERhF2D5Z+8R=pRsH!CH)$F16PBIDH69iO`QhI%cE z-nE|M4CahD7tji1ttX|VSI021o{mwd_{t+YRd=0OF&3FQhwO0_weZ25YE6#qsA?=k zUgzct${_LpV)vIFLsr?)AnE;le{4chQji3ig3{`0+*cN{k>cx5N%b5k+P&!=r_GDw zLmzPZFcQHcz$oRsox&`9&p>a-sq^Q~k$8cMkrThVD7h##)w8EEb(=5Wsfv*rY|=`t z{a$)vPTyOrZuH^I>(d9VSA{Lh4BUukiB@)pl~s}1`ri3VU=(Sy@OJIpH6IM*Y)7W62z{5P^>4_{)^vF~8 z5&t2!PytlhxDm}Kj|%Jzs(~f08652Ax38ge@nnF>5?>}%4DvW-@K?IgU_#=8t0Q1a zOY7bESV+HVPkGf-6<6PNa{q!F$ zPc0bkrmJSIBF!$UU;5nssg#di=BwqqZ<_loOex;Wnx8(*XRdr^rL}7AgR^JfqyMR@ zsj=L-bIA_V`W9!5#0m4V-=7;a|LBUbYXkw^L7!)tE1FFOLL>H0{rxYL6xw0eJG+?=c z4vVUfIIFjq*gJDoYXb?(?OBU16gKxBI2tIJ^qU98+A*~r-ls0BHge=v+Gm=S{npmUIq{DjV_mb;tovFYW;EN~ zt`f)AQdi%5zGiiH6*|nHz~|MTOrt2!JP>Kqp$jF7qH+y!a$K}%;PA$Rf zY!1iBsSZB+{COB46|2MA|J?i#f=CASIb!|Vy1&cxo`;_xhGKi6!;H7B5%5xr@`cvc zO>8}~1I%?jzKJng0YX)OE_;6-tP@TWZgJHr$w`^hL7ssrvhN#oJ#-laXJ@n{Ix56u z?6heC>8OHPjTHHqd-p=p+}VWaGxM_h51KTM_>Xy!9w5qB7oR3B05Afb2B0DwX1A_g z!I(dOQA|-uN=l+LLnZfzwNCA$hjD7IwY0Esz+6u4xZZlCh`AZ%i+1<~LSr(WFN>z~+$^uy0Hki(e ze>4+45|%NXuYwW|4C>Np^{zrn)XQ$eMWCoDx7hAW;}BB;)NX$ApLiE6DAPh#T+cGE zI6msrvYqDU<~%4B-K(DFt25-XEeUI4);3IA9kwbfb0w#6SlB3;K*iH(jPq1bYEa0E zu@z#nt%l^q&{Iv6%67$me(bYK58C5 z5at;QOA&Hp>%r@3m-tmoDDXmP+&L@m@8D0?vU3!4ZoM}&Fc6c|{DYjwB;FQyXQ`p# z1?DQS6OCu48b_IHy}fts+4Gh}0eyX=WY=~)()_uj*i#Osn@R+60+g>gdNjN4*ju}+ zW@$Q#0}^F6O;!Ws2NMIglOYCxHkWLc2>u^lud8$a1xAQ8%w7A3v5v~k?q&bIFlpqy zj?urc4g7%7VfgTLe|@$;K`@UDCSobY84e>!EB)a9{XQ_98-c3${O7gYToHb}l$+JF zw*vjhzWw{rHg4awk&40Q0g7Hg*V~_MN=J40zyHizuG8xC?BP#Yq=IhYg#0HP32Et> z03v<+dM6~zj@`6}7O%EecE}L8biIKsL@_NtKNabGmXhim>p_{y4R9{3xU1*SZ!k6v zq7}tCj8zzRN%NKrK1KZ7x|7_x+!7$O{Lc7=Tf(1T|1@|5}28|)n%-kh6)nD2q#EZP*>eh+u| zOzCapE`TIr$O7%KsP>dFwXlGubMx48$2jrk`<*FIpK^3?VDYapp;cOPgj@uMymU#X zWvg^O&hkNWa#qe=pj$|v7)ME`w)*J~l9s;y*Rsn$;N*lXL}h^t!Fwb>Kk(e zyc9x)UAyv`KnXZFueZ=nzuR>t4KO^G!e0hqB(X^h#apCfH^~BoP-=)4L3o+%q$D9q zvozbS!YO$Vy2z*NWI|8hE8^?iOv-tF>`K_-tLPjC^eY!L6Dde z*%H=tIcH#I+0G>)Lkkwf#s!{#rw|-zFcHw1>OtMOykTH(1=ZL_P#s`wmnYB_G>GdE z$9zBY%-p$;{@}a=c`qJSmXwuoK1K2iO=9;GS#u(0{FxBfk?y)-tAJ8{79u8DcJY+^N&eNq`;bO1lQ^zZ%DSY3Z}@%hh`$u>+tl)IeY`EJ4YAQ=Ih; z#PIwM)l-XxEAqXu(`Gp~jr|Lr$@0{#t*!e%qy`&~KZ|NJ^TPpBfUaFD=V#N%ns40u z?C1alnu#bJgpYsf)r?pg=1WdAZf$^(m^^M9M&Cs1Du7^AR@%m9l6fAO9jfmy`ma%# zEzv~0#rQ^>o1oK|7V5pn4w6yMV$mo?U+_rLYa6 z;p*z~35*uQ-M&^-%(VQZN?NAVl#UmcD$ zS54oYr&99t*PJ!~T{9Zk^^iQR?Zk<m z$b&O^d%c%kqv$|5-~!il{bRpx-#s10kkg5LNFN`4z8_#BaLZ3$y8%&}u%xG*ek z@|0tW)2o!N3*bK$#CmfZD1hyjycSL4oFU!aYNoEfN3Hh z!x05gV9OB;gKjWt;v4=r-|R)cTA@XN+6k#{TL*3~M9~FL_xjZ<(~L3zKN=)KTQYlP zc}(Ae%f^uzKxhbs*!BoRSfgm_k&{o|^1~W zE6IGjZ&zpRs01s91RmP5tg(ep>n=edV>(30Iq@Is)l?kfU4x(>i4*@VDT*vOX6^Hc z5pekg1mwDPG|HjZWQI3F22rlQ_uqyiw*U2ic`bc4eY7(RL&P1*^NdH%7%X9Qs-SE8 zy%a;cMuqrsaUa=9wR1N+Z9P8JDsa!Sh;8-P98=6Q7M9z@&&Jw0Ch=<2mDx^8mzEz& zeEDL>r$$*Hr<#gLAdTfgvtt3+=mLa%xgzJrH%t($H9DA-@a)RF8YRPbIJZ0fzL(>2Lrr8&(4D~ys! z&ZTLyz5TqTo=%3i zieJHSwmr-x>Q7b%0=mr6%^%Eb9Ut8Syxy)>v)pf=k zXgC-R4vUKyIo>vsNJ&wFx2%Y|`!;mD`SUfTP>mt=iKiTpUWQ5zn1=U=VPt`xo|wxo zbNSUulEUwL`}Pj3KPz0AZm)efk4#J8uAwX_>EKde6?Dxc$-NGmb1}%<(=!$F6<>HL z(&0peCNMjFj$C>4C@(#|3XT-FV*$8yd|gsL8joCKr#ES7i$k;U=Q+ckfmH{>_d_nx z1gZ|}w^2p7QHa+U%|(rutkpEnSr4|V`0+koJF2Ai;fLZB@mWTWccQFQ8>HN3%v+i< zJfZD|mSduEXx813fZEA*1tYcvOt95l#)CYs7lVX=)AH9ZTXyx6!@ZVYP)#c;3jWsp z`yRVXZmNa*1BP5}oa**neRyP{!vaHlKA9;_GcX`ds?%eZ*P;ve@p&UNt@iU9zoxr- z{k=}CsP8N5D0U_O$8{u+9}}JIz(dij7);!rGM+_?9JhcksXoIOJt)N| z89dv8N7DfNhbitgK?dW-`7H_i2cqnLwYBvMT*^bMBGz5_&pW~t42Y|;81?JfR{%7m zn#_URwC*#ca&&jyhwxs^C@!o`w5xx`Y|e!MdNJV}j6i8A`ZMA^X-+99tQM#&KV6*5^e`7s zpKi?C>YKHAjcUXCRjckp@xu_&M-TJgDjkleX5>h|l;L72&{aKq_8dKCj20ejniZqF zn-4)iRKYk3y?nf_&$pN2efoer2qB(Cn0a}H*xcn?f;-hjvP28*#g!9!5F4Eo=j*VAV4<#G&OaK^2yvRu9w(6C% z2h2MhaOg9^HrVUzEWp@|^58j6GZ>|5T2xifB>u*~f=UYD^lyth*RRKbgR@1o=SX{C zpL<8*&jb1ht$=h7y?JaWcv2it3GLIUB0;eToB5;I3d&A)b!`tu2FYq zb)$s@1B4RzD>I~zNB2Wc=abfelR+ouhhTe!2LoPVbl_j^R@4^}VxvzcZ*7SGt01~G z=DvBfVc4p1l3sCvCG)pRmim5?N>M=x+%u!%s@43X`@{~r>fTy1EcsMr)7}!B%BBM` zD{j^+T@;^n*{Ab%mickJ9SQaE7Tu+-^ut!&8}&^6Sw3RT;EcKkv)4Tz7dn(*qWZ93 zj)pG?e~{{^+3{AxO!@w@YgK#yH2D)J=P3OmKWk?+YgzSE^OIh3&cBO2HSB6fXt~bT z$a?epRpzZF*SzXO$w9HQ zD*x*YV<@G532L>Y14fd3wjp4tt?tT#;#Rl-P7LJn%3U=+2K$@^_Pu9tJo2MRe`Ar| zMM>;Y1(BX^Z2_YHsdfGT?DT{3FDj!u41+^eCecm(>69TWYQ^>!ZW5mGNX?0d!C z9)^ETTVGi8+3e93?ceS_vn&3LA9ij_=WF!iuM@(DcAYgs+&2|0xY~Eqhsr*4gn0h@r2~iNOwc>6ZClub%LFo&KbLJ$ z5!>oq^zm6{lmERTcRh6t%ANGB6z3S)PV(4NVV2C<4jS&!UydNc{i%_UtTmd3UT!R{ zn6!Dhd(Wtfd0+^RITm01)64pF@9J1$9x=T{>681(cn2|&FRqqVy?du9%s%5n#6#Pe z;?9od^)??3!YA35yqK}E^jy36du^G3pnxtS^1h{a_s29An+z{Z^&cAQGBQwW_T|vQ z9}PFXkZ}|dwD7;<3sraDG|j#-b6xqfN2-R}CJ$8)W|b|>Tfe^C#ik{sKCaqSRn;_M zWcIj0I$MWVhu9vyXA_%RoB6nZeDqu8g4#Q4do2mOk2+?db%l3e&{De_4}E--Q%vm= zOjS+EeU3sX%Ynf$d}wYaitc|VO+g)n=J`^FU!sQUm7KDlbu9ybO@1JEe@d3@ADMZyv1+bP4${F z^zq?e1#1@Bo9?eR%5E5Fkt-?Q(I=(oP_d-VgxN$nqg0&qxQXd$t_}UqM*k^~d7*NgBL<-1(n_60Uq2tHe5+wRrL`A_wx4bjwwha@s%QAA4%SR@(#XGBwGS-OHJ-mu>kNKzIp;hpv$sA_C z1a-~JB9nxWIm!nzY<6||qS@j2YGl|A9b2EVKfAm67S}mkf24C`^ohj1qeQ;cDXzCT zyR*P#x7AelDFHtm0y|$NQ6-aDY~b92!x*>9H96*b7vgF;ui^Y-nDy(=bd6d3T1Aie zRGOGzr`lQ68ub;&-;C`z_;!}iJ^W3+|LjtFTtZPoGzj?}QyuNyaJOY0_Y?x%CGdPR zC}7OK2H3<#fg%Nk0h5{6IeCflCHy>OV#9?aqQl#}p#1d~X9{|A2Q&Od&K~e zZVeB6JZ|!FAM@<2$id{1vwCfjZfGg44t^_Tp!-`rvAA%m-1nxQQ-UAXv=lyB_RaC| zp~lqa0X_>45P6Gi@MC^H)XPcnv+;aZ`pK(V<^)L92mxNhyZ5t(8Lx%!6&lNw?*ADJ zpGZgvl=n3dIi6mIY_g@bwIjW#_pA{obQF7wisET=dYN?M)wcT}HYHxx=MMG|X?}aT zGr3cwBWTPqg`RV!NdNu9uS}DUQa`+I$L|SURAe4{yPZRwZ7>n%Ce6Ym8W&Mf6=^Ys z7<6;n9vopi2&r^ot2l)z=x%OqoQk5wjV*+gy^%9UOpA~`%N(|t$OE|xdYk^e(YuRc z4F<&pb?NXAbn4VmP$MJ7|3U42*Zjjyb1Kz#8ah{<7&od*$19Ujvjz5n`#QV4Q0Z(g zO6>7CZezgqdB?rIb9P2EWdR1UQfUtn4AV6t?{q)OlS0#p33QdBA916T45KOpF;tN< znIbg<$4;KyK~^@09Xuh#U7=H5B5dsEM~gyk++KI9pL8R-oc=b~?#z|9e-!T_Arh~B z!1LG5ZjWVBR(78La(ZFt7N;L_7u;@F{@hmLpngd_L;9rK?$M)OIPgXvYwKOhL4iX4 zE?#26IE-36y=w54(8>7@B8?M1 z_E+K7PZ}89Jk94$xKuVmQW8+pt1m@Rq_p@_cd22+0I=c#QsBf{)~E>yNJ=gVR=4?1 z_b=FDY;D6g90YFgTG_k;jD&F=of)tMv1$BM=n%9{nM;32@c4mg6B3+JgwQuJ%9-9X zxbt^E{$B#!GQj9=K>TnHOFg=_xoMfc7U3r;WI zS63hXLdAWHuHCHzv7OD{H1w=gWUbGhKK)PJIXoD|MM#9x6;+^-CEPU3ELhqD*E}qc zygWG~9$U_V+-F+OP*uIG`Yv>u`DYtyLRv1%E;V-LRd5*Ue9|bB8I17R1gxfuw`##9>60aV>Ul$_|5mEKkwchA2Dm{lqr5&q)Sdr z`{WB&N~>@ONQf_~sjeuPzmq}NKrDxUP!Ki@SocN8rHd;nj=Hjw<@^80l$bAiUb05= zi}~czeYLS0Oy%8EiyyswW}P6~)=44Vp0ERzOyT{`ZmN&zsEn z(0q93(BX?J;1`l}{&5I7lfpKn1I&PQvwe;{&COK<=XO2uP{m=JdLIkrV(mcLJ|YMI zEWb72N%AzM0GCMez!oXBE|3rzY3J8^o~)MMTOJJ)5izfteYxi1+ksvx|NS&^ealAy z%IB2xh(|J=DehcpyXjFO3nr&<4seoZy`0paSq&CLw}F3~_hXY}it!c!80 zCCsxFk@1RY^+M@kD5qSdY5c)$V~OXV^@ahsh-{_J=Zj8x+wioczLoP0a-=mBA!z$y z=nA0Hk2cg}UV9(New3QtcYQaJFD4by2i?jO7t#lERBh~a@Q?mhPni)T$iN%ihkL30 z3?|n8_>p5A3qr(viM(G;RTU(@A@yn^J~r4JCrT>VcIn=k!YrBO9E(?N;PTlDQr-i) zb>m(B9&Djf@zY(!{d4}^v2lvpj{+wb9*O!qPNq2}X@W(pe#~s?Nr{Vx9pU-y&|ssZugVG3Q*kQ zAA9C02~!NpJibn&2iyBy3?*5jp7{8=h*=advyx1>=P6H{E<13Q-r+eE5m~Xt6gC?^MEwB)LcHqE+eOW(&k8!O24J%qG z+(pPqhj@yoz4^3o&$943*=x+oJ}D}HO)#SC5C7R}q|L&Z9567{I#cLbL=L)LFpRhp z5kX#s@3Lb3hU9a_lTW8n0{2d@4R#Nv*NW;VfbY0BTie?D51qOV$!=+K-@^z3d-mwT zQ6CpKSN`t3d(-TorZ4x~)e^Z}#ate&C9P0+(VkZnbhOZK5 zvY+m6XU*;7+6U$mE{w?rZj02Sty>T8+OO5=1NAJJMF48a_Yn*`?cUqxkz+=(pS;9f zx7E@fd}Of{?k&yM_b29b!u%gO#E0zJ{hjbW|9=1SzCWUNp=_1%Hk3TYPgEcb^Vu^p zEEAKGjBmZq7Rd{p{k=SC(t?fa*V_?X2xkS*hyF&i`+sa7zCZH6(Co2|NU#LFClBje z-}mOK;Mso*V_+g#l{bjfAWJ*yTE^uZ$-^g#e@Jw8<;^BI{LXk|fFr5Xa2HoJJgtFn zmhWHi!?am4=3H=bMtew-b!^ugaRq@~QwLVbv z*=>MIsQ8(;S<1xaNFxhDaTt(}*`fNNH9li}aLEAXsy6r4=ePyiJ>-Mm-$-VgGK)I8p zR$jUbo8p{aJ73QoaOlkI**YUqI;<|bOU$=cFQAfwJK~{yt#W+bt)IVsg`bX!t4=c= zs5ET(u&Ti6_Zr7Ey~)qaybC%`@;H~hsHe59)U^>7p)j@csO^sHO=;d5voL#HPuqZQ zwiTkL3`1D=K%BY9>N-5@Fdq*o%l{T-QpHhj&}e{M(OP7X&Lrgxi^T5w=y|Nh7qD)} zQfGw3Am+wN&JGBl_^YJB6ei|Be=g9G99uFAFF#m5vFF8ZB99M0xja%`CTmycDiOWN zn%UKdw@5=^!c6*Vwq8$(geCi@Z)36`4$^GuPz7AsH<6y_=W7sRGC82v-}D9avs|!4 zRJHq&Bj+z%ken}Q^m1~5+EL)?jc&v`ev1%6V%>;+pUh8ymcT$ovBuB)F@vM&@(u>W z&Yp`q2Nvk`oG)6uzxH#qcJhYu(o%uWpbsZ5>oxe+X4Gj*UFmH&kKLNG78x5G3r8|o zZRN>zG>b9XGuqv~w( zm?57octxqV7bW%83|Kv3{c}fy$;+BXmUd>BHf1JFkrqRVmyh-q*)lqLE&CsvKP4%+ zUte>RM?u_xnvzl}*9mO)zJ=@glU~T-|2}p}CNeH6stGEMlVL}BMP}K@+cP`2+w_s| z3@!B(OMyrJP7#lqR?D`8`m@`&Zv%EX@B#BHO0Crc=Ht{rS;4lc@I}%ERe&;uA>Rb) z{GFUia4JEZ0##f3kb|OO?>mvL()+EfRO3w5s{TrK^NY287UHiB!c9hU-D_B!BSVbO zP2YtJ1hH@_qm>lHA#(_jD@02N`;U7Q8W}jyX(A+=SH6W%6xSb5dOTX^eE` z#4Q8DMdf=Z#Upvds20z~IYex7X$vinvVua$0b`-^RUA)`^)(IvlmyM^NhIwp7F1>^ zsoK90mvxW!gUT7ZiICxE>$=s1$eZ(@E?nqA7I1ywe(PQXP)Uh=DGr||ZSNjy{3)u@ zI_XA)*OIp8UXOKVFI#G~@$`J{ZktP&9qM!V$;sg0WDLtF>kw@qp4k_>$uOdcq$9z! zgZYp6aSM^-G3(V|SDBv98bFZtA;ydRo>!)&sK0)@rQ7bgve~7c?kD-C-u_-x(y+U_ zajx89SWXc0B<-7F*sgeKt#uQpTF?H}Z3Wr(2!5F!EAyu*DJjXze_<$r`D|wdC9PsF z{5NOLi?lQgQ~-Q+p;@KhzF|D{C2Wf1o*RGJKn=H!KUfu6TEkJYF!+x*!$Wy;_gHG`gRrNf3c^npNXWJtHR!Olx7N8p4uQBaKpj2A7jE78b+nkas-eqv zv!(jCmRPCml{WpoamS%4&o1W-^iY^m>p!*9NdN7(#uh+qsus_J(HAuzcVwLa-8%v#zW3wcegL&ESf*=8^os1;_V)Ho|5~ zRCHu69u%6O5U<7x_a`qeeXsa6;!@4zX=7M{)-4T|=H@)O%Wk#=Jxhy$If#mhIg=PJ zDohRPKoCggU!0IxI;O&xkb0{0n>UtpT5K`C=ZE}>!{ZTM2-T2dOx8Ex;zcKDS7=#6 zPJ)AjgMwt`6AO&?{GMUh&q$UDg_Q zmKiJjmuyW|>rmM@Dt)5&I2nFy$+y{gDJa9NqwtQkhr)QDpmei!vj>bj-ABx$^WxEE zjuWjy*4@Hc4PS}+nQiyEpkVFz_b7KTmXd76x}fa#R)8L10pjxwnLvI9d|t*S4ZD{o z70}G@ArU)sgqK(fSIAg0C!%4bSLC4$9Ib~Wk4)OIl>1qmfd%KBvoaQc653ZJQ~y}G ztZx6AdrrWp2Y)SC|O!L^XX8e1gLIFG1)`l%#JOptj z$8~UjIZf2}`n$CBAY@@}8H{9>gboyT-~5m~x><%Gq<8>qfLBlq#`eWM=$TaaeW@+k zVZVkaSo`}s@?4~Lv>;R3wovPUQ!zM`&sRAWY7aCb>dAJvIPMI(xQ!*k=K-4`!}qJu z+PI%&{&eB3Og#^Hsg3DSi2qn<>x)8^*Zup#by7TQa_*LdP302r(Tk>T)|vQqiuuzn zA}2N6pX}WD{&_#k@e#(4%PKlQtRLgK<T zUSPcr37N+=>wj}W3*WvK_azkc`0PjTU9t+>1BM5TAXWJw$%I6d@*{8GxY5EPVWIVs zM~(Xoc#ZUM4QfUDuJtmr^$VLtPP+ zYa1SX!?()?4RwjlL38CV_m|?kt6Y7_8RaYH{v3 zkTItm__*Vxjacc*WpxXh&WZf08$G;OzC!eeNK#U7&n*>hZgu`2-*nul`EIR#W6k%n zGVJPTweaK$*DavV;nF@50))!zLvj&e6?i(V=xMUdX+Yd~{KBN$+KMhIYatxpwH{N2 z{6aJxsFvOU45p-vL~D<~L(pyS-#<*sDLM5g#W&_; z)VqPc22)*{J4Xd?%M1|{ak~@GAw(M!7aJ=y11N{!i}RCQ;<-!{G=ks1Bc}7eznLpp zS{n@vUSCwJL;T8cjig4bPajha9dqBs$S+9$CqS$oej(@n7Qw9fWHZ?f&pC(z)2Ta) zBHuqBwMn!1N8Qf}!?mTwi+{vdmoP5Ce_6&%5u*i!C{;F!8#G{m!s#?o4uhMdo6q>3 zH&xc!C`MsX`lp+$b*f zGW2}Q$+s$F7c1n>I2CTHsG`tQ=1#iS#Y2m4DXtnWsS?!vcxz-l4f+@-PZH-0CQ?vr zam|b$zXX3WXbkoc7Aw0^^nAM)-9M}^Q&N+bwppCj|fpH&nA*>IAd9^iL#$(0*p45v?iq4meSadD`J z!Jw~8L>`+c1f=s2he=4>rLDn;LtmwA7zO6N2PAp7kSio5CB>8fiRJ)2Un~X7RZf0> zJi{<*O?_)^jTIoYwA%Pggp1}_q`6f9sgoQG*R9(QQdhh;^A(%o;38e8X%-(O^!sHM zRf+YVqwt^9m7J5y%BEesa3L=)qI&ap!0$N5DhMvLPWTsV8KSxBy zTvKT)=|+Z0#E&UB7kIP6*g{Pwa$@YD>_JEI1t35{1*z!wI#^3Ey-`y3SzBY};9fz{ z5-=|FZ+?q3Iu;mCSX?}7mCNa)la7jax$7qBsr{~xY4MT~Pc;hR6t#wmY&|d%tviU0 z10M~(o@%OkWNJ%j$~A5z05zl_EG2oz%gZlKI7y?f9ToQq4=al{wB$_Y%%$-B1Hv(k z5xxU54c$p+P$6b>Rev;P`%)N0ZA>x-@=!`kOa`ftbuF-&A682=k2czS<4Qcg=WYxs*H1JWvnP zFETPRI5M%diO*R$K}f=XIr3ETQ3=Uem-2cI462Z=>Y>8*j_&Crr>farRDFqmzx?(2 zl(PLF&kbxpj1mVg+j(4}kav<^^w1T9?qJrUam@hpoje;ysJh-o3FMc*@rW#1xKMIF zB4j~01tx~21yBwOlPHS$$jsB*>XPMTWtWK##fS?`1|LOnq~y`Lpj%$?bYO?>t5k_@ zLg;_+5W|nXiXwm+Wzq`7Xk#)m>Sz?e*vPtAtfzO?NWIio#DF`9uwc;$3+C3oM~>-S zp{Cf*?pGl0bDbMT5WoFPZ+ozKkdWO$tGif9a=z%PZo+Y;>nM|D(NU-M``V89Dpj4x z=K}F&Ftfe$9`_=yTHD;2s#RX7VY$P}#9;FV1OGyev3*3Z=N;`4eY49>&m_pcNbkM7}s3b*jDmtTaQswOom9=&ymw?$h#DK zpm?9{)4(}(2Q=k!ZPT$E6fFjeyv z=q0Pd>u{;vxPJW+chJ(-ja2l~5kd!0twpGPwXd1afJ<9~0m!Z4bg=dJcV1x%3LMuX z`c%nztXdMi*xNMn(D#Rl2kw8=M#(uUU{eE3ivIbjqfnKQ77)>(?ug{`}02 zg!xP);hWaX*gJAtiM3VZGWaZNT05}{sIzWBxfb?7M@cVR@hN(O3zx$@R#>EQrJ(Ne zjPqM+9R}9D>)5k;qE*YdSeg8b*BshSPDfPQIYm5Nt>JL)b^KHZ+oE{ws$Hk-mTIPJ z?s4AWvHW3ce@h30t-12k-abCGe)^1^8h+At=J^nl&)jWA@VNjKz(%A^^*T|a zB-z{QeJEn>@*t;LU$;LckZf(ImQGG1E@S6TM}Anq#0~q?Cy_dH_0gU5Rs`HL-N&vz z^U-#2M6$)GT^ZMGy>A$re5vtn4WH22whOAUaH!&zWi?lwW*_rh4^Zu%chpo;@g1cnI%*?vx zMT&l<5vPWb^B;KN?W}N%jxuGpSXNuV6mFdn?maaNFp?7OKC_fDmzVgwaLECSdmHTV zshE9leNf44e@rrHO^aciK`xBS1xlGK-r_t zZ1y_398}B=Wrg2QKHLb^)Rxfr7WITLDm$0vf+6Cb92t%;hVHN?kF&1%v}^A!(js3j z7f%x#Fw4$5?U`|lYx+CO6=FK$20tu#J;vflZ97J{#j7-P*R#orUDBluPnCVw8}NSnTD`MoV_TO03`k5~PF55V zIDxkhoZIwZ)siDA#Wb?b%=awRAF`E2$(?hWKR@8&m0TM(>bX;=_LHvM+TL;eIG>C) z!ue9>5^-ky)zNOcCe99=IbF!l5 zH@xpUvvAO}y5|1FRCNt4Tk3bJrmGDqtVEAd6&`L_MJGkdapa`&!iV@+RqK>%Ba>SH zYI*dY)c74|$46eVuiBL$(^`1KDYA7`;#!f*bEfq(a~-;@rgH>oGov&f)k*1}50A~? zf70Rt!ffJvmNxjouYNFj*s)HB2AS7yuk?@+2cv8C;+y+?GCurqPG1M7fiiV{9W%Nf zj4F{l8gpyy#+a4U&-{LEwX*EvzCf$icjg6yjK-C$Wtvqk_Vx83St2jhns&GO-Z;Bz{D#<&pSO*5CZ_K!2=U2YB_dy=K0u;i-Hv3X zk7CvNzeMsIM=sPEk-E=FE%s`O(e3CDh8M$coN4esoZzcc_qFt4#6vs#ss$7Kr71`s zbg|s=Dbi)6YtFE;Juc?wD?|=P<@eL{*l8s=4&_1YFeJ0agG?`6`gc; zi?nNUu$($?NZ!e)rha=CM?O8$E_3s-cwLB-B$%eEC8jyLWF`vX=R_@`s)r|*744p2 zvv2?JszPj?%$Nw@`=t)c(fz}^-SM4r&4vTNxFUcLI1zEMi# zVC0;<4mW3ipCP>AgU)RW6e5JqDwwS2Acs@OXeuz>@(19B|IjBR$ME&^a?6 zeSj!FBQ6 zWny0u;z>}Ua%|}-PHBUQ-v)o)4H-5ztfSu7?K4mt0|0m0H@DumZw%>As1f&VWTd4z z6dxG^X!?#xk7TkAu+YY!0?W6;vgKu=_EQ?`#Rcu-aXli!h4TjEfi-|J20$~w z2>{)FV+X}i3KMqaRsK8TGWVPhN4<`9gd5RiQa>ITm8x#8Ma-M-O%kHn)`TPAc4Ppak@(P=|K%9erVM^QS!{tE4AcAiG(jQ#qOIeg%gUq z>^Y1-J2)Ar7%KQj_xb zk)6}}a-{E{icnwD9LG8B9=6{ow{VoKZ=J&@I9}m(zkgo^^%Gn3ZL4ghBb;`?X(zA% z5pjcQRWOKGX&d3e00;u;G`?k@qk4ALlg-q@TqM5Jr+Xb;^(x-i;=&;z5DesEuKWu0 zS|sqCIyGO-gz~p(oknLH8JzYP?Zi@ke|qpExwE|vl^3FyCbZKaNmf@%jQ$tJ2GzpP zB+T5*o|rD_2k5=btBc5|ZgqCQ=VQ_rpfl3TxCnJYaomsU#@UjY;68<19^Zb;q%;$GIb!^~dC`fQPFi~o?Pz4zYcSg8q%GF7V%-ptPR)dX`@~=5p z5W!HH%%5z$+u zV=UbuAL!fU&{`y#g>eGXdJ2$j$v(>CN$p1pW^J?jy#9W2gmag?+=iVBOqRy`(?%g7 z5WIe~Wf?)7NU$(m&n1OsX6M5z-`E%qS+-`$$C!vSJ7rEgraq7QK;iyO%GRb08!R^X ztNBR|P+mj-e&6!ptS)GyM07Rs!=-#vxpqakQj~l&u&N<(HG=waV(H6t~_p_@_c+ zRxN*X(JtTe;m4SoxIG+TosS_8Ai5;Av~uA@3{ zBW31Q`jFGI&}&NJD3QC$V^@EgH+ZX+E3+ruGsW=%MB9KVVktsd#Wx{T6JoFt0_rbvtz{$^a>($?PbVXfS$jc*dpDq49gFVhyulk2Q~7&>T-tS_Ox zGo-wY94o_&L&J0wv*>Zyf{wu>oxCm?M!t{g__XnbP&wM}p0>&xUNiG8oGW}#jm(#i z=`QlUR)}CVSa9|3UE~{BkhwUgN7qB8s~L7IUFzW=H3+dNY-tEsx*G-`2gZ`-6c zt*3Xd#x7QG@-HrG?sy&m_AqDY!3g8T*8Xn4wHXs=_u)?xc91*%^=FRlh}81NQDcT0 z%lgk=6<95IKJbzKq(_Mz`S*8uE}A-HSG%OIWqyQOKW>dCRAlL`0tJsPQ9*;FlZ4yi z<$JAc9qj#_j*U?_K_(j+3ty?f8JV8PbjeL`_-d}|2#wVI{e2bkgJ0Xz!4(|&XvWz1 zsGqp3xo_zrcP$T_zH<$B_=GvX)5cj(t!;=&iY`3dpKTg-R5I7!BSLbQM9nd2#iAOm z=S!j{ELm)O<9ABuo4$Ws-N21ujPJzPsw>|#Z~r*J`}qeR4nY#+O~l{9KBdl~#T^4V zs{HRl%!^1?07=N2-_L#xw>Uu*2W$|%El_>O&9%40QqDmRlckV2oWm6T_YUg*iIQ{S z=P_V1IgtSiaBLsEy0CJam08-pKyX2Uf=5|G+7FYp9NCuO-r6A&?+=$A6n&gfvH{R? zLzHcz?A>p69d?8=swtwtCgq&41H?YnGa|Hy3z_bxsv& zQzn9s)XGh^AI*jsSqtwX;UJ?_MwOSP^b6K1Giu}+0x!mKuUpbxz)(Iguj0MGDTdLO z@vPKK>NX8+?c_ah95=T(gD+rLO6wm_r_PmVPIB7BS_re~9Di_>%JwKMs2C z(xb5eZ+1AX5I&P7GxHpn1c}Gw(vpZcXPA#Gw>J2jMc^riq!8?kv&sWY&aTQd#K4kV z1dRS2w<%Yp@iT1rwM%Z$H<5%_#2LjYWrP|Su#oWrgW(6quF57gU2fZM`O{_YuYG0O zW=pPY@Sij3qL$Er zN*A)c>u8PfsOH5xutFCMF?ttiqGi=1Z9)&O$V>2c(KG=+-UVR=6LkC z4VtIAjS^{`@j#i3SynY{0*}hh2ieWm)qeoX%NNWmBAB~?1+LzNBM*T|n{yJv7X&^hhD{$YEjB(ZW>0}5D_AJ%U`uJf z5#E#I#!8C`7aQZo^LcK{)ZCKg>$+ysrfL^=?%}QElhA0@HE;BP&*Z?55+6EM$I!CR z;u)K!ixEc9O8+5vJ<;=U$1Zn?SzNpHfpfalsyZR;?@6?tfj%JiaK@1zx)~UChW=X6o{z<0|tuRE$Yk~ zGV1Fyvz)FQ>aQr7nzkgDxNd$Wp)vW&wx&^?9Rtg>+@vUxgq%;9=5OZE{*dW5hHWV@ zYZaOEcFBnKqzBF+697l!xp0!79>KS85CSz_4G-Uw9}^K0vIQh4%iNlQ0a3nSqFt~+ zn373@iTc1lApw0q3k*^5(Uop#e_7}*s>6PyYiL8BG8|J69ozyzoSnpL-- zw@e%~mec(&*QimA{1)=CND$6AQP07H9&Ie?66u#G*hN8oA%(uN+M0j$6EwpQ3vBZl z@e)lM9MqT%zQ})xUe7$anxS$~%eP@(_jmbR=T0z=RKLi{BWSs)o%ZchMMSbY)E2k> z_jUQ;lrh_fci+5l&6#np{?x5UX+$`bGo93_Q4*AHW6*LidIAF)q3E?rj-#kLSKQoI zC)kho#M746+NSg*X!#5GNBE%Ioa-Y-dD=P#dKuS1RCQh{9Ah8M%Fq9*P_UxB4c zc$xs?fd_BPWC@(K37s=}- z(&l|{XO#;v7$x-tVAQ$PIk_emX-H7~etByBDTW3TL`3>IO}5ew4@TtLK!SCW_+hg5 zNsr{;&y^Eu?g+>TML5Xe+j%Ne?T0jWEU&rZw?j97YHxNcatK+lvS_DM)ZezuiN-l` z0e6rIU@`ayCyZ9}=L3SBi-(c0OzIj-iC@}D#ICGEsgU`{q!qHloKi`c$pAlONm_i1 zkPz&7Xo{1ozO#JXC?tsuUb1zW{ELgkJV7CFfh!Fbe?-NS7iVF{n&os~!{rS;HiwP3 z1UMe8q_V-?FO<4VQ_cEVDb8BaRVCtQkp80N8&VJK>i1kqG%Rvgd@CZ-GGnL#aZpqu z&cE+rOXzsHZtxQz6IpslYJzl?O!I9?;Gl`n%MtD+AY0Yq0;!Xn0LH~SRK3lQMIed# z4gYX&>!JZ^DB8eDgUN}8Qro6r5}eVTy;M13Q*3rj4NXNIof<7lgjSct$mkF3MzlNz z_qU}%E(NgV=E`s0@PXrmh8&#r#GgOTxi&3#1)h9_&Jl^uwlD>&sR{Y3(_&Spr*si1 zIwnk$-0NWEPZuZn^)nOm1v`AM(F##)<4S4sqz{V1XsUc=7?p>m-{|9HD0M`)iSoF_&qQI znoqDK&TCGMi4vmb5#0_w7SMjqZnjudNA=%-DJM1vH`&v{81AxieUN`S+` zXcc3~-2Skoy(93)ykggE6gD0JT7NLoOU7Pr!jwRlsS-Q|Y;BdjX5FjnBs4K8_YOn? z*e`zg@MVs$^QPlyjO5m{VDIylP|c{{=mdJZ7xNlp%QQDAC+VQCf{hIlUV}}(-ktaM zK_*sp^|#KVX)H3(NJ4KUupXf+pdl3EGVzI{)1GMuJx9LUl%7#_7Z^ojPWh+dXXttl zv&0&J7OE=)9UWdz2M^cKlFl7T1d!#o(%z@UE(CKA2VxN7z>;14%eZg(Iv?Y z*$MF)jX_?~JN(sf7zMJ$l%B_?1`_BdPBTy+0X`yR?9MJsb{tN@Vrn#Ll)4u5Kj?J2 z?^TiWM3om_|GtZ|sD(jSd8ljE;9z&sKo80(Fr{R2pjR-u?~MZUnZ+tejvaGP4}d4M z(VvLE%4>W$*Pmr^#5u#{@H305Qr(m#I7d55C);|kurYC3xC?0lnoo~{_qBx$+Q*-Y|3yH}mpnUjbj= z8*~marc<~}I52d^DaD@3jkL$9;_d7I<)VBzj!Qw?TM8#X zI|Cwi`v(SYs6w=X4zMF*DF(fP$0w+Q(BP8=ZU)iuI0KC`U>tywvd| z)jFdmuevyG*s#bI*AOwZvCwEzF|#}MBs-S;oU}s``pxg6gNIt2KIA;<+&nfn?_IXf zU8$9l*8=3iRCS=xY3sV59x)zweU6QLv{FP+8@^Fn_{VTs^B?NvN^i9-(7ds%Mn5NE zG5Pn&oOCesO*K2**xGcH#0;k1xo~Fc96f7L=8Nm#-7I_uk_s5AU^e^k5Y@s}kIhq|7s ztK@7c&TaQDnJ(fh>pVAhy?-mw)O_~2-!oJa7ak!uFQpwL?>w1zd&sqZ$Ua53`-k)2 z@IB6)M`3^2ID9zyssFslAfjta?}>97EKR2UrA@>Mw#)C}X+0xW=TQ8s)`hbp-?p_a zxmTDw-%&j+-?IBd0gYI2+#1kmAuQ~?8D1<3U5Jy3x3~Ev0d2WJSTAaWmANsmc+`Phdx`@-r<+8O;$4(*xzP{bSEcd>)!(Yv$kq^+tl z$QKB35|)q);tXYp#cBtNsv|#jQrPin#G9`Z$NyxNluVQf=FQ%|#2P^OWqd0#X8ZP6 zFZ+YT(x|n-83BJ~ZV+u)`>_c@bb+j5ReHmW!4_(_4k<~==NX$;E+^7~bLT_`yS4Lh z{6^u`+}diN4jc!y8S2)63hIZ`m9om~V?Vf3G_bin08_6ES`k#wL+JPoTxoMFC1l?N zWHMk!`-3JkTd>vR#EgS>F4me|8*k+=tn$VotJU~i9ZCSAF!`PovC}C3Eyd*E2I_Cv zFAZwPm(xRXdh77kfKTAMF*Ea8NcflbQF-Lk6~_g&7z*Zr?SZ)XpDQoT=6~n|5QO)~ z2j^V00H~LrHjZoH=SC~LMX1~Esq#7%4eu!z8^G!Cozhwgq-bPm=VG^{eI@Eh{1}1$ zWWYx8^Vn7f>SLo-c@0zaKv?2XLBK!o;Xm2zM9H4WJ2FPa$s9JsBB0ckgbJ&>Uq{h!aJ2EYP`(j3cgG zJQL$jTiDOhzVC8#{PWJd{`SV&7dQ}3y;!!^0mYPO_navXtI8FW&I@u*270^pX{!Nf zO41Q#?GQ27R&zIl>dSv+>`UsWym(k+L6(py+0h|=N5^4|xarx!%s9Y5M9FI##cjb3 z=>arlYbhAYf#40n8_%?xp#sBMy_C@8`hsEphxi(M1me!Dr!5;R`Cs5Ox6T#HM`}HW zcNsFU3n1o$z%zl)mjDPY#z6K+I0bMtLmAf!^_P(mW(qbM##f8>P}LH0C}DP6*K;CI6huck*y9Vf;r?*uQ-<3qAcL?b z$;+E4GY3=v$Y}&jf_k@4)9Kk4zsx`G?Yb{DhF>cSGBIAFJ>f6Q$!{wiG>AAEnasg> zU8EM7Mai~N$=_9s8*P4(FU@mXZWn?-H#t3fh)P&Zut}oC5{%!VKTi-T`7m5d6#ZAT z3PS|bkA_9q_(P`MIIHl0@>v3|I(CG06oh#G?{90bM?Lp9X%W!@!T=>O0niF)(=JOK zv1$N3{l>`mMumVfjP!y6A(@hQ1uCQm{USxRLfVD}EdN(0cz&~wROt~ka?)^ExD$lvj^Nv)|$a5i-7$8w*~9@!6VXYvq2v-Q6G^v>R$};Buki;Wzvv zylLMO+7tY)DGt#DQuvpCzYHm>X7nD-DMN*9QXN9y$gY8R;6+_5?zo;~)G*{)8KTz~ zIc+{z<>r|`Sz9(`Kzj>00n+&n-9BeNzUF0^mfh$jRu|gR{KBWf{O@Lnx6-~L?PsWq zHtk>O=oHt|_9r^dsN9x}L7AY0Jj~pjCoLt%^IC#>pJk-wu`*%mHGP^`TIHgwEZA@I z;t>*+mYWY-$0y`XB?}hG56bt~oehQDV5o&#VP@R9@b8BYH+5+XC52iUc<$umWAiCq zJyndgY2}j0q0wK1_UAJDp5jNW!YA@XoiEaE4qal&&VK_`0Z;)?!V7DFx|$kVM~@4F z+QyiHJ_Iks9^c8%XWH6WQzyz8KU&S zs${s9Cwmq282>CMUghq^~peE4t3fmJw#DH5|2;8TZiX-74K&HfQ zhSeVBSUvKZFe*SwW3?mFo`uceyj=z&d@>9v}GW zT!RR*HYuGd$p8%r5)L}ry3S!&RiF(;?h?Q_s1B5_ECZhQVR;;Cdi><>KOsd6h z;!ERjaS<{;z{Z-GNHsMsCi)-4PUryXy*m8QC43q}I;Cp}0TXs1)TmPRm>ue>I|7Ai76Dwp%>DJp`!f=|&PVa8&6)fDBG$ zNRIx4U|Vm@xXoTaUlIg)hJ%HR`rYVkeIzd_gO!iP?8f)%#FB%yN3Ql)Peu)(i#KAK zrO@*2n7{|1TOb^vQXmnkXnFW^ZXN(BIa85?H_onnaLwQ>!5l!|0N#rOi0Vmp;WbOh zSf8_sPY8{Ikm@jhEN1f*(jB*B+^}8R{~5?VxEt&tSy}J$hfy`H-uaBkkpV~xqm!hA zgBMnMQVvwG9OXRsRve=arBT_!Wai?plzsBQ-YIeS#72D8qraxbsf8`>l523a6&98;Y_D+2mcI;!c5ynXTRFJZ1GV-5OXksVMW)5=tcYf@m?hG zlY9?lWwf+Q4@xG41UyI8z{n-zfFl_^!8icQfrBWH(1=r*M~}T&MDl`n1eM@){e^Ms zDnN|OY9HpLtb zPHZ3Zhxtwf^_~dN1I*EYCkmPT^wcE!3Z?^F$F0B&$DKDEMDr3bk)Uy~?84YH`p9$K z$?xO^>sp#7>r;zoAni$H-R3A7x~Ia&7O2rA!Eg#`r=T*N4<3At(>l(isGN`*a!s+O zH7c3o-)pFzQT1e!c;sK3!BYZs16hlnhTIkgdN?a%Ia_v#t|MUy-MXb&`LlBd;SFEs zk`=F+YV}J)sRx+i0+1QhDINf7sUl@~UEv>rP=@G2G@Gyip5sg@Ec9q7a>Uk$u}fgr z4UE@e8&1ocn(-=Dr~5pJ92vE%7neHLZL;h~h9Di?XQAQU#U+if^%A)W)H@AWd;l3& zXFT>(OSL?@X4D>e8dZRsYBU=HlzZS_zc7?d>b7Ng)!&eS*|W7jTGy*b=Sx7Dmj z;_Af`#pQb+EzMdS5H5DBo+m^LZVjPVwqSgBakx6O-DbP%uD>G*irtHmZ|B-&|0Sze zCm=FhNVpYW?Y88^#GgBt_+~D?)Ajnj3&=dSME+LFn({|jjXqym0j=saa57`WKZ3X# z|KIc8khbfty=#)TKS23azGGYiRO4YcpVeFW`2(T6YBj;;m39hiJRwkYu0SXC_9{q#BfkC;<;1GoBo$5u-3*fTd?Ap}KP zh-dD4Sl|PFiiywsBq7>T0ngV-wqE!iF|7lv4R{BzN}MRTgU@iLp!GGVaSV09yJ03p zSMU1hVdZF*Y3|j%oZPaTu3Eofv;TBacUi_Ak+{Ql$2T<*0kQ@YGqX`Xqo7_12??mLfOcXT_IP6%b$YPe6oS}G`+eVB$B5FNIu_vX zFmqzhMS*M&@r$p@!X4+-OSie|yqbAGd8TG`GAwRsAKls)#otl>9flPgw-JLrq>0Hn z=qxq`vX_uE9;6UoF~0rh6f!dA{Xs*ajh9BTS*W&rb{0c-LFLRNLTTHEF& zOW>3S`j}i7b{ib0Vo+5;Y}QO#xR-c(Ub}p^R-wk5Bi|7sf%orUh1<~GaW-YWn;zI7 z;-h-;+Ha*E83v6_yMzOp)lHob3(fAL<5|4BY#-f3kaZorfiU<2dVoufG|xm?00fL4 z2AT8UV5^)ZY;VfGd0UX0kket@qEpr7m*%Khm=19UV{S%8$v~$-_)+wuSNL+31u|xE zLFlFMgly?uf08H1M4h$5G+JFdelMf@XyUP=#z6GmbBikWn|l_XFy81AOr5#8eCo+R z>7gDVxwk;P2VA7@r6@2n1P@F95o^i`t>CVEy*q7w^^Wvdk%NV1YwHSbiv+kGp?vJa z{cPV`jR><=KR*l>WB5Y7jM%sAz6v_E@M7T-p?sntn? zhmBU4H+lrL1hQC*^*vbi0_L5iSy0cVJ$SHHN=jdF5<57c^FYzk3pmze6URyYI1;De z(?I8uRP0C2uJ2KR0Gzk7wzf}4SClh2o|w6HQi%8*(6X)VcOtO|X5C_4jkK$#eN8Ue z2^LjYq_#+e<)Or=kP4F-0&|1{WAm+pB`aVk>&6)rD9MLh3BE!FrzfeBCXKx^ybOGk zE~hS*jQu#cxGE|8)%pl=oc4$J(HWsX18xfx@z^@Fen4ArU&{IZNp_fNnS&8G2(L5R zj{*MnIqF0Y10&8*AnaCOQv?K#lO2J(3Cu#PF;4*l?@G3AxdzP5I?`gc^v_X_n}<5+ z&66voYY(sjf9K<7Gd}YYw!0xN_38XC&oZKegST;Gc9U~V@jz0#)WC`GFcdUJt_N?U z%LQg2hNs_2s6*atPA|ji!f1?@gKU@M9hjof`#b~70D{|vv-Q~BxSpV$=hfeL`W}_4 z{BUk?>A5|#GAVntWvUEFJmv5`{U2xGA_s@H*uEMQ?s##NHAP9g)=~OH&4Galb;kR2Z&&ByP*?oS{-~*Y98SR{-7g`c?V7#z=QFHy2eel< z8dWqJZt}~9v;#C65jw!f(@tsfDm;~+kdV=0A$xb@`Rjdr15V?*dxZ3_o^2pp|1G5n zPaixAoN_oL(-doJGzT+rseR_(8Ag-L@ZCY6pndZ92RY=dmjq}=y_pWi7j%|6<)<&Xh+=pMDU|UMgH0?&0CpC>IrBk0g23MDUhZW8D z%3EM6dg+Gfd)$RZ_~Oxq9(?7ioYu6{Vtk zuQ0e}1o#v4cl+xhIrE3MQM~^JYq_Xui8HzXQiAvS)RNS$lCkRjw-uWLZdi$7+L70a&H9#BVRIjIly#pT$yi^>#S}bPRdc+v z?t~(%^EuNKwq+$RyV{=YUbgGm6^`6Lhg`FlD!Alj2`|T)K`d7a&;RPOA8$`y+Fd2! zk|z-SKzt%EJV`bt#KUl=%`eFRtnQH;E*-pP-DlN9RgD+tJ3p$39=z@<;dwqU=Cmg0 za`M``;&c0*)c!|WX-ZM!iqH}U{wTY6*XHJ6aAmT;#Ow1P8hLKq3P@T~d&g1JV{FfK z?3yDdKe8XQykLU)fXh%VdUEw!zD?&7m4KFbp8B_y0eASSrn1i0MnuFYyyMUKsGG5? z(j`&7kZJ1hTh?q__y3TLKe}xAI?vr4d0ylyHP?45%=Kxytkt70Tnvpp1&MAM;#tQw zByT)WrnAScN>i@r)kvh%uX?FJ%I4&-dL?&ohrgjRM|@s!N&SM?bx(`ulFur}-)ypD zLf5;Dv?$7_U`fgP(XPO?J9h;MWLNP0<$LZdD^f51;~8u-W#_3Kd%vqSF533Tvm+B} zA2@fni3#&3zB$LhSGa9JCZj9wQN`A!bXY8g-5w_}95=jwB7CLcS>*t$-=Qqc+&y;U z40$$169q?mwm9b%NPhp|TR0v0xw<~tsgYHiliXRzBJQ=aD%rQ0_Lr8meGh#Y^uz8( zS_zMZnzEOgqMEX+&PUPoBUk4io0W3>6l!I2il$gB!&8iN1c}cy4u?OlDj3F zwncmNOLp!z&3yM>3tsfP9uak`Zg%+A$l{ztaEQgtq0?=axGm(hVpo#Nz4%9LcF@7(Tau&eaCZg~2hmcj6YTx$9mn*4uZ z$-QUhEd0asBuDs-hRbC(ow}jPHJ^iY9ObIXpF3NAnkq1*W}YAYBR2K9=W1I23Z?mN zaW-|YZRqwFm9wt#svMwq8)2&#@4RUBJlT%vTx(xasmkaR%BJW%8*$Bm*ZrNMF>n0O z*XX2fYh-+i=eW=mb(so-!b&q(Xy$q8Y3+SBUb7MTw7k=**vEf%YU-&l1n~EjXpRJ( z-dkL;qhUAin3X-l@py*dt4BUO3y_iG*~%Y2_kP)rz>NhvAFHei(Wdh~vy@>tB%yNr zutZP2>8V4^XT6RJ?bCj4x=c(dS18Vbve}qfv_>p>DoaBt+`(;hR^a}Rh~76MK98B4 zKX`{6UruN49I9oPS(Ox~1-o{G=n6cF1!oq$)PTY*x*ul*?eI|b1_|UYx)*79Fo8K(A8!rmkGq;v< z1h(Jh3LWEX`9A;T5|>7S)pQL2y^q>JA*kLTD_-XBDAS<89Ne#NZvufn3S9`UYIERK zhK&N$b_g4!bLnPfrH>y|6}Y;nLDANYm#jTAM`kSqn2hvvpVzt-o|4_vnX@KaMY*`i zB(PwwEYEupbxQ5-$~(=nvHanD@%bZRr!48ip8cvMl@xospmqT7dG8Y@=T2;G&iq#^ zj5oK4&YYWTCNqZBPVcAG?fUm==(G6m3rITo^L6$*P%>|T8Jp4n2q1A< zX6bCWkrNC!>RGvv43^<^R5nxRjDT@w#_I$ZvCnv(4Ac^EP%|T-_>0homLat|-x2X| z3s9PJBHzPGJOYQ57jD_&?OK|3BX`xLzEnpZ(L4E=*=UoRav<~JF?Fk?xs%s|+E-OI zyBwF^J-`eO%-|Fs8=_&vBkn+FU&4MNK*CQhN4AhKYGtxF>({Bc{7E*S{ zEjV&I)S@0L7xm=Y6torTG4T1lq~C&1O&c-8K>)!94A&INwLvcI&~fBGY`r+uaS<6W zIy)iAa32s_pwm!yfnMX;PWEB7>bv5xZ}0GNy$^FO%NgjEN|bArOHF}WsKW7kWCr~Pj+1fk8Lci6fZA`_ zslwjf(^F3>V?h2c9){}xp<~J#{&e+X5)@vr?tZr1~Npp{n zo)PNPPAG~>s1+7h4)qtZ2>fXHD`GBj37t(uRWuftcT>i#6tJnYNqJMH#7&78xToS} zCk+SDz6Yl_xOw=Q1HgdbL;}q;P&9wISHDh#g@-#qJ_mPhK~di8NL;{Yqj&MWhEhKF zyoc*qxte9-DIqO&hWw=(ICIg+L(VtFmV@?jk0CnXtg@fx1N2Hot@Plj`tV_WU?so- z2w&Iq)~2h&%w%N+7zUY>VUyG>Dhm4{3|U#%9CoirbjRJbX=H{DGV-i0VrgW2g#JkKg-nnWBg? z_48;2^hf<-B@+liAq8AhQaojXBRdXY7?WSlNJGMO`gBWk^Ye^B6Y~yNs!IAzb@k89 zOu-OuQ_Z_2&Zk7`YW1Gvg(ho|egprx%-ny{^9Bn|W%@4;hY9JZp$TVVN(xNuU4hR+ zwE#^3M=?zf!&ws1c3}3J5wn<*B9sJ=4!To!0v87EjIVG7-B5dleC`i^+C6c+QJjfS zLVzsmbadC*uWZ9V?p!?ku~woEy&2*0dj*pRnvdqec`*%So=wE?7ZxNajbLzx<-sUi z^5m=KM7=2Y<52=!4fkO)w~?^xm?Gjhq@r+wX@R`#{bRd$uxO6_%&R)`LDLF)|L=*+ zMi#`2A+*(yii5T%GHl>}v9a<<3B{KIc}m1@xP?&8O#`#a1D1l&;~3A8=a8+hXA)gy z1eO=;Y@ti`xDIhFtT%kmRde;SxihCI+b7SOp6Sc_AK7umtxD zy!z%x5%;(NnCU(i^(ru8pwg!yl>sWXJ0BY){|ieW{eO2+?NCrMk`)!?iCc?-HT;w^ zK~1yOtpNOf0-q$-jG?xP#E>H-hU08_LZ})qGjVaFUngz^$ShYF5}`dGze1Z>cU)t< zIsBMzS0U~v2mB90<5dzGfo*nXv_X)75zWWFZ?3I@20w!7HHD538G_|vSPDspA5gh5 zm{_3sp$vcqzYPJDh9g1L+%(X3D>pgT;TeAuV&=iqE6 zOaahYVF3YRpF!ruBTS~&qJx5Y*c8DE8{@~RK96q^(Cc$p$6zB0>XQp_quqMn+}f!9 zYN=QTd`3OHiFzLB-9?4CUg;Wpi|miYWel;>l4bP9SRWDE@f}gWzY!(44~9#8EcZB+ z&%`wXD?-WV%d3fIes_Z$nxGIv4p6ud6Wwd3&f#&bDaQs*M6SS?y?-TaA$E%h6W2Dtnxr!x z2^<<5kg8cvTUP0YZ`np+gMm&KNjQwlm(~=&F=B(M!UO3TYsvu|Dnkej>g}0JFSNrF zP>SP8_*X+Jm5VO|2}%x@)O9P7Zj^S4TU|jr#0S7gWj$j@f zZs^UJj-N?NOG>Ess6 zsAMYxC=Mm+AXO;qb~a$$2L_%`Kvtj z1SQe;?}FS&tYs!z3gX!kiOl>=qn-RQW3 zL?+zTPqyeogU;)NNj4D6f-BF@Z&}^-8w(sZY)6S&NT6z-nx&^GtvzclVe+1f_#jm~I4CK_7+NWA_P_e2gRBf*njaHH zwXgNYB?j^lY~IjTy7R4rIEIJ#O5%OwsH%%mZSit32xX8}C%1XJbVD%Oy|hxmQmY_; z1zBm(ojT|A4Aa}$*klO{aWe8d_jhUvN&;xd^m$+V8r~9M$dYIwpJ_zH=IGit)aFnv zCl|)0BYLGl)8`7KW)Q-#MF)n2M$2A?Di@er@PC?`z_jn^$x9>oUe4*0wCJ{{!uD8B zNS%C={nGyZQ-%9rm0#yOf4i7ICEw9Lom7RmmlrO92#4x&0=C1!I+Nm4qoB=UoyGlT z4Tc&gCME_YlweZv^CQsfD{ za2FVzD|=lse;%c#)xvg)Ee#u+>8&ks4F#~K0Q86Z9)f^l$9`f_BEs*qgQl6Ht(1xJ zaYQBOw%c-{+oLBh?s(f?d^)Fp`&`NeG4@|GUhse+o0F3f{z0U!WeT4Jp9Ym=>l1?s zto!csq<1x>eW7SEtEab}8-Cd>(q}&7OBxv%e2?|&hG?JAR#2s2YPKa@J~zJAOPCeD zDac`l#%NRR<82L60b^kV&<$lMK4k6krCl$dU{WLa46+l^%7xDuT zdmE;O@Em9Q+tZZRU-Hj~APMP}&UXa6T;+nz4Ys0)dt*Ep ziqcD_I>&>o;Y7E?kD!#rQ$&t4i0ugY`)&jV;-KSX&;ltRvdbn5%H}l%bsk!;=6HhQ8pgZA|axxZJzj2>8>0W_7Ro~3aIck8gxfM)@NFj)_ z-f$4KRg7!9ttdF*yjIf=Xok@w8Z(^yB}%-SAoi}f=GnxE0)Yw;t0>@}+=8lI(-;@K zYLxQ?cQ7P_{KB;|XsAl!E%K0JSOj0HGxU)ta?t|s0>~!9qM^?`l38LDE*9qg;G^NL5GpN+w2eY;z~V&QVhq;8yLYkPuw98oJpsa= z1!+S_Bz$fO_iJ3~*a2o+^}kQLx2L;hhP!Vkjef{N}aq}XG8Ko#|ssGDnyUSFx>LSn;$E7 zv30$F_Ya%#yIBL!Y(SbiZWrHt47m-8c0Dyd{+%@`cem-`xhZ%(bF*WC6_5z- z3Fw}9t9Lf-ms9J|)P+GFvziUtz)|89nYGL!JVcHoT;tVL@v}+g>jsR}(FM}Wx_F`2 zqP{D0+ccF&V|-`8_#X`!-oo3s2EY05i*_oZ{eh~l{QLK`LnZAG|Er;-Q7?c0e%bv> zpk|C}vuWKs4$_u)+Ub_jQf*jr9ZO@nmbj)OZBT4o(fHbCJ}kEJMr;%Lr7sS+FV`sD zwymkCw1t6#`hmWjyqglHH@XYX{HV8~Ud(WGOFV;ZP*HPTk5rjld%yp3&9KeuYLC^} zS7cT+YBI(4u<#^SusV*qIQ?A^SFkEoq*VO2tFW>^T&=IJ?vm2{;HLyb-llIoOIVvdvuJug zkou3JJTg)IQ@_H#va4n9pu}#G}s@3JS9E7wMPL_{gm*J{8_!Zu|70yWKqV zvFlT%9pb&)%(h$d5$7Sr@bhnUdi?!|ZhotZ*uK$X)~|e7lELdB|G5_W zuO*tUDd#CCRs{r5?|+wUtlpmIKC@fzZ_qI~@IA&h)N0e02k$ckm>eH{TE8k%tK*yB zsU92KBi}CTgfShnu)pF+BSY!VKA<;uIV8-dBpX>ZIeA!>cPwnDnUGuI(ey0-u&CXB zv!Qn{e0pNrxK`wF=vV3Mlx>*6Flzu}bHab-&|Q zn>{a4KlIhp_1b(@Yy6=IgAHqD>;K9A!u2-9W2R#Au{`ZGy`S;zN{yZj2gmbL!{?h6 zEdmmMhuV4>bclViNvE7veZIu%U|z$Wn-9i0db~L9G}3FVd;xuR#1;oXRpaRzDQDRo zXQuYY`9Hq#t=81``M|A6tslQGdAsED_Vt`xs9Q6ezqaSLSGbM8`VrL(`L|M8)$ha| zcU93A0O|eDnSUKN30#=>%$6Of((=i+tiW&=jA$qcZMJ@d9O=y_dWas1E`uAZaHxwjc;vui(N))h0gfCN6C z2iwC8Q>KD5?wwZB*q8Njp(d?S=-_Mv$2S&{)B}{c#COgED%Nt{ccYnab-Wj;dUih2 z$H7|LxSkqzN;e$Q!knWVdgD-Ti^YjuiPhikJ3dKwschl?F*!LkI5>2U{`b+1BWxn^ zNdmg^IlSW^-&gdV6{^!}-%#mAJKgSQgwXHe_|5kkJ_jD7At7gMM7)y+|3bC(Sa9sy z&20yj0=-Y_S{!<+F=$Jv6}L0&3*6|oz?!0-+*tPR!EUOx`rQ%R^cG9hAIW*D@`-C&H=n^fc$w9r34_VuMp7e^93ZUG*h*Mqwcp zD?uiG=DPM{yB>auDyy9NY8{}fd*rsmsfE*DgJ#Cc)!%jmtx2|GXKwVF7h70V&`eyR zlPOpBu)=cPT2`H>%jv2QtoIIx)G`>|`N`bp`1gvQcGslj!wtslW=6f6TPm5g1FG+E z^Mv1t(CY}3jd^f1KEF6yBD?U-@cmPk$(u5i(zI!pv-cQ_7?X=ik;RTi!-_!;(Vl1A z+*=$e3`(F`-sjv3-S1_cXk1tw{D@yo_w3xBG?9iTCxcGbqW%hyE7n&8+gfKPxx( zYRBBIHQDRc!Rh!Yv`ZykN#beeo~JF$ca~-Dx})`;y(ut%?=5lpXVq^R(_Tl)Wr>Y_ zVRf_QPt(6IXy``~d#bd{`qnv1{i358*-3{R=3lV}zZd3dKB|3z7!dZiJJKiThFV6m zt=(Nel;SAjt#r10N1uK?-`>C)b=}?cGeJTH7WpUq5@&ReoCsicVORWn|F_z2v0G)h zqb^gSbKtG1y}neSP`vVy;X&EdlrWCpIg+n4Z!^@JIxf1J3Y$N^Ds({I$H(7U?OvGh zy_Mt_Kj5mT6rVD^XM6B;@^p!+qWvMm73S?>=KCpXlBL27!(Q&UEaGT7V_(iko#IQA zul{+QbNIf=$x(kBCXN%9G3{0Q_w6rCuF+moICkHw^I7^2EXR9e!XdjghG`~YBEXc zi%ZKXmB+Zb+rxhOMzz#pt8_Tx-~G;HS6z;S()=7J2UU1tTk!RT#^jb{VL#?8dueEg zFQ;5lJY0QGUY|BR%SHD&v3!fCXYK#3MWZ`Z z=VTWqfrLXGmx7pe_sf=5ph3i$PzsK~bqBx;jdO5{JJ(5Ry|rauml#9R2SPzX za{D+j5mwBOqE%P^7925z=(*$CL?;X>`@q0yYij@tOo$KrH8&5SEZG+A6H4Kuz{&H} z>zm>XO7@)uguOV6)*qQ@%dDK+a&sH?ThppZ)wxGLkMeekiXu8~h~(Yk8mla_LG>tr z`h)$KdQJfOgC~K5D}a}himwxt@9(W}Fvh|5{SUEwbGi(o)Q?=JwiSzjd0BOReJOxG zU>eQ<>X0W>h8Bi`lDHt8m553e3FvB?nvyp~3w9cWlLRg4BWS|te_?WMm{$7gZ63CN z3sJId;m+(A`PKvxv6qr^FL>>MY* z!J>hnRTM;x=_yblU+D0g^1>Mf!o1wkFdk=ln}Rp{7UzlhX|55Wsel^~-eeDshyc(n zTuWmAK?ovsv+LtWgyKR*3-edWwN2?Dvw(zX0P!GFf2Lqywj`qk?uOcO?ptg2mCVYh zKY#TJdot&Tsr$Bq5W(jN=ld=r5Z4O!R*I4Say5FB@#b62HHV4^XI`S2>QuRUIsu*L zDCmU&00*qOKPV;S1=>R&hch_NwrZ&usp#*71OSBW2l`7D+>@|{6gK4UbZ+lh+`@Qk z{3&SvmCWhrK7Z~jbb=-iWIeuBZp)W5&%kN}K!817rP?Kiid^U5ILwEJ$ zpFf{Lg1~d|?EIQh66l)+JbD5-IwZN_^dYM8h$L7dgIX5U7V%EO0{o=3^u7!BCg~-v z`w5H*w;xapSWu!U8Mko_&iH?2e$B)uL%RoC_Reac2@mh?*IpOy7 z$~pLHd^wkPmLUzP5GgX~{LFGh8qsLCtMmb)AQl^Q0_MrUN<^EQVnqWw24BA_FT!u6 z96sK;f8WV~bv0N^GA>(##xe#?!2p0hu|!e|3_U${woZs)4ml!I^K~LX6~HlB2qAli zP7_i2#0%U#*ELNDl^kB2H`{N6->C`V-{d!jD|hHF?Hrv(bcY>c-{464l`M~j8RQ3m zG84#6x*l$|2I*dq%Lt3@x2A*Kzaq$oH26b&HfghndtgNaTJYS##bW(Mb|)D_NZo?} z3BP3s&Fcuyi1lh8Fef}}FeK=_aFdtDY6;HgIC?_)3-0bS7(rss0qG)X-|`8Xeb_Qa zfw{M#t8vl?e2P2zFvK8S4e?iM0_$h15GzJnVgR)OQX$50g&gVcxSm<5p$rAU5fUVM zRKdMr?`^jOa2+5-g3vGG7MKO=B8(dX4ko~{rl*Dw=|XggQ-+a+q>f{`ffzL5(IcCe zm;WJ{4E$vZb{_kTHlochRaDgehPSQ5LQ$7X@VB zfomm#a4bdKyU-~Uf7}8M^`<=z-{3|?(jESzO~({gDPtt-aAPY#%qI!oCdP3DJ9g;2 zhIAcRTu|%2E7MpsK3X?L^D-S*L;kBr{9R-JnRYPiXu*Kwpa&1kk=zH`uZxGqG6NQ) zS)`1MDt9;jsCYf<>}MgnOCKg?k<0!KVq$d z>8?m*6Q8X0324EA>~Oy_#K?hLuc+FT8scp`fsKzz!mafDkqe!Mw<7$yT-U8m}f zfr5Y*ZG zv(kbDv68xp{6BK%mbU%_3{aZd#q7e&0ayZ8F7He0_Y2j6 zTz?;EH`u?4F`XdIKR%=et6p`Z)m6T^DP2FgwTz7BK)J!wOT<4&1m-^5ZktjUD?1GU z*)+@iB@&de=LoY-%vxL+?t{64J9y>wa;QCOHbE#vHW3o0*dyK~0g!zGc?WGE-_}mF zgi^oA@Rfid5@|}j-WavO%co~4K-#%rSn-){io*sc0o4PRDX;`!0g)-)k>4V-`L@2k zK4jdItL#k{kNs_eakm>%k{wCXKWJd%J4Og)K-IwCidbcLp?wdJJ%UUf9{5L(9!U>n zl_OapLd1v_!P9{zt&UDk*b?!Ql+-nxY*)qhudW`V7pMr^XV;9_YYym2KU|s@M3!d5 zSNjrceon?fe=7rS7<1lZf5Uq9&J$H2vLiq&TVvhD5|dN4#5J=Ck(ylt55SeR+`@b( zudTxmq>86iwyvwLttF*CoU+AX#6OLNc`GL)>I$JGkhj>J5K=UWiWUnL*iJy`Nhv94 z0XsYIJ!5C9Oq~15xJvHeM`%D{YYQJ;k?t|&nNLC~)iZCg~d9L{Awz>ezZcf@QyK&eY z$SYS0Wj>Oj-OsU$)IGc;u?3(7y$pt8dhhuPHM5k_7&&0`suA%E&_E10P#evuMZG7Fv2L;xx%-V@D1sjcj z|2lZ}UMh`tbOvP?l$tk?9TBfHpU;{UOumOpyC`fCggeEgEpMl?%T_9dz!<~eFq+N! z98XwU!uGf!gZ|Zf>q>cGRJi(FlJ3Dp%F?;pZ0oQ;;ac!n(l);-8qa&0b}C&O_1gn; zK@|seHKLu&aO`OlRf?h5Dz)~bTW-)MdVbfRCdd3j-iK}&YCL}R3dje%sCf-9O8aj7 zn_4kBS=Fhxx69F%`OU)TB69)V*1NwA&b8%nXRI9ELEcRJWOK7~EbT#oENl^vmX4cn z(rLdrA}}nrp1k4j$9Y$V=?u`(m8c(9KA;mHs%0p6TqmvEZNjgo1h)rQzBP;OFJX&6 zy;>z!z1V)M{GCO0#NvT==}(gD*Bm8pgNx&VN}l0*i|2~%9>-NHK7W(J7Ro;LrOH{O zVuLMHz^;w&TWk}a-P}!mx6Rs6X|*clj`)OlNBYDyw%X@)&g)!tp~pp)EA*)D4-~xn z>PTEZ+qwXORZ%yo7lP~+@1<`)?AZE-dBb`Yv8HeY&u-YDW8t!tfeu*6+~=4g=I7g8 z8bca+WGY{|bXaM$hc<}kABwKxm67|?|9jKh3)EkYG>Z+}m<$9;x>uW-h8S?ITyETY z(y~2B%dhvNpx~D;cGX|HjvhF^nu&a>qkUR^Ti?M`P69vd4kl>+W1Lrhi*=CGj|PAZ zxpjQH8L_D-Geb~y?Tkaqwf4KVkHW8N_bopc^Qqje|Bm8PdMp5b`Jp@OPU=RaF^gBO z%F6H8Kd2#Tec1OQ^>XOuV$&$v!pA!}TMb!!4{usw9{en1K#HqQdKn(!fhpa!Vm#aQ z6yGlIIFgudRJ(Ciw!_1JXb*3bpFR2bJNfqX z+cWfn^fL4~>Fl-bTBUctg#zu*2n+3($ikw@jVod+H;^Z zjZWA`bt|{xEKbp69+hotJQv+ak5iWSz0HL^?LFe>t_5&D@M z%v2e!FxEIKJUnl5IJY{qTg`h^vt_FbVM%=P0Sj79u%4U!Rbzc zH~%GxJ<=h=i^w7rW^*s{7ush#K-jc2hOMgMVoaLfFu? zKkZb^Yzc+uV3#ufh!+(rJo5nRE{N+FP*QH%xDm$Qx#>|eY+DQ^DAy5N^~|YLCY^$f z&X18RDmJ!m8z33-qK;OZ>$xq4gE;-kA^U>#s=#3eZ#@D#IdMyiiXK&V=vct9&IuFzR>S-)=CQ6grEx3L`-9$nJ;o6^a3XCMdLV=+%b% z-8PE!zk(1U1yL3d%9n|2PC%(u3P=I9Sk+CA2~9p0JT*oxBJb>_sH0gSlnDpi)AOdE z3_TXqG_a-ZDY=zA&O0Xd$zkATZGo(S$Qz+-FaF}U33-EQq2@-qd-DCCKCgL znUJ_Ymf-5uQsGi1dpJ4S1ByYk3)@5Sn{?=~k{5A8UC_!P+$#GY7*Mv+g)GapyHhaV zMlng!8I*iL<;1hPZ~MUUXo2G@id2AXZO_l8w8*eCBqt@gvqYlEgUpr~XK_$Dre>Rt z>I_XP$(PjA)g|e0zDhBU9oXD~6xusDK*xg~GJt;A89dGU#; zC#RRfmR>?gkD5Qa2VEuWqBz5;f`9&VF{rCDva`jR1IW$Xi&HR>d!lPh50D&NCnwfm z9Oa-?LI^B!8=RebCuX2!%Y|YN7uu%@kvnIV7d-qHaQdREzbRFT)eZaH-gQ%&MHxlsz8>kw2VnX;FT$~_ z*g&~BjK}pbKsDDSM9)LQLX7#Sm^SDeBm0W9i|Aflm`2hCu%BEaVMB5Y@ANP9wFnP~ z!u-^!grObd#YVfcK77zg2EV(X@zTUEpt(W4eFFn%ipGcTB`GPMTxG>=$9b8>84^$` zVF2TiqPtZ>BO1Dd`%#q$Q;3->7X$u7>2NH-JD^^LlF!KLxfL46n_k+=y0*pYwbl8v^5G@IX_``L80LVYxB*`@`i#y zYsZMb2B+*~vrV|#PHqfF!MBNZSZJ0vz7iItgj zE1QdL@%ZxU8nGlJ4ydlq1OX&unxF)n$CKqiFdVux{X_s7WN!F3F(Dy!*Wt9&>`Oj( zoUJ@l`QAb>Tlx2OopvM)!9p9)K;OG=)r;b95b~f3Me^+E2)e#Ccu(zy;tD!ev@x2- zJis_rOC`E+DAz@Wh5w)xETnQIQsu0GI18$=#)K+>S6o%%nonVkfM^j@@e`GIcxf)S@s>xlXK}zWbirwn!P&}H zM+HzZ4$+p?-dQCH6Vw9&CwfZ#}^5(Gdz2X6wJf}`)wVs@TZ;KQ_vTmC^Sg_IoC1JYDl z{VUj4?_Iw%t8d5>pgD-i@-_DJZaUZ}7 z@|^Y}|F}uQq*YQg1l<6s>e zVu+;BW{#ZfKqb+y*|;9Qu!6IkRYEZ~#8Vfbd^zYb-A_r^`OD7@!+gH%+q?Pk9xv~@ zeUXkeVsEeBNSu|KzO&P$v`}Wn-V@7^2-q|B8=MS!9gd(g4TR5F!VJRw88%8(cWfcy z<=`UF3+pr%Sp>tl#Nb$@5h?ZsI_FHl7!3{Gj<;{Ow0l03syrFLjLvLA^k>Gs`nciI zi|aEFYc4;vXVEY}{lT7%y&~ODSKnr7{6D0kc>Cd`6lElPl^H_z zNcP@Y$v9+2$X>}_`P6_(>aJn+r|JlEOk~`ukw2 z1WjiXaBzbDH9!!+w^Rfd8nAUG;33>?Vzsom*w)I5^w^`f&zZnmPwC@$?jjIpVRjdO?fWz;peEKkAJVXZ=Iv`RVkl z9gJaj&K!fd@c~~i?dj7&;QUTcoAmSh+?W7QH2@62O#pfm5bb763vo6uy@7Q<>>1(f z*D<(mdRcas@a6;6^|cskGTB8{^I1Vf_RUcBL*)@i&LR_38 zY*wL74Bq}?Fpo$Mxq?QZ4eSLF&N=k6_` zPZxLsmVfz3PAKqX5*w-6sfPy!h7EijNB26G&0z9C0C=5CS2 zyUo7+j$3mtPv`^}SS!rt(oX+~ap62_6gl(lz^rNsdKJYbCF6KoU07@Z`am*sV8(zB z`N5NCZvP^x>H?VE0GMM-0L@IDEge;i1^)=N#6Tb=EGp^)`)rMXWB&F}D7kqXsR7YlTKHKou7uTL-al z1nV`Jk07_<2_ZF>5Jldy7QlPy57ZYgbpO)ZPlh+SN>zeC{Q;}T*Fd-gmhr_daJH052UA#&1St3{XQYf^ z2*Pj#H?dpsJm?s3GEqtu77!DgAbZt3wFadFj2q|#A0BdrMe@4q;=rd9jquJ{Rh!2q z;4=om1p)#g_LtDNmW`yZ0hu3gEnmZO1TDJS+7ZIiw~Is&FfYxFhVa&RAIJ3|IUx-! zmjK6xK03mZZ-5CWgwcx=67334wtiwhs0%j+g=4O5L7O9@V+Qf31t3{Er@H!gMHlY_ z5P5+489X6k=L67EfecRgzFBc#P6gfR8F(UI zLc6K-WOddFu=>e9Neb)k|PEXJ@zJb`@sGBy&Of zjWBu;2twW=lBGc)U$%7t6$QjYKxYS9S8uQW1miizTjMowPoaR&{c215Fddq zAO|x{gUmpr22we+*1-1?kiGi1Hzg#RrrRFZA2VY92rg^yoO^Aqb^9NU>f) zgVWLy(R`k0;pFA*dH3$Z#fyj)Er=rS7#OVl+ycxD;(=BV%1I2l@AJ2I6`h&3gkWQ6 zpm}jiCY2OGl~Wde_*Y=vr;$~p2`wZhwhuQJv}j6#^d%7A4xXE^pupNClLNmy(klc` z0&oIgeF5+v$*=*BFl*R2jMw}gW5<>(K`$M~Lxe0O0RW)*8A(hvJI6bhmi{Acpz30wHZS9`hCUi#=6;AW=tH`p zn%Z~h>)F8PK{^UzONf`|xF-9c?(uc7Nqb`+4M2^u|Jw$AMkjqOu0h~L14nok80Phm z7yt^ADj32@s5zMLL()OYC*i+Nh*0H>Aaxv2=V5g10^|7GNafNTbn7d-rywu5$5*l6 zW=xY2t{RTzuzNZHES&{zH8P-Jsu89nhUpUO@-4)4l8dYF?&dPV9qMl+tH&3-j6#si z_gYx20G9+bN8asea=fUQ8S!=|5$ZfDcGrveeRBS&L(2((sJvn9BajTNTF4dw&UhlE z#X#~CRH2C1aVhxWLz@^3Frz@u^s+~|5GuJkhG$T)!qG^?0Ub%WH!wuNW9bDfkx*4! zh1NW*^R&TJf{_!e5Fhs&h9uy%Q_#x>f5=FPIRvaa*OGKe@-MKune_pAFkz0MhjOtW zsv(Z5Cok$?_g7l;B?+;%VxHdIKKu|R=6dk4C?U=;`OSsC8K59k|5+?VDlahJM*NNp z-aU(aVO^{=MTH1KRw?}%=-|Nl<`UsXBHHIfnZVxh+t@s8QA>2XcTJEO^7d{ zYh8fm1C9(fw3Jjv`kUAJn51{2LQ=o6QN&ENp>zNJw`0NN+YUWnyX0PXIQGoB-&0*E zTZNq!iit=zb^AKspG8PrG5Gf%4=B0&`}o{l>Wo8LTPehA-~aYX{`Gp`fl=_k{}?$3 zG=ctmh|9wk^dARY7pnI&3G;U)MwY$ZmVdk={E_bnYE7RifL=l}I*Sr5l%gTK*yr?J zj}nay#=^4)iy8H4yHHd{^3?RC-{o)Fe7A?yN?i4#TNEhsN%N~QhYmhGb^nVJQ@2qL zl~4dq<7teH83~nPZ8>!SCIW|ctXXX8Jh&e5&C_^GpVWpQ{`fjgHrdYxSSG^tN)D|C zmpWEjQ|QsdgOo%$4a9sPTTlg4plV5FSY%9dsL*JRilahumee^GISb(!VOl}3#AR(n zWjH(27uZg&8;@hqlB)RhIra;ocCz7tzqLrixiA9xuiEX1AIDxE7=ODk1id#n2A0p7 zYrL}94!D`ldS4@$!Fl)-`+BN=iFDPyACL5>AxJnE9y36oU@HP2_M8>w91*2YR>@+>T-*Gg;w1iK|#!BA0kZR~dPZ(=n75ZGgZPpru@{dLxMlHU2 z8m{;}QK4`{koxDKuIyJXk}%UgUES^po@+06->JxcWqc%bm5Y=_g670d;4t=Y>1prX^v%!d^h|wALVIe&~!n zxJ>^ZZh~B+$P&9+{FK3t&xKsmPJ5P&6 zE!_3w>&j$QcsI!-Ag1P6t*yTNy0-7nyqgGz1ec(`&Vud_nW(j6VmVFtJa zc@9-yl$fzfkY?|=Jguf=Ct(U;D$n^Cs%>Hs|778wvLdbBsViI5h26nr)y8?{`42yg zSiBWA&a?dciwhIE$tO~5dz3chOPu&z#8r?IH=Po1UtEHbB-YeKLbib82W2kgf9S*q zNx-ir?8qb=H*-JVZm=*`_x^iTD!p%yoF4d`D7B;xI&=IiYB0D}tji{<=a?Di*^>@( zMmv9RBX46UY5$bH{mY@%c_m|m+ubiVK9(@#a{NhTU@>{+lCaw>{Bu)%ENE+lW80)a z@?GZ7e@zp4+ovhQcrHafFZ)C*6u>~tEx^>~g5$agTnktPoSmH56%!kUR?F-aGtkT^ zm(Z@1iS8ZgoGTwgj~rF%vkN0Xcgq1wC8^12^|7G7=acY!u3B)e>Q`TW@gpcnfGTQ_ z$uQaVPsv{YSg1moBex+0nv7tE-+UcGGdEFJAp(UAR8FsC&7C6JpQbsi?v0nM9qKEXfg zELSE{-^%yC?*6nnK{|9~t3`eE%(42)ZiBmDUwf9{Zz1A%9<*xbn1#=?qDkHu_PMQD z70LE@x>ns>36Pg=Hvh4b?^kh!wR^nRB8OP>UY3))rnU7FFu6dtN!~Kt;PZfw)*E1a z2x$R!6*PD?HQQ(piF3Spm(P3ke&KqDN_VtOzCo>d8J1bgwNN^IBzrnmw5No9{!5>% zS1t1qG|Ai~1t5LM9TgVf#o;i@80uM*nV$nM!zu*^d(!Tt#bjJ)<(Jv7Cyh4JTu=^iykqmIMTaxhWYc{vDjg(sfxa0FkpQ{=(m*egjJ z%(UtI6}EE1S056ICuCgCO02eg<+#h2&BS~vp0Gb`(iZspEpfIxzP5IBZ{E$?Y~Q3D@*y|26lt%G@C3Vq^}9VN(nt54v5ic+bqaf}Z)&u1lQbmeED4*lvaO z3eU5}Z~Tl?N2TgLU&o{u5g#x7>q5PNr zw=Ytt=X^=ALv62b#HT0{T_g0hiWQZqaQAxM=S*L5 zyt(-^zurQxj0~u zq>^1Ayw}dY6mfCmqG|Yzd{QCiOPX(;xum57I3F(O&#lJm?0$SY<-<=(YD~pNd+T5g zTEH)|*jUHb=0C)+EB3fm6@I?q>y}xc-R@XzrE_XN1s6yejwRqjR%Gntiy5Yx#=g~scu$1mSGYZG@4VoZq>hWtihye=AsGFXJmRlY!8^52e)EH`$xeMFo%DeSfN=4i{Ze^FiOfMlll8H&k zjb^qG4|e)0?&E>C;$wDP6SO$EVANtR+apUxUq`iXDU$tPT4~Ra)(9}sQX4if+{Ogq z5YvB%%n(2Cp9!<*uMQKwplYS$rIbV^ArhWRbEeoEh2>{irbipRCNzQsX>vJ(&Vg1#ov_2@A%@Xs<-;pPzxI7v$VK%#M9p|CJ7bkQ0pza#@S{3kF zIue(F!fp&cyBLBqore|}94X>QIH(jmsl;XVqW?U-*w&iadHLN@q71TchfKq%^c0N; zs4@>rWEKuw$;k20&U%cM4Tx=?{_J;~Ha}b=NFxa2a_rFG`B{1C{$d&S+XR1TyT{+E zGF80(3eG2c`}}M@DuY}9GY-eu|6<1`&asF`MCqYAGy}lX9cP^vz}xzg#C74zD4<>1@De!cH$Iz$i~5K zMy)dpq~ZUg;8mUfM$)R(lzp7qfK=r7Ifi2P5$xMgQcWhB^}fHO9y#m5;rcO6`~r*S zuI$OZFHuKOf)|cT{rjbZ|NcMD3;*)}p^*N^`~TnS?0>xce_r+fe)j+I;k`7Lw8#eG z;8^$=NEtap%tUKiP;j|@dcui5#93K794n)SIXX89e-d~^`?T%?F%xc~%vEt`iORHS zh7PHLGN{|_W}oEF6vz@c2_=x7-MYvF=o$)@C)Fs|AIbOyanR8u2TK6>?w?#w3(K82 z%rt`_onz^c^#kIJS!ax~Lvaq-W@$pDncNHEF9U(W^T83qHmI6b)6o_chIZ62m8&!zM zgYJj%F0ukm3P$Ey0z-9cz0^+>_QVJg2P6Te2k8v8CBSS)yfYwlWfZz-;3S1a=D{wV z6^lg!gof%}b`2?kypt>K&@rqB8y%HIzRdFS7#vU6lhl*2uiku_zFP!hZZPhxg@jo! z-U-n{))irn9#4pA0Ir@R_=X^k`M%mR{B*m}A3^Mff$!LpB(MZ#;7Ql)4LC8)IOJhS zU1O6D%NoXmY#6cnkOOT#EAwf!q+G!ML;)iL^rr?|2Vg`b3RG)22hyMeC;2^|V}K3& zmmMzZzpT{H7aj#L2RNqtfI}C!Cuj9>qIKe*Fa3c=55kTEev}>Be6WZB+J9Pjv`9KH;*io-R6Cl6f4^W4Ze7e5@ z2Y<9uU6F4f&LO)ST~NRcK3u?G1ag&Dk@nQO*Vo>jGKl#=^1y)y3}M8+(b3V9>t4FL zx=3&a^jDxC$ON=0l=v`gUQ0X|Aw7xjmrM+%uVNVgbLj+X%f z8?%L|Wl(!81632KTJew1>QExJ@S2$6M@lt8dS9Sh0}m41F;)aA=JkB*D=S?AhJ_R; zXmBmUC4mFTrJ7l)7QS(y(1Pm%<`RsW#!yAgLEyjx{fvP30p^o+k~slS{`(ak55WxM zjwuM5#>CWAQ3Rt6EMCBg3LtCn+HquP6RHx9RteCAJ{dd$8*kPD(t+IpNH@eNiHGqQ zwK!@^Rv~W+!aE`5qv6Lp?$A#BGNK)aE)oEq*0#26SuIxHfs{LxXIz_i;54W|C3rsw z5AlWzkL6HdgjSJWNT;R}c>X}A4_d=uLlQ(Oi37SLv{fL@ydg7_hy(%cGpM&wWiS}> zDk_|SRK}6&LgmWo4(fv9!opjMiUY3t@v2waNA0SNX~AA5#5MK~Mh1vjL!yjPB}*_q z3`!w>_1j6fBd|SQ@KfXLrcJ(bAHsUxf<5z2NDUvJsYNjJgNP21biw5A0FP@yF8=@ja29$D<~<6LM6tp6uWhyCJwS@ z!Afe`t!v;k+A`_OcMlCsU?f7gg-hPmB1u2dKFQ687Z!U%~(Cs(^_o z(tE^$pN=Agp#v?+%Fh02U?77Ud4TBc!^XY_Lw*^VqYNWGG9m9C zO&c@USbc;%AN~$UAQ|h~y=_B;0Nc<@20}yin4P9(%aj9HKp7aMUAJUBy8ri96v}da8k59tyToZ)d*qwF7P7t11IOI=|qiVM*DIZ@(_})D*o;1FRVV z_8~D*sXvgiV$4}mvYF(%=6nHj$0Qo%`9>{@HKD44C`v*J} zARy?ijK=NTPqH|96Sx7VYDil2=!C(Yw)%Xj_QU*R4j8SQTrW}}k3o?B6My&8I(#cg znF5m#+F%Je`m8=Bxp=ZB1$wnYnv;9PObO4WC4C>!Zfgy|>IIDo5x2~&FJHdEccTsd z4#wx&@ohq-rKR@v_F{m`K!Y<3rul1dW0u{(s;;X-k2m4H)6qu~nwoPrIrr3f{UBfa zCbThGsf@!t>&Jm84BgKwRG}%Heb+kJJ94FN2{Rob>Cs5d7v>7bCEDesu^Q`M|M-qP zy`av6pVKB*)c|~an&5b<;Ma4Lp4?jNBngT}~3F5p?I}S=i z0JcXeZ>eFF`jw*}YU=s6Eib7q@W>N4F&N8u@+h(<7GPVtU9OofHkIn4rzxC_4wh*K zDJOL;h!jO66u^oPmF8EnwzoH|ak|Gxn*tOPa4Ql}x}~C`a_bgYSrksJCWzE3_7@ct zIMwJu^E^Z9!JBCnm>MU5Fx0+JOBw{iA>Mxey8Ww{a&g*%uWUVYrmvX)#tD)%@k_Nb z-*s|p#=Wd;bukIksS?q^e=I0vm1woS$o4_(w+oAap^H4?%Gl_4fu7=Qu$rOaKG@55 zW)Bq>7Q(7y2$ojR3)zJbA0=gF04qQr_L7I&pyoAvJnZ(x&z}#BCQ1cYwDSCX1vN}h zO+i6~lF|!h`VNIVU&1auZ(3_Y1fc^#1Uc%MuDJ`GoM5A~3w#a@L&HnDdjM%b{29=8 z!F{qkFOL%_;*fk-S*ckPgX5%&0Jj=Q4}JE`bGC1lF^XevyR}uig-gFq#=F2k{6$Y+6sB`*L*nsM55;aatIk^8m z51a<6h>!Swe{ATo^9OqNbwFH)ZxDkMoQG8!ApYNP_P5_aPXh^s2sQ?5sWp&sAR-*V zts=iMvfdV=J(x z?n5@LFr*Ea0^O^*S(2$0x)k7G@)~{+m;kWt@LK?t1&J+!wu@(6karqDp1)(~rL(>n zWu9b_;m{PJeL6|u7(z^FhTkBAtTcnXrSt7urmV>4?{h7YJT0)&_g%;gG5cl#Do2== zyx~~``4E`kK$JHk)qsishS|HtMGxawg3@Vq=*Mkl;R}IGMeX&Owq2gp7a6&zB4wm) znxC&UqnodGkLbtzc(RbDq@1JVx)uJOIrq#8pnuI>~FF-!wL$%t6!_# z{TLHy#H-T0_L928Krw)tWH7b&)oiJ`{___eMQJHZfx3Z{1=p~i?@s!(nI2)WYah9@ zo9#H29#O>X-lQt>u^r}nnCkWcS^#MT9N$X;^X{Mj2{F(2!H4k&HzH028=m{!NkBo$ zELdDBeFL6AKtoD-_N>P2?GyNgpuBz;9ijJum5uEL!&N;^jD&RG)sde<)}u=0=Pem; zer2jqVYa_4i(pW-{5>__Hl?JYH5RM}3>8B|Lv{6+FdM;7+dd2>HDXf-5dnZYLA3<( zEYOqafkFW)<}9h*lV1(*>zDuD`W}{5Mt#5kItx`;osox?B;DtDdJ4u9czf;E;De#ZLV6ow{O_p_90?o2~_1DlkeiFOjso2 z3?|swQ#FTv(|-P^|JN%<#lGI7ux*3EBWx!ZaP-ha#FH4L3GPl#m(gu4;$RW#4I3F` zFHxgc!lHYy0hbkAhc zcA91d1#d!GKB*hO-a2zBEDOB;*1*mAjEI}fPOoc1mjLVlKp_iwev0!Ahsj1rbOYx& zbRVqrNK3tgEdC_C1NI%2RaKj-Ls4Xzcd=oW>Lyod!qLGYl1fER0)%?_rg5LhSdd=n zfIfbJS`EN%fE)RhoNM%?S#`HrIXEVO_yy`O6^4#J*Rf@{js$IS!y7DVxUOZRfc%(L z>*Y^g_WKG}CbeZ*?;Wh)3WZRRvkb;&u+5V;N%Kgj#JMIua)ee2)GBZ^QSBbX1j6+NF!b4Jy;T*cO z*?xPMxsCb0^QNT7;DRT$X)Xhc2=O!hHTQ@YTDHjC2xxa?gRo~iZ6T1EpnOF{KVf0j zGkghA70OxK(TTE(s^_(4PuxouGwOaIV?~6e33&)ZN8J7HO*U56-oB5f--RtRN<&FW zwhA4RHrfiR@)ays(xeoKnPtP#Br@*Us&w?@wcotRIdV9*;W&yeGFwIPg`n}*B? z0)G8-%O~InRyIsFOu6Dx#H5*wyjtMO)46(DTV#f}8@K}zcd27`{X-?1$t(CxJJ@LwiPwZL%|(90Po-@Tn1)A#s{on6vYahKJ^ z@5)7$pR?)G+9J?Fq3>twjwz(8$=OQMJYiY{yC0a)GcqzD(J`{+a}!_Sd6Aoa=Y>uM zB@gcv$Hhr~tyg=FaODSJ#jGHg z)}U>fCOmLbIj5VX%BuEZ5U@vJc@a;o8_{#DNs;G!<(i)q{pH=)59F6*MncUFDXNVz zHZgDv@B{?p2fwg*m6l>!H7L}?&c^iA=4=;qBK-G@fwr~+tqWiPz;fWae&TqQ2N!8j zl1>{bsX&bB6A`svbSf*-A&-tpvE5ahn)3ZB=RR-0aJ^AHBC^n~K z+!(ExyNfN3scRa`WIu2p&NSEh&=e-}kp4Jg?kc|D?{&Yc0{W>_PBnivmLKGaFtfc#bu6;3@ zYnI3;OmZ}of%By8p0?8awNnx1ilKvAc)z_86OY$zrWnHtY8#UaUqGYTxc{x1tbG`o zDUhlRd4-61c+0s=i&+JBrp^R*%v0NK9K$gC?FW?o4&(`yVFAJ72Spr_>q_IZteTYedh>2Kl_>|&dJfY9$`nk5 zAcslG=w9n`XUT_Tt=AW9)W8286Ajt=lm6}9g)e=RO$X|LomDV)SOq}I69b_{x*4fB9nA_zk(WXgVBvq{&2_yu}D0-BMpiJvsTjwB{FHC`2GUG_$3;Ej0Z-OK1 zb4Q;xsSQi!Muw@d`!Pkq`00&0vJmR|QF5}56_2l{@Cspz?|7Z&Po8hbiHwGkUXiT8 z5DR}`4v}Z-Z{smh()RW}y+prt?%DV6$5Fr2=}~yt+`|SC%18(ma_*s#VWP^(!`S51 zKhN3jOjZoLnJJ5}igQWmT$EE}dq{ThEhtHtW#;a@w;Ek~CBWA$Qy|eSq_L@xbjip` zq{7*@C^sCZVOUW$A+5D1elc1m#dJq_XzXDbKY_XOjAQ2NLOuMFWGqC`6P39C;h|%4 zNKz=RdL*Y_v_h$T9i{E%l@IbvNAoW&nmu@<5tOHp6DOE0(9v;3%IK%y8%ucyW0A~q zX12NB-%|H&<|HHy@R7G;f0wRK_n>O=ut5iAlS=Yc*i--TAP;c9?47fyQ5h+t8!D1x zF?#~n{5@`zdb0%?JH6O%E&K^Eb!E|6NnQxO^rBKj|5ne>Q&EGrf8YoOVuPLE+FY&) zQDB3Y4O8#0o@OB}R2Xb{7}nKMcKDk}=T*|4O4X92SyBEyq`fP_VHcF=GiHLzua0y# zXV16G>dsm#8b0T(sE*OtIJbZHh;n9Py&fjb+hQlPfBCVRfC(uHQ}xd|T|tQ)J|*7- zvW|8Oi3Bi-d~pIy|3QMHydy=>I9l^M?sJq&dYLJ!VE(Zh>dsVo!8ZrOtcHOzof@O# zfyP%7v&gue)=qs@y`FB#>)vFfvKpf}h?95VrN1@&WyL3jk?`;=3M&s$9JrsUkJ1{K2Ga$64VEmw_P#83Aeo%U!SH9sFoUK z@|K3X?07v+D>{JM^I@cpbTVMD3)hG`#PZGu@?}d(N4oj32HG;bt{3(=9R46r`8ScY z^ni`k;{wr8JAJj7jO#tCXM(DwY}J<7)gMQRxwJn{ew|Aq{BA^%am9JSo(NeF2NX76 zlbIaST3OBUmp1B~5F#*M4&r)mSA5b=-+XZO&UKQ8*xc#|6zKBv*dRfz*CcMYY#q8j z4(~B|Ss6@s{?t&(D$5caqO7&UYY{imn###?AK?&@jod0VAu;nNLM>E(dXy}k!s)^1 zOtiL~CoTP6@|Nng8YpVXmHzf!;L-p1`U zy?A5$zz3h~9H=`R$(^}t;uz3%hU@bP1)i5#)$cKLgUQXe)vGQ*lmN*Pr5=Qi+n z+ZB`9-K8I^j3?yQ8RgkeVzgv0H3@MQ@U_I~r-$H+%XF>BM31qPi|PJ+LDC`F#QFEi zJx>dbs?~Eroq6}ht_YV^bJ>;fA`{~d6M=h*SImg$=kbi4AHDOF#Ajlc>^htu5+xlmY~S!9}4d=PveG-}6E}}dEH3aKd-!z~m3Lt)1bUwBI2&pN7(sP}CBH`< zjg@z&q<&=jh`SY+WsE3E8?R+rxjDO9Y`<{p+G|xi{ri~W9leI(hGO&n@kgl=N3~p{ z>V_P;lQF-3r>dU4>Wc=d6VygqUEVHLI#pdoWBD&m!zZ^EG*G(5oiP|ZtxA59L;{d0 zw0Wytse5yAt5EHAq(xtD+wm=WIy&G8Eq$HBa|f4UD9wHcrzb~J6ST|)mVa)f8kue2 z={8C23e#BaOJkbL15LT@{9s@GjBvJiq%oVR$@beE3u_~MyzoAA2vIBOBD^EUH? z24Y+NcaJWHUFuWkZznv!sGsy%!v=BDscZbp*Aw328rA;>6C@Yl)XT&!=qi{lPn&}DYHq9}MO|E7(fXIF(*c%1h{BUf{n0Pk=0 zpFf@{ULkHnIH(857?pY;!;JZ`-3`jIt!FiF0_3Fbw2W^=oD0VDI5!vnkZ8rxN`>PP z&J~cLG?rKrSJ3hK7P8X|WV=$zo2Q}_(*Cfx+wHI6=gjrlV$QesZczT~)EUXf(yh2; zV@69;-t-q9uk3sCNu*vBj_1gGDinE%U`@gT@+kif)pfidiQLbln6ctop9UgzjG;fS zhAbH70$1kcJ1vaNfX(*=nUbwUQ?dq5Mmq3N(X;%eNI?;!zdothlz4O0IJoPnSntz* z6_p;W)1MlrKO{ZfBdOO%*#nL8BG?aZd|n}2V^Ly!Qt5q+aHe_P^Sh2)13CPRC+>C+ zN{20q4KF>bslRKIv`EG`*5)F$&StG}Msd?<9lrX((Hn$)njbu^FmOmmu}_*uGV=MK zLt)oK$C~!mI#|NBNsYk- z%vhbk-O4_7zW1FAGOakSJ2M7__>VTjwpE{m`;1)N^ED0gJ*d`m6sLv-iD>?PGnb|U zzVZrS^#xvEAC;BlYmrezm*erq?Pd2!)n zl?SPuLzj)t50fIiq$``Yl7Ot;o5r_V*cPQx<0ROO-FRgx;Mf)Vij-ifdu1pT&k<46 zDSv5l>Q1``;>vSyh-)>|lJt;QaTiu;>e{VL7@N^7z10~Fdv>C(hM~WoOvCVkDQT5b zyR8!iV}wMcRHRY>wbX~}2iK87UFr%gkJ43bl_sN?c2y2M7rCThhCq}K|MKJR;^`$OJ5)#f@9#yt3)~q6=UTcgM zi>5`J!T@2ktJJkl-7vT7$kI$s!5m+Ma_C5_i+VQ!G3a+FbAH` zqdE?9D&0f3okD3rjulABdPE)L#KQv;roTs?HU1b?WU<$i>-Dn27hR{iZ;gyBCQhxN ziu%4TqNAh;^aS_H1YgS0Y8->`dSSVF-LwL^Vl|KP@H1&rNvQ*5Ui>~geKP%HOaw-T zezd)3TDL*I57WNTD=7yVhmvcL<}+XpIXJ`jxAv#!D{_`@zH~r`Ff5~Gwm@@wRekkdXb?ZOJ|K-^^ zC{9TI=e_zdlmX7Xfs~SzG0-8+;%gVa0hmaS5E|P)dzjA-{tlQ53EB&-e)qx|@U5X@ zUzYxg$&oYYQ(XrcJvte{B?SY1Gq;+bA5Z4 zgoGqSlpR9~O+B6XIk!4$YU(k&Ywge$@pm{z>l(Cdxc^lPIX`k_0Bm3l`ZA=M2=Xzo zR}uz#JBTMsYipB)T@G8>*dT5q?8+(HdV1afp!YyD4j_+G$iDXg>t1KubOnp|B`~eJ zbn&7l=3a9k2{@1Bcg)00MC|`TaC~rS>$59tr+|?0Qf{4gA;DNpT z7xxfs7H*K*i_haFoHqeF|N1-uT+h-H6Nf>$@a4-FBq9dEb^t=02e*}Be6i(S(D;I* z84`F5aQ#&{8DMG%^$-z)fwBMVjelS0fIw8sdFHMP7yUPo_>Fj$K~Eo42wH|d>tG^9 z3;z0GOkP;9h#1iWM*~EGh=U*}504(WL;`aa!RP;OwK^WZz~;bt15e>nZEIo^69wUp zBiUjg)_4u{2;S<+0MMs;fL;hdwy>@$NT{@g z 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 P>2?SAd%IU4Ph9>7>V|4C diff --git a/pr-assets/matplotlib-gallery-consolidation/horizontal-barchart-legend.png b/pr-assets/matplotlib-gallery-consolidation/horizontal-barchart-legend.png index 3cdb77255a08bab9dd688e33b43fb18847d30f7b..7dd31a001255d3ebd6660adb1a0144d292d00c02 100644 GIT binary patch literal 118266 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