{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"contentcontainer med left\" style=\"margin-left: -50px;\">\n",
    "<dl class=\"dl-horizontal\">\n",
    "  <dt>Title</dt> <dd> RGB Element</dd>\n",
    "  <dt>Dependencies</dt> <dd>Matplotlib</dd>\n",
    "  <dt>Backends</dt> <dd><a href='./RGB.ipynb'>Matplotlib</a></dd> <dd><a href='../bokeh/RGB.ipynb'>Bokeh</a></dd>\n",
    "</dl>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import holoviews as hv\n",
    "hv.extension('matplotlib')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``RGB`` element is a subclass of [``Image``](./Image.ipynb) that supports red, green, blue channels. One of the simplest ways of creating an ``RGB`` element is to load an image file (such as PNG) off disk, using the ``load_image`` classmethod:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hv.RGB.load_image('../assets/penguins.png')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you have ``PIL`` or [``pillow``](https://python-pillow.org) installed, you can also pass in a PIL Image as long as you convert it to Numpy arrays first:\n",
    "\n",
    "```\n",
    "from PIL import Image\n",
    "hv.RGB(np.array(Image.open('../assets/penguins.png')))\n",
    "```\n",
    "\n",
    "This Numpy-based method for constructing an ``RGB`` can be used to stack up arbitrary 2D arrays into a color image:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x,y = np.mgrid[-50:51, -50:51] * 0.1\n",
    "\n",
    "r = 0.5*np.sin(np.pi  +3*x**2+y**2)+0.5\n",
    "g = 0.5*np.sin(x**2+2*y**2)+0.5\n",
    "b = 0.5*np.sin(np.pi/2+x**2+y**2)+0.5\n",
    "\n",
    "hv.RGB(np.dstack([r,g,b]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can see how the RGB object is created from the original channels:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%opts Image (cmap='gray')\n",
    "hv.Image(r,label=\"R\") + hv.Image(g,label=\"G\") + hv.Image(b,label=\"B\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "``RGB`` also supports an optional alpha channel, which will be used as a mask revealing or hiding any ``Element``s it is overlaid on top of:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%opts Image (cmap='gray')\n",
    "mask = 0.5*np.sin(0.2*(x**2+y**2))+0.5\n",
    "rgba = hv.RGB(np.dstack([r,g,b,mask]))\n",
    "\n",
    "bg = hv.Image(0.5*np.cos(x*3)+0.5, label=\"Background\") * hv.VLine(x=0,label=\"Background\")\n",
    "overlay = (bg*rgba).relabel(\"RGBA Overlay\")\n",
    "bg + hv.Image(mask,label=\"Mask\") + overlay"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One additional way to create RGB objects is via the separate [ImaGen](http://ioam.github.io/imagen) library, which creates parameterized streams of images for experiments, simulations, or machine-learning applications.\n",
    "\n",
    "For full documentation and the available style and plot options, use ``hv.help(hv.RGB).``"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
