File: C:/Users/fred/anaconda3/Lib/site-packages/holoviews/examples/gallery/demos/bokeh/dragon_curve.ipynb
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Dragon curve example from the [L-systems](../../topics/geometry/lsystems.ipynb) topic notebook in ``examples/topics/geometry``.\n",
"\n",
"Most examples work across multiple plotting backends, this example is also available for:\n",
"* [Matplotlib - dragon_curve](../matplotlib/dragon_curve.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",
"hv.extension('bokeh')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## L-system definition"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following class is a simplified version of the approach used in the [L-systems](../../topics/geometry/lsystems.ipynb) notebook, made specifically for plotting the [Dragon Curve](https://en.wikipedia.org/wiki/Dragon_curve)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class DragonCurve(object):\n",
" \"L-system agent that follows rules to generate the Dragon Curve\"\n",
" \n",
" initial ='FX'\n",
" productions = {'X':'X+YF+', 'Y':'-FX-Y'}\n",
" dragon_rules = {'F': lambda t,d,a: t.forward(d),\n",
" 'B': lambda t,d,a: t.back(d),\n",
" '+': lambda t,d,a: t.rotate(-a),\n",
" '-': lambda t,d,a: t.rotate(a),\n",
" 'X':lambda t,d,a: None,\n",
" 'Y':lambda t,d,a: None }\n",
" \n",
" def __init__(self, x=0,y=0, iterations=1):\n",
" self.heading = 0\n",
" self.distance = 5\n",
" self.angle = 90\n",
" self.x, self.y = x,y\n",
" self.trace = [(self.x, self.y)]\n",
" self.process(self.expand(iterations), self.distance, self.angle)\n",
" \n",
" def process(self, instructions, distance, angle):\n",
" for i in instructions: \n",
" self.dragon_rules[i](self, distance, angle)\n",
" \n",
" def expand(self, iterations):\n",
" \"Expand an initial symbol with the given production rules\"\n",
" expansion = self.initial\n",
" \n",
" for i in range(iterations):\n",
" intermediate = \"\"\n",
" for ch in expansion:\n",
" intermediate = intermediate + self.productions.get(ch,ch)\n",
" expansion = intermediate\n",
" return expansion\n",
"\n",
" def forward(self, distance):\n",
" self.x += np.cos(2*np.pi * self.heading/360.0)\n",
" self.y += np.sin(2*np.pi * self.heading/360.0)\n",
" self.trace.append((self.x,self.y))\n",
" \n",
" def rotate(self, angle):\n",
" self.heading += angle\n",
" \n",
" def back(self, distance):\n",
" self.heading += 180\n",
" self.forward(distance)\n",
" self.heading += 180\n",
" \n",
" @property\n",
" def path(self):\n",
" return hv.Path([self.trace])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"hmap = hv.HoloMap(kdims='Iteration')\n",
"for i in range(7,17):\n",
" hmap[i] = DragonCurve(-200, 0, i).path\n",
"\n",
"hmap.opts(\n",
" opts.Path(axiswise=False, color='black', line_width=1, \n",
" title='', xaxis=None, yaxis=None, framewise=True))"
]
}
],
"metadata": {
"language_info": {
"name": "python",
"pygments_lexer": "ipython3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}