{ "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 }