{ "cells": [ { "cell_type": "markdown", "id": "7e9e9a56-c560-4e9d-b912-b7f04cc42465", "metadata": {}, "source": [ "# Using SVG Visualizations" ] }, { "cell_type": "code", "execution_count": 1, "id": "39d7c8bf-c258-4de2-8f13-f5363cdc4d70", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
show html
<svg  width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">\n",
       "  <rect x="0.00" y="0.00" width="100.00" height="100.00" />\n",
       "  <line x1="45" y1="45" x2="55" y2="55" stroke="white"/>\n",
       "  <line x1="45" y1="55" x2="55" y2="45" stroke="white"/>\n",
       "  <g>\n",
       "    <!-- This is the svg_g Group -->\n",
       "    <circle cx="30.00" cy="20.00" r="5.00" fill="red" stroke="yellow" />\n",
       "  </g>\n",
       "</svg>
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from svg_snip.Composer import Composer\n", "from svg_snip.Composer import Group, comment\n", "\n", "import svg_snip.Elements as e2d\n", "\n", "def x(x=0, y=0, **kwargs):\n", " return f\"\"\"\\\n", "\n", "\"\"\"\n", "\n", "svg = Composer((100,100))\n", "svg.add(e2d.rect, x=0, y=0, width=100, height=100)\n", "svg.add(x, x=50, y=50)\n", "\n", "svg_g = Group()\n", "svg_g.add(comment, text=\"This is the svg_g Group\")\n", "svg_g.add(e2d.circle, cx=30, cy=20, r=5, stroke='yellow', fill='red')\n", "\n", "svg.add(svg_g)\n", "\n", "svg.display(debug=True)" ] }, { "cell_type": "code", "execution_count": 2, "id": "b4439113-c67d-4da4-96e0-3beaa34cbb47", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "''" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "\u001b[31mSignature:\u001b[39m e2d.circle(**kwargs)\n", "\u001b[31mDocstring:\u001b[39m\n", "Generate SVG code for the element.\n", "\n", "Parameters:\n", "- cx: (float): The x-coordinate of the center of the circle.\n", "- cy: (float): The y-coordinate of the center of the circle.\n", "- r: (float): The radius of the circle.\n", "- fill: (str): The fill color. Examples: 'currentColor' keyword, 'red', #FF0000, rgb(255,0,0) ...\n", "- fill_opacity: (float): The opacity of the shape's fill. A value between 0 (completely transparent) and 1 (completely opaque).\n", "- fill_rule: (str): Defines the inside of the shape to dertermine the fill region. Possible values are 'nonzero' and 'evenodd'.\n", "- pattern: (str): URL referencing a element to be used as the fill.\n", "- gradient: (str): URL referencing a or element to be used as the fill.\n", "- stroke: (str): The stroke color of the outline. Examples: 'currentColor' keyword, 'red', #FF0000, rgb(255,0,0) ...\n", "- stroke_width: (float): The width of the outline.\n", "- stroke_opacity: (float): The opacity of the outline. A value between 0 (transparent) and 1 (opaque).\n", "- stroke_dasharray: (str): Defines the pattern of dashes and gaps used in the outline.\n", "- stroke_linecap: (str): Specifies the shape to be used at the end of the outline. Possible values are 'butt', 'round', and 'square'.\n", "- stroke_linejoin: (str): Specifies the shape to be used at the corners of the outline. Possible values are 'miter', 'round', and 'bevel'.\n", "- stroke_miterlimit: (float): Sets the limit for the length of the miter on joined corners of the outline.\n", "- marker_start: (str): Specifies the marker symbol for the start of the line.\n", "- marker_mid: (str): Specifies the marker symbol for the middle of the line.\n", "- marker_end: (str): Specifies the marker symbol for the end of the line.\n", "- style: (str): Inline style attribute for setting multiple CSS properties at once.\n", "- transform: (str): Specifies a transformation such as \n", "\n", "Returns:\n", "str: SVG code for the element with the specified attributes.\n", "\u001b[31mFile:\u001b[39m ~/nc_local/work/svg_snip/svg_snip/Elements.py\n", "\u001b[31mType:\u001b[39m function" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Here is how the basic drawing works: functions that return text!\n", "e2d.circle?\n", "e2d.circle(cx=30, cy=20, r=5, stroke='yellow', fill='red')" ] }, { "cell_type": "markdown", "id": "141dfd77-45af-4137-8467-0a6bee0a78e6", "metadata": {}, "source": [ "# How to interact with simple UI elements\n", "\n", "Jupyter is decently fast with updating short HTML fragments.\n", "You loose most time because running the python kernel in the backend and sending resulting text to the frontend.\n", "\n", "For debugging and scientific visualizations, this is quite fast enough." ] }, { "cell_type": "code", "execution_count": 3, "id": "4aa0a3df-a00d-4b0e-998e-efafcf3e39d6", "metadata": { "scrolled": true }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "f909294435f445f5a8fae06d21fee9ac", "version_major": 2, "version_minor": 0 }, "text/plain": [ "IntSlider(value=0, description='Angle', max=360, step=2)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "9d24fc92efbb4721a0a18e55613ed453", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Output()" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import ipywidgets as w\n", "from IPython.display import clear_output, display\n", "\n", "s = w.IntSlider(value=0, min=0, max=360, step=2, description='Angle')\n", "out = w.Output()\n", "\n", "def update(c):\n", " with out:\n", " clear_output(wait=True)\n", " svg = Composer((100,100))\n", " svg.add(e2d.rect, x=0, y=0, width=100, height=100)\n", " g = Group()\n", " g.add(e2d.rect, x=20, y=20, width=30, height=30, fill='blue')\n", " svg.add(g, transform=f'rotate({c[\"new\"]} 50 50)')\n", " svg.display()\n", "\n", "s.observe(update, names='value')\n", "display(s, out)\n", "update({\"new\": s.value})" ] }, { "cell_type": "markdown", "id": "ff734d53-40a9-4a98-a002-918592912223", "metadata": {}, "source": [ "# Using 3D Visualizations\n", "\n", "SVG does not suport 3D rendering. But it is a vector graphic that is easily exported and used in papers, for example.\n", "\n", "This is easily fast enough to support interactively tuning parameters and rotating the camera for simple 3D geometry.\n", "\n", "Note that the backface removal is based on the normal. So shaded faces work only for simple, convex geometry." ] }, { "cell_type": "code", "execution_count": 4, "id": "6b749423-44b2-4842-9638-ec351c97ff9d", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "37bfa27a89f6455dbf7bcdaa907559a4", "version_major": 2, "version_minor": 0 }, "text/plain": [ "IntSlider(value=0, description='R', max=255)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "761fedc85f3048099dc340227c2c4a25", "version_major": 2, "version_minor": 0 }, "text/plain": [ "IntSlider(value=120, description='G', max=255)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "723520d6d14143db8be2e540a2cd184e", "version_major": 2, "version_minor": 0 }, "text/plain": [ "IntSlider(value=255, description='B', max=255)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "97c70cc4fb394e9b90f568331fcebb39", "version_major": 2, "version_minor": 0 }, "text/plain": [ "VBox(children=(HTML(value='\\n