{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Demo version of the ``square_limit`` topic notebook in ``examples/topics/geometry``.\n", "\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "* [Matplotlib - square_limit](../matplotlib/square_limit.ipynb)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import holoviews as hv\n", "from holoviews import opts\n", "import numpy as np\n", "from matplotlib.path import Path\n", "from matplotlib.transforms import Affine2D\n", "hv.extension('bokeh')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Declaring data and transforms" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "spline=[(0.0,1.0),(0.08,0.98),(0.22,0.82),(0.29,0.72),(0.29,0.72),(0.3,0.64),(0.29,0.57),(0.3,0.5),\n", "(0.3,0.5),(0.34,0.4),(0.43,0.32),(0.5,0.26),(0.5,0.26),(0.58,0.21),(0.66,0.22),(0.76,0.2),(0.76,0.2),\n", "(0.82,0.12),(0.94,0.05),(1.0,0.0),(1.0,0.0),(0.9,0.03),(0.81,0.04),(0.76,0.05),(0.76,0.05),(0.69,0.04),\n", "(0.62,0.04),(0.55,0.04),(0.55,0.04),(0.49,0.1),(0.4,0.17),(0.35,0.2),(0.35,0.2),(0.29,0.24),(0.19,0.28),\n", "(0.14,0.31),(0.14,0.31),(0.09,0.35),(-0.03,0.43),(-0.05,0.72),(-0.05,0.72),(-0.04,0.82),(-0.02,0.95),(0.0,1.0),\n", "(0.1,0.85),(0.14,0.82),(0.18,0.78),(0.18,0.75),(0.18,0.75),(0.16,0.74),(0.14,0.73),(0.12,0.73),(0.12,0.73),\n", "(0.11,0.77),(0.11,0.81),(0.1,0.85),(0.05,0.82),(0.1,0.8),(0.08,0.74),(0.09,0.7),(0.09,0.7),(0.07,0.68),\n", "(0.06,0.66),(0.04,0.67),(0.04,0.67),(0.04,0.73),(0.04,0.81),(0.05,0.82),(0.11,0.7),(0.16,0.56),(0.24,0.39),\n", "(0.3,0.34),(0.3,0.34),(0.41,0.22),(0.62,0.16),(0.8,0.08),(0.23,0.8),(0.35,0.8),(0.44,0.78),(0.5,0.75),\n", "(0.5,0.75),(0.5,0.67),(0.5,0.59),(0.5,0.51),(0.5,0.51),(0.46,0.47),(0.42,0.43),(0.38,0.39),(0.29,0.71),\n", "(0.36,0.74),(0.43,0.73),(0.48,0.69),(0.34,0.61),(0.38,0.66),(0.44,0.64),(0.48,0.63),(0.34,0.51),(0.38,0.56),\n", "(0.41,0.58),(0.48,0.57),(0.45,0.42),(0.46,0.4),(0.47,0.39),(0.48,0.39),(0.42,0.39),(0.43,0.36),(0.46,0.32),\n", "(0.48,0.33),(0.25,0.26),(0.17,0.17),(0.08,0.09),(0.0,0.01),(0.0,0.01),(-0.08,0.09),(-0.17,0.18),(-0.25,0.26),\n", "(-0.25,0.26),(-0.2,0.37),(-0.11,0.47),(-0.03,0.57),(-0.17,0.26),(-0.13,0.34),(-0.08,0.4),(-0.01,0.44),\n", "(-0.12,0.21),(-0.07,0.29),(-0.02,0.34),(0.05,0.4),(-0.06,0.14),(-0.03,0.23),(0.03,0.28),(0.1,0.34),(-0.02,0.08),\n", "(0.02,0.16),(0.09,0.23),(0.16,0.3)]\n", "\n", "rotT = Affine2D().rotate_deg(90).translate(1, 0)\n", "rot45T = Affine2D().rotate_deg(45).scale(1. / np.sqrt(2.), 1. / np.sqrt(2.)).translate(1 / 2., 1 / 2.)\n", "flipT = Affine2D().scale(-1, 1).translate(1, 0)\n", "\n", "def combine(obj):\n", " \"Collapses overlays of Splines to allow transforms of compositions\"\n", " if not isinstance(obj, hv.Overlay): return obj\n", " return hv.Spline((np.vstack([el.data[0] for el in obj.values()]),\n", " np.hstack([el.data[1] for el in obj.values()])))\n", " \n", "def T(spline, transform):\n", " \"Apply a transform to a spline or overlay of splines\"\n", " spline = combine(spline) \n", " result = Path(spline.data[0], codes=spline.data[1]).transformed(transform)\n", " return hv.Spline((result.vertices, result.codes))\n", "\n", "def beside(spline1, spline2, n=1, m=1):\n", " den = float(n + m)\n", " t1 = Affine2D().scale(n / den, 1)\n", " t2 = Affine2D().scale(m / den, 1).translate(n / den, 0)\n", " return combine(T(spline1, t1) * T(spline2, t2))\n", "\n", "def above(spline1, spline2, n=1, m=1):\n", " den = float(n + m)\n", " t1 = Affine2D().scale(1, n / den).translate(0, m / den)\n", " t2 = Affine2D().scale(1, m / den)\n", " return combine(T(spline1, t1) * T(spline2, t2))\n", "\n", "def nonet(p, q, r, s, t, u, v, w, x):\n", " return above(beside(p, beside(q, r), 1, 2),\n", " above(beside(s, beside(t, u), 1, 2),\n", " beside(v, beside(w, x), 1, 2)), 1, 2)\n", "\n", "def quartet(p, q, r, s):\n", " return above(beside(p, q), beside(r, s))\n", "\n", "def side(n,t):\n", " if n == 0: \n", " return hv.Spline(([(np.nan, np.nan)],[1]))\n", " else: \n", " return quartet(side(n-1,t), side(n-1,t), rot(t), t)\n", "\n", "def corner(n,u,t):\n", " if n == 0:\n", " return hv.Spline(([(np.nan, np.nan)],[1]))\n", " else:\n", " return quartet(corner(n-1,u,t), side(n-1,t), rot(side(n-1,t)), u)\n", " \n", "def squarelimit(n,u,t):\n", " return nonet(corner(n,u,t), side(n,t), rot(rot(rot(corner(n,u,t)))),\n", " rot(side(n,t)), u, rot(rot(rot(side(n,t)))), \n", " rot(corner(n,u,t)), rot(rot(side(n,t))), rot(rot(corner(n,u,t))))\n", "\n", "def rot(el): return T(el,rotT)\n", "def rot45(el): return T(el, rot45T)\n", "def flip(el): return T(el, flipT)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fish = hv.Spline((spline, [1,4,4,4]*34)) # Cubic splines\n", "smallfish = flip(rot45(fish))\n", "t = fish * smallfish * rot(rot(rot(smallfish)))\n", "u = smallfish * rot(smallfish) * rot(rot(smallfish)) * rot(rot(rot(smallfish)))\n", "squarelimit(3,u,t).opts(\n", " opts.Spline(width=600, height=600, xaxis=None, yaxis=None))" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 2 }