1&&this.view0){let t=this._axisRange(e,this.view0),n=this._axisCoord(a,t[0]),r=this._axisCoord(a,t[1]),o=Math.abs(r-n);if([n,r].every(Number.isFinite)&&o>0&&Math.abs(u-l)>o){let e=o*Math.sign(u-l);return[this._axisValue(a,c-i*e),this._axisValue(a,c+(1-i)*e)]}}return[this._axisValue(a,l),this._axisValue(a,u)]},_zoomAt(e,t,n,r=!1,i=120,a={}){let o=this._viewAnim?this._viewAnim.target:this.view,s=Array.isArray(a.axes)?new Set(a.axes.filter(e=>this._zoomAxes().has(e))):this._zoomAxes(),c=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e,o)]])),l={};for(let r of s){let i=this._axisDim(r)===`x`?t:n,[a,o]=c[r],s=this._zoomAxisRange(r,a,o,e,i);s&&(c[r]=s),l[r]=i}return this._setView({ranges:c},{animate:r,duration:i,anchors:l,source:a.source||`wheel_zoom`,phase:a.phase||`update`,interactionId:a.interactionId})},_queueWheelZoom(e,t,n,r=null){if(!Number.isFinite(e)||e<=0)return;clearTimeout(this._wheelZoomEndTimer),this._wheelZoomEndTimer=null;let i=Array.isArray(r)?r.join(`,`):``;if(this._wheelGesture&&this._wheelGesture.scopeKey!==i){let e=this._wheelGesture;this._wheelGesture=null,e.axes.size&&this._emitViewChange(`wheel_zoom`,{axes:[...e.axes],phase:`end`,interactionId:e.interactionId})}this._wheelGesture||={interactionId:++this._interactionSeq,axes:new Set,scopeKey:i},this._pendingWheelZoom||={factor:1,fx:t,fy:n,interactionId:this._wheelGesture.interactionId,axes:[],axesScope:r},this._pendingWheelZoom.factor*=e,this._pendingWheelZoom.fx=t,this._pendingWheelZoom.fy=n,this._pendingWheelZoom.axesScope=r,!this._wheelZoomRaf&&(this._wheelZoomRaf=requestAnimationFrame(()=>{this._wheelZoomRaf=null;let e=this._pendingWheelZoom;if(this._pendingWheelZoom=null,!(!e||this._destroyed)){e.axes=this._zoomAt(e.factor,e.fx,e.fy,!1,120,{source:`wheel_zoom`,phase:`update`,interactionId:e.interactionId,axes:e.axesScope||void 0})||[];for(let t of e.axes)this._wheelGesture?.axes.add(t);clearTimeout(this._wheelZoomEndTimer),this._wheelZoomEndTimer=setTimeout(()=>{let e=this._wheelGesture;this._wheelGesture=null,!(this._destroyed||!e||!e.axes.size)&&this._emitViewChange(`wheel_zoom`,{axes:[...e.axes],phase:`end`,interactionId:e.interactionId})},90)}}))},_zoomToBox(e,t,n=!1,r={}){let i=this._zoomAxes(),a={};for(let n of[`x`,`y`]){let r=this._axis(n),[i,o]=this._axisRange(n),s=this._axisCoord(r,i),c=this._axisCoord(r,o),l=this._axisCoord(r,e[n===`x`?0:1]),u=this._axisCoord(r,t[n===`x`?0:1]);if(![s,c,l,u].every(Number.isFinite)||s===c)return[];a[n]=[(l-s)/(c-s),(u-s)/(c-s)]}let o=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]])),s={};for(let e of i){let t=this._axis(e),[n,r]=o[e],i=this._axisCoord(t,n),c=this._axisCoord(t,r),[l,u]=a[this._axisDim(e)],d=i+l*(c-i),f=i+u*(c-i),p=Math.max(Math.abs(d),Math.abs(f),1e-30)*1e-12;if(!Number.isFinite(d)||!Number.isFinite(f)||Math.abs(f-d)[e,[...this._axisRange(e)]]));for(let e of n||this._resetAxisPolicy())r[e]=[...this._axisRange(e,this.view0)];return this._setView({ranges:r},{animate:e,source:t,phase:`end`,interactionId:++this._interactionSeq})},_exportConfig(){let e=this.spec&&this.spec.export;return e&&typeof e==`object`?e:{}},_exportFilename(e){let t=this._exportConfig().filename;return typeof t==`string`&&t?`${t}.${e}`:`${String(this.spec.title||`xy-chart`).trim().toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)||`xy-chart`}.${e}`},_downloadExport(e,t){let n=URL.createObjectURL(e),r=document.createElement(`a`);r.href=n,r.download=t,r.style.display=`none`,document.body.appendChild(r),r.click(),r.remove(),setTimeout(()=>URL.revokeObjectURL(n),0)},_exportSvgMarkup(){this._drawNow?.(),this.gl?.finish?.();let e=this.size.w,t=this.size.h,n=this.root.cloneNode(!0);n.style.width=`${e}px`,n.style.height=`${t}px`,n.style.margin=`0`,n.setAttribute(`xmlns`,`http://www.w3.org/1999/xhtml`);let r=getComputedStyle(this.root),i=[`color`,`font-family`,`font-size`,`font-style`,`font-weight`,`letter-spacing`,`line-height`],a=[`--chart-bg`,`--chart-text`,`--chart-grid`,`--chart-axis`,`--chart-tooltip-bg`,`--chart-tooltip-text`,`--chart-legend-bg`,`--chart-badge-bg`,`--chart-badge-text`,`--chart-modebar-bg`,`--chart-modebar-active`,`--chart-selection`,`--chart-selection-fill`,`--chart-zoom-selection`,`--chart-zoom-selection-fill`,`--chart-crosshair`,`--chart-annotation-text`,`--chart-cursor`,`--chart-cursor-pan`];for(let e=0;ee.remove());let c=document.createElement(`style`);return c.textContent=w,n.prepend(c),``},_exportSvg(){let e=this._exportSvgMarkup();this._downloadExport(new Blob([e],{type:`image/svg+xml;charset=utf-8`}),this._exportFilename(`svg`))},_exportPng(){return this._exportRaster(`png`)},_exportRaster(e){let t=this._exportSvgMarkup(),n=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(t)}`,r=new Image,i=this._exportConfig(),a={png:`image/png`,jpeg:`image/jpeg`,webp:`image/webp`}[e];return a?new Promise((t,o)=>{r.onload=()=>{let n=Number.isFinite(i.scale)&&i.scale>0?i.scale:Math.max(1,window.devicePixelRatio||1),s=document.createElement(`canvas`);s.width=Math.round(this.size.w*n),s.height=Math.round(this.size.h*n);let c=s.getContext(`2d`),l=typeof i.background==`string`&&i.background!==`auto`?i.background:null,u=l===`transparent`||l===`none`;e===`jpeg`?(c.fillStyle=l&&!u?l:`#ffffff`,c.fillRect(0,0,s.width,s.height)):l&&!u&&(c.fillStyle=l,c.fillRect(0,0,s.width,s.height)),c.scale(n,n),c.drawImage(r,0,0,this.size.w,this.size.h);let d=Number.isFinite(i.quality)?Math.min(1,Math.max(.01,i.quality/100)):.9;s.toBlob(n=>{if(!n){o(Error(`${e.toUpperCase()} encoding returned no data`));return}let r=n.type===`image/jpeg`?`jpg`:n.type===`image/webp`?`webp`:`png`;this._downloadExport(n,this._exportFilename(r)),t()},a,e===`png`?void 0:d)},r.onerror=()=>{o(Error(`chart SVG could not be rasterized`))},r.src=n}):Promise.reject(Error(`unsupported raster export ${e}`))},_exportCsvText(){let e=[[`trace`,`name`,`kind`,`index`,`x`,`y`,`x0`,`x1`,`y0`,`y1`,`value`]],t=e=>Number.isFinite(e)?e:``;for(let n of this.gpuTraces||[]){let r=n.trace||{},i=[r.id??``,r.name??``,r.kind??``];if(n._cpuRect){let r=n._cpuRect,a=Math.min(r.x0.length,r.x1.length,r.y0.length,r.y1.length);for(let n=0;n{let t=String(e??``),n=t.split(`"`).join(`""`);return t.includes(`,`)||t.includes(`"`)||t.includes(`\r`)||t.includes(`
-`)?`"${n}"`:t};return e.map(e=>e.map(n).join(`,`)).join(`\r
-`)+`\r
-`},_exportCsv(){this._downloadExport(new Blob([this._exportCsvText()],{type:`text/csv;charset=utf-8`}),this._exportFilename(`csv`))},_icon(e){let t=e=>``;switch(e){case`zoomin`:return t(``);case`zoomout`:return t(``);case`pan`:return t(``);case`zoom`:return t(``);case`select`:return t(``);case`lasso`:return t(``);case`selectx`:return t(``);case`selecty`:return t(``);case`chevrondown`:return t(``);case`collapse`:return t(``);case`expand`:return t(``);case`png`:return t(``);case`jpeg`:return t(``);case`webp`:return t(``);case`svg`:return t(``);case`csv`:return t(``);case`reset`:return t(``);case`historyback`:return t(``);case`historyforward`:return t(``);case`drag`:return t(``);default:return t(``)}}});var gt=`
-const DATA = new Map();
-self.onmessage = (e) => {
- const m = e.data;
- if (m.type === "init") {
- DATA.set(m.trace, { x: new Float64Array(m.x), y: new Float64Array(m.y) });
- return;
- }
- const d = DATA.get(m.trace);
- if (!d) return;
- const w = m.w, h = m.h;
- const grid = new Float32Array(w * h);
- const sx = w / ((m.x1 - m.x0) || 1);
- const sy = h / ((m.y1 - m.y0) || 1);
- let max = 0;
- const X = d.x, Y = d.y, n = X.length;
- for (let i = 0; i < n; i++) {
- const cx = (X[i] - m.x0) * sx;
- const cy = (Y[i] - m.y0) * sy;
- if (cx < 0 || cy < 0 || cx >= w || cy >= h) continue;
- const v = ++grid[(cy | 0) * w + (cx | 0)];
- if (v > max) max = v;
- }
- self.postMessage(
- { type: "grid", seq: m.seq, trace: m.trace, w, h, max,
- x0: m.x0, x1: m.x1, y0: m.y0, y1: m.y1, grid: grid.buffer },
- [grid.buffer]
- );
-};
-`;function _t(){try{let e=URL.createObjectURL(new Blob([gt],{type:`application/javascript`})),t=new Worker(e);return t._fcUrl=e,t}catch{return null}}Object.assign(Q.prototype,{_scheduleViewRequest(e=this.view,t={}){if(this._destroyed||this._glLost)return;if(!this.comm){this._scheduleSampleRebin(e,t);return}let n=this.spec.traces.some(e=>e.tier===`decimated`),r=this.gpuTraces.some(e=>e.tier===`density`);if(!n&&!r)return;let i=t.seq??++this.seq,a=this._copyView(e),o=Math.round(this.plot.w),s=Math.round(this.plot.h);if(r){let e=this._now();for(let t of this.gpuTraces)t.tier===`density`&&(t._lodPendingView=a,t._lodPendingSeq=i,t._lodPendingAt=e)}let c=t.delay??120;if(t.maxWait!==void 0&&t.maxWait!==null){let e=this._now();(this._viewRequestBurstStart===void 0||this._viewRequestBurstStart===null)&&(this._viewRequestBurstStart=e);let n=t.maxWait-(e-this._viewRequestBurstStart);c=n<=0?0:Math.min(c,n)}else this._viewRequestBurstStart=null;clearTimeout(this._viewTimer);let l=()=>{if(!this._destroyed&&(this._viewRequestBurstStart=null,i===this.seq&&(n&&this.comm.send({type:`view`,seq:i,x0:Math.min(a.x0,a.x1),x1:Math.max(a.x0,a.x1),px:o}),r)))for(let e of this.gpuTraces){if(e.tier!==`density`)continue;let[t,n]=this._axisRange(e.xAxis,a),[r,c]=this._axisRange(e.yAxis,a);this.comm.send({type:`density_view`,seq:i,trace:e.trace.id,x0:Math.min(t,n),x1:Math.max(t,n),y0:Math.min(r,c),y1:Math.max(r,c),w:o,h:s})}};return c<=0?l():this._viewTimer=setTimeout(l,c),i},_scheduleSampleRebin(e=this.view,t={}){if(this._destroyed||this._glLost||this._sampleRebinDisabled)return;let n=(this.gpuTraces||[]).filter(e=>e.tier===`density`&&e.sampleOverlay&&e.sampleOverlay._cpu);if(!n.length)return;let r=t.seq??++this.seq,i=this._copyView(e);clearTimeout(this._rebinTimer),this._rebinTimer=setTimeout(()=>{if(!(this._destroyed||r!==this.seq))for(let e of n)this._requestSampleRebin(e,i,r)},t.delay??120)},_requestSampleRebin(e,t,n){e._homeDensity||=e.density;let[r,i]=this._axisRange(e.xAxis,t),[a,o]=this._axisRange(e.yAxis,t),[s,c]=this._axisRange(e.xAxis,this.view0),[l,u]=this._axisRange(e.yAxis,this.view0),d=Math.max(Math.abs(c-s),1e-300),f=Math.max(Math.abs(u-l),1e-300),p=Math.abs(i-r),m=Math.abs(o-a);if(p>=d*.999999&&m>=f*.999999){if(e.density!==e._homeDensity){let t=e._homeDensity;this._applySampleRebinGrid(e,{...t,tex:this._uploadGrid(t.grid,t.w,t.h,t.normMax||t.max||1)},!1)}return}if(!this._sampleRebinDisabled){if(!this._rebinWorker){if(this._rebinWorker=_t(),!this._rebinWorker){this._sampleRebinDisabled=!0;return}this._rebinWorker.onmessage=e=>this._onRebinResult(e.data),this._rebinInit=new Set}if(!this._rebinInit.has(e.trace.id)){let t=e.sampleOverlay._cpu,n=Math.min(t.x.length,t.y.length),r=new Float64Array(n),i=new Float64Array(n);for(let e=0;et.trace.id===e.trace&&t.tier===`density`);if(!t)return;let n=new Float32Array(e.grid);this._applySampleRebinGrid(t,{w:e.w,h:e.h,max:e.max,normMax:e.max,colormap:t.density.colormap,xRange:[e.x0,e.x1],yRange:[e.y0,e.y1],grid:n,tex:this._uploadGrid(n,e.w,e.h,e.max||1),lut:t.density.lut},!0)},_applySampleRebinGrid(e,t,n){e.prevDensity=e.density,e._densityFadeStart=this._now(),e.densityNormMax=t.normMax||t.max,e.density=t,e._sampleRebinned=!!n,V(this,e,e.density),this._refreshReductionBadges(),this.draw()},_applyAppend(e,t){let n=e.spec;if(!n||!n.traces)return;let r=n.buffer_layout===`split`?t:t&&t[0];if(r==null)return;let i=l(n,r),a=(e,t)=>Math.max(Math.abs(t-e),1e-300)*1e-9,o=a(this.view0.x0,this.view0.x1),s=a(this.view0.y0,this.view0.y1),c=Math.abs(this.view.x0-this.view0.x0)<=o&&Math.abs(this.view.x1-this.view0.x1)<=o&&Math.abs(this.view.y0-this.view0.y0)<=s&&Math.abs(this.view.y1-this.view0.y1)<=s,u=!c&&Math.abs(this.view.x1-this.view0.x1)<=o,d={x0:n.x_axis.range[0],x1:n.x_axis.range[1],y0:n.y_axis.range[0],y1:n.y_axis.range[1]},f={...this.view};if(c)f={...d};else if(u){let e=this.view.x1-this.view.x0;f={...this.view,x1:d.x1,x0:d.x1-e}}if((n.animation||n.traces.some(e=>!!e.animation))&&!this._glLost&&this.gl&&this.updatePayload(n,i)){this._transitionView?this._transitionView.to={...f}:this.view={...f},this._scheduleViewRequest(f,{delay:0});return}if(this.spec=n,this.axes=this._normalizeAxes(n),this._payload=i,this.view0=this._copyView({ranges:Object.fromEntries(Object.entries(this.axes).map(([e,t])=>[e,[...t.range]]))}),c)this.view=this._copyView(this.view0);else if(u){let e=this.view.x1-this.view.x0;this.view=this._viewFrom({x1:this.view0.x1,x0:this.view0.x1-e})}if(this._glLost||!this.gl)return;let p=new Set;for(let t of e.affected||[]){let e=this.gpuTraces.findIndex(e=>e.trace.id===t),r=n.traces.find(e=>e.id===t);e<0||!r||(this._destroyTraceResources(this.gpuTraces[e],p),this.gpuTraces[e]=this._buildTrace(i,r))}this._updatePickable(),this._scheduleViewRequest(this.view,{delay:0}),this.draw()},_onKernelMsg(e,t){if(!this._destroyed&&e&&!(this._glLost&&e.type!==`append`&&e.type!==`pick_result`))if(e.type===`tier_update`){if(e.seq!==this.seq)return;for(let n of e.traces){let e=this.gpuTraces.find(e=>e.trace.id===n.id);if(!e)continue;let r=this.gl,i=this._asF32(t[n.x.buf]),a=this._asF32(t[n.y.buf]),o=n.base&&e.baseBuf?this._asF32(t[n.base.buf]):null,s=Math.min(n.x.len,n.y.len);o&&(s=Math.min(s,n.base.len));let c=this._smoothArrays(e.trace,i,a,o,s),l=c||{x:i,y:a,n:s},u=this._stepArrays(e.trace,l.x,l.y,l.n);r.bindBuffer(r.ARRAY_BUFFER,e.xBuf),r.bufferData(r.ARRAY_BUFFER,u?u.x:l.x,r.STATIC_DRAW),r.bindBuffer(r.ARRAY_BUFFER,e.yBuf),r.bufferData(r.ARRAY_BUFFER,u?u.y:l.y,r.STATIC_DRAW),e.xMeta={...e.xMeta,offset:n.x.offset,scale:n.x.scale},e.yMeta={...e.yMeta,offset:n.y.offset,scale:n.y.scale},e._dashX=u?u.x:l.x,e._dashY=u?u.y:l.y,o&&(r.bindBuffer(r.ARRAY_BUFFER,e.baseBuf),r.bufferData(r.ARRAY_BUFFER,c?c.extra:o,r.STATIC_DRAW),e.baseMeta={...e.baseMeta,offset:n.base.offset,scale:n.base.scale}),e.n=u?u.n:l.n}this.draw()}else if(e.type===`density_update`){if(e.seq!==void 0&&e.seq!==this.seq)return;let n=e.traces||[],r=new Set(n.map(e=>Number(e.id)));r.size===0&&e.trace!==void 0&&r.add(Number(e.trace));let i=r.size===0&&e.stale,a=t=>{e.seq!==void 0&&t._lodPendingSeq!==e.seq||(t._lodPendingView=null,t._lodPendingSeq=null,t._lodPendingAt=null)};if(r.size||i)for(let e of this.gpuTraces)e.tier===`density`&&(!i&&!r.has(e.trace.id)||a(e));for(let e of n){let n=this.gpuTraces.find(t=>t.trace.id===e.id&&t.tier===`density`);if(n){if(a(n),e.mode===`points`){this._applyDrill(n,e,t);continue}$e(this,n,e,t)}}this._updatePickable(),this.draw()}else if(e.type===`append`)this._applyAppend(e,t);else if(e.type===`pick_result`){if(e.seq!==void 0&&e.seq!==this._pickSeq)return;if(!e.row){this._hideTooltip();return}let t=this._lastRow;if(t&&t.trace===e.row.trace&&t.index===e.row.index)for(let[n,r]of Object.entries(t))e.row[n]===void 0&&(e.row[n]=r);this._applySharedTooltipFields(e.row),this._lastRow=e.row,this._tooltipAnchor&&Number.isFinite(e.row.x)&&Number.isFinite(e.row.y)&&(this._tooltipAnchor.x=e.row.x,this._tooltipAnchor.y=e.row.y);let n=this._lastHoverXY;if(n&&this._renderTooltip(e.row,n.clientX,n.clientY,{announce:!this._a11yKeyboardReadout}),this._interactionFlag(`hover`)){let t={row:e.row,trace:e.row.trace,index:e.row.index,exact:!0,view:this._eventView(`hover`)};n&&Object.assign(t,this._hoverPayload(e.row,this._hoverTarget,n.clientX,n.clientY,!0)),this._dispatchChartEvent(`hover`,t)}}else e.type===`selection`?(e.bounds?this._lastBrush={mode:`box`,...e.bounds}:e.polygon&&(this._lastBrush={mode:`poly`,points:e.polygon}),(!e.traces||!e.traces.length)&&(this._lastBrush=null),this._applySelectionBuffers(e,t),this._selectionCount=e.total||0,this.draw(),this._interactionFlag(`select`,!0)&&this._dispatchChartEvent(`select`,{total:this._selectionCount,view:this._eventView(`select`)})):e.type===`state_patch`?this._applyStatePatch(e.state,{source:`api`,animate:e.animate===!0,history:e.history!==!1}):e.type===`view_nav`?e.op===`reset`&&this._navReset(e.axes):e.type===`selection_rows`&&this._applyRowsSelection(e,t)},_applySelectionBuffers(e,t){if(!e.traces||!e.traces.length){for(let e of this.gpuTraces)e.selActive=!1,e.drill&&(e.drill.selActive=!1);return}for(let n of e.traces){let e=this.gpuTraces.find(e=>e.trace.id===n.id);if(!e)continue;let r=e.tier===`density`?e.drill:e;if(!r||!r.n||e.tier===`density`&&n.drill_seq!==void 0&&r.seq!==void 0&&n.drill_seq!==r.seq)continue;let i=this._asU32(t[n.buf]),a=new Float32Array(r.n);for(let e=0;e=d-a&&c<=f+a&&l>=p-o&&u<=m+o},_viewOverlaps(e){if(!e)return!1;let{x0:t,x1:n,y0:r,y1:i}=this.view,a=Math.min(t,n),o=Math.max(t,n),s=Math.min(r,i),c=Math.max(r,i),l=Math.min(e.x0,e.x1),u=Math.max(e.x0,e.x1),d=Math.min(e.y0,e.y1),f=Math.max(e.y0,e.y1);return a<=u&&o>=l&&s<=f&&c>=d},_viewInsideRange(e,t){return!e||!t?!1:this._viewInside({x0:e[0],x1:e[1],y0:t[0],y1:t[1]})}});var vt={linear:[0,0,1,1],ease:[.25,.1,.25,1],"ease-in":[.42,0,1,1],"ease-out":[0,0,.58,1],"ease-in-out":[.42,0,.58,1]};function yt(e,t){let n=Number(t[0]),r=Number(t[1]),i=Number(t[2]),a=Number(t[3]),o=(e,t,n)=>{let r=1-e;return 3*r*r*e*t+3*r*e*e*n+e*e*e},s=(e,t,n)=>{let r=1-e;return 3*r*r*t+6*r*e*(n-t)+3*e*e*(1-n)},c=e;for(let t=0;t<5;t++){let t=s(c,n,i);if(Math.abs(t)<1e-6)break;c=Math.max(0,Math.min(1,c-(o(c,n,i)-e)/t))}let l=0,u=1;for(let t=0;t<8;t++)o(c,n,i){let t=e*6/a;if(o<1){let e=a*Math.sqrt(1-o*o);return 1-Math.exp(-o*a*t)*(Math.cos(e*t)+o*a/e*Math.sin(e*t))}return 1-Math.exp(-a*t)*(1+a*t)},c=s(1),l=Math.abs(c)>1e-9?s(e)/c:e;return Math.max(0,Math.min(1.15,l))}function $(e,t){return t&&typeof t==`object`&&!Array.isArray(t)&&t.type===`spring`?bt(e,t):yt(e,Array.isArray(t)?t:vt[t]||vt[`ease-out`])}Object.assign(Q.prototype,{_resolvedAnimation(e){return{...this.spec.animation||{},...e&&e.animation||{},_present:!!this.spec.animation||!!(e&&e.animation)}},_animationEnabled(e){return!e._present||e.enabled===!1?!1:e.enabled===!0||!this._prefersReducedMotion()},_defaultEntrance(e){return e===`line`||e===`area`||e===`error_band`?`reveal`:e===`bar`||e===`column`?`grow`:e===`scatter`||e===`errorbar`?`scale`:`none`},_setTransitionVisual(e,t,n,r){let i=Math.max(0,Math.min(1,n));if(e._transitionOpacity=1,e._transitionScale=1,e._transitionReveal=1,e._transitionGrow=1,t===`exit`){e._transitionOpacity=0;return}if(t===`update`){e._transitionPositionProgress=i;return}let a=r.enter||`auto`;a===`auto`&&(a=this._defaultEntrance(e.trace.kind)),a!==`none`&&(a===`scale`&&(e.trace.kind===`scatter`||e.trace.kind===`errorbar`?e._transitionScale=i:e.trace.kind===`bar`||e.trace.kind===`column`?e._transitionGrow=i:(e.trace.kind===`line`||e.trace.kind===`area`||e.trace.kind===`error_band`)&&(e._transitionReveal=i)),a===`reveal`&&(e._transitionReveal=i),a===`grow`&&(e._transitionGrow=i))},_clearTransitionVisual(e){delete e._transitionOpacity,delete e._transitionScale,delete e._transitionReveal,delete e._transitionGrow,delete e._transitionPositionProgress,delete e._transitionPhase,delete e._transitionPrevXValues,delete e._transitionPrevYValues,delete e._transitionPrevPosValues,delete e._transitionPrevValue1Values,delete e._transitionPrevValue0Values,delete e._transitionPrevWidth,delete e._transitionPositionInterpolated,this._deleteBuffers(e,[`_transitionPrevXBuf`,`_transitionPrevYBuf`,`_transitionPrevPosBuf`,`_transitionPrevValue1Buf`,`_transitionPrevValue0Buf`])},_emitAnimationLifecycle(e,t,n={}){let r={stage:e,phase:t,...n,view:this._eventView(`animation_${e}`)};this._dispatchChartEvent(`animation_${e}`,r),this.comm?.send?.({type:`animation_${e}`,phase:t,...n})},_runDataAnimation(e,t,n=[]){this._dataAnimRaf&&cancelAnimationFrame(this._dataAnimRaf);let r=(this._dataAnimEpoch||0)+1;this._dataAnimEpoch=r;let i=[];for(let n of t){let t=this._resolvedAnimation(n.trace),r=n._transitionPhase||e;if(!this._animationEnabled(t)||r===`enter`&&t.enter===`none`||r===`update`&&t.update===`none`){this._clearTransitionVisual(n);continue}i.push({g:n,config:t,phase:r,delay:Number(t.delay)||0,duration:Math.max(0,Number(t.duration)||0)})}for(let e of n)e._transitionOpacity=0;if(!i.length){for(let e of t)this._clearTransitionVisual(e);return this._transitionView&&=(this.view={...this._transitionView.to},null),this._destroyTransitionOldTraces(),this.draw(),!1}let a=this._now();this._dataAnim={epoch:r,phase:e,start:a},this._emitAnimationLifecycle(`start`,e);let o=()=>{if(this._destroyed||!this._dataAnim||this._dataAnim.epoch!==r)return;let t=this._now(),n=!1,s=0;for(let e of i){let r=e.duration<=0?+(t>=a+e.delay):Math.max(0,Math.min(1,(t-a-e.delay)/e.duration));this._transitionView&&(s=Math.max(s,r));let i=$(r,e.config.easing);this._setTransitionVisual(e.g,e.phase,i,e.config),r<1&&(n=!0)}if(this._transitionView){let e=$(s,(this.spec.animation||{}).easing),t=this._transitionView.from,n=this._transitionView.to;this.view={x0:t.x0+(n.x0-t.x0)*e,x1:t.x1+(n.x1-t.x1)*e,y0:t.y0+(n.y0-t.y0)*e,y1:t.y1+(n.y1-t.y1)*e}}if(this.draw(),n)this._dataAnimRaf=requestAnimationFrame(o);else{this._dataAnimRaf=null;for(let e of i)this._clearTransitionVisual(e.g);this._finishDataAnimation(e)}};return this._dataAnimRaf=requestAnimationFrame(o),!0},_finishDataAnimation(e){this._dataAnim=null,this._transitionView&&=(this.view={...this._transitionView.to},null),this._destroyTransitionOldTraces(),this._emitAnimationLifecycle(`end`,e)},_startEntranceAnimation(){let e=Number(this.spec.animation_capture_progress);if(Number.isFinite(e)&&e>=0&&e<=1){for(let t of this.gpuTraces||[]){let n=this._resolvedAnimation(t.trace);n._present&&n.enabled!==!1&&n.enter!==`none`?this._setTransitionVisual(t,`enter`,$(e,n.easing),n):this._clearTransitionVisual(t)}this.draw();return}this._runDataAnimation(`enter`,this.gpuTraces||[])},_destroyTransitionOldTraces(){if(!this._transitionOldTraces||!this.gl){this._transitionOldTraces=null;return}let e=new Set;for(let t of this._transitionOldTraces)this._destroyTraceResources(t,e);this._transitionOldTraces=null},_transitionMatches(e,t,n){let r=n.match||`index`,i=[],a=t.trace.animation_fallback||null;if((e.n||0)>2e5||(t.n||0)>2e5)return{strategy:`snap`,pairs:i,fallback:a||`snap:${r}-match-limit`};if(r===`key`)if(e._transitionKeyIndex&&t._transitionKeys)for(let n=0;n(e-(Number(t.offset)||0))*(Number(t.scale)||1),c=(t,n)=>{let r=e._cpu[t],i=e[t===`x`?`_transitionPrevXValues`:`_transitionPrevYValues`],a=e._transitionPositionProgress;if(!i||!Number.isFinite(a))return this._decodeValue(r,e[`${t}Meta`],n);let o=i[n]+(r[n]-i[n])*a,s=e[`${t}Meta`];return o/(s.scale||1)+s.offset};for(let[e,n]of r.pairs){let r=c(`x`,e),i=c(`y`,e);Number.isFinite(r)&&Number.isFinite(i)&&(a[n]=s(r,t.xMeta),o[n]=s(i,t.yMeta))}return t._transitionPrevXBuf=this._upload(a),t._transitionPrevYBuf=this._upload(o),t._transitionPrevXValues=a,t._transitionPrevYValues=o,t._transitionPositionProgress=0,t._transitionPositionInterpolated=!0,e._transitionSkipExit=!0,!0},_prepareBarPositionInterpolation(e,t,n){let r=e._cpuBar,i=t._cpuBar;if(!r||!i||e.orientation!==t.orientation||t.n!==i.pos.length||e.n!==r.pos.length)return n.fallback||=`snap:layout-mismatch`,!1;let a=new Float32Array(i.pos),o=new Float32Array(i.value1),s=new Float32Array(t.n),c=(e,t)=>(e-(Number(t.offset)||0))*(Number(t.scale)||1),l=(e,t)=>e/(Number(t.scale)||1)+(Number(t.offset)||0),u=(e,t)=>e.value0?l(e.value0[t],e.value0Meta):Number(e.value0Const)||0,d=(t,n,r,i)=>{let a=e._transitionPositionProgress;return l(!t||!Number.isFinite(a)?n[i]:t[i]+(n[i]-t[i])*a,r)},f=t=>{let n=e._transitionPrevValue0Values,i=e._transitionPositionProgress,a=u(r,t);if(!n||!Number.isFinite(i))return a;let o=l(n[t],r.value1Meta);return o+(a-o)*i};for(let e=0;e[e,[...t.range]]))});let i={...this.view0};if(this._glLost||!this.gl)return this.view={...i},!0;this.gpuTraces=e.traces.map(e=>this._buildTrace(t,e));for(let e of this.gpuTraces){let t=n.find(t=>t.trace.id===e.trace.id&&t.trace.kind===e.trace.kind);if(t){let n=this._resolvedAnimation(e.trace);t._transitionExitTrace=e.trace,this._animationEnabled(n)&&n.update!==`none`&&(e._transitionMatch=this._transitionMatches(t,e,n),this._preparePositionInterpolation(t,e,n),t._transitionSkipExit=!0,this._recordAnimationFallback(e.trace,e._transitionMatch.fallback))}else e._transitionPhase=`enter`}this._transitionOldTraces=n;let a=this.gpuTraces.some(e=>{let t=this._resolvedAnimation(e.trace);return this._animationEnabled(t)&&t.update===`interpolate`&&(t.interpolate||[]).includes(`domain`)});return this._transitionView=a?{from:r,to:i}:null,a||(this.view={...i}),this._updatePickable(),this._runDataAnimation(`update`,this.gpuTraces,n)||(this.view={...i},this._transitionView=null),!0}});var xt=64;Object.assign(Q.prototype,{_initViewState(){this._historyPast=[],this._historyFuture=[],this._historyLastInteractionId=null,this._stateSelection=null,this._customTooltip=null,this.root.xy={applyState:(e,t={})=>this._applyStatePatch(e,{source:`api`,animate:t.animate===!0,history:t.history!==!1}),state:()=>this._durableState(),back:()=>this._historyBack(),forward:()=>this._historyForward()}},_durableState(){let e=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]])),t=this._stateSelection;return{v:1,ranges:e,selection:t==null?null:t.rows?{rows:!0}:t.range?{range:{...t.range}}:{polygon:t.polygon.map(e=>[...e])}}},_validateStatePatch(e){if(!e||typeof e!=`object`||Array.isArray(e))return`state patch must be an object`;if(e.v!==void 0&&e.v!==1)return`unsupported state version ${e.v}`;for(let t of Object.keys(e))if(![`v`,`ranges`,`selection`].includes(t))return`unknown key ${t}`;if(e.ranges!==void 0){if(!e.ranges||typeof e.ranges!=`object`||Array.isArray(e.ranges))return`ranges must be an object`;let t=new Set(this._axisIds());for(let[n,r]of Object.entries(e.ranges)){if(!t.has(n))return`unknown axis ${n}`;if(!Array.isArray(r)||r.length!==2||!r.every(e=>Number.isFinite(e))||r[0]===r[1])return`invalid range for axis ${n}`}}if(e.selection!==void 0&&e.selection!==null){let t=e.selection;if(typeof t!=`object`||Array.isArray(t))return`invalid selection`;let n=Object.keys(t);if(n.length!==1)return`invalid selection`;if(n[0]===`range`){let e=t.range;if(!e||typeof e!=`object`||![`x0`,`x1`,`y0`,`y1`].every(t=>Number.isFinite(e[t])))return`invalid selection range`}else if(n[0]===`polygon`){let e=t.polygon;if(!Array.isArray(e)||e.length<3||!e.every(e=>Array.isArray(e)&&e.length===2&&e.every(Number.isFinite)))return`invalid selection polygon`}else if(n[0]===`rows`)return`rows selections are not applicable state`;else return`invalid selection`}return null},_applyStatePatch(e,t={}){if(this._destroyed)return!1;let n=this._validateStatePatch(e);if(n)return typeof console<`u`&&console.warn&&console.warn(`xy: state patch rejected: ${n}`),!1;let r=t.source||`api`,i=++this._interactionSeq;if(e.ranges!==void 0){let n=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e)]]));for(let[t,r]of Object.entries(e.ranges))n[t]=[Number(r[0]),Number(r[1])];this._setView({ranges:n},{animate:t.animate===!0,source:r,phase:`end`,interactionId:i,history:t.history})}if(e.selection!==void 0){let n=e.selection,a={history:t.history,interactionId:i,source:r};if(n===null)this._clearSelection(a);else if(n.range){let{x0:e,x1:t,y0:r,y1:i}=n.range;this._sendSelect([e,r],[t,i],a)}else n.polygon&&this._sendSelectPolygon(n.polygon.map(e=>[...e]),a)}return!0},_historyEnabled(){return this._interactionFlag(`history`,!0)},_historyRecord(e={}){if(!this._historyPast||!this._historyEnabled()||this._destroyed||e.history===!1||e.source===`linked`||e.source===`history`)return;let t=e.interactionId;t!=null&&t===this._historyLastInteractionId||(this._historyLastInteractionId=t===void 0?null:t,this._historyPast.push(this._durableState()),this._historyPast.length>xt&&this._historyPast.shift(),this._historyFuture.length=0,this._updateHistoryButtons())},_historyBack(){if(!this._historyEnabled()||!this._historyPast.length)return!1;let e=this._historyPast.pop();return this._historyFuture.push(this._durableState()),this._historyApply(e),!0},_historyForward(){if(!this._historyEnabled()||!this._historyFuture.length)return!1;let e=this._historyFuture.pop();return this._historyPast.push(this._durableState()),this._historyApply(e),!0},_historyApply(e){let t={v:1,ranges:e.ranges};(!e.selection||!e.selection.rows)&&(t.selection=e.selection??null),this._applyStatePatch(t,{source:`history`,animate:!0,history:!1}),this._historyLastInteractionId=null,this._updateHistoryButtons()},_updateHistoryButtons(){let e=(e,t)=>{e&&(e.disabled=!t,e.setAttribute(`aria-disabled`,String(!t)),e.style.opacity=t?``:`0.4`)};e(this._historyBackBtn,this._historyPast.length>0),e(this._historyForwardBtn,this._historyFuture.length>0)},_navReset(e){let t=Array.isArray(e)?e.filter(e=>this._axisIds().includes(e)):null;this._resetView(!0,`reset`,t)},_applyRowsSelection(e,t){this._clearLassoOverlay();for(let e of this.gpuTraces)e.selActive=!1,e.drill&&(e.drill.selActive=!1);this._lastBrush=null,this._applySelectionBuffers(e,t),this._stateSelection={rows:!0},this._selectionCount=e.total||0,this.draw(),this._interactionFlag(`select`,!0)&&this._dispatchChartEvent(`select`,{total:this._selectionCount,view:this._eventView(`select`)})},_axisBandNavigable(e){if(!this._interactionFlag(`navigation`,!0))return!1;let t=this._interactionFlag(`pan`,!0)&&this._axisPolicy(`pan_axes`).includes(e),n=this._interactionFlag(`zoom`,!0)&&this._axisPolicy(`zoom_axes`).includes(e);return t||n},_axisBandCursor(e,t){return this._interactionFlag(`zoom`,!0)&&this._axisPolicy(`zoom_axes`).includes(e)?t===`x`?`ew-resize`:`ns-resize`:`grab`},_initAxisBands(){if(this.root){this._axisBands={};for(let e of this._axisIds()){if(!this._axisBandNavigable(e))continue;let t=this._axisDim(e),n=document.createElement(`div`);n.dataset.xyAxisBand=e,n.style.cssText=`position:absolute;z-index:2;touch-action:none;cursor:${this._axisBandCursor(e,t)};`,this.root.appendChild(n),this._axisBands[e]=n,this._bindAxisBand(n,e,t)}this._layoutAxisBands()}},_layoutAxisBands(){if(this._axisBands)for(let[e,t]of Object.entries(this._axisBands)){let n=this._axisDim(e),r=this._axis(e).side;n===`x`?(t.style.left=`${this.plot.x}px`,t.style.width=`${this.plot.w}px`,r===`top`?(t.style.top=`${Math.max(0,this.plot.y-24)}px`,t.style.height=`30px`):(t.style.top=`${this.plot.y+this.plot.h-6}px`,t.style.height=`30px`)):(t.style.top=`${this.plot.y}px`,t.style.height=`${this.plot.h}px`,r===`right`?(t.style.left=`${this.plot.x+this.plot.w-6}px`,t.style.width=`30px`):(t.style.left=`${Math.max(0,this.plot.x-24)}px`,t.style.width=`30px`))}},_axisBandValue(e,t,n){let r=this.canvas.getBoundingClientRect();if(this._axisDim(e)===`x`){let n=Math.max(0,Math.min(r.width,t-r.left));return this._dataFromCanvas(n,0,e,`y`)[0]}let i=Math.max(0,Math.min(r.height,n-r.top));return this._dataFromCanvas(0,i,`x`,e)[1]},_bindAxisBand(e,t,n){let r=null;this._listen(e,`wheel`,e=>{if(!this._interactionFlag(`navigation`,!0)||!this._interactionFlag(`zoom`,!0)||!this._interactionFlag(`wheel_zoom`,!0)||!this._axisPolicy(`zoom_axes`).includes(t))return;e.preventDefault();let n=1.0015**e.deltaY,r=this.canvas.getBoundingClientRect(),i=(e.clientX-r.left)/r.width,a=1-(e.clientY-r.top)/r.height;this._queueWheelZoom(n,i,a,[t])},{passive:!1}),this._listen(e,`pointerdown`,n=>{if(!(n.pointerType===`mouse`&&n.button!==0)&&this._interactionFlag(`navigation`,!0)){this._cancelViewAnimation(),r={pointerId:n.pointerId,sx:n.clientX,sy:n.clientY,view:this._copyView(this.view),d0:this._axisBandValue(t,n.clientX,n.clientY),mode:null,interactionId:++this._interactionSeq,changedAxes:[]};try{e.setPointerCapture(n.pointerId)}catch{}this.tooltip.style.display=`none`,n.preventDefault()}});let i=()=>this._interactionFlag(`pan`,!0)&&this._axisPolicy(`pan_axes`).includes(t)?!0:this._axisContained(t),a=()=>this._interactionFlag(`zoom`,!0)&&this._interactionFlag(`box_zoom`,!0)&&this._axisPolicy(`zoom_axes`).includes(t);this._listen(e,`pointermove`,o=>{if(!r||o.pointerId!==r.pointerId)return;let s=o.clientX-r.sx,c=o.clientY-r.sy;if(!r.mode){if(Math.hypot(s,c)<=3)return;r.mode=Math.abs(n===`x`?s:c)>=Math.abs(n===`x`?c:s)?i()?`pan`:a()?`span`:`none`:a()?`span`:i()?`pan`:`none`,r.mode===`pan`&&(e.style.cursor=`grabbing`)}if(r.mode===`pan`){let e=Object.fromEntries(this._axisIds().map(e=>[e,[...this._axisRange(e,r.view)]])),i=this._axis(t),[a,o]=this._axisRange(t,r.view),l=this._axisCoord(i,a),u=this._axisCoord(i,o);if(![l,u].every(Number.isFinite)||l===u)return;let d=n===`x`?this.plot.w:this.plot.h,f=(n===`x`?s:c)/d*(u-l),p=n===`x`?-f:f;e[t]=[this._axisValue(i,l+p),this._axisValue(i,u+p)];let m=this._setView({ranges:e},{source:`pan_drag`,phase:`update`,interactionId:r.interactionId});r.changedAxes=[...new Set([...r.changedAxes,...m])]}else if(r.mode===`span`){let e=this.root.getBoundingClientRect();if(this.selRect.dataset.xyBand=`zoom`,this.selRect.style.display=`block`,n===`x`){let t=Math.max(this.plot.x,Math.min(this.plot.x+this.plot.w,Math.min(r.sx,o.clientX)-e.left)),n=Math.max(this.plot.x,Math.min(this.plot.x+this.plot.w,Math.max(r.sx,o.clientX)-e.left));this.selRect.style.left=`${t}px`,this.selRect.style.width=`${Math.max(0,n-t)}px`,this.selRect.style.top=`${this.plot.y}px`,this.selRect.style.height=`${this.plot.h}px`}else{let t=Math.max(this.plot.y,Math.min(this.plot.y+this.plot.h,Math.min(r.sy,o.clientY)-e.top)),n=Math.max(this.plot.y,Math.min(this.plot.y+this.plot.h,Math.max(r.sy,o.clientY)-e.top));this.selRect.style.top=`${t}px`,this.selRect.style.height=`${Math.max(0,n-t)}px`,this.selRect.style.left=`${this.plot.x}px`,this.selRect.style.width=`${this.plot.w}px`}}o.preventDefault()});let o=i=>{if(!r||i.pointerId!==r.pointerId)return;let a=r;if(r=null,e.style.cursor=this._axisBandCursor(t,n),a.mode===`span`&&(this.selRect.style.display=`none`),i.type!==`pointercancel`){if(a.mode===`pan`&&a.changedAxes.length)this._emitViewChange(`pan_drag`,{axes:a.changedAxes,phase:`end`,interactionId:a.interactionId});else if(a.mode===`span`){let e=this._axisBandValue(t,i.clientX,i.clientY),n=this._axis(t),r=this._axisCoord(n,a.d0),o=this._axisCoord(n,e),s=Math.max(Math.abs(r),Math.abs(o),1e-30)*1e-12;if(![r,o].every(Number.isFinite)||Math.abs(o-r)[e,[...this._axisRange(e)]]));p[t]=[this._axisValue(n,u?f:d),this._axisValue(n,u?d:f)],this._setView({ranges:p},{animate:!0,anchors:{[t]:.5},source:`box_zoom`,phase:`end`,interactionId:a.interactionId})}}};this._listen(e,`pointerup`,o),this._listen(e,`pointercancel`,o)},_seriesColorCss(e){let t=e&&e.color;if(!Array.isArray(t)||t.length<3)return null;let n=e=>Math.max(0,Math.min(255,Math.round(Number(e)*255)));return`rgb(${n(t[0])}, ${n(t[1])}, ${n(t[2])})`},_hoverPayload(e,t,n,r,i=!1){let a=this.root.getBoundingClientRect(),o=this.canvas.getBoundingClientRect(),s=Math.max(0,Math.min(o.width,n-o.left)),c=Math.max(0,Math.min(o.height,r-o.top)),l={};for(let e of this._axisIds()){let t=this._axisDim(e),[n,r]=this._dataFromCanvas(s,c,t===`x`?e:`x`,t===`y`?e:`y`);l[e]=t===`x`?n:r}let u=t&&t.g,d=e?[{trace:u&&u.trace&&u.trace.name||e.trace,index:e.index,row:e,x_axis:u&&u.xAxis||`x`,y_axis:u&&u.yAxis||`y`,color:this._seriesColorCss(u)}]:[],f={active:!0,cursor:{px:[n-a.left,r-a.top],data:l},points:d};return i&&(f.exact=!0),f},setCustomTooltip(e){if(this.tooltip){if(!e){this._customTooltip=null,delete this.tooltip.dataset.xyCustomTooltip,this.tooltip.style.background=``,this.tooltip.style.border=``,this.tooltip.style.padding=``,this.tooltip.replaceChildren(),this.tooltip.style.display=`none`;return}this._customTooltip=e,this.tooltip.dataset.xyCustomTooltip=``,this.tooltip.style.background=`transparent`,this.tooltip.style.border=`none`,this.tooltip.style.padding=`0`,e.style.display=``,this.tooltip.replaceChildren(e)}}});function St({model:e,el:t}){let n=e.get(`spec`),r=new Q(t,n,l(n,e.get(`buffers`)),{send:t=>e.send(t),wantsViewChange:()=>e.get(`spec`)?.interaction?._transport_view_change===!0,onMessage:t=>{let n=(e,n)=>t(e,n);return e.on(`msg:custom`,n),()=>e.off?.(`msg:custom`,n)}}),i={seq:n.append?.seq??null,buffers:e.get(`buffers`)},a=()=>{let t=e.get(`spec`),n=t?.append;if(!n)return;let a=e.get(`buffers`);n.seq===i.seq&&a===i.buffers||c(t,a)&&(i.seq=n.seq,i.buffers=a,r._applyAppend({type:`append`,affected:n.affected,spec:t},a))};return e.on(`change:spec`,a),e.on(`change:buffers`,a),()=>{e.off?.(`change:spec`,a),e.off?.(`change:buffers`,a),r.destroy()}}function Ct(e,t,n){let r=s(n),i=new Q(e,t,r,null),a=e=>i._columnView(r,t.columns[e]);for(let e of i.gpuTraces)J(e.trace.kind).retainCpu&&e.tier!==`density`&&(e._cpu={x:a(e.trace.x),y:a(e.trace.y),xMeta:e.xMeta,yMeta:e.yMeta},e.trace.color&&Number.isInteger(e.trace.color.buf)&&(e._cpu.color=a(e.trace.color.buf)),e.trace.size&&Number.isInteger(e.trace.size.buf)&&(e._cpu.size=a(e.trace.size.buf)));return i}var wt={render:St,decodeFrame:m};return e.ChartView=Q,e.MARK_KINDS=q,e.decodeFrame=m,e.default=wt,e.markOf=J,e.render=St,e.renderStandalone=Ct,e})({});
\ No newline at end of file
diff --git a/tests/pyplot/test_matplotlib_mismatch_regressions.py b/tests/pyplot/test_matplotlib_mismatch_regressions.py
new file mode 100644
index 00000000..3dde0532
--- /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.0, 4.0, -2.0, 5.0))
+
+
+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_p3_option_contracts.py b/tests/pyplot/test_p3_option_contracts.py
index 3b78f346..1eee66e4 100644
--- a/tests/pyplot/test_p3_option_contracts.py
+++ b/tests/pyplot/test_p3_option_contracts.py
@@ -36,7 +36,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"),
],
)