diff --git a/examples/simple.ipynb b/examples/simple.ipynb
index 2d4961ac3..9ca764283 100644
--- a/examples/simple.ipynb
+++ b/examples/simple.ipynb
@@ -14,7 +14,7 @@
},
{
"cell_type": "code",
- "execution_count": 1,
+ "execution_count": null,
"id": "fb57c3d3-f20d-4d88-9e7a-04b9309bc637",
"metadata": {},
"outputs": [],
@@ -34,52 +34,10 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": null,
"id": "237823b7-e2c0-4e2f-9ee8-e3fc2b4453c4",
"metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "22e188ba0769451ba369b4a5a2d5d313",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "RFBOutputContext()"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- "

initial snapshot
"
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "997ba4e4d8b540ffa3f100c2fde27920",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "JupyterWgpuCanvas()"
- ]
- },
- "execution_count": 2,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"# create a `Plot` instance\n",
"plot = Plot()\n",
@@ -112,7 +70,7 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": null,
"id": "de816c88-1c4a-4071-8a5e-c46c93671ef5",
"metadata": {},
"outputs": [],
@@ -122,7 +80,7 @@
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": null,
"id": "09350854-5058-4574-a01d-84d00e276c57",
"metadata": {},
"outputs": [],
@@ -132,7 +90,7 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": null,
"id": "83b2db1b-2783-4e89-bcf3-66bb6e09e18a",
"metadata": {},
"outputs": [],
@@ -143,7 +101,7 @@
},
{
"cell_type": "code",
- "execution_count": 6,
+ "execution_count": null,
"id": "3e298c1c-7551-4401-ade0-b9af7d2bbe23",
"metadata": {},
"outputs": [],
@@ -161,42 +119,20 @@
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": null,
"id": "e6ba689c-ff4a-44ef-9663-f2c8755072c4",
"metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "('random-image': ImageGraphic @ 0x7fbb681a1360,)"
- ]
- },
- "execution_count": 7,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"plot.graphics"
]
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": null,
"id": "5b18f4e3-e13b-46d5-af1f-285c5a7fdc12",
"metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'random-image': ImageGraphic @ 0x7fbb681a1360"
- ]
- },
- "execution_count": 8,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"plot[\"random-image\"]"
]
@@ -211,42 +147,20 @@
},
{
"cell_type": "code",
- "execution_count": 9,
+ "execution_count": null,
"id": "2b5c1321-1fd4-44bc-9433-7439ad3e22cf",
"metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'random-image': ImageGraphic @ 0x7fbb681a1360"
- ]
- },
- "execution_count": 9,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"image_graphic"
]
},
{
"cell_type": "code",
- "execution_count": 10,
+ "execution_count": null,
"id": "b12bf75e-4e93-4930-9146-e96324fdf3f6",
"metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"image_graphic is plot[\"random-image\"]"
]
@@ -265,52 +179,10 @@
},
{
"cell_type": "code",
- "execution_count": 11,
+ "execution_count": null,
"id": "aadd757f-6379-4f52-a709-46aa57c56216",
"metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "543d56b0c4fa4eb18927358bd7d0d2fa",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "RFBOutputContext()"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- "
initial snapshot
"
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "ca2343e7c6294dddb4d71253c5dd0050",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "JupyterWgpuCanvas()"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"# create another `Plot` instance\n",
"plot_v = Plot()\n",
@@ -348,52 +220,10 @@
},
{
"cell_type": "code",
- "execution_count": 12,
+ "execution_count": null,
"id": "86e70b1e-4328-4035-b992-70dff16d2a69",
"metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "2fca1a70597f4f2c813245b472557980",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "RFBOutputContext()"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- "
initial snapshot
"
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "655dee7f343d4ad1b9d1dca8bf499fa2",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "JupyterWgpuCanvas()"
- ]
- },
- "execution_count": 12,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"plot_sync = Plot(controller=plot_v.controller)\n",
"\n",
@@ -430,25 +260,10 @@
},
{
"cell_type": "code",
- "execution_count": 13,
+ "execution_count": null,
"id": "ef9743b3-5f81-4b79-9502-fa5fca08e56d",
"metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "98e198424c434dfcaf932bdf67e8c1b2",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "VBox(children=(JupyterWgpuCanvas(frame_feedback={'index': 211, 'timestamp': 1673222194.8195093, 'localtime': 1…"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
+ "outputs": [],
"source": [
"VBox([plot_v.show(), plot_sync.show()])"
]
@@ -464,25 +279,10 @@
},
{
"cell_type": "code",
- "execution_count": 14,
+ "execution_count": null,
"id": "11839d95-8ff7-444c-ae13-6b072c3112c5",
"metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "f97d3b3fd53040388be0f2527a832b41",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "HBox(children=(JupyterWgpuCanvas(frame_feedback={'index': 236, 'timestamp': 1673222197.978218, 'localtime': 16…"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
+ "outputs": [],
"source": [
"HBox([plot_v.show(), plot_sync.show()])"
]
@@ -507,7 +307,7 @@
},
{
"cell_type": "code",
- "execution_count": 15,
+ "execution_count": null,
"id": "0bcedf83-cbdd-4ec2-b8d5-172aa72a3e04",
"metadata": {},
"outputs": [],
@@ -582,21 +382,10 @@
},
{
"cell_type": "code",
- "execution_count": 16,
+ "execution_count": null,
"id": "8b560151-c258-415c-a20d-3cccd421f44a",
"metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(1000, 512, 512)"
- ]
- },
- "execution_count": 16,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"movie.shape"
]
@@ -619,39 +408,10 @@
},
{
"cell_type": "code",
- "execution_count": 17,
+ "execution_count": null,
"id": "62166a9f-ab43-45cc-a6db-6d441387e9a5",
"metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "716bb151456446c283aa842c008fc805",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "RFBOutputContext()"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "6ef37682df3f409b8d2a7ac36974d7ce",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "VBox(children=(JupyterWgpuCanvas(), IntSlider(value=0, max=999)))"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
+ "outputs": [],
"source": [
"plot_movie = Plot()\n",
"\n",
@@ -710,7 +470,7 @@
},
{
"cell_type": "code",
- "execution_count": 18,
+ "execution_count": null,
"id": "8e8280da-b421-43a5-a1a6-2a196a408e9a",
"metadata": {},
"outputs": [],
@@ -741,52 +501,10 @@
},
{
"cell_type": "code",
- "execution_count": 19,
+ "execution_count": null,
"id": "93a5d1e6-d019-4dd0-a0d1-25d1704ab7a7",
"metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "5a78ff5b74a64ba28afcd7844a5bd1de",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "RFBOutputContext()"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- "
initial snapshot
"
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "59f97de592804347a60996be35bcab2c",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "JupyterWgpuCanvas()"
- ]
- },
- "execution_count": 19,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"# Create a plot instance\n",
"plot_l = Plot()\n",
@@ -804,6 +522,48 @@
"plot_l.show()"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "22dde600-0f56-4370-b017-c8f23a6c01aa",
+ "metadata": {},
+ "source": [
+ "### \"stretching\" the camera, useful for large timeseries data\n",
+ "\n",
+ "Set `maintain_aspect = False` on a camera, and then use the right mouse button and move the mouse to stretch and squeeze the view!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2695f023-f6ce-4e26-8f96-4fbed5510d1d",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "plot_l.camera.maintain_aspect = False"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1651e965-f750-47ac-bf53-c23dae84cc98",
+ "metadata": {},
+ "source": [
+ "### reset the plot area"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ba50a6ed-0f1b-4795-91dd-a7c3e40b8e3c",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "plot_l.auto_scale(maintain_aspect=True)"
+ ]
+ },
{
"cell_type": "markdown",
"id": "dcd68796-c190-4c3f-8519-d73b98ff6367",
@@ -814,7 +574,7 @@
},
{
"cell_type": "code",
- "execution_count": 20,
+ "execution_count": null,
"id": "cb0d13ed-ef07-46ff-b19e-eeca4c831037",
"metadata": {},
"outputs": [],
@@ -842,7 +602,7 @@
},
{
"cell_type": "code",
- "execution_count": 21,
+ "execution_count": null,
"id": "cfa001f6-c640-4f91-beb0-c19b030e503f",
"metadata": {},
"outputs": [],
@@ -856,32 +616,10 @@
},
{
"cell_type": "code",
- "execution_count": 22,
+ "execution_count": null,
"id": "bb8a0f95-0063-4cd4-a117-e3d62c6e120d",
"metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "FeatureEvent @ 0x7fbacc955060\n",
- "type: colors\n",
- "pick_info: {'index': range(15, 50, 3), 'collection-index': None, 'world_object': , 'new_data': array([[0., 1., 1., 1.],\n",
- " [0., 1., 1., 1.],\n",
- " [0., 1., 1., 1.],\n",
- " [0., 1., 1., 1.],\n",
- " [0., 1., 1., 1.],\n",
- " [0., 1., 1., 1.],\n",
- " [0., 1., 1., 1.],\n",
- " [0., 1., 1., 1.],\n",
- " [0., 1., 1., 1.],\n",
- " [0., 1., 1., 1.],\n",
- " [0., 1., 1., 1.],\n",
- " [0., 1., 1., 1.]], dtype=float32)}\n",
- "\n"
- ]
- }
- ],
+ "outputs": [],
"source": [
"# more complex indexing of colors\n",
"# from point 15 - 30, set every 3rd point as \"cyan\"\n",
@@ -898,7 +636,7 @@
},
{
"cell_type": "code",
- "execution_count": 23,
+ "execution_count": null,
"id": "d1a4314b-5723-43c7-94a0-b4cbb0e44d60",
"metadata": {},
"outputs": [],
@@ -909,7 +647,7 @@
},
{
"cell_type": "code",
- "execution_count": 24,
+ "execution_count": null,
"id": "682db47b-8c7a-4934-9be4-2067e9fb12d5",
"metadata": {},
"outputs": [],
@@ -927,7 +665,7 @@
},
{
"cell_type": "code",
- "execution_count": 25,
+ "execution_count": null,
"id": "fcba75b7-9a1e-4aae-9dec-715f7f7456c3",
"metadata": {},
"outputs": [],
@@ -937,7 +675,7 @@
},
{
"cell_type": "code",
- "execution_count": 26,
+ "execution_count": null,
"id": "763b9943-53a4-4e2a-b47a-4e9e5c9d7be3",
"metadata": {},
"outputs": [],
@@ -955,7 +693,7 @@
},
{
"cell_type": "code",
- "execution_count": 27,
+ "execution_count": null,
"id": "64a20a16-75a5-4772-a849-630ade9be4ff",
"metadata": {},
"outputs": [],
@@ -965,7 +703,7 @@
},
{
"cell_type": "code",
- "execution_count": 28,
+ "execution_count": null,
"id": "fb093046-c94c-4085-86b4-8cd85cb638ff",
"metadata": {},
"outputs": [],
@@ -975,7 +713,7 @@
},
{
"cell_type": "code",
- "execution_count": 29,
+ "execution_count": null,
"id": "f05981c3-c768-4631-ae62-6a8407b20c4c",
"metadata": {},
"outputs": [],
@@ -993,60 +731,10 @@
},
{
"cell_type": "code",
- "execution_count": 30,
+ "execution_count": null,
"id": "9c51229f-13a2-4653-bff3-15d43ddbca7b",
"metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "4beed0a67834408aa4549374af4b36d8",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "RFBOutputContext()"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/home/kushalk/repos/fastplotlib/fastplotlib/layouts/_base.py:214: UserWarning: `center_scene()` not yet implemented for `PerspectiveCamera`\n",
- " warn(\"`center_scene()` not yet implemented for `PerspectiveCamera`\")\n"
- ]
- },
- {
- "data": {
- "text/html": [
- "
initial snapshot
"
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "52aa9698dbe2430099c3d88159bcb47b",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "JupyterWgpuCanvas()"
- ]
- },
- "execution_count": 30,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"# just set the camera as \"3d\", the rest is basically the same :D \n",
"plot_l3d = Plot(camera='3d')\n",
@@ -1067,6 +755,18 @@
"plot_l3d.show()"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "28eb7014-4773-4a34-8bfc-bd3a46429012",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "plot_l3d.auto_scale(maintain_aspect=True)"
+ ]
+ },
{
"cell_type": "markdown",
"id": "a202b3d0-2a0b-450a-93d4-76d0a1129d1d",
@@ -1081,7 +781,7 @@
},
{
"cell_type": "code",
- "execution_count": 31,
+ "execution_count": null,
"id": "2ecb2385-8fa4-4239-881c-b754c24aed9f",
"metadata": {},
"outputs": [],
@@ -1093,52 +793,10 @@
},
{
"cell_type": "code",
- "execution_count": 32,
+ "execution_count": null,
"id": "39252df5-9ae5-4132-b97b-2785c5fa92ea",
"metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "58954cd128264eb38a4afc87f940194e",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "RFBOutputContext()"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- "
initial snapshot
"
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "3eac2f2a71334813a958c144d22089d4",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "JupyterWgpuCanvas()"
- ]
- },
- "execution_count": 32,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "outputs": [],
"source": [
"# create a random distribution of 10,000 xyz coordinates\n",
"n_points = 10_000\n",
@@ -1185,7 +843,7 @@
},
{
"cell_type": "code",
- "execution_count": 35,
+ "execution_count": null,
"id": "8fa46ec0-8680-44f5-894c-559de3145932",
"metadata": {},
"outputs": [],
@@ -1196,7 +854,7 @@
},
{
"cell_type": "code",
- "execution_count": 36,
+ "execution_count": null,
"id": "e4dc71e4-5144-436f-a464-f2a29eee8f0b",
"metadata": {},
"outputs": [],
@@ -1207,7 +865,7 @@
},
{
"cell_type": "code",
- "execution_count": 37,
+ "execution_count": null,
"id": "5b637a29-cd5e-4011-ab81-3f91490d9ecd",
"metadata": {},
"outputs": [],
@@ -1218,7 +876,7 @@
},
{
"cell_type": "code",
- "execution_count": 38,
+ "execution_count": null,
"id": "a4084fce-78a2-48b3-9a0d-7b57c165c3c1",
"metadata": {},
"outputs": [],
@@ -1229,7 +887,7 @@
},
{
"cell_type": "code",
- "execution_count": 39,
+ "execution_count": null,
"id": "f486083e-7c58-4255-ae1a-3fe5d9bfaeed",
"metadata": {},
"outputs": [],
@@ -1250,25 +908,10 @@
},
{
"cell_type": "code",
- "execution_count": 40,
+ "execution_count": null,
"id": "f404a5ea-633b-43f5-87d1-237017bbca2a",
"metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "36ce2e79024a4906aef9530ea238631d",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "VBox(children=(HBox(children=(JupyterWgpuCanvas(frame_feedback={'index': 812, 'timestamp': 1673222184.132576, …"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
+ "outputs": [],
"source": [
"row1 = HBox([plot.show(), plot_v.show(), plot_sync.show()])\n",
"row2 = HBox([plot_l.show(), plot_l3d.show(), plot_s.show()])\n",
@@ -1301,7 +944,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.10.5"
+ "version": "3.11.3"
}
},
"nbformat": 4,
diff --git a/fastplotlib/VERSION b/fastplotlib/VERSION
index 229bb9495..6cb992894 100644
--- a/fastplotlib/VERSION
+++ b/fastplotlib/VERSION
@@ -1 +1 @@
-0.1.0.a9
+0.1.0.a10
\ No newline at end of file
diff --git a/fastplotlib/graphics/features/_colors.py b/fastplotlib/graphics/features/_colors.py
index a5147b95e..f8e7c8c3d 100644
--- a/fastplotlib/graphics/features/_colors.py
+++ b/fastplotlib/graphics/features/_colors.py
@@ -220,8 +220,8 @@ def __init__(self, parent, cmap: str):
self.name = cmap
def _set(self, cmap_name: str):
- self._parent.world_object.material.map.texture.data[:] = make_colors(256, cmap_name)
- self._parent.world_object.material.map.texture.update_range((0, 0, 0), size=(256, 1, 1))
+ self._parent.world_object.material.map.data[:] = make_colors(256, cmap_name)
+ self._parent.world_object.material.map.update_range((0, 0, 0), size=(256, 1, 1))
self.name = cmap_name
self._feature_changed(key=None, new_data=self.name)
@@ -246,8 +246,8 @@ class HeatmapCmapFeature(ImageCmapFeature):
"""
def _set(self, cmap_name: str):
- self._parent._material.map.texture.data[:] = make_colors(256, cmap_name)
- self._parent._material.map.texture.update_range((0, 0, 0), size=(256, 1, 1))
+ self._parent._material.map.data[:] = make_colors(256, cmap_name)
+ self._parent._material.map.update_range((0, 0, 0), size=(256, 1, 1))
self.name = cmap_name
self._feature_changed(key=None, new_data=self.name)
diff --git a/fastplotlib/graphics/features/_data.py b/fastplotlib/graphics/features/_data.py
index 3d877bace..5063b4200 100644
--- a/fastplotlib/graphics/features/_data.py
+++ b/fastplotlib/graphics/features/_data.py
@@ -1,7 +1,7 @@
from typing import *
import numpy as np
-from pygfx import Buffer, Texture, TextureView
+from pygfx import Buffer, Texture
from ._base import GraphicFeatureIndexable, cleanup_slice, FeatureEvent, to_gpu_supported_dtype
@@ -87,7 +87,7 @@ def _feature_changed(self, key, new_data):
class ImageDataFeature(GraphicFeatureIndexable):
"""
- Access to the TextureView buffer shown in an ImageGraphic.
+ Access to the Texture buffer shown in an ImageGraphic.
"""
def __init__(self, parent, data: Any):
@@ -102,7 +102,7 @@ def __init__(self, parent, data: Any):
@property
def buffer(self) -> Texture:
"""Texture buffer for the image data"""
- return self._parent.world_object.geometry.grid.texture
+ return self._parent.world_object.geometry.grid
def update_gpu(self):
"""Update the GPU with the buffer"""
@@ -153,7 +153,7 @@ class HeatmapDataFeature(ImageDataFeature):
@property
def buffer(self) -> List[Texture]:
"""list of Texture buffer for the image data"""
- return [img.geometry.grid.texture for img in self._parent.world_object.children]
+ return [img.geometry.grid for img in self._parent.world_object.children]
def update_gpu(self):
"""Update the GPU with the buffer"""
diff --git a/fastplotlib/graphics/image.py b/fastplotlib/graphics/image.py
index cb4cf1587..835061328 100644
--- a/fastplotlib/graphics/image.py
+++ b/fastplotlib/graphics/image.py
@@ -4,7 +4,6 @@
import numpy as np
import pygfx
-from pygfx.utils import unpack_bitfield
from ._base import Graphic, Interaction, PreviouslyModifiedData
from .features import ImageCmapFeature, ImageDataFeature, HeatmapDataFeature, HeatmapCmapFeature
@@ -87,18 +86,18 @@ def __init__(
if (vmin is None) or (vmax is None):
vmin, vmax = quick_min_max(data)
- texture_view = pygfx.Texture(buffer_init, dim=2).get_view(filter=filter)
+ texture = pygfx.Texture(buffer_init, dim=2)
- geometry = pygfx.Geometry(grid=texture_view)
+ geometry = pygfx.Geometry(grid=texture)
# if data is RGB
if data.ndim == 3:
self.cmap = None
- material = pygfx.ImageBasicMaterial(clim=(vmin, vmax))
+ material = pygfx.ImageBasicMaterial(clim=(vmin, vmax), map_interpolation=filter)
# if data is just 2D without color information, use colormap LUT
else:
self.cmap = ImageCmapFeature(self, cmap)
- material = pygfx.ImageBasicMaterial(clim=(vmin, vmax), map=self.cmap())
+ material = pygfx.ImageBasicMaterial(clim=(vmin, vmax), map=self.cmap(), map_interpolation=filter)
world_object = pygfx.Image(
geometry,
@@ -151,21 +150,13 @@ class _ImageTile(pygfx.Image):
"""
Similar to pygfx.Image, only difference is that it contains a few properties to keep track of
row chunk index, column chunk index
-
-
"""
def _wgpu_get_pick_info(self, pick_value):
- tex = self.geometry.grid
- if hasattr(tex, "texture"):
- tex = tex.texture # tex was a view
- # This should match with the shader
- values = unpack_bitfield(pick_value, wobject_id=20, x=22, y=22)
- x = values["x"] / 4194304 * tex.size[0] - 0.5
- y = values["y"] / 4194304 * tex.size[1] - 0.5
- ix, iy = int(x + 0.5), int(y + 0.5)
+ pick_info = super()._wgpu_get_pick_info(pick_value)
+
+ # add row chunk and col chunk index to pick_info dict
return {
- "index": (ix, iy),
- "pixel_coord": (x - ix, y - iy),
+ **pick_info,
"row_chunk_index": self.row_chunk_index,
"col_chunk_index": self.col_chunk_index
}
@@ -281,7 +272,7 @@ def __init__(
vmin, vmax = quick_min_max(data)
self.cmap = HeatmapCmapFeature(self, cmap)
- self._material = pygfx.ImageBasicMaterial(clim=(vmin, vmax), map=self.cmap())
+ self._material = pygfx.ImageBasicMaterial(clim=(vmin, vmax), map=self.cmap(), map_interpolation=filter)
for start, stop, chunk in zip(start_ixs, stop_ixs, chunks):
row_start, col_start = start
@@ -290,8 +281,8 @@ def __init__(
# x and y positions of the Tile in world space coordinates
y_pos, x_pos = row_start, col_start
- tex_view = pygfx.Texture(buffer_init[row_start:row_stop, col_start:col_stop], dim=2).get_view(filter=filter)
- geometry = pygfx.Geometry(grid=tex_view)
+ texture = pygfx.Texture(buffer_init[row_start:row_stop, col_start:col_stop], dim=2)
+ geometry = pygfx.Geometry(grid=texture)
# material = pygfx.ImageBasicMaterial(clim=(0, 1), map=self.cmap())
img = _ImageTile(geometry, self._material)
diff --git a/fastplotlib/layouts/_base.py b/fastplotlib/layouts/_base.py
index c98c010ea..70bd6dbaa 100644
--- a/fastplotlib/layouts/_base.py
+++ b/fastplotlib/layouts/_base.py
@@ -70,18 +70,11 @@ def __init__(
self._camera = camera
self._controller = controller
- self.controller.add_default_event_handlers(
+ self.controller.add_camera(self.camera)
+ self.controller.register_events(
self.viewport,
- self.camera
)
- # camera.far and camera.near clipping planes get
- # wonky with setting controller.distance = 0
- if isinstance(self.camera, OrthographicCamera):
- self.controller.distance = 0
- # also set a initial zoom
- self.controller.zoom(0.8 / self.controller.zoom_value)
-
self.renderer.add_event_handler(self.set_viewport_rect, "resize")
# list of hex id strings for all graphics managed by this PlotArea
@@ -158,7 +151,6 @@ def set_viewport_rect(self, *args):
def render(self):
# does not flush
- self.controller.update_camera(self.camera)
self.viewport.render(self.scene, self.camera)
for child in self.children:
@@ -213,17 +205,7 @@ def _check_graphic_name_exists(self, name):
if name in graphic_names:
raise ValueError(f"graphics must have unique names, current graphic names are:\n {graphic_names}")
- def _refresh_camera(self):
- self.controller.update_camera(self.camera)
- if sum(self.renderer.logical_size) > 0:
- scene_lsize = self.viewport.rect[2], self.viewport.rect[3]
- else:
- scene_lsize = (1, 1)
-
- self.camera.set_view_size(*scene_lsize)
- self.camera.update_projection_matrix()
-
- def center_graphic(self, graphic: Graphic, zoom: float = 1.3):
+ def center_graphic(self, graphic: Graphic, zoom: float = 1.35):
"""
Center the camera w.r.t. the passed graphic
@@ -236,17 +218,14 @@ def center_graphic(self, graphic: Graphic, zoom: float = 1.3):
zoom the camera after centering
"""
- if not isinstance(self.camera, OrthographicCamera):
- warn("`center_graphic()` not yet implemented for `PerspectiveCamera`")
- return
- self._refresh_camera()
+ self.camera.show_object(graphic.world_object)
- self.controller.show_object(self.camera, graphic.world_object)
+ # camera.show_object can cause the camera width and height to increase so apply a zoom to compensate
+ # probably because camera.show_object uses bounding sphere
+ self.camera.zoom = zoom
- self.controller.zoom(zoom)
-
- def center_scene(self, zoom: float = 1.3):
+ def center_scene(self, zoom: float = 1.35):
"""
Auto-center the scene, does not scale.
@@ -259,15 +238,11 @@ def center_scene(self, zoom: float = 1.3):
if not len(self.scene.children) > 0:
return
- if not isinstance(self.camera, OrthographicCamera):
- warn("`center_scene()` not yet implemented for `PerspectiveCamera`")
- return
-
- self._refresh_camera()
+ self.camera.show_object(self.scene)
- self.controller.show_object(self.camera, self.scene)
-
- self.controller.zoom(zoom)
+ # camera.show_object can cause the camera width and height to increase so apply a zoom to compensate
+ # probably because camera.show_object uses bounding sphere
+ self.camera.zoom = zoom
def auto_scale(self, maintain_aspect: bool = False, zoom: float = 0.8):
"""
@@ -303,9 +278,7 @@ def auto_scale(self, maintain_aspect: bool = False, zoom: float = 0.8):
self.camera.width = width
self.camera.height = height
- # self.controller.distance = 0
-
- self.controller.zoom(zoom / self.controller.zoom_value)
+ self.camera.zoom = zoom
def remove_graphic(self, graphic: Graphic):
"""
diff --git a/fastplotlib/layouts/_defaults.py b/fastplotlib/layouts/_defaults.py
index 3c5732613..314774751 100644
--- a/fastplotlib/layouts/_defaults.py
+++ b/fastplotlib/layouts/_defaults.py
@@ -8,9 +8,9 @@
controller_types = {
'2d': pygfx.PanZoomController,
- '3d': pygfx.OrbitOrthoController,
+ '3d': pygfx.OrbitController,
pygfx.OrthographicCamera: pygfx.PanZoomController,
- pygfx.PerspectiveCamera: pygfx.OrbitOrthoController,
+ pygfx.PerspectiveCamera: pygfx.OrbitController,
}
diff --git a/fastplotlib/layouts/_subplot.py b/fastplotlib/layouts/_subplot.py
index 7bb1f0540..a5f57451e 100644
--- a/fastplotlib/layouts/_subplot.py
+++ b/fastplotlib/layouts/_subplot.py
@@ -6,7 +6,7 @@
from inspect import signature, getfullargspec
from warnings import warn
-from pygfx import Scene, OrthographicCamera, PanZoomController, OrbitOrthoController, \
+from pygfx import Scene, OrthographicCamera, PanZoomController, OrbitController, \
AxesHelper, GridHelper, WgpuRenderer
from wgpu.gui.auto import WgpuCanvas
@@ -22,7 +22,7 @@ def __init__(
position: Tuple[int, int] = None,
parent_dims: Tuple[int, int] = None,
camera: str = '2d',
- controller: Union[PanZoomController, OrbitOrthoController] = None,
+ controller: Union[PanZoomController, OrbitController] = None,
canvas: WgpuCanvas = None,
renderer: WgpuRenderer = None,
name: str = None,
diff --git a/fastplotlib/plot.py b/fastplotlib/plot.py
index 74c35ef6e..89c73a5f2 100644
--- a/fastplotlib/plot.py
+++ b/fastplotlib/plot.py
@@ -10,7 +10,7 @@ def __init__(
canvas: WgpuCanvas = None,
renderer: pygfx.Renderer = None,
camera: str = '2d',
- controller: Union[pygfx.PanZoomController, pygfx.OrbitOrthoController] = None,
+ controller: Union[pygfx.PanZoomController, pygfx.OrbitController] = None,
**kwargs
):
"""
diff --git a/fastplotlib/utils/functions.py b/fastplotlib/utils/functions.py
index d919a88d6..1ba72b322 100644
--- a/fastplotlib/utils/functions.py
+++ b/fastplotlib/utils/functions.py
@@ -68,7 +68,7 @@ def make_colors(n_colors: int, cmap: str, alpha: float = 1.0) -> np.ndarray:
def get_cmap_texture(name: str, alpha: float = 1.0) -> Texture:
cmap = _get_cmap(name)
- return Texture(cmap, dim=1).get_view()
+ return Texture(cmap, dim=1)
def make_colors_dict(labels: iter, cmap: str, **kwargs) -> OrderedDict: