{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "pn.extension('vega')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``Vega`` pane renders Vega-based plots (including those from Altair) inside a panel. It optimizes the plot rendering by using binary serialization for any array data found on the Vega/Altair object, providing huge speedups over the standard JSON serialization employed by Vega natively. Note that to use the ``Vega`` pane in the notebook the Panel extension has to be loaded with 'vega' as an argument to ensure that vega.js is initialized.\n",
    "\n",
    "#### Parameters:\n",
    "\n",
    "For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n",
    "\n",
    "* **``object``** (dict or altair Chart): Either a dictionary containing a Vega or Vega-Lite plot specification, or an Altair Chart\n",
    "\n",
    "___"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``Vega`` pane supports both ``vega`` and ``vega-lite`` specs which may be provided in a raw form (i.e. a dictionary) or by defining an ``altair`` plot.\n",
    "\n",
    "To display ``vega`` and ``vega-lite`` specification simply construct a ``Vega`` pane directly or pass it to ``pn.panel``:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "vegalite = {\n",
    "  \"$schema\": \"https://vega.github.io/schema/vega-lite/v3.json\",\n",
    "  \"data\": {\"url\": \"https://raw.githubusercontent.com/vega/vega/master/docs/data/barley.json\"},\n",
    "  \"mark\": \"bar\",\n",
    "  \"encoding\": {\n",
    "    \"x\": {\"aggregate\": \"sum\", \"field\": \"yield\", \"type\": \"quantitative\"},\n",
    "    \"y\": {\"field\": \"variety\", \"type\": \"nominal\"},\n",
    "    \"color\": {\"field\": \"site\", \"type\": \"nominal\"}\n",
    "  }\n",
    "}\n",
    "vgl_pane = pn.panel(vegalite, height=240)\n",
    "vgl_pane"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Like all other panes, the ``Vega`` pane ``object`` can be updated, either in place and triggering an update:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "vegalite['mark'] = 'area'\n",
    "vgl_pane.param.trigger('object')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "or by replacing the ``object`` entirely:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "vgl_pane.object = {\n",
    "  \"$schema\": \"https://vega.github.io/schema/vega-lite/v3.json\",\n",
    "  \"data\": {\n",
    "    \"url\": \"https://raw.githubusercontent.com/vega/vega/master/docs/data/disasters.csv\"\n",
    "  },\n",
    "  \"width\": 600,\n",
    "  \"height\": 400,\n",
    "  \"transform\": [\n",
    "    {\"filter\": \"datum.Entity !== 'All natural disasters'\"}\n",
    "  ],\n",
    "  \"mark\": {\n",
    "    \"type\": \"circle\",\n",
    "    \"opacity\": 0.8,\n",
    "    \"stroke\": \"black\",\n",
    "    \"strokeWidth\": 1\n",
    "  },\n",
    "  \"encoding\": {\n",
    "    \"x\": {\n",
    "      \"field\": \"Year\",\n",
    "      \"type\": \"ordinal\",\n",
    "      \"axis\": {\"labelAngle\": 0}\n",
    "    },\n",
    "    \"y\": {\"field\": \"Entity\", \"type\": \"nominal\", \"axis\": {\"title\": \"\"}},\n",
    "    \"size\": {\n",
    "      \"field\": \"Deaths\",\n",
    "      \"type\": \"quantitative\",\n",
    "      \"legend\": {\"title\": \"Annual Global Deaths\", \"clipHeight\": 30},\n",
    "      \"scale\": {\"range\": [0, 5000]}\n",
    "    },\n",
    "    \"color\": {\"field\": \"Entity\", \"type\": \"nominal\", \"legend\": None}\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Vega specification can also be responsively sized by declaring the width or height to match the container:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "responsive_spec = dict(vgl_pane.object, width='container')\n",
    "\n",
    "pn.pane.Vega(responsive_spec)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Altair\n",
    "\n",
    "A more convenient way of defining a Vega chart is to declare it using [altair](https://altair-viz.github.io), which provides a declarative API on top of vega-lite. The ``Vega`` pane will automatically render the Vega-Lite spec when passed an Altair chart:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import altair as alt\n",
    "from vega_datasets import data\n",
    "\n",
    "cars = data.cars()\n",
    "\n",
    "chart = alt.Chart(cars).mark_circle(size=60).encode(\n",
    "    x='Horsepower',\n",
    "    y='Miles_per_Gallon',\n",
    "    color='Origin',\n",
    "    tooltip=['Name', 'Origin', 'Horsepower', 'Miles_per_Gallon']\n",
    ").interactive()\n",
    "\n",
    "altair_pane = pn.panel(chart)\n",
    "altair_pane"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Altair chart can also be updated by updating the pane ``object``:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "altair_pane.object = chart.mark_circle(size=100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "All the usual layouts and composition operators that Altair supports can also be rendered:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "chart1 = alt.Chart(data.iris.url).mark_point().encode(\n",
    "    x='petalLength:Q',\n",
    "    y='petalWidth:Q',\n",
    "    color='species:N'\n",
    ").properties(\n",
    "    height=300,\n",
    "    width=300\n",
    ")\n",
    "\n",
    "chart2 = alt.Chart(data.iris.url).mark_bar().encode(\n",
    "    x='count()',\n",
    "    y=alt.Y('petalWidth:Q', bin=alt.Bin(maxbins=30)),\n",
    "    color='species:N'\n",
    ").properties(\n",
    "    height=300,\n",
    "    width=100\n",
    ")\n",
    "\n",
    "pn.panel(chart1 | chart2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Controls\n",
    "\n",
    "The `Vega` pane exposes a number of options which can be changed from both Python and Javascript. Try out the effect of these parameters interactively:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.Row(vgl_pane.controls(jslink=True), vgl_pane)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
