Skip to content

Commit ef5efe8

Browse files
committed
docs(normalization): fix LogNorm image attribution, real datashader-percentile demo, RGB composite note
1 parent 6390d17 commit ef5efe8

1 file changed

Lines changed: 104 additions & 96 deletions

File tree

tutorials/normalization_and_contrast.ipynb

Lines changed: 104 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@
7171
"id": "72eea5119410473aa328ad9291626812",
7272
"metadata": {
7373
"execution": {
74-
"iopub.execute_input": "2026-08-18T20:28:37.420687Z",
75-
"iopub.status.busy": "2026-08-18T20:28:37.420548Z",
76-
"iopub.status.idle": "2026-08-18T20:28:48.574330Z",
77-
"shell.execute_reply": "2026-08-18T20:28:48.573679Z"
74+
"iopub.execute_input": "2026-08-19T03:27:06.525812Z",
75+
"iopub.status.busy": "2026-08-19T03:27:06.525675Z",
76+
"iopub.status.idle": "2026-08-19T03:27:17.136245Z",
77+
"shell.execute_reply": "2026-08-19T03:27:17.135628Z"
7878
}
7979
},
8080
"outputs": [
@@ -125,7 +125,10 @@
125125
"source": [
126126
"## 1. The default — per-channel min/max\n",
127127
"\n",
128-
"With no `norm`, every channel is scaled independently to its own min and max. This is the historical default."
128+
"With no `norm`, every channel is scaled independently to its own min and max. This is the historical default.\n",
129+
"\n",
130+
"`blobs_image` has three channels, so with the default colormap they are composited into a single\n",
131+
"RGB image — channel 0 → red, 1 → green, 2 → blue."
129132
]
130133
},
131134
{
@@ -134,10 +137,10 @@
134137
"id": "10185d26023b46108eb7d9f57d49d2b3",
135138
"metadata": {
136139
"execution": {
137-
"iopub.execute_input": "2026-08-18T20:28:48.576243Z",
138-
"iopub.status.busy": "2026-08-18T20:28:48.575796Z",
139-
"iopub.status.idle": "2026-08-18T20:28:49.449727Z",
140-
"shell.execute_reply": "2026-08-18T20:28:49.449061Z"
140+
"iopub.execute_input": "2026-08-19T03:27:17.138118Z",
141+
"iopub.status.busy": "2026-08-19T03:27:17.137720Z",
142+
"iopub.status.idle": "2026-08-19T03:27:17.636015Z",
143+
"shell.execute_reply": "2026-08-19T03:27:17.635446Z"
141144
}
142145
},
143146
"outputs": [
@@ -173,10 +176,10 @@
173176
"id": "7623eae2785240b9bd12b16a66d81610",
174177
"metadata": {
175178
"execution": {
176-
"iopub.execute_input": "2026-08-18T20:28:49.451178Z",
177-
"iopub.status.busy": "2026-08-18T20:28:49.451051Z",
178-
"iopub.status.idle": "2026-08-18T20:28:49.749636Z",
179-
"shell.execute_reply": "2026-08-18T20:28:49.749171Z"
179+
"iopub.execute_input": "2026-08-19T03:27:17.637827Z",
180+
"iopub.status.busy": "2026-08-19T03:27:17.637698Z",
181+
"iopub.status.idle": "2026-08-19T03:27:17.941547Z",
182+
"shell.execute_reply": "2026-08-19T03:27:17.940795Z"
180183
}
181184
},
182185
"outputs": [
@@ -203,7 +206,7 @@
203206
"## 3. Clipping — what happens outside `[vmin, vmax]`\n",
204207
"\n",
205208
"With `clip=False` (the default), values below `vmin` or above `vmax` are drawn in the colormap's **under/over**\n",
206-
"colors. With `clip=True`, they are clamped to the ends instead. We use a cmap with distinct under/over colors\n",
209+
"colors (the special colors a colormap shows for values past each end, set via `set_under` / `set_over`). With `clip=True`, they are clamped to the ends instead. We use a cmap with distinct under/over colors\n",
207210
"to make the difference obvious.\n",
208211
"\n",
209212
"First, `clip=False` — out-of-range pixels show magenta (under) and red (over):"
@@ -215,10 +218,10 @@
215218
"id": "b118ea5561624da68c537baed56e602f",
216219
"metadata": {
217220
"execution": {
218-
"iopub.execute_input": "2026-08-18T20:28:49.751429Z",
219-
"iopub.status.busy": "2026-08-18T20:28:49.751310Z",
220-
"iopub.status.idle": "2026-08-18T20:28:50.044237Z",
221-
"shell.execute_reply": "2026-08-18T20:28:50.043729Z"
221+
"iopub.execute_input": "2026-08-19T03:27:17.943396Z",
222+
"iopub.status.busy": "2026-08-19T03:27:17.943254Z",
223+
"iopub.status.idle": "2026-08-19T03:27:18.251735Z",
224+
"shell.execute_reply": "2026-08-19T03:27:18.251205Z"
222225
}
223226
},
224227
"outputs": [
@@ -255,10 +258,10 @@
255258
"id": "504fb2a444614c0babb325280ed9130a",
256259
"metadata": {
257260
"execution": {
258-
"iopub.execute_input": "2026-08-18T20:28:50.045966Z",
259-
"iopub.status.busy": "2026-08-18T20:28:50.045841Z",
260-
"iopub.status.idle": "2026-08-18T20:28:50.337591Z",
261-
"shell.execute_reply": "2026-08-18T20:28:50.337086Z"
261+
"iopub.execute_input": "2026-08-19T03:27:18.253470Z",
262+
"iopub.status.busy": "2026-08-19T03:27:18.253361Z",
263+
"iopub.status.idle": "2026-08-19T03:27:18.554196Z",
264+
"shell.execute_reply": "2026-08-19T03:27:18.553558Z"
262265
}
263266
},
264267
"outputs": [
@@ -284,8 +287,10 @@
284287
"source": [
285288
"## 4. Logarithmic scaling — `LogNorm`\n",
286289
"\n",
287-
"For data spanning orders of magnitude. `spatialdata-plot` guards the log domain: limits autoscale from the\n",
288-
"**strictly-positive** values only, so a non-positive `vmin` never raises a late \"Invalid vmin or vmax\"."
290+
"For data spanning orders of magnitude. On the non-image renderers (shapes, points, labels),\n",
291+
"`spatialdata-plot` resolves `LogNorm` limits from the **strictly-positive** data and falls back to a valid\n",
292+
"domain when none exist, so a non-positive `vmin` never raises a late \"Invalid vmin or vmax\". On images,\n",
293+
"as below, `LogNorm` is applied directly by matplotlib."
289294
]
290295
},
291296
{
@@ -294,10 +299,10 @@
294299
"id": "b43b363d81ae4b689946ece5c682cd59",
295300
"metadata": {
296301
"execution": {
297-
"iopub.execute_input": "2026-08-18T20:28:50.339208Z",
298-
"iopub.status.busy": "2026-08-18T20:28:50.339081Z",
299-
"iopub.status.idle": "2026-08-18T20:28:50.890720Z",
300-
"shell.execute_reply": "2026-08-18T20:28:50.890160Z"
302+
"iopub.execute_input": "2026-08-19T03:27:18.555637Z",
303+
"iopub.status.busy": "2026-08-19T03:27:18.555530Z",
304+
"iopub.status.idle": "2026-08-19T03:27:19.131506Z",
305+
"shell.execute_reply": "2026-08-19T03:27:19.130942Z"
301306
}
302307
},
303308
"outputs": [
@@ -333,10 +338,10 @@
333338
"id": "c3933fab20d04ec698c2621248eb3be0",
334339
"metadata": {
335340
"execution": {
336-
"iopub.execute_input": "2026-08-18T20:28:50.892412Z",
337-
"iopub.status.busy": "2026-08-18T20:28:50.892286Z",
338-
"iopub.status.idle": "2026-08-18T20:28:51.205309Z",
339-
"shell.execute_reply": "2026-08-18T20:28:51.204851Z"
341+
"iopub.execute_input": "2026-08-19T03:27:19.133164Z",
342+
"iopub.status.busy": "2026-08-19T03:27:19.133053Z",
343+
"iopub.status.idle": "2026-08-19T03:27:19.454771Z",
344+
"shell.execute_reply": "2026-08-19T03:27:19.454261Z"
340345
}
341346
},
342347
"outputs": [
@@ -361,10 +366,10 @@
361366
"id": "4dd4641cc4064e0191573fe9c69df29b",
362367
"metadata": {
363368
"execution": {
364-
"iopub.execute_input": "2026-08-18T20:28:51.207123Z",
365-
"iopub.status.busy": "2026-08-18T20:28:51.206996Z",
366-
"iopub.status.idle": "2026-08-18T20:28:51.584866Z",
367-
"shell.execute_reply": "2026-08-18T20:28:51.584316Z"
369+
"iopub.execute_input": "2026-08-19T03:27:19.456458Z",
370+
"iopub.status.busy": "2026-08-19T03:27:19.456338Z",
371+
"iopub.status.idle": "2026-08-19T03:27:19.842885Z",
372+
"shell.execute_reply": "2026-08-19T03:27:19.842303Z"
368373
}
369374
},
370375
"outputs": [
@@ -407,10 +412,10 @@
407412
"id": "3ed186c9a28b402fb0bc4494df01f08d",
408413
"metadata": {
409414
"execution": {
410-
"iopub.execute_input": "2026-08-18T20:28:51.586724Z",
411-
"iopub.status.busy": "2026-08-18T20:28:51.586602Z",
412-
"iopub.status.idle": "2026-08-18T20:28:51.879653Z",
413-
"shell.execute_reply": "2026-08-18T20:28:51.879176Z"
415+
"iopub.execute_input": "2026-08-19T03:27:19.844726Z",
416+
"iopub.status.busy": "2026-08-19T03:27:19.844610Z",
417+
"iopub.status.idle": "2026-08-19T03:27:20.144334Z",
418+
"shell.execute_reply": "2026-08-19T03:27:20.143732Z"
414419
}
415420
},
416421
"outputs": [
@@ -443,10 +448,10 @@
443448
"id": "379cbbc1e968416e875cc15c1202d7eb",
444449
"metadata": {
445450
"execution": {
446-
"iopub.execute_input": "2026-08-18T20:28:51.881382Z",
447-
"iopub.status.busy": "2026-08-18T20:28:51.881261Z",
448-
"iopub.status.idle": "2026-08-18T20:28:52.200023Z",
449-
"shell.execute_reply": "2026-08-18T20:28:52.199442Z"
451+
"iopub.execute_input": "2026-08-19T03:27:20.145835Z",
452+
"iopub.status.busy": "2026-08-19T03:27:20.145705Z",
453+
"iopub.status.idle": "2026-08-19T03:27:20.468944Z",
454+
"shell.execute_reply": "2026-08-19T03:27:20.468316Z"
450455
}
451456
},
452457
"outputs": [
@@ -482,10 +487,10 @@
482487
"id": "db7b79bc585a40fcaf58bf750017e135",
483488
"metadata": {
484489
"execution": {
485-
"iopub.execute_input": "2026-08-18T20:28:52.201748Z",
486-
"iopub.status.busy": "2026-08-18T20:28:52.201630Z",
487-
"iopub.status.idle": "2026-08-18T20:28:52.458391Z",
488-
"shell.execute_reply": "2026-08-18T20:28:52.457659Z"
490+
"iopub.execute_input": "2026-08-19T03:27:20.470504Z",
491+
"iopub.status.busy": "2026-08-19T03:27:20.470385Z",
492+
"iopub.status.idle": "2026-08-19T03:27:20.735216Z",
493+
"shell.execute_reply": "2026-08-19T03:27:20.734664Z"
489494
}
490495
},
491496
"outputs": [
@@ -511,10 +516,10 @@
511516
"id": "916684f9a58a4a2aa5f864670399430d",
512517
"metadata": {
513518
"execution": {
514-
"iopub.execute_input": "2026-08-18T20:28:52.460096Z",
515-
"iopub.status.busy": "2026-08-18T20:28:52.459987Z",
516-
"iopub.status.idle": "2026-08-18T20:28:52.770054Z",
517-
"shell.execute_reply": "2026-08-18T20:28:52.769391Z"
519+
"iopub.execute_input": "2026-08-19T03:27:20.736812Z",
520+
"iopub.status.busy": "2026-08-19T03:27:20.736710Z",
521+
"iopub.status.idle": "2026-08-19T03:27:21.031545Z",
522+
"shell.execute_reply": "2026-08-19T03:27:21.030731Z"
518523
}
519524
},
520525
"outputs": [
@@ -560,10 +565,10 @@
560565
"id": "33b0902fd34d4ace834912fa1002cf8e",
561566
"metadata": {
562567
"execution": {
563-
"iopub.execute_input": "2026-08-18T20:28:52.771939Z",
564-
"iopub.status.busy": "2026-08-18T20:28:52.771811Z",
565-
"iopub.status.idle": "2026-08-18T20:28:53.078033Z",
566-
"shell.execute_reply": "2026-08-18T20:28:53.077502Z"
568+
"iopub.execute_input": "2026-08-19T03:27:21.034004Z",
569+
"iopub.status.busy": "2026-08-19T03:27:21.033866Z",
570+
"iopub.status.idle": "2026-08-19T03:27:21.345615Z",
571+
"shell.execute_reply": "2026-08-19T03:27:21.345045Z"
567572
}
568573
},
569574
"outputs": [
@@ -600,10 +605,10 @@
600605
"id": "f5a1fa73e5044315a093ec459c9be902",
601606
"metadata": {
602607
"execution": {
603-
"iopub.execute_input": "2026-08-18T20:28:53.079759Z",
604-
"iopub.status.busy": "2026-08-18T20:28:53.079634Z",
605-
"iopub.status.idle": "2026-08-18T20:28:55.137282Z",
606-
"shell.execute_reply": "2026-08-18T20:28:55.136740Z"
608+
"iopub.execute_input": "2026-08-19T03:27:21.347219Z",
609+
"iopub.status.busy": "2026-08-19T03:27:21.347116Z",
610+
"iopub.status.idle": "2026-08-19T03:27:22.511292Z",
611+
"shell.execute_reply": "2026-08-19T03:27:22.510555Z"
607612
}
608613
},
609614
"outputs": [
@@ -629,10 +634,10 @@
629634
"id": "cdf66aed5cc84ca1b48e60bad68798a8",
630635
"metadata": {
631636
"execution": {
632-
"iopub.execute_input": "2026-08-18T20:28:55.140305Z",
633-
"iopub.status.busy": "2026-08-18T20:28:55.139930Z",
634-
"iopub.status.idle": "2026-08-18T20:28:55.382857Z",
635-
"shell.execute_reply": "2026-08-18T20:28:55.382321Z"
637+
"iopub.execute_input": "2026-08-19T03:27:22.513936Z",
638+
"iopub.status.busy": "2026-08-19T03:27:22.513574Z",
639+
"iopub.status.idle": "2026-08-19T03:27:22.764241Z",
640+
"shell.execute_reply": "2026-08-19T03:27:22.763465Z"
636641
}
637642
},
638643
"outputs": [
@@ -676,10 +681,10 @@
676681
"id": "0e382214b5f147d187d36a2058b9c724",
677682
"metadata": {
678683
"execution": {
679-
"iopub.execute_input": "2026-08-18T20:28:55.384402Z",
680-
"iopub.status.busy": "2026-08-18T20:28:55.384289Z",
681-
"iopub.status.idle": "2026-08-18T20:28:55.545244Z",
682-
"shell.execute_reply": "2026-08-18T20:28:55.544741Z"
684+
"iopub.execute_input": "2026-08-19T03:27:22.765788Z",
685+
"iopub.status.busy": "2026-08-19T03:27:22.765668Z",
686+
"iopub.status.idle": "2026-08-19T03:27:22.944998Z",
687+
"shell.execute_reply": "2026-08-19T03:27:22.944436Z"
683688
}
684689
},
685690
"outputs": [
@@ -704,10 +709,10 @@
704709
"id": "5b09d5ef5b5e4bb6ab9b829b10b6a29f",
705710
"metadata": {
706711
"execution": {
707-
"iopub.execute_input": "2026-08-18T20:28:55.546687Z",
708-
"iopub.status.busy": "2026-08-18T20:28:55.546563Z",
709-
"iopub.status.idle": "2026-08-18T20:28:55.719287Z",
710-
"shell.execute_reply": "2026-08-18T20:28:55.718703Z"
712+
"iopub.execute_input": "2026-08-19T03:27:22.946566Z",
713+
"iopub.status.busy": "2026-08-19T03:27:22.946421Z",
714+
"iopub.status.idle": "2026-08-19T03:27:23.134294Z",
715+
"shell.execute_reply": "2026-08-19T03:27:23.133744Z"
711716
}
712717
},
713718
"outputs": [
@@ -740,10 +745,10 @@
740745
"id": "46a27a456b804aa2a380d5edf15a5daf",
741746
"metadata": {
742747
"execution": {
743-
"iopub.execute_input": "2026-08-18T20:28:55.720819Z",
744-
"iopub.status.busy": "2026-08-18T20:28:55.720692Z",
745-
"iopub.status.idle": "2026-08-18T20:28:55.930368Z",
746-
"shell.execute_reply": "2026-08-18T20:28:55.929846Z"
748+
"iopub.execute_input": "2026-08-19T03:27:23.135832Z",
749+
"iopub.status.busy": "2026-08-19T03:27:23.135711Z",
750+
"iopub.status.idle": "2026-08-19T03:27:23.363321Z",
751+
"shell.execute_reply": "2026-08-19T03:27:23.362703Z"
747752
}
748753
},
749754
"outputs": [
@@ -776,10 +781,10 @@
776781
"id": "d6ca27006b894b04b6fc8b79396e2797",
777782
"metadata": {
778783
"execution": {
779-
"iopub.execute_input": "2026-08-18T20:28:55.931901Z",
780-
"iopub.status.busy": "2026-08-18T20:28:55.931781Z",
781-
"iopub.status.idle": "2026-08-18T20:28:56.505322Z",
782-
"shell.execute_reply": "2026-08-18T20:28:56.504859Z"
784+
"iopub.execute_input": "2026-08-19T03:27:23.365001Z",
785+
"iopub.status.busy": "2026-08-19T03:27:23.364875Z",
786+
"iopub.status.idle": "2026-08-19T03:27:23.734416Z",
787+
"shell.execute_reply": "2026-08-19T03:27:23.733810Z"
783788
}
784789
},
785790
"outputs": [
@@ -807,7 +812,10 @@
807812
"\n",
808813
"On the **datashader** backend, contrast autoscales to the aggregated value range, **not** to a norm's\n",
809814
"percentiles. Explicit `vmin`/`vmax` are still honored. For percentile-driven contrast on points, use the\n",
810-
"default matplotlib backend."
815+
"default matplotlib backend.\n",
816+
"\n",
817+
"The cell below passes `PercentileNormalize(5, 95)`, but on datashader those percentile limits are\n",
818+
"ignored — the contrast follows the aggregate range instead."
811819
]
812820
},
813821
{
@@ -816,10 +824,10 @@
816824
"id": "84d5ab97d17b4c38ab41a2b065bbd0c0",
817825
"metadata": {
818826
"execution": {
819-
"iopub.execute_input": "2026-08-18T20:28:56.507129Z",
820-
"iopub.status.busy": "2026-08-18T20:28:56.506802Z",
821-
"iopub.status.idle": "2026-08-18T20:28:58.669656Z",
822-
"shell.execute_reply": "2026-08-18T20:28:58.669067Z"
827+
"iopub.execute_input": "2026-08-19T03:27:23.736132Z",
828+
"iopub.status.busy": "2026-08-19T03:27:23.735789Z",
829+
"iopub.status.idle": "2026-08-19T03:27:25.983316Z",
830+
"shell.execute_reply": "2026-08-19T03:27:25.982720Z"
823831
}
824832
},
825833
"outputs": [
@@ -835,7 +843,7 @@
835843
}
836844
],
837845
"source": [
838-
"sdata.pl.render_points(\"blobs_points\", color=\"instance_id\", method=\"datashader\", norm=Normalize()).pl.show()"
846+
"sdata.pl.render_points(\"blobs_points\", color=\"instance_id\", method=\"datashader\", norm=PercentileNormalize(5, 95)).pl.show()"
839847
]
840848
},
841849
{
@@ -859,14 +867,14 @@
859867
},
860868
{
861869
"cell_type": "code",
862-
"execution_count": 22,
870+
"execution_count": 21,
863871
"id": "015066fb96f841e5be1e03a9eaadc3b6",
864872
"metadata": {
865873
"execution": {
866-
"iopub.execute_input": "2026-08-18T20:28:59.253659Z",
867-
"iopub.status.busy": "2026-08-18T20:28:59.253536Z",
868-
"iopub.status.idle": "2026-08-18T20:28:59.256245Z",
869-
"shell.execute_reply": "2026-08-18T20:28:59.255764Z"
874+
"iopub.execute_input": "2026-08-19T03:27:25.984887Z",
875+
"iopub.status.busy": "2026-08-19T03:27:25.984762Z",
876+
"iopub.status.idle": "2026-08-19T03:27:25.987400Z",
877+
"shell.execute_reply": "2026-08-19T03:27:25.986972Z"
870878
}
871879
},
872880
"outputs": [
@@ -895,14 +903,14 @@
895903
},
896904
{
897905
"cell_type": "code",
898-
"execution_count": 23,
906+
"execution_count": 22,
899907
"id": "9075f00cfa8d463f84130041b1e44ca7",
900908
"metadata": {
901909
"execution": {
902-
"iopub.execute_input": "2026-08-18T20:28:59.257685Z",
903-
"iopub.status.busy": "2026-08-18T20:28:59.257561Z",
904-
"iopub.status.idle": "2026-08-18T20:28:59.260002Z",
905-
"shell.execute_reply": "2026-08-18T20:28:59.259452Z"
910+
"iopub.execute_input": "2026-08-19T03:27:25.989054Z",
911+
"iopub.status.busy": "2026-08-19T03:27:25.988938Z",
912+
"iopub.status.idle": "2026-08-19T03:27:25.991305Z",
913+
"shell.execute_reply": "2026-08-19T03:27:25.990752Z"
906914
}
907915
},
908916
"outputs": [

0 commit comments

Comments
 (0)