{ "cells": [ { "cell_type": "markdown", "id": "a5000001", "metadata": {}, "source": [ "# Colormaps, Colorbars and Clipping\n", "\n", "This notebook demonstrates how to map scalar values to colors using `Colormap`,\n", "display a legend with `Colorbar`, and clip geometry with `Clipping`." ] }, { "cell_type": "markdown", "id": "a5000002", "metadata": {}, "source": [ "## Basic colormap\n", "\n", "Pass scalar `values` and a `Colormap` to `ShapeRenderer` instead of explicit RGBA colors.\n", "Each instance needs two values (start and end of the shape)." ] }, { "cell_type": "code", "execution_count": null, "id": "a5000003", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from webgpu.shapes import generate_cylinder, ShapeRenderer\n", "from webgpu.colormap import Colormap, Colorbar\n", "from webgpu.jupyter import Draw\n", "\n", "n = 5\n", "positions = [[i, 0, 0] for i in range(n)]\n", "directions = [[0, 0, 1]] * n\n", "values = [float(i) / (n - 1) for i in range(n)]\n", "\n", "cmap = Colormap(colormap=\"viridis\")\n", "renderer = ShapeRenderer(\n", " generate_cylinder(n=16, radius=0.1, height=0.8),\n", " positions=positions,\n", " directions=directions,\n", " values=values * 2, # two values per instance (start and end)\n", " colormap=cmap,\n", ")\n", "Draw([renderer, Colorbar(cmap)])" ] }, { "cell_type": "markdown", "id": "a5000004", "metadata": {}, "source": [ "## Different colormaps\n", "\n", "Several built-in colormaps are available: `\"viridis\"`, `\"plasma\"`, `\"matlab:jet\"`, `\"cet_l20\"`,\n", "`\"matplotlib:coolwarm\"`, and any name supported by the `cmap` package." ] }, { "cell_type": "code", "execution_count": null, "id": "a5000005", "metadata": {}, "outputs": [], "source": [ "cmap = Colormap(colormap=\"plasma\")\n", "renderer = ShapeRenderer(\n", " generate_cylinder(n=16, radius=0.1, height=0.8),\n", " positions=positions,\n", " directions=directions,\n", " values=values * 2,\n", " colormap=cmap,\n", ")\n", "Draw([renderer, Colorbar(cmap)])" ] }, { "cell_type": "markdown", "id": "a5000006", "metadata": {}, "source": [ "## Controlling the mapped range\n", "\n", "Use `minval` and `maxval` to fix the value range that maps to the colormap.\n", "Values outside this range are clamped to the colormap extremes." ] }, { "cell_type": "code", "execution_count": null, "id": "a5000007", "metadata": {}, "outputs": [], "source": [ "cmap = Colormap(minval=0.2, maxval=0.8, colormap=\"viridis\")\n", "renderer = ShapeRenderer(\n", " generate_cylinder(n=16, radius=0.1, height=0.8),\n", " positions=positions,\n", " directions=directions,\n", " values=values * 2,\n", " colormap=cmap,\n", ")\n", "Draw([renderer, Colorbar(cmap)])" ] }, { "cell_type": "markdown", "id": "a5000008", "metadata": {}, "source": [ "## Discrete colormaps\n", "\n", "Enable discrete mode to quantize the colormap into a fixed number of color bands." ] }, { "cell_type": "code", "execution_count": null, "id": "a5000009", "metadata": {}, "outputs": [], "source": [ "cmap = Colormap(colormap=\"viridis\")\n", "cmap.set_discrete(True)\n", "cmap.set_n_colors(5)\n", "renderer = ShapeRenderer(\n", " generate_cylinder(n=16, radius=0.1, height=0.8),\n", " positions=positions,\n", " directions=directions,\n", " values=values * 2,\n", " colormap=cmap,\n", ")\n", "Draw([renderer, Colorbar(cmap)])" ] }, { "cell_type": "markdown", "id": "a500000a", "metadata": {}, "source": [ "## Clipping\n", "\n", "The `Clipping` object defines a clipping region that discards fragments on one side\n", "of a plane or outside/inside a sphere. Renderers that support clipping use it to\n", "cut away parts of the geometry.\n", "\n", "### Clipping modes\n", "\n", "| Mode | Description |\n", "|------|-------------|\n", "| `Clipping.Mode.DISABLED` | No clipping (default) |\n", "| `Clipping.Mode.PLANE` | Clip by a plane defined by `center` and `normal` |\n", "| `Clipping.Mode.SPHERE` | Clip by a sphere defined by `center` and `radius` |\n", "\n", "### Creating a clipping object" ] }, { "cell_type": "code", "execution_count": null, "id": "a500000b", "metadata": {}, "outputs": [], "source": [ "from webgpu.clipping import Clipping\n", "\n", "# Plane clipping: discard everything on the negative side of the plane\n", "clip_plane = Clipping(\n", " mode=Clipping.Mode.PLANE,\n", " center=[0, 0, 0],\n", " normal=[1, 0, 0],\n", ")\n", "\n", "# Sphere clipping: discard everything outside a sphere\n", "clip_sphere = Clipping(\n", " mode=Clipping.Mode.SPHERE,\n", " center=[0, 0, 0],\n", " radius=0.5,\n", ")\n", "\n", "print(f\"Plane mode: {clip_plane.mode}\")\n", "print(f\"Sphere mode: {clip_sphere.mode}\")" ] }, { "cell_type": "markdown", "id": "a500000c", "metadata": {}, "source": [ "The `Clipping` object is passed to the scene alongside renderers.\n", "Renderers that support clipping will use it to discard fragments.\n", "You can also adjust the clipping interactively via `set_offset()`,\n", "`set_x_value()`, etc." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.14.4" } }, "nbformat": 4, "nbformat_minor": 5 }