{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "#### **Title**: Segments Element\n", "\n", "**Dependencies** Matplotlib\n", "\n", "**Backends** [Bokeh](../bokeh/Segments.ipynb), [Matplotlib](./Segments.ipynb)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import holoviews as hv\n", "from holoviews import dim\n", "hv.extension('matplotlib')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Segments` visualizes a collection of line segments, each starting at a position (`x0`, `y0`) and ending at a position (`x1`, `y1`). To specify it, we hence need four key dimensions, listed in the order (`x0`, `y0`, `x1`, `y1`), and an arbitrary number of value dimensions as attributes to each line segment." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Basic usage" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Declare mock data:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "event = [1, 2]\n", "data = dict(\n", " start=[1999, 2001],\n", " end=[2010, 2020], \n", " start_event = event,\n", " end_event = event\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define the `Segments`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "seg = hv.Segments(data, [hv.Dimension('start', label='Year'), \n", " hv.Dimension('start_event', label='Event'), \n", " 'end', 'end_event'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Display and style the Element:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "seg.opts(color='k', linewidth=10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### A fractal tree" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from functools import reduce\n", "def tree(N):\n", " \"\"\"\n", " Generates fractal tree up to branch N.\n", " \"\"\"\n", " # x0, y0, x1, y1, level\n", " branches = [(0, 0, 0, 1)]\n", " theta = np.pi/5 # branching angle\n", " r = 0.5 # length ratio between successive branches\n", " \n", " # Define function to grow successive branches given previous branch and branching angle\n", " angle = lambda b: np.arctan2(b[3]-b[1], b[2]-b[0])\n", " length = lambda b: np.sqrt((b[3]-b[1])**2 + (b[2]-b[0])**2)\n", " grow = lambda b, ang: (b[2], b[3], \n", " b[2] + r*length(b)*np.cos(angle(b)+ang), \n", " b[3] + r*length(b)*np.sin(angle(b)+ang))\n", " ctr = 1\n", " while ctr<=N:\n", " yield branches\n", " ctr += 1\n", " branches = [[grow(b, theta), grow(b, -theta)] for b in branches]\n", " branches = reduce(lambda i, j: i+j, branches)\n", " \n", "t = reduce(lambda i, j: i+j, tree(14))\n", "data = np.array(t[1:])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Declare a `Segments` Element and add an additional value dimension `c` that we can use for styling:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = hv.Segments(np.c_[data, np.arange(len(data))], ['x', 'y', 'x1', 'y1'], 'c')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, let's style the Element into a digital broccoli painting:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.opts(xaxis=None, yaxis=None, fig_size=150, linewidth=10,\n", " color=np.log10(1+dim('c')), cmap='Greens')" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 4 }