{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "from matplotlib import cm\n",
    "from matplotlib.figure import Figure\n",
    "import panel as pn\n",
    "\n",
    "pn.extension(sizing_mode=\"stretch_width\", template=\"fast\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Styling Matplotlib for Panel\n",
    "\n",
    "In this example we will show how to style Matplotlib charts with Panel for both the `default` and the `dark` theme.\n",
    "\n",
    "![MatplotlibStyle.gif](https://assets.holoviews.org/panel/thumbnails/gallery/styles/matplotlib-styles.gif)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get or set the theme\n",
    "\n",
    "When we use the Fast templates the `theme` can be found in the `session_args`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_theme():\n",
    "    return pn.state.session_args.get(\"theme\", [b'default'])[0].decode()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "theme=get_theme()\n",
    "theme"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Select a nice accent color\n",
    "\n",
    "Below we create some functionality to *cycle through* a list of nice accent colors. You would probably just set the `accent_color` and `color` for your specific use case."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "nice_accent_colors = [\n",
    "    (\"#00A170\", \"white\"), # Mint\n",
    "    (\"#DAA520\", \"white\"), # Golden Rod\n",
    "    (\"#F08080\", \"white\"), # Light Coral\n",
    "    (\"#4099da\", \"white\"), # Summery Sky\n",
    "    (\"#2F4F4F\", \"white\"), # Dark Slate Grey\n",
    "    (\"#A01346\", \"white\"), # Fast\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_nice_accent_color():\n",
    "    \"\"\"Returns the 'next' nice accent color\"\"\"\n",
    "    if not \"color_index\" in pn.state.cache:\n",
    "        pn.state.cache[\"color_index\"]=0\n",
    "    elif pn.state.cache[\"color_index\"]==len(nice_accent_colors)-1:\n",
    "        pn.state.cache[\"color_index\"]=0\n",
    "    else:\n",
    "        pn.state.cache[\"color_index\"]+=1\n",
    "    return nice_accent_colors[pn.state.cache[\"color_index\"]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "accent_color, color = get_nice_accent_color()\n",
    "pn.pane.Markdown(f\"# Color: {accent_color}\", background=accent_color, height=70, margin=0, style={\"color\": color, \"padding\": \"10px\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Matplotlib\n",
    "\n",
    "There are nearly 30 builtin styles to matplotlib that can be activated with the `plt.style.use` function. The style names are available in the `plt.style.available` list.\n",
    "\n",
    "Let's define a [`Select`](https://panel.holoviz.org/reference/widgets/Select.html) widget to explore the templates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "style=pn.widgets.Select(options=[style for style in sorted(plt.style.available) if not style.startswith(\"_\")])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If the theme is `dark` we will use the `dark_background` style as the default value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if theme==\"dark\":\n",
    "    style.value=\"dark_background\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lets define a plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.arange(-2, 8, .1)\n",
    "y = .1 * x ** 3 - x ** 2 + 3 * x + 2\n",
    "\n",
    "def get_plot(theme=\"default\", accent_color=accent_color, style=style.value):\n",
    "    plt.style.use(\"default\") # Resets to default style. Just in case it was styled to something non-default somewhere else in your app\n",
    "    plt.style.use(style) # changes to the specified style\n",
    "    fig0 = Figure(figsize=(12, 6))\n",
    "    ax0 = fig0.subplots()\n",
    "    ax0.plot(x, y, linewidth=10.0, color=accent_color)\n",
    "    ax0.set_title(f'Matplotlib Style: {style}');\n",
    "    plt.style.use(\"default\") # Resets to default style. Do this if you are styling matplotlib in multiple places in your app.\n",
    "    return fig0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lets [bind](https://panel.holoviz.org/user_guide/APIs.html#reactive-functions) `get_plot` to the `style` widet and lay out the two in a `Column`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "get_plot=pn.bind(get_plot, style=style)\n",
    "matplotlib_component = pn.Column(style,pn.panel(get_plot, height=500, sizing_mode=\"scale_width\"))\n",
    "matplotlib_component.servable()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For more check out the [Matplotlib style sheets reference](https://matplotlib.org/stable/gallery/style_sheets/style_sheets_reference.html) and the alternative themes [dracula theme](https://draculatheme.com/matplotlib) and [gadfly](https://towardsdatascience.com/a-new-plot-theme-for-matplotlib-gadfly-2cffc745ff84)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Style the app template"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.state.template.param.update(accent_base_color=accent_color, header_background=accent_color)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can serve the app via `panel serve MatplotlibStyle.ipynb` and find it at `http://localhost:5006/MatplotlibStyle`. You should add the `--autoreload` flag while developing for *hot reloading*."
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
