diff --git a/README.md b/README.md index 037b7c8405..be2c0a2032 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,9 @@ | Latest dev release | [![Github tag](https://img.shields.io/github/v/tag/holoviz/panel.svg?label=tag&colorB=11ccbb)](https://github.com/holoviz/panel/tags) [![dev-site](https://img.shields.io/website-up-down-green-red/https/pyviz-dev.github.io/panel.svg?label=dev%20website)](https://pyviz-dev.github.io/panel/) | | Latest release | [![Github release](https://img.shields.io/github/release/holoviz/panel.svg?label=tag&colorB=11ccbb)](https://github.com/holoviz/panel/releases) [![PyPI version](https://img.shields.io/pypi/v/panel.svg?colorB=cc77dd)](https://pypi.python.org/pypi/panel) [![panel version](https://img.shields.io/conda/v/pyviz/panel.svg?colorB=4488ff&style=flat)](https://anaconda.org/pyviz/panel) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/panel.svg?label=conda%7Cconda-forge&colorB=4488ff)](https://anaconda.org/conda-forge/panel) [![defaults version](https://img.shields.io/conda/v/anaconda/panel.svg?label=conda%7Cdefaults&style=flat&colorB=4488ff)](https://anaconda.org/anaconda/panel) | | Docs | [![gh-pages](https://img.shields.io/github/last-commit/holoviz/panel/gh-pages.svg)](https://github.com/holoviz/panel/tree/gh-pages) [![site](https://img.shields.io/website-up-down-green-red/https/panel.holoviz.org.svg)](https://panel.holoviz.org) | +| Binder | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/holoviz/panel/binder?urlpath=lab/tree/examples) | | Support | [![Discourse](https://img.shields.io/discourse/status?server=https%3A%2F%2Fdiscourse.holoviz.org)](https://discourse.holoviz.org/) | - ## What is it? Panel provides tools for easily composing widgets, plots, tables, and other viewable objects and controls into custom analysis tools, apps, and dashboards. Panel works with visualizations from [Bokeh](https://bokeh.pydata.org), [Matplotlib](https://matplotlib.org/), [HoloViews](https://holoviews.org), and many other Python plotting libraries, making them instantly viewable either individually or when combined with interactive widgets that control them. Panel works equally well in [Jupyter Notebooks](http://jupyter.org), for creating quick data-exploration tools, or as standalone deployed apps and dashboards, and allows you to easily switch between those contexts as needed. @@ -50,7 +50,7 @@ Panel can be used in a wide range of development environments: ### Editor + Server -You can edit your Panel code as a .py file in any text editor, marking the objects you want to render as `.servable()`, then launch a server with `panel serve my_script.py --show` to open a browser tab showing your app or dashboard and backed by a live Python process. +You can edit your Panel code as a .py file in any text editor, marking the objects you want to render as `.servable()`, then launch a server with `panel serve my_script.py --show` to open a browser tab showing your app or dashboard and backed by a live Python process. If you want the server to automatically reload when you save code changes during development, then you should use `panel serve my_script.py --auto --show`. ### JupyterLab and Classic notebook diff --git a/binder/apt.txt b/binder/apt.txt new file mode 100644 index 0000000000..df634497d3 --- /dev/null +++ b/binder/apt.txt @@ -0,0 +1,2 @@ +libgl1-mesa-dev +xvfb \ No newline at end of file diff --git a/binder/jupyter-panel-apps-server/__init__.py b/binder/jupyter-panel-apps-server/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/binder/jupyter-panel-apps-server/examples-icon.svg b/binder/jupyter-panel-apps-server/examples-icon.svg new file mode 100644 index 0000000000..8be79f5432 --- /dev/null +++ b/binder/jupyter-panel-apps-server/examples-icon.svg @@ -0,0 +1,144 @@ + + \ No newline at end of file diff --git a/binder/jupyter-panel-apps-server/jupyter_panel_apps_server.py b/binder/jupyter-panel-apps-server/jupyter_panel_apps_server.py new file mode 100644 index 0000000000..7406108be9 --- /dev/null +++ b/binder/jupyter-panel-apps-server/jupyter_panel_apps_server.py @@ -0,0 +1,55 @@ +""" +Function to configure serving the panel example apps via jupyter-server-proxy. +""" +import pathlib +from glob import glob + +ICON_PATH = str((pathlib.Path(__file__).parent / "examples-icon.svg").absolute()) + +DONT_SERVE = [ + "examples/gallery/demos/attractors.ipynb", + "examples/gallery/demos/gapminders.ipynb", + "examples/gallery/demos/glaciers.ipynb", + "examples/gallery/demos/nyc_taxi.ipynb", + "examples/gallery/demos/portfolio-optimizer.ipynb", +] + + +def get_apps(): + return [ + app + for app in glob("examples/gallery/**/*.ipynb", recursive=True) + if not app in DONT_SERVE + ] + + +def panel_serve_examples(): + """Returns the jupyter-server-proxy configuration for serving the example notebooks as Panel + apps. + + Returns: + Dict: The configuration dictionary + """ + apps = get_apps() + # See: + # https://jupyter-server-proxy.readthedocs.io/en/latest/server-process.html + # https://github.com/holoviz/jupyter-panel-proxy/blob/master/panel_server/__init__.py + return { + "command": [ + "panel", + "serve", + *apps, + "--allow-websocket-origin=*", + "--port", + "{port}", + "--prefix", + "{base_url}panel", + ], + "absolute_url": True, + "timeout": 360, + "launcher_entry": { + "enabled": True, + "title": "Apps", + "icon_path": ICON_PATH, + }, + } diff --git a/binder/jupyter-panel-apps-server/setup.py b/binder/jupyter-panel-apps-server/setup.py new file mode 100644 index 0000000000..06ad936bb3 --- /dev/null +++ b/binder/jupyter-panel-apps-server/setup.py @@ -0,0 +1,14 @@ +"""This setup.py will install a package that configures the jupyter-server-proxy to +panel serve the example notebooks.""" +import setuptools + +setuptools.setup( + name="jupyter-panel-examples-server", + py_modules=["jupyter_panel_apps_server"], + entry_points={ + "jupyter_serverproxy_servers": [ + "panel = jupyter_panel_apps_server:panel_serve_examples", + ] + }, + install_requires=["jupyter-server-proxy", "panel"], +) diff --git a/binder/jupyter-voila-docs-server/__init__.py b/binder/jupyter-voila-docs-server/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/binder/jupyter-voila-docs-server/examples-icon.svg b/binder/jupyter-voila-docs-server/examples-icon.svg new file mode 100644 index 0000000000..8be79f5432 --- /dev/null +++ b/binder/jupyter-voila-docs-server/examples-icon.svg @@ -0,0 +1,144 @@ + + \ No newline at end of file diff --git a/binder/jupyter-voila-docs-server/jupyter_voila_docs_server.py b/binder/jupyter-voila-docs-server/jupyter_voila_docs_server.py new file mode 100644 index 0000000000..ed1e1fccd5 --- /dev/null +++ b/binder/jupyter-voila-docs-server/jupyter_voila_docs_server.py @@ -0,0 +1,56 @@ +""" +Function to configure serving the panel example apps via jupyter-server-proxy. +""" +import pathlib +from glob import glob + +ICON_PATH = str((pathlib.Path(__file__).parent / "examples-icon.svg").absolute()) + +DONT_SERVE = [ + "examples/gallery/demos/attractors.ipynb", + "examples/gallery/demos/gapminders.ipynb", + "examples/gallery/demos/glaciers.ipynb", + "examples/gallery/demos/nyc_taxi.ipynb", + "examples/gallery/demos/portfolio-optimizer.ipynb", +] + + +def get_apps(): + return [ + app + for app in glob("examples/gallery/**/*.ipynb", recursive=True) + if not app in DONT_SERVE + ] + + +def voila_serve_examples(): + """Returns the jupyter-server-proxy configuration for serving the example notebooks as Voila + Apps. + + Returns: + Dict: The configuration dictionary + """ + # See: + # https://jupyter-server-proxy.readthedocs.io/en/latest/server-process.html + # https://github.com/holoviz/jupyter-panel-proxy/blob/master/panel_server/__init__.py + return { + "command": [ + "voila", # voila examples/gallery/dynamic --strip_sources=False --base_url + "examples", + "--no-browser", + "--strip_sources=False", + "--port", + "{port}", + "--base_url", + "{base_url}docs/", + "--VoilaConfiguration.file_whitelist", + "'*.*'", + ], + "absolute_url": True, + "timeout": 360, + "launcher_entry": { + "enabled": True, + "title": "Docs", + "icon_path": ICON_PATH, + }, + } diff --git a/binder/jupyter-voila-docs-server/setup.py b/binder/jupyter-voila-docs-server/setup.py new file mode 100644 index 0000000000..2282c7a0ec --- /dev/null +++ b/binder/jupyter-voila-docs-server/setup.py @@ -0,0 +1,14 @@ +"""This setup.py will install a package that configures the jupyter-server-proxy to +panel serve the example notebooks.""" +import setuptools + +setuptools.setup( + name="jupyter-voila-docs-server", + py_modules=["jupyter_voila_docs_server"], + entry_points={ + "jupyter_serverproxy_servers": [ + "docs = jupyter_voila_docs_server:voila_serve_examples", + ] + }, + install_requires=["jupyter-server-proxy", "voila"], +) diff --git a/binder/postBuild b/binder/postBuild new file mode 100644 index 0000000000..8983f943d8 --- /dev/null +++ b/binder/postBuild @@ -0,0 +1,9 @@ +pip install voila>=0.2.10 -U +conda install -c conda-forge code-server +code-server --install-extension ms-python.python +SERVICE_URL=https://open-vsx.org/vscode/gallery ITEM_URL=https://open-vsx.org/vscode/item code-server --install-extension wesbos.theme-cobalt2 +SERVICE_URL=https://open-vsx.org/vscode/gallery ITEM_URL=https://open-vsx.org/vscode/item code-server --install-extension RandomFractalsInc.vscode-data-preview +SERVICE_URL=https://open-vsx.org/vscode/gallery ITEM_URL=https://open-vsx.org/vscode/item code-server --install-extension RandomFractalsInc.geo-data-viewer +SERVICE_URL=https://open-vsx.org/vscode/gallery ITEM_URL=https://open-vsx.org/vscode/item code-server --install-extension ritwickdey.liveserver +bokeh sampledata +panel build panel \ No newline at end of file diff --git a/binder/requirements.txt b/binder/requirements.txt new file mode 100644 index 0000000000..cbd0780066 --- /dev/null +++ b/binder/requirements.txt @@ -0,0 +1,10 @@ +-e .['all'] +-e binder/jupyter-panel-apps-server/. +-e binder/jupyter-voila-docs-server/. +pydeck +pyecharts +idom +xlsxwriter +pyarrow +jupyter_bokeh +jupyter-vscode-proxy diff --git a/binder/start b/binder/start new file mode 100644 index 0000000000..cf080bc09c --- /dev/null +++ b/binder/start @@ -0,0 +1,14 @@ +#!/bin/bash +export BOKEH_ALLOW_WS_ORIGIN=hub.gke2.mybinder.org +echo '' >> panel/template/base.py +echo 'BasicTemplate.param.site_url.default="./"' >> panel/template/base.py +export DISPLAY=:99.0 +export PYVISTA_OFF_SCREEN=true +export PYVISTA_USE_IPYVTK=true +export PYVISTA_PLOT_THEME=document +which Xvfb +Xvfb :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & +sleep 3 +jupyter trust examples/**/*.ipynb +jupyter trust examples/**/**/*.ipynb +exec "$@" \ No newline at end of file diff --git a/examples/gallery/apis/stocks_altair.ipynb b/examples/gallery/apis/stocks_altair.ipynb index 88cc8f790c..08c40ce608 100644 --- a/examples/gallery/apis/stocks_altair.ipynb +++ b/examples/gallery/apis/stocks_altair.ipynb @@ -12,7 +12,7 @@ "\n", "from bokeh.sampledata import stocks\n", "\n", - "pn.extension('vega')" + "pn.extension('vega', sizing_mode=\"stretch_width\")" ] }, { @@ -41,7 +41,7 @@ "\n", "def get_plot(ticker, window_size):\n", " df = get_df(ticker, window_size)\n", - " return alt.Chart(df).mark_line().encode(x='date', y='close')" + " return alt.Chart(df).mark_line().encode(x='date', y='close').properties(width=\"container\", height=\"container\",)" ] }, { @@ -62,7 +62,7 @@ "interact = pn.interact(get_plot, ticker=tickers, window_size=(1, 21, 5))\n", "\n", "pn.Row(\n", - " pn.Column(title, interact[0]),\n", + " pn.Column(title, interact[0], sizing_mode=\"fixed\", width=300),\n", " interact[1]\n", ")" ] @@ -88,7 +88,7 @@ "@pn.depends(ticker.param.value, window.param.value)\n", "def get_plot(ticker, window_size):\n", " df = get_df(ticker, window_size)\n", - " return alt.Chart(df).mark_line().encode(x='date', y='close')\n", + " return alt.Chart(df).mark_line().encode(x='date', y='close').properties(width=\"container\", height=\"container\",)\n", "\n", "pn.Row(\n", " pn.Column(title, ticker, window),\n", @@ -121,10 +121,10 @@ " \n", " @param.depends('ticker', 'window_size')\n", " def plot(self):\n", - " return get_plot(self.ticker, self.window_size)\n", + " return get_plot(self.ticker, self.window_size).properties(width=\"container\", height=\"container\",)\n", " \n", "explorer = StockExplorer()\n", - "pn.Row(explorer.param, explorer.plot)" + "pn.Row(pn.Column(explorer.param, sizing_mode=\"stretch_width\", width=300), explorer.plot)" ] }, { @@ -146,7 +146,7 @@ "window = pn.widgets.IntSlider(name='Window', value=6, start=1, end=21)\n", "\n", "row = pn.Row(\n", - " pn.Column(title, ticker, window),\n", + " pn.Column(title, ticker, window, sizing_mode=\"fixed\", width=300),\n", " get_plot(ticker.options[0], window.value)\n", ")\n", "\n", @@ -156,7 +156,7 @@ "ticker.param.watch(update, 'value')\n", "window.param.watch(update, 'value')\n", "\n", - "row.servable()" + "row" ] }, { @@ -165,6 +165,30 @@ "source": [ "In practice, different projects will be suited to one or the other of these APIs, and most of Panel's functionality should be available from any API." ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Let's wrap it into nice template that can be served via `panel serve stocks_altair.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "description=\"\"\"This example compares **four different implementations of the same app** using \n", + "\n", + "- the quick and easy ``interact`` function, \n", + "- more flexible *reactive* functions,\n", + "- declarative *Param-based* code, and \n", + "- explicit *callbacks*.\"\"\"\n", + "pn.template.FastListTemplate(site=\"Panel\", title=\"Altair Stock Explorer\", sidebar=[ticker, window], main=[description, row[1]]).servable();" + ] } ], "metadata": { @@ -174,5 +198,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/apis/stocks_hvplot.ipynb b/examples/gallery/apis/stocks_hvplot.ipynb index cd80f3bbc7..3e4c51e103 100644 --- a/examples/gallery/apis/stocks_hvplot.ipynb +++ b/examples/gallery/apis/stocks_hvplot.ipynb @@ -12,7 +12,7 @@ "\n", "from bokeh.sampledata import stocks\n", "\n", - "pn.extension()" + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { @@ -41,7 +41,7 @@ "\n", "def get_plot(ticker, window_size):\n", " df = get_df(ticker, window_size)\n", - " return df.hvplot.line('date', 'close', grid=True)" + " return df.hvplot.line('date', 'close', grid=True, responsive=True, height=300)" ] }, { @@ -62,7 +62,7 @@ "interact = pn.interact(get_plot, ticker=tickers, window_size=(1, 21, 5))\n", "\n", "pn.Row(\n", - " pn.Column(title, interact[0]),\n", + " pn.Column(title, interact[0], sizing_mode=\"fixed\", width=300),\n", " interact[1]\n", ")" ] @@ -88,10 +88,10 @@ "@pn.depends(ticker, window)\n", "def get_plot(ticker, window_size):\n", " df = get_df(ticker, window_size)\n", - " return df.hvplot.line('date', 'close', grid=True)\n", + " return df.hvplot.line('date', 'close', grid=True, responsive=True, height=300)\n", "\n", "pn.Row(\n", - " pn.Column(title, ticker, window),\n", + " pn.Column(title, ticker, window, sizing_mode=\"fixed\", width=300),\n", " get_plot\n", ")" ] @@ -123,7 +123,7 @@ " return get_plot(self.ticker, self.window_size)\n", " \n", "explorer = StockExplorer(name='Stock Explorer hvPlot')\n", - "pn.Row(explorer.param, explorer.plot)" + "pn.Row(pn.Column(explorer.param, sizing_mode=\"fixed\", width=300), explorer.plot)" ] }, { @@ -145,7 +145,7 @@ "window = pn.widgets.IntSlider(name='Window', value=6, start=1, end=21)\n", "\n", "row = pn.Row(\n", - " pn.Column(title, ticker, window),\n", + " pn.Column(title, ticker, window, sizing_mode=\"fixed\", width=300),\n", " get_plot(ticker.options[0], window.value)\n", ")\n", "\n", @@ -155,7 +155,7 @@ "ticker.param.watch(update, 'value')\n", "window.param.watch(update, 'value')\n", "\n", - "row.servable()" + "row" ] }, { @@ -164,6 +164,30 @@ "source": [ "In practice, different projects will be suited to one or the other of these APIs, and most of Panel's functionality should be available from any API." ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve stocks_hvplot.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "description=\"\"\"This example compares **four different implementations of the same app** using \n", + "\n", + "- the quick and easy ``interact`` function, \n", + "- more flexible *reactive* functions,\n", + "- declarative *Param-based* code, and \n", + "- explicit *callbacks*.\"\"\"\n", + "pn.template.FastListTemplate(site=\"Panel\", title=\"hvPlot Stock Explorer\", sidebar=[ticker, window], main=[description, row[1]]).servable();" + ] } ], "metadata": { @@ -173,5 +197,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/apis/stocks_mpl.ipynb b/examples/gallery/apis/stocks_matplotlib.ipynb similarity index 85% rename from examples/gallery/apis/stocks_mpl.ipynb rename to examples/gallery/apis/stocks_matplotlib.ipynb index 3ff8b27a58..fcacbb2cbf 100644 --- a/examples/gallery/apis/stocks_mpl.ipynb +++ b/examples/gallery/apis/stocks_matplotlib.ipynb @@ -14,7 +14,7 @@ "\n", "from bokeh.sampledata import stocks\n", "\n", - "pn.extension()" + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { @@ -68,7 +68,7 @@ "interact = pn.interact(get_plot, ticker=tickers, window_size=(1, 21, 5))\n", "\n", "pn.Row(\n", - " pn.Column(title, interact[0]),\n", + " pn.Column(title, interact[0], sizing_mode=\"fixed\", width=300),\n", " interact[1]\n", ")" ] @@ -101,7 +101,7 @@ " return fig\n", "\n", "pn.Row(\n", - " pn.Column(title, ticker, window),\n", + " pn.Column(title, ticker, window, sizing_mode=\"fixed\", width=300),\n", " get_plot\n", ")" ] @@ -134,7 +134,7 @@ " return get_plot(self.ticker, self.window_size)\n", " \n", "explorer = StockExplorer()\n", - "pn.Row(explorer.param, explorer.plot)" + "pn.Row(pn.Column(explorer.param, sizing_mode=\"fixed\", width=300), explorer.plot)" ] }, { @@ -156,8 +156,8 @@ "window = pn.widgets.IntSlider(name='Window', value=6, start=1, end=21)\n", "\n", "row = pn.Row(\n", - " pn.Column(title, ticker, window),\n", - " get_plot(ticker.options[0], window.value)\n", + " pn.Column(title, ticker, window, sizing_mode=\"fixed\", width=300),\n", + " get_plot(ticker.options[0], window.value),\n", ")\n", "\n", "def update(event):\n", @@ -166,7 +166,7 @@ "ticker.param.watch(update, 'value')\n", "window.param.watch(update, 'value')\n", "\n", - "row.servable()" + "row" ] }, { @@ -175,6 +175,30 @@ "source": [ "In practice, different projects will be suited to one or the other of these APIs, and most of Panel's functionality should be available from any API." ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve stocks_matplotlib.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "description=\"\"\"This example compares **four different implementations of the same app** using \n", + "\n", + "- the quick and easy ``interact`` function, \n", + "- more flexible *reactive* functions,\n", + "- declarative *Param-based* code, and \n", + "- explicit *callbacks*.\"\"\"\n", + "pn.template.FastListTemplate(site=\"Panel\", title=\"Matplotlib Stock Explorer\", sidebar=[ticker, window], main=[description, row[1]]).servable();" + ] } ], "metadata": { @@ -184,5 +208,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/apis/stocks_plotly.ipynb b/examples/gallery/apis/stocks_plotly.ipynb index 91e5991083..2a27f4ed65 100644 --- a/examples/gallery/apis/stocks_plotly.ipynb +++ b/examples/gallery/apis/stocks_plotly.ipynb @@ -12,7 +12,7 @@ "\n", "from bokeh.sampledata import stocks\n", "\n", - "pn.extension('plotly')" + "pn.extension('plotly', sizing_mode=\"stretch_width\")" ] }, { @@ -60,7 +60,7 @@ "interact = pn.interact(get_plot, ticker=tickers, window_size=(1, 21, 5))\n", "\n", "pn.Row(\n", - " pn.Column(title, interact[0]),\n", + " pn.Column(title, interact[0], sizing_mode=\"fixed\", width=300),\n", " interact[1]\n", ")" ] @@ -89,7 +89,7 @@ " return go.Scatter(x=df.date, y=df.close)\n", "\n", "pn.Row(\n", - " pn.Column(title, ticker, window),\n", + " pn.Column(title, ticker, window, sizing_mode=\"fixed\", width=300),\n", " get_plot\n", ")" ] @@ -122,7 +122,7 @@ " return get_plot(self.ticker, self.window_size)\n", " \n", "explorer = StockExplorer()\n", - "pn.Row(explorer.param, explorer.plot)" + "pn.Row(pn.Column(explorer.param, sizing_mode=\"fixed\", width=300), explorer.plot)" ] }, { @@ -144,7 +144,7 @@ "window = pn.widgets.IntSlider(name='Window', value=6, start=1, end=21)\n", "\n", "row = pn.Row(\n", - " pn.Column(title, ticker, window),\n", + " pn.Column(title, ticker, window, sizing_mode=\"fixed\", width=300),\n", " get_plot(ticker.options[0], window.value)\n", ")\n", "\n", @@ -154,7 +154,7 @@ "ticker.param.watch(update, 'value')\n", "window.param.watch(update, 'value')\n", "\n", - "row.servable()" + "row" ] }, { @@ -163,6 +163,30 @@ "source": [ "In practice, different projects will be suited to one or the other of these APIs, and most of Panel's functionality should be available from any API." ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve stocks_plotly.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "description=\"\"\"This example compares **four different implementations of the same app** using \n", + "\n", + "- the quick and easy ``interact`` function, \n", + "- more flexible *reactive* functions,\n", + "- declarative *Param-based* code, and \n", + "- explicit *callbacks*.\"\"\"\n", + "pn.template.FastListTemplate(site=\"Panel\", title=\"Plotly Stock Explorer\", sidebar=[ticker, window], main=[description, row[1]]).servable();" + ] } ], "metadata": { @@ -172,5 +196,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/VTKInteractive.ipynb b/examples/gallery/demos/VTKInteractive.ipynb index 3496577fa2..0ba9f00f70 100644 --- a/examples/gallery/demos/VTKInteractive.ipynb +++ b/examples/gallery/demos/VTKInteractive.ipynb @@ -9,7 +9,7 @@ "import panel as pn\n", "import pyvista as pv\n", "from pyvista import examples\n", - "pn.extension('vtk')" + "pn.extension('vtk', sizing_mode=\"stretch_width\")" ] }, { @@ -364,7 +364,17 @@ "metadata": {}, "outputs": [], "source": [ - "pn.Row(vtkpan,pn.Column(actor_selection,pn.Tabs(('Scene controller', pn.Column(scene_props, light_props)), ('Actor properties',actor_props))), sizing_mode=\"stretch_both\").servable()" + "settings = pn.Column(actor_selection,pn.Tabs(('Scene controller', pn.Column(scene_props, light_props)), ('Actor properties',actor_props)))\n", + "pn.Row(vtkpan, settings)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve VTKInteractive.ipynb`" ] }, { @@ -372,26 +382,16 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "description=\"This example demonstrates the use of **VTK and pyvista** to display a *scene*\"\n", + "pn.template.FastListTemplate(site=\"Panel\", title=\"VTK Interactive\", sidebar=[settings], main=[description, vtkpan]).servable();" + ] } ], "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.2" + "pygments_lexer": "ipython3" } }, "nbformat": 4, diff --git a/examples/gallery/demos/VTKSlicer.ipynb b/examples/gallery/demos/VTKSlicer.ipynb index 6f462414a4..a33f7c94cd 100644 --- a/examples/gallery/demos/VTKSlicer.ipynb +++ b/examples/gallery/demos/VTKSlicer.ipynb @@ -292,22 +292,9 @@ } ], "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.5" + "pygments_lexer": "ipython3" } }, "nbformat": 4, diff --git a/examples/gallery/demos/VTKWarp.ipynb b/examples/gallery/demos/VTKWarp.ipynb index 6d5fa2db93..6dde53e5c6 100644 --- a/examples/gallery/demos/VTKWarp.ipynb +++ b/examples/gallery/demos/VTKWarp.ipynb @@ -9,14 +9,14 @@ "import panel as pn\n", "import numpy as np\n", "import pyvista as pv\n", - "pn.extension('vtk')" + "pn.extension('vtk', sizing_mode=\"stretch_width\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Temporal function inpired from http://holoviews.org/user_guide/Live_Data.html" + "Temporal function inspired from http://holoviews.org/user_guide/Live_Data.html" ] }, { @@ -71,7 +71,7 @@ " 'viewUp': [-0.41067028045654297, -0.40083757042884827, 0.8189500570297241]\n", "}\n", "vtkpan = pn.panel(pl.ren_win, orientation_widget=True, sizing_mode='stretch_both', camera=camera)\n", - "frame = pn.widgets.Player(value=0, start=0, end=50, interval=100, loop_policy=\"reflect\")\n", + "frame = pn.widgets.Player(value=0, start=0, end=50, interval=100, loop_policy=\"reflect\", height=100)\n", "\n", "@pn.depends(frame=frame.param.value)\n", "def update_3d_warp(frame):\n", @@ -83,7 +83,17 @@ " mesh_warped.points = mesh_ref.warp_by_scalar(factor=0.5).points\n", " vtkpan.synchronize()\n", "\n", - "pn.Column(frame, vtkpan, update_3d_warp, width=600, height=600).servable()" + "component = pn.Column(frame, vtkpan, update_3d_warp, height=600)\n", + "component" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve VTKWarp.ipynb`" ] }, { @@ -91,26 +101,15 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"VTK Warp\", main=[\"This app demonstrates the use of `VTK`\", component]).servable();" + ] } ], "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.5" + "pygments_lexer": "ipython3" } }, "nbformat": 4, diff --git a/examples/gallery/demos/attractors.ipynb b/examples/gallery/demos/attractors.ipynb index f5dc7546fa..6a1201f198 100644 --- a/examples/gallery/demos/attractors.ipynb +++ b/examples/gallery/demos/attractors.ipynb @@ -44,5 +44,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/gapminders.ipynb b/examples/gallery/demos/gapminders.ipynb index cde2c46116..7740b49790 100644 --- a/examples/gallery/demos/gapminders.ipynb +++ b/examples/gallery/demos/gapminders.ipynb @@ -44,5 +44,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/glaciers.ipynb b/examples/gallery/demos/glaciers.ipynb index 1d1c509365..48499c3bb1 100644 --- a/examples/gallery/demos/glaciers.ipynb +++ b/examples/gallery/demos/glaciers.ipynb @@ -44,5 +44,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/nyc_taxi.ipynb b/examples/gallery/demos/nyc_taxi.ipynb index 51cd94c78e..5ff29e0dd0 100644 --- a/examples/gallery/demos/nyc_taxi.ipynb +++ b/examples/gallery/demos/nyc_taxi.ipynb @@ -44,5 +44,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/dynamic/dynamic_plot_layout.ipynb b/examples/gallery/dynamic/dynamic_plot_layout.ipynb index 06b22cc184..bb694f2103 100644 --- a/examples/gallery/dynamic/dynamic_plot_layout.ipynb +++ b/examples/gallery/dynamic/dynamic_plot_layout.ipynb @@ -10,14 +10,14 @@ "import numpy as np\n", "import holoviews as hv\n", "\n", - "pn.extension()" + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This example demonstrates how to dynamically add and remove plots from a layout (in this case a Column) using the ``pop`` and ``append`` methods (requires a live Pytbon server):" + "This example demonstrates how to dynamically add and remove plots from a layout (in this case a Column) using the ``pop`` and ``append`` methods (requires a live Python server):" ] }, { @@ -28,7 +28,7 @@ "source": [ "slider = pn.widgets.IntSlider(name='N', start=0, end=5)\n", "\n", - "column = pn.Column('This column will be populated with N Plots')\n", + "column = pn.Column('This column will be populated with N Plots', sizing_mode=\"stretch_width\")\n", "\n", "def set_plots(event):\n", " nplots = event.new-event.old\n", @@ -36,12 +36,33 @@ " if nplots < 0:\n", " column.pop(len(column)-1)\n", " elif nplots > 0:\n", - " column.append(hv.Scatter(np.random.randn(1000, 2)))\n", + " column.append(hv.Scatter(np.random.randn(1000, 2)).opts(responsive=True, height=300))\n", + " \n", + " column[0]=f'This column will be populated with {event.new} Plots'\n", " \n", "slider.param.watch(set_plots, 'value')\n", "slider.value = 1\n", "\n", - "pn.Row(slider, column).servable()" + "pn.Row(pn.Column(slider, sizing_mode=\"fixed\", width=300), column, sizing_mode=\"stretch_width\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve dynamic_plot_layout.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "description = \"This example demonstrates **how to dynamically add and remove plots** from a layout (in this case a Column) using the ``pop`` and ``append`` methods.\"\n", + "pn.template.FastListTemplate(site=\"Panel\", title=\"Dynamic Plot Layout\", sidebar=[slider], main=[description, column]).servable();" ] } ], @@ -52,5 +73,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/dynamic/dynamic_timeseries_image_analysis.ipynb b/examples/gallery/dynamic/dynamic_timeseries_image_analysis.ipynb index 9effe4536e..c4b6fb6af2 100644 --- a/examples/gallery/dynamic/dynamic_timeseries_image_analysis.ipynb +++ b/examples/gallery/dynamic/dynamic_timeseries_image_analysis.ipynb @@ -31,7 +31,7 @@ "import panel as pn\n", "\n", "hv.extension('bokeh')\n", - "pn.config.sizing_mode=\"stretch_width\"" + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { @@ -194,7 +194,7 @@ " ),\n", " ),\n", ")\n", - "app.servable()" + "app" ] }, { @@ -212,6 +212,29 @@ "\n", "The `plots = ((plot_a + plot_b + plot_c) * vline_dmap).cols(1)` line is essential for making the app fast and responsive. Initially the `plot_a + plot_b + plot_c` where regenerated together with the `vline` everytime the `frame_slider.value` was changed. That made the app slower because it had to recalculate and retransfer much more data." ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve dynamic_timeseries_image_analysis.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", title=\"Dynamic Timeseries Image Analysis\", \n", + " main=[\n", + " \"The purpose of this app is to illustrate how you can **make an interactive and responsive tool for timeseries analysis of images** by combining a Panel `IntSlider`, some `@pn.depends` annotated plotting functions and a few HoloViews `DynamicMap`.\",\n", + " *app[2:]]\n", + ").servable();" + ] } ], "metadata": { diff --git a/examples/gallery/dynamic/dynamic_ui.ipynb b/examples/gallery/dynamic/dynamic_ui.ipynb index e7588efe1e..3f809c2bb6 100644 --- a/examples/gallery/dynamic/dynamic_ui.ipynb +++ b/examples/gallery/dynamic/dynamic_ui.ipynb @@ -15,7 +15,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "This example demonstrates how to dynamically replace widgets in a layout to create responsive user interfaces (requires a live Python server)." + "This example demonstrates **how to dynamically replace widgets in a layout** to create responsive user interfaces (requires a live Python server)." ] }, { @@ -52,7 +52,25 @@ "pn.Column(\n", " '## Dynamically generated user interfaces',\n", " row\n", - ").servable()" + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve dynamic_ui.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Dynamic UI\", main=[\"This example demonstrates **how to dynamically replace widgets in a layout** to create responsive user interfaces\", row]).servable();" ] } ], @@ -63,5 +81,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/dynamic/dynamic_widget_values.ipynb b/examples/gallery/dynamic/dynamic_widget_values.ipynb index 0cd09e6fe2..ea5aeca04c 100644 --- a/examples/gallery/dynamic/dynamic_widget_values.ipynb +++ b/examples/gallery/dynamic/dynamic_widget_values.ipynb @@ -8,14 +8,14 @@ "source": [ "import panel as pn\n", "\n", - "pn.extension()" + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This example demonstrates how to control one set of widgets with another set of widgets, such as when the value of one widget changes the allowable values of another. Here the ``title_widget`` and ``value_widget`` control the title and ranges of the other set of widgets, respectively." + "This example demonstrates **how to control one set of widgets with another set of widgets**, such as when the value of one widget changes the allowable values of another. Here the ``title_widget`` and ``value_widget`` control the title and ranges of the other set of widgets, respectively." ] }, { @@ -55,7 +55,25 @@ "\n", "value_widget.param.watch(update_values, 'value')\n", "\n", - "pn.Row(meta_widgets, widgets).servable()" + "pn.Row(meta_widgets, widgets)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve dynamic_widget_values.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Dynamic Widget Labels and Values\", sidebar=[meta_widgets], main=[\"This example demonstrates **how to control one set of widgets with another set of widgets**.\", widgets]).servable();" ] } ], @@ -66,5 +84,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/external/DataTable.ipynb b/examples/gallery/external/DataTable.ipynb index 58a734fd45..42b69d261d 100644 --- a/examples/gallery/external/DataTable.ipynb +++ b/examples/gallery/external/DataTable.ipynb @@ -99,25 +99,30 @@ "table_with_export_buttons = pn.pane.HTML(html+script, sizing_mode='stretch_width', margin=(10,5,35,5))\n", "table_with_export_buttons" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Let's wrap the above into a nice app that can be run via `panel serve DataTable.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel Gallery\", title=\"DataTable\", main=[\"This example demonstrates **how to use the [jQuery DataTable extension](https://datatables.net/) with Panel** and use it to render a pandas DataFrame.\", table_with_export_buttons]).servable();" + ] } ], "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.6" + "pygments_lexer": "ipython3" } }, "nbformat": 4, diff --git a/examples/gallery/external/Folium.ipynb b/examples/gallery/external/Folium.ipynb index 36862c0cc2..aec9ac58a4 100644 --- a/examples/gallery/external/Folium.ipynb +++ b/examples/gallery/external/Folium.ipynb @@ -35,7 +35,7 @@ "outputs": [], "source": [ "def get_map(lat=20.5936832, long=78.962883, zoom_start=5):\n", - " return fm.Map(location=[lat,long], zoom_start=zoom_start)\n", + " return fm.Map(location=[lat,long], zoom_start=zoom_start, width='100%', height=800)\n", "\n", "map = get_map()\n", "\n", @@ -151,11 +151,11 @@ " def __init__(self, **params):\n", " super().__init__(**params)\n", " self.map = get_map()\n", - " self.html_pane = pn.pane.HTML(sizing_mode=\"stretch_width\", min_height=600) \n", + " self.html_pane = pn.pane.HTML(sizing_mode=\"stretch_width\", height=830, margin=0) \n", " self.view = pn.Column(\n", " self.param.points_count,\n", " self.html_pane,\n", - " sizing_mode=\"stretch_width\", min_height=600,\n", + " sizing_mode=\"stretch_width\", height=875\n", " )\n", " self._update_map()\n", "\n", @@ -170,25 +170,30 @@ "app = PanelFoliumMap()\n", "app.view.embed()" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve Folium.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Folium\", main=[\"This app demonstrates **how to use Folium with Panel**.\", app.view]).servable();" + ] } ], "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.5" + "pygments_lexer": "ipython3" } }, "nbformat": 4, diff --git a/examples/gallery/external/deck.gl.ipynb b/examples/gallery/external/deck.gl.ipynb index f05a94b389..10140efb48 100644 --- a/examples/gallery/external/deck.gl.ipynb +++ b/examples/gallery/external/deck.gl.ipynb @@ -15,11 +15,11 @@ "source": [ "import panel as pn\n", "\n", - "js_files = {'deck': 'https://unpkg.com/deck.gl@^6.0.0/deckgl.min.js',\n", - " 'mapboxgl': 'https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'}\n", - "css_files = ['https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css']\n", + "js_files = {'deck': 'https://cdn.jsdelivr.net/npm/deck.gl@8.1.12/dist.min.js',\n", + " 'mapboxgl': 'https://api.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.js'}\n", + "css_files = ['https://api.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.css']\n", "\n", - "pn.extension(js_files=js_files, css_files=css_files)" + "pn.extension(js_files=js_files, css_files=css_files, sizing_mode=\"stretch_width\")" ] }, { @@ -57,7 +57,7 @@ "outputs": [], "source": [ "html = \"\"\"\n", - "
\n", + "\n", "\n", "\n", "\"\"\" % cities\n", - "deckgl = pn.pane.HTML(html, height=500, width=800)" + "deckgl = pn.pane.HTML(html, height=500)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Next we can declare a Panel widget and define a ``jslink`` to update the deck.gl plot whenever the widget state changes. The example is adapted from http://deck.gl/showcases/gallery/viewport-transition but replaces D3 widgets with Panel-based widgets." + "Next we can declare a Panel widget and define a ``jslink`` to update the deck.gl plot whenever the widget state changes. The example is adapted from https://deck.gl/gallery/viewport-transition but replaces D3 widgets with Panel-based widgets." ] }, { @@ -99,19 +102,38 @@ "update_city = \"\"\"\n", "var d = CITIES[source.active];\n", "deckgl.setProps({\n", - " viewState: {\n", - " longitude: d.longitude,\n", - " latitude: d.latitude,\n", - " zoom: 10,\n", - " transitionInterpolator: new deck.FlyToInterpolator(),\n", - " transitionDuration: 5000\n", - " }\n", + " initialViewState: {\n", + " longitude: d.longitude,\n", + " latitude: d.latitude,\n", + " zoom: 10,\n", + " transitionInterpolator: new deck.FlyToInterpolator({speed: 1.5}),\n", + " transitionDuration: 'auto'\n", + " }\n", "});\n", "\"\"\"\n", "\n", "widget.jslink(deckgl, code={'active': update_city});\n", "\n", - "pn.Column(widget, deckgl)" + "component = pn.Column(widget, deckgl)\n", + "component" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve deckgl.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Deck.gl\", main=[\"This app **demonstrates loading deck.gl JSS and CSS components** and then linking it to Panel widgets.\", component]).servable();" ] } ], @@ -122,5 +144,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/layout/distribution_tabs.ipynb b/examples/gallery/layout/distribution_tabs.ipynb index 15851c87e0..b2f6b73160 100644 --- a/examples/gallery/layout/distribution_tabs.ipynb +++ b/examples/gallery/layout/distribution_tabs.ipynb @@ -10,7 +10,7 @@ "import numpy as np\n", "import holoviews as hv\n", "\n", - "pn.extension()" + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { @@ -27,13 +27,13 @@ "outputs": [], "source": [ "distributions = {\n", - " 'normal': np.random.normal,\n", - " 'uniform': np.random.uniform,\n", - " 'log-normal': np.random.lognormal,\n", - " 'exponential': np.random.exponential\n", + " 'NORMAL': np.random.normal,\n", + " 'UNIFORM': np.random.uniform,\n", + " 'LOG-NORMAL': np.random.lognormal,\n", + " 'EXPONENTIAL': np.random.exponential\n", "}\n", "\n", - "checkboxes = pn.widgets.ToggleGroup(options=distributions, behavior='radio')\n", + "checkboxes = pn.widgets.ToggleGroup(options=distributions, behavior='radio', button_type=\"success\")\n", "slider = pn.widgets.IntSlider(name='Number of observations', value=500, start=0, end=2000)\n", "\n", "@pn.depends(checkboxes.param.value, slider.param.value)\n", @@ -41,12 +41,31 @@ " values = hv.Dataset(distribution(size=n), 'values')\n", " return pn.Tabs(\n", " ('Plot', values.hist(adjoin=False).opts(\n", - " responsive=True, max_height=500, padding=0.1)),\n", + " responsive=True, max_height=500, padding=0.1, color=\"#00aa41\")),\n", " ('Summary', values.dframe().describe().T),\n", " ('Table', hv.Table(values)),\n", " )\n", "\n", - "pn.Row(pn.Column('### Distribution Type', checkboxes, slider), tabs).servable()" + "selections = pn.Column('### Distribution Type', checkboxes, slider)\n", + "pn.Row(selections, tabs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve distribution_tabs.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Distribution Tabs\", main=[\"This example demonstrates **how to plot several different types of outputs in a Tab**.\", selections, tabs]).servable();" ] } ], @@ -57,5 +76,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/layout/dynamic_tabs.ipynb b/examples/gallery/layout/dynamic_tabs.ipynb index fe8a74c6c8..e1f879bdde 100644 --- a/examples/gallery/layout/dynamic_tabs.ipynb +++ b/examples/gallery/layout/dynamic_tabs.ipynb @@ -8,7 +8,7 @@ "source": [ "import panel as pn\n", "\n", - "pn.extension('deckgl', 'plotly', 'vega')" + "pn.extension('deckgl', 'echarts', 'plotly', 'vega')" ] }, { @@ -96,7 +96,7 @@ "p.axis.visible=False\n", "p.grid.grid_line_color = None\n", "\n", - "bokeh_pane = pn.pane.Bokeh(p)" + "bokeh_pane = pn.pane.Bokeh(p, sizing_mode=\"stretch_both\", max_width=1300)" ] }, { @@ -145,6 +145,41 @@ "deck_gl = pn.pane.DeckGL(json_spec, mapbox_api_key=MAPBOX_KEY, sizing_mode='stretch_width', height=800)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Echarts" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "echart = {\n", + " 'title': {\n", + " 'text': 'ECharts entry example'\n", + " },\n", + " 'tooltip': {},\n", + " 'legend': {\n", + " 'data':['Sales']\n", + " },\n", + " 'xAxis': {\n", + " 'data': [\"shirt\",\"cardign\",\"chiffon shirt\",\"pants\",\"heels\",\"socks\"]\n", + " },\n", + " 'yAxis': {},\n", + " 'series': [{\n", + " 'name': 'Sales',\n", + " 'type': 'bar',\n", + " 'data': [5, 20, 36, 10, 10, 20]\n", + " }],\n", + " }\n", + " \n", + "echarts_pane = pn.pane.ECharts(echart, height=800, width=800)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -169,12 +204,12 @@ " return pd.DataFrame(dict(y=ys), index=xs).hvplot(responsive=True)\n", "\n", "dmap = hv.DynamicMap(sine, kdims=['frequency', 'amplitude', 'function']).redim.range(\n", - " frequency=(0.1, 10), amplitude=(1, 10)).redim.values(function=['sin', 'cos', 'tan'])\n", + " frequency=(0.1, 10), amplitude=(1, 10)).redim.values(function=['sin', 'cos', 'tan']).opts(height=800, line_width=4)\n", "\n", "hv_panel = pn.pane.HoloViews(dmap, widgets={\n", " 'amplitude': pn.widgets.LiteralInput(value=1., type=(float, int)),\n", " 'function': pn.widgets.RadioButtonGroup,\n", - " 'frequency': {'value': 5}\n", + " 'frequency': {'value': 5}, \n", "}, center=True, sizing_mode='stretch_both').layout" ] }, @@ -208,7 +243,7 @@ "strm = ax0.streamplot(X, Y, U, V, color=U, linewidth=2, cmap=plt.cm.autumn)\n", "fig0.colorbar(strm.lines)\n", "\n", - "mpl_pane = pn.pane.Matplotlib(fig0, dpi=144)" + "mpl_pane = pn.pane.Matplotlib(fig0, dpi=144, height=800)" ] }, { @@ -256,15 +291,35 @@ "metadata": {}, "outputs": [], "source": [ - "pn.Tabs(\n", + "tabs = pn.Tabs(\n", " ('Altair', altair_pane),\n", " ('Bokeh', bokeh_pane),\n", " ('deck.GL', deck_gl),\n", + " ('Echarts', echarts_pane),\n", " ('HoloViews', hv_panel),\n", " ('Matplotlib', mpl_pane),\n", " ('Plotly', plotly_pane),\n", " dynamic=True\n", - ").servable()" + ")\n", + "tabs" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve dynamic_tabs.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Dynamic Tabs\", main=[\"This example demonstrates **how to efficiently render a number of complex components in ``Tabs``** by using the `dynamic` parameter.\", tabs]).servable();" ] } ], diff --git a/examples/gallery/layout/plot_with_columns.ipynb b/examples/gallery/layout/plot_with_columns.ipynb index 449f162d10..40dd201446 100644 --- a/examples/gallery/layout/plot_with_columns.ipynb +++ b/examples/gallery/layout/plot_with_columns.ipynb @@ -11,14 +11,14 @@ "\n", "from bokeh.sampledata.autompg import autompg_clean\n", "\n", - "pn.extension()" + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This example demonstrates how to combine multiple columns of widgets into layout an overall layout." + "This example demonstrates how to combine multiple columns of widgets into an overall layout." ] }, { @@ -40,16 +40,38 @@ "def plot(x, y, color, facet):\n", " cmap = 'Category10' if color in cat else 'viridis'\n", " return autompg_clean.hvplot.scatter(\n", - " x, y, color=color or 'darkblue', by=facet, subplots=True, padding=0.1,\n", - " cmap=cmap, responsive=True, min_height=300\n", + " x, y, color=color or 'green', by=facet, subplots=True, padding=0.1,\n", + " cmap=cmap, responsive=True, min_height=500, size=100\n", " )\n", "\n", + "settings = pn.Row(pn.WidgetBox(x, y, color, facet))\n", "pn.Column(\n", " '### Auto MPG Explorer', \n", + " settings,\n", " plot,\n", - " pn.Row(pn.WidgetBox(x, y, color), pn.WidgetBox(facet)),\n", " width_policy='max'\n", - ").servable()" + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve dynamic_widget_values.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", title=\"Auto MPG Explorer\", sidebar=[settings], \n", + " main=[\"This example demonstrates **how to combine multiple columns of components into an overall layout**.\", plot]\n", + ").servable();" ] } ], @@ -60,5 +82,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/links/bokeh_property_editor.ipynb b/examples/gallery/links/bokeh_property_editor.ipynb index a194c4d009..7ff5886877 100644 --- a/examples/gallery/links/bokeh_property_editor.ipynb +++ b/examples/gallery/links/bokeh_property_editor.ipynb @@ -26,11 +26,18 @@ "outputs": [], "source": [ "from bokeh.core.enums import LineDash, LineCap, MarkerType, NamedColor\n", - "from bokeh.models.plots import Model, _list_attr_splat\n", - "\n", - "def meta_widgets(model):\n", - " tabs = pn.Tabs(width=500)\n", - " widgets = get_widgets(model)\n", + "from bokeh.models.plots import Model, _list_attr_splat" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def meta_widgets(model, width=500):\n", + " tabs = pn.Tabs(width=width)\n", + " widgets = get_widgets(model, width=width-25)\n", " if widgets:\n", " tabs.append((type(model).__name__, widgets))\n", " for p, v in model.properties_with_values().items():\n", @@ -54,8 +61,15 @@ " return None\n", " elif not len(tabs) > 1:\n", " return tabs[0]\n", - " return tabs\n", - " \n", + " return tabs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "def get_widgets(model, skip_none=True, **kwargs):\n", " widgets = []\n", " for p, v in model.properties_with_values().items():\n", @@ -75,19 +89,23 @@ " w = pn.widgets.Select(options=list(NamedColor), **ps)\n", " else:\n", " w = pn.widgets.ColorPicker(**ps)\n", + " elif p==\"width\":\n", + " w = pn.widgets.IntSlider(start=400, end=800, **ps)\n", + " elif p in [\"inner_width\", \"outer_width\"]:\n", + " w = pn.widgets.IntSlider(start=0, end=20, **ps)\n", " elif p.endswith('width'):\n", " w = pn.widgets.FloatSlider(start=0, end=20, **ps)\n", " elif 'marker' in p:\n", - " w = pn.widgets.Select(name=p, options=list(MarkerType), value=v)\n", + " w = pn.widgets.Select(options=list(MarkerType), **ps)\n", " elif p.endswith('cap'):\n", - " w = pn.widgets.Select(name=p, options=list(LineCap), value=v)\n", + " w = pn.widgets.Select(options=list(LineCap), **ps)\n", " elif p == 'size':\n", " w = pn.widgets.FloatSlider(start=0, end=20, **ps)\n", " elif p.endswith('text') or p.endswith('label'):\n", " w = pn.widgets.TextInput(**ps)\n", " elif p.endswith('dash'):\n", " patterns = list(LineDash)\n", - " w = pn.widgets.Select(name=p, options=patterns, value=v or patterns[0])\n", + " w = pn.widgets.Select(options=patterns, value=v or patterns[0], **kwargs)\n", " else:\n", " continue\n", " w.jslink(model, value=p)\n", @@ -114,7 +132,29 @@ "xs = np.linspace(0, 10)\n", "r = p.scatter(xs, np.sin(xs))\n", "\n", - "pn.Row(p, meta_widgets(p))" + "editor=pn.Row(meta_widgets(p), p)\n", + "editor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve bokeh_property_editor.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", title=\"Bokeh Property Editor\", \n", + " main=[pn.pane.Markdown(\"The Bokeh Property Editor enables you to fine tune the Bokeh plot.\", sizing_mode=\"stretch_width\"), editor]\n", + ").servable();" ] } ], @@ -125,5 +165,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/links/deck_gl_json_editor.ipynb b/examples/gallery/links/deck_gl_json_editor.ipynb index 3c4189b5c8..b84b42eace 100644 --- a/examples/gallery/links/deck_gl_json_editor.ipynb +++ b/examples/gallery/links/deck_gl_json_editor.ipynb @@ -16,7 +16,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "This example demonstrates how to link a JSON editor to a DeckGL pane to enable live editing of a plot:" + "This example demonstrates how to `jslink` a JSON editor to a DeckGL pane to enable super fast, live editing of a plot:" ] }, { @@ -63,27 +63,39 @@ "view_editor.jscallback(args={'deck_gl': deck_gl}, value=\"deck_gl.initialViewState = JSON.parse(cb_obj.code)\")\n", "layer_editor.jscallback(args={'deck_gl': deck_gl}, value=\"deck_gl.layers = [JSON.parse(cb_obj.code)]\")\n", "\n", - "pn.Row(pn.Column(view_editor, layer_editor), deck_gl)" + "editor = pn.Row(pn.Column(view_editor, layer_editor), deck_gl)\n", + "editor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve deck_gl_json_editor.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", title=\"Deck.gl Json Editor\", \n", + " main=[\n", + " pn.pane.Markdown(\"This example demonstrates two JSON editors `jslink`ed to a DeckGL pane to enable super fast, live editing of a plot:\", sizing_mode=\"stretch_width\"),\n", + " editor\n", + " ]\n", + ").servable();" ] } ], "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.5" + "pygments_lexer": "ipython3" } }, "nbformat": 4, diff --git a/examples/gallery/links/holoviews_glyph_link.ipynb b/examples/gallery/links/holoviews_glyph_link.ipynb index 689c164d3c..73445322df 100644 --- a/examples/gallery/links/holoviews_glyph_link.ipynb +++ b/examples/gallery/links/holoviews_glyph_link.ipynb @@ -41,7 +41,7 @@ "\n", "# Declare a Points object and apply some options\n", "points = hv.Points(np.random.randn(200, 2)).options(\n", - " padding=0.1, width=500, height=500, line_color='black')\n", + " padding=0.1, height=500, line_color='black', responsive=True)\n", "\n", "# Link the widget value parameter to the property on the glyph\n", "alpha_widget.jslink(points, value='glyph.fill_alpha')\n", @@ -49,7 +49,32 @@ "color_widget.jslink(points, value='glyph.fill_color')\n", "marker_widget.jslink(points, value='glyph.marker')\n", "\n", - "pn.Row(points, pn.Column(alpha_widget, color_widget, marker_widget, size_widget))" + "editor=pn.Row(pn.Column(alpha_widget, color_widget, marker_widget, size_widget), points)\n", + "editor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve holoviews_glyph_link.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", title=\"Holoviews Property Links\", \n", + " main=[\n", + " pn.pane.Markdown(\"HoloViews-generated Bokeh plots can be **`jslinked`** to widgets that control their properties. \\n\\nThis allows you to **export static HTML files that allow end-user customization** of appearance.\", sizing_mode=\"stretch_width\"), \n", + " editor\n", + " ]\n", + ").servable();" ] } ], @@ -60,5 +85,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/links/plotly_link.ipynb b/examples/gallery/links/plotly_link.ipynb index 86fea915e7..377bfb8abe 100644 --- a/examples/gallery/links/plotly_link.ipynb +++ b/examples/gallery/links/plotly_link.ipynb @@ -31,7 +31,7 @@ "fig = dict(data=contour, layout=layout)\n", "plotly_pane = pn.pane.Plotly(fig, width=600, height=500)\n", "\n", - "buttons = pn.widgets.RadioButtonGroup(value='Medium', options=['Low', 'Medium', 'High'])\n", + "buttons = pn.widgets.RadioButtonGroup(value='Medium', options=['Low', 'Medium', 'High'], button_type=\"success\")\n", "\n", "range_callback = \"\"\"\n", "var ncontours = [2, 5, 10]\n", @@ -41,7 +41,32 @@ "\n", "buttons.jslink(plotly_pane, code={'active': range_callback})\n", "\n", - "pn.Column(buttons, plotly_pane)" + "component=pn.Column(buttons, plotly_pane)\n", + "component" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve plotly_link.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", title=\"Plotly JS Links\", main_max_width=\"650px\",\n", + " main=[\n", + " pn.pane.Markdown(\"Since Plotly plots are represented as simple JavaScript objects, we can easily define a **JS callback** to modify the data and trigger an update in a plot. \\n\\nThis allows you to **export your app as a static HTML file**.\", sizing_mode=\"stretch_width\"), \n", + " component\n", + " ]\n", + ").servable();" ] } ], @@ -52,5 +77,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/links/vega_heatmap_link.ipynb b/examples/gallery/links/vega_heatmap_link.ipynb index 31dd4a3d6a..44f74e276d 100644 --- a/examples/gallery/links/vega_heatmap_link.ipynb +++ b/examples/gallery/links/vega_heatmap_link.ipynb @@ -7,7 +7,7 @@ "outputs": [], "source": [ "import panel as pn\n", - "pn.extension('vega')" + "pn.extension('vega', sizing_mode=\"stretch_width\")" ] }, { @@ -33,7 +33,7 @@ " ]}\n", " }],\n", " \"mark\": \"rect\",\n", - " \"width\": 600,\n", + " \"width\": \"container\",\n", " \"height\": 400,\n", " \"encoding\": {\n", " \"x\": {\n", @@ -56,32 +56,92 @@ " \"stroke\": \"transparent\"\n", " }\n", " }\n", - "}\n", - "\n", - "vega = pn.pane.Vega(imdb, width=750, height=425)\n", - "\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "vega = pn.pane.Vega(imdb, height=425)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "# Declare range slider to adjust the color limits\n", "color_lims = pn.widgets.RangeSlider(name='Color limits', start=0, end=125, value=(0, 40), step=1)\n", "color_lims.jslink(vega, code={'value': \"\"\"\n", "target.data.encoding.color.scale = {domain: source.value};\n", "target.properties.data.change.emit()\n", - "\"\"\"})\n", - "\n", + "\"\"\"});" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "# Declare slider to control the number of bins along the x-axis\n", "imdb_bins = pn.widgets.IntSlider(name='IMDB Ratings Bins', start=0, end=125, value=60, step=25)\n", "imdb_bins.jslink(vega, code={'value': \"\"\"\n", "target.data.encoding.x.bin.maxbins = source.value;\n", "target.properties.data.change.emit()\n", - "\"\"\"})\n", - "\n", + "\"\"\"});" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "# Declare slider to control the number of bins along the y-axis\n", "tomato_bins = pn.widgets.IntSlider(name='Rotten Tomato Ratings Bins', start=0, end=125, value=40, step=25)\n", "tomato_bins.jslink(vega, code={'value': \"\"\"\n", "target.data.encoding.y.bin.maxbins = source.value;\n", "target.properties.data.change.emit()\n", - "\"\"\"})\n", + "\"\"\"});" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.Row(vega, pn.Column(color_lims, imdb_bins, tomato_bins, sizing_mode=\"fixed\", width=400))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", "\n", - "pn.Row(vega, pn.Column(color_lims, imdb_bins, tomato_bins))" + "Lets wrap it into nice template that can be served via `panel serve vega_heatmap_link.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", title=\"Vega Heatmap w. JS Links\", \n", + " sidebar=[color_lims, imdb_bins, tomato_bins],\n", + " main=[\n", + " pn.pane.Markdown(\"This example demonstrates how to link Panel widgets to a **Vega pane** by editing the Vega spec using **js callbacks** and triggering updates in the plot.\"), \n", + " vega\n", + " ]\n", + ").servable();" ] } ], @@ -92,5 +152,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/param/action_button.ipynb b/examples/gallery/param/action_button.ipynb index 1fcf0ad33e..cbc076e60f 100644 --- a/examples/gallery/param/action_button.ipynb +++ b/examples/gallery/param/action_button.ipynb @@ -9,14 +9,16 @@ "import param\n", "import panel as pn\n", "\n", - "pn.extension()" + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This example demonstrates how to use ``param.Action`` to trigger an update in a method that depends on that parameter. Actions can trigger any function, but if we simply want to trigger a method that depends on that action we can define a small ``lambda`` function that triggers the parameter explicitly." + "## param.Action Example\n", + "\n", + "This example demonstrates how to use ``param.Action`` to trigger an update in a method that depends on that parameter. Actions can trigger any function, but if we simply want to trigger a method that depends on that action, then we can define a small ``lambda`` function that triggers the parameter explicitly." ] }, { @@ -30,22 +32,47 @@ " Demonstrates how to use param.Action to trigger an update.\n", " \"\"\"\n", "\n", - " number = param.Number(default=0)\n", - " \n", " action = param.Action(lambda x: x.param.trigger('action'), label='Click here!')\n", + " \n", + " number = param.Integer(default=0)\n", " \n", " @param.depends('action')\n", " def get_number(self):\n", + " self.number += 1\n", " return self.number\n", " \n", "action_example = ActionExample()\n", - "pn.Column(\n", - " '# param.Action Example',\n", + "component = pn.Column(\n", " pn.Row(\n", - " pn.Column(pn.panel(action_example.param, show_labels=False, show_name=False, margin=0),\n", - " 'Click the button to trigger an update in the output.'),\n", - " pn.WidgetBox(action_example.get_number, width=300))\n", - ").servable()" + " pn.Column(pn.panel(action_example, show_name=False, margin=0, widgets={\"action\": {\"button_type\": \"primary\"}, \"number\": {\"disabled\": True}}),\n", + " '**Click the button** to trigger an update in the output.'),\n", + " pn.panel(action_example.get_number, width=300), max_width=600)\n", + ")\n", + "component" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve action_button.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", title=\"param.Action Example\", \n", + " main=[\n", + " \"This example demonstrates **how to use ``param.Action`` to trigger an update** in a method that depends on that parameter.\\n\\nActions can trigger any function, but if we simply want to trigger a method that depends on that action, then we can define a small ``lambda`` function that triggers the parameter explicitly.\",\n", + " component,\n", + " ]\n", + ").servable();" ] } ], @@ -56,5 +83,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/param/deck_gl_global_power_plants.ipynb b/examples/gallery/param/deck_gl_global_power_plants.ipynb index f5b08319d0..c1591ef299 100644 --- a/examples/gallery/param/deck_gl_global_power_plants.ipynb +++ b/examples/gallery/param/deck_gl_global_power_plants.ipynb @@ -8,7 +8,7 @@ "source": [ "import panel as pn\n", "import pydeck as pdk\n", - "pn.extension('deckgl')" + "pn.extension('deckgl', sizing_mode=\"stretch_width\")" ] }, { @@ -195,25 +195,34 @@ " self.pane.param.trigger('object')\n", " \n", " def view(self):\n", - " return pn.Row(pn.Column(self.param, self._info), self.pane)\n", + " return pn.Row(pn.Column(self.param, pn.panel(self._info, height=200)), self.pane)\n", "\n", - "app = GlobalPowerPlantDatabaseApp()\n", - "app.view().servable()" + "component = GlobalPowerPlantDatabaseApp()\n", + "component.view()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Credits\n", + "## App\n", "\n", - "The DeckGl pane and this reference example was contributed by\n", - "\n", - "- [Marc Skov Madsen](https://datamodelsanalytics.com)\n", - "\n", - "and improved by\n", - "\n", - "- Philipp Rüdiger" + "Lets wrap it into nice template that can be served via `panel serve deck_gl_global_power_plants.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Global Power Plants\", \n", + " sidebar=[pn.Param(component, show_name=False)], \n", + " main=[\n", + " \"The data is from the [Global Power Plant Database](http://datasets.wri.org/dataset/540dcf46-f287-47ac-985d-269b04bea4c6/resource/c240ed2e-1190-4d7e-b1da-c66b72e08858/download/globalpowerplantdatabasev120).\",\n", + " pn.Column(component.pane, pn.panel(component._info, height=100))\n", + " ]\n", + " ).servable();" ] } ], diff --git a/examples/gallery/param/download_upload_csv.ipynb b/examples/gallery/param/download_upload_csv.ipynb index 0cbaec5856..d396cb5fcd 100644 --- a/examples/gallery/param/download_upload_csv.ipynb +++ b/examples/gallery/param/download_upload_csv.ipynb @@ -8,9 +8,7 @@ "\n", "In Panel the FileDownload widget allows downloading a file generated on the server the app is running on while the `FileInput` widget allows uploading a file. In this example we demonstrate a pipeline of two little apps one which allows generating a sample data CSV file and one which allows uploading this file and displays it as a Plotly plot. \n", "\n", - "For more details on how to use these components see [`FileInput`](../../reference/widgets/FileInput.ipynb) and [`FileDownload`](../../reference/widgets/FileDownload.ipynb) reference guides.\n", - "\n", - "**Authors**: [Marc Skov Madsen](https://datamodelsanalytics.com/) and Philipp Rudiger" + "For more details on how to use these components see [`FileInput`](../../reference/widgets/FileInput.ipynb) and [`FileDownload`](../../reference/widgets/FileDownload.ipynb) reference guides." ] }, { @@ -29,7 +27,7 @@ "\n", "import plotly.express as px\n", "\n", - "pn.extension('plotly')" + "pn.extension('plotly', sizing_mode=\"stretch_width\")" ] }, { @@ -65,17 +63,18 @@ " sample_df = param.DataFrame(doc=\"\"\"\n", " The current dataframe of samples.\"\"\")\n", " \n", - " generate_sample_df = param.Action(lambda self: self.update_sample_df(), doc=\"\"\"\n", + " generate_sample_df = param.Action(lambda self: self.update_sample_df(), label=\"Generate Data\", doc=\"\"\"\n", " An action callback which will update the sample_df.\"\"\")\n", " \n", - " file_name = param.String(default=\"sample_data.csv\", doc=\"\"\"\n", + " file_name = param.String(default=\"data.csv\", doc=\"\"\"\n", " The filename to save to.\"\"\")\n", " \n", " def __init__(self, **params):\n", " super().__init__(**params)\n", " self.update_sample_df()\n", - " self.download = pn.widgets.FileDownload(filename=self.file_name,\n", - " callback=self._download_callback)\n", + " self.download = pn.widgets.FileDownload(name=\"Download Data\", filename=self.file_name, callback=self._download_callback, button_type=\"primary\")\n", + " self.table = pn.widgets.Tabulator(self.sample_df.head(10), layout='fit_data_stretch', theme='site', height=360)\n", + " \n", "\n", " @pn.depends('file_name', watch=True)\n", " def _update_filename(self):\n", @@ -103,7 +102,11 @@ " \"FubId\": [random.choice(self.fub_ids) for _ in range(0,self.samples)],\n", " }\n", " self.sample_df = pd.DataFrame(sample_data) \n", - " \n", + " \n", + " @pn.depends(\"sample_df\", watch=True)\n", + " def _update_table(self):\n", + " if hasattr(self, \"table\"):\n", + " self.table.value = self.sample_df.head(10)\n", " \n", " def save_sample_data(self, event=None):\n", " if not self.sample_df is None:\n", @@ -111,15 +114,18 @@ " \n", " def view(self):\n", " return pn.Column(\n", + " \"## Generate and Download Data\",\n", " pn.Row(\n", - " pn.Param(self, parameters=['samples', 'voltage_bounds', 'time_bounds']),\n", - " pn.Column(self.param.generate_sample_df, self.param.file_name, self.download, align='end')\n", + " pn.Param(self, parameters=['samples', 'voltage_bounds', 'time_bounds', 'generate_sample_df'], show_name=False, widgets={\"generate_sample_df\": {\"button_type\": \"primary\"}}),\n", + " pn.Column(self.param.file_name, self.download, align='end', margin=(10,5,5,5)),\n", " ),\n", - " self.param.sample_df,\n", + " \"**Sample data (10 Rows)**\",\n", + " self.table,\n", " )\n", "\n", "sample_data_app = SampleDataApp()\n", - "sample_data_app.view()" + "sample_data_app_view = sample_data_app.view()\n", + "sample_data_app_view" ] }, { @@ -150,8 +156,11 @@ " @pn.depends(\"file_input.value\", watch=True)\n", " def _parse_file_input(self):\n", " value = self.file_input.value\n", - " string_io = io.StringIO(value.decode(\"utf8\"))\n", - " self.data = pd.read_csv(string_io, parse_dates=[\"Time\"])\n", + " if value:\n", + " string_io = io.StringIO(value.decode(\"utf8\"))\n", + " self.data = pd.read_csv(string_io, parse_dates=[\"Time\"])\n", + " else:\n", + " print(\"error\")\n", "\n", " @pn.depends('data', watch=True)\n", " def get_plot(self):\n", @@ -169,13 +178,15 @@ " \n", " def view(self):\n", " return pn.Column(\n", + " \"## Upload and Plot Data\",\n", " self.file_input,\n", " self.plotly_pane,\n", " )\n", " \n", "voltage_app = VoltageApp()\n", "\n", - "voltage_app.view()" + "voltage_app_view = voltage_app.view()\n", + "voltage_app_view" ] }, { @@ -191,25 +202,39 @@ "metadata": {}, "outputs": [], "source": [ - "sample_data_app = SampleDataApp()\n", - "voltage_app = VoltageApp()\n", - "\n", "description = \"\"\"\n", - "This application demonstrates the ability to download a file using the FileDownload widget \n", - "and uploading a file using the FileInput widget.\n", + "This application demonstrates the ability to **download** a file using the `FileDownload` widget \n", + "and **upload** a file using the `FileInput` widget.\n", "\n", - "Try filtering the data on the left, download the file by clicking on the Download button\n", + "Try filtering the data, download the file by clicking on the Download button\n", "and then plot it on the right by uploading that same file.\n", "\"\"\"\n", "\n", - "pn.Row(\n", - " sample_data_app.view(),\n", - " pn.Column(\n", - " description,\n", - " voltage_app.view(),\n", - " ),\n", + "component = pn.Column(\n", + " description,\n", + " sample_data_app_view,\n", + " voltage_app_view,\n", " sizing_mode='stretch_both'\n", - ").servable()" + ")\n", + "component" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve download_upload_csv.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Download and Upload CSV File\", main=[ description, sample_data_app_view, voltage_app_view,]).servable();" ] } ], diff --git a/examples/gallery/param/loading_indicator.ipynb b/examples/gallery/param/loading_indicator.ipynb index 1a799df1db..14d3fbca7e 100644 --- a/examples/gallery/param/loading_indicator.ipynb +++ b/examples/gallery/param/loading_indicator.ipynb @@ -12,24 +12,21 @@ "import numpy as np\n", "import holoviews.plotting.bokeh\n", "\n", - "pn.extension(loading_spinner='dots', loading_color='#00aa41')\n", + "pn.extension(loading_spinner='dots', loading_color='#00aa41', sizing_mode=\"stretch_width\")\n", "hv.extension('bokeh')" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pn.panel(hv.Curve([1, 2, 3], label='ABC').opts(fontsize={'title': '18pt'}))" - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Every pane, widget and layout provides the `loading` parameter. When set to `True` a spinner will overlay the panel and indicate that the panel is currently loading. When you set `loading` to false the spinner is removed. Using the `pn.extension` or by setting the equivalent parameters on `pn.config` we can select between different visual styles and colors for the loading indicator.\n", + "Every pane, widget and layout provides the **`loading` parameter**. When set to `True` a spinner will overlay the panel and indicate that the panel is currently loading. When you set `loading` to false the spinner is removed. \n", + "\n", + "Using the `pn.extension` or by setting the equivalent parameters on `pn.config` we can select between different visual styles and colors for the loading indicator.\n", + "\n", + "```python\n", + "pn.extension(loading_spinner='dots', loading_color='#00aa41')\n", + "```\n", "\n", "We can enable the loading indicator for reactive functions annotated with `depends` or `bind` globally using:\n", "\n", @@ -51,14 +48,50 @@ "metadata": {}, "outputs": [], "source": [ - "button = pn.widgets.Button(name=\"Update\", button_type=\"primary\")\n", + "button = pn.widgets.Button(name=\"UPDATE\", button_type=\"primary\")\n", "\n", "def random_plot(event):\n", - " if event: time.sleep(10)\n", + " if event: time.sleep(2)\n", " return hv.Points(np.random.rand(100, 2)).opts(\n", - " width=400, height=400, size=5)\n", + " width=400, height=400, size=8, color=\"green\")\n", "\n", - "pn.Column(button, pn.panel(pn.bind(random_plot, button), loading_indicator=True)).servable()" + "component = pn.Column(button, pn.panel(pn.bind(random_plot, button), loading_indicator=True))\n", + "component" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve download_upload_csv.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "description = \"\"\"\n", + "Every pane, widget and layout provides the **`loading` parameter**. When set to `True` a spinner will overlay the panel and indicate that the panel is currently loading. When you set `loading` to false the spinner is removed. \n", + "\n", + "Using the `pn.extension` or by setting the equivalent parameters on `pn.config` we can select between different visual styles and colors for the loading indicator.\n", + "\n", + "```python\n", + "pn.extension(loading_spinner='dots', loading_color='#00aa41')\n", + "```\n", + "\n", + "We can enable the loading indicator for reactive functions annotated with `depends` or `bind` globally using:\n", + "\n", + "```python\n", + "pn.param.ParamMethod.loading_indicator = True\n", + "```\n", + "\"\"\"\n", + "pn.template.FastListTemplate(\n", + " site=\"Panel\", title=\"Loading Indicator\", \n", + " main=[ description, component]).servable();" ] } ], diff --git a/examples/gallery/param/param_subobjects.ipynb b/examples/gallery/param/param_subobjects.ipynb index 47d3663858..2406c941c4 100644 --- a/examples/gallery/param/param_subobjects.ipynb +++ b/examples/gallery/param/param_subobjects.ipynb @@ -46,7 +46,7 @@ " if 'style' not in params:\n", " params['style'] = Style(name='Style')\n", " super(Shape, self).__init__(**params)\n", - " self.figure = figure(x_range=(-1, 1), y_range=(-1, 1), width=400, height=400)\n", + " self.figure = figure(x_range=(-1, 1), y_range=(-1, 1), sizing_mode=\"stretch_width\", height=400)\n", " self.renderer = self.figure.line(*self._get_coords())\n", " self._update_style()\n", "\n", @@ -119,17 +119,39 @@ " return '## %s (radius=%.1f)' % (type(self.shape).__name__, self.shape.radius)\n", " \n", " def panel(self):\n", - " return pn.Column(self.title, self.view)\n", + " return pn.Column(self.title, self.view, sizing_mode=\"stretch_width\")\n", " \n", " \n", "# Instantiate and display ShapeViewer\n", "viewer = ShapeViewer()\n", "subpanel = pn.Column()\n", "\n", - "pn.Row(\n", - " pn.Column(pn.Param(viewer.param, expand_layout=subpanel), subpanel),\n", + "component = pn.Row(\n", + " pn.Column(pn.Param(viewer.param, expand_layout=subpanel, name=\"Shape Settings\"), subpanel),\n", " viewer.panel(),\n", - ").servable()" + ")\n", + "component" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve param_subobjects.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Param Sub Objects\", main=[ \n", + " pn.pane.Markdown(\"This example demonstrates how to use the `Param` library to express **nested hierarchies of classes** whose parameters can be edited in Panel or any other GUI.\", sizing_mode=\"stretch_width\"), \n", + " component,\n", + "]).servable();" ] } ], @@ -140,5 +162,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/param/precedence.ipynb b/examples/gallery/param/precedence.ipynb index 265c5fc667..ecb8897cd7 100644 --- a/examples/gallery/param/precedence.ipynb +++ b/examples/gallery/param/precedence.ipynb @@ -74,8 +74,15 @@ " self.param.z.precedence = self.z_precedence \n", " self.dummy_app.display_threshold = self.dummy_app_display_threshold\n", "\n", - "precedence_model = Precedence()\n", - "\n", + "precedence_model = Precedence()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "# Bulding the control app as a Param pane too.\n", "control_app = pn.Param(\n", " precedence_model.param,\n", @@ -86,8 +93,15 @@ " \"z_precedence\": {\"background\": \"#00c0d9\"},\n", " },\n", " show_name=False\n", - ")\n", - "\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "# Building the complete interactive example.\n", "interactive_precedence_app = pn.Column(\n", " \"## Precedence Example\",\n", @@ -97,7 +111,7 @@ " pn.Column(\"**Dummy app**\", precedence_model.dummy_app)\n", " )\n", ")\n", - "interactive_precedence_app.servable()" + "interactive_precedence_app" ] }, { @@ -105,7 +119,13 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Parameter Precedence\", main_max_width=\"700px\",\n", + " main=[\n", + " pn.pane.Markdown(\"This example demonstrates how to order and hide widgets by means of the **``precedence`` and ``display_threshold``** parameter attributes.\", sizing_mode=\"stretch_width\"),\n", + " interactive_precedence_app,\n", + " ]).servable();" + ] } ], "metadata": { diff --git a/examples/gallery/param/reactive_plots.ipynb b/examples/gallery/param/reactive_plots.ipynb index 1b7da32a99..93d7eb4b91 100644 --- a/examples/gallery/param/reactive_plots.ipynb +++ b/examples/gallery/param/reactive_plots.ipynb @@ -19,7 +19,7 @@ "\n", "from bokeh.sampledata.iris import flowers\n", "\n", - "pn.extension()" + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { @@ -61,10 +61,13 @@ " \n", " @param.depends('X_variable', 'Y_variable')\n", " def plot(self):\n", - " return flowers.hvplot.scatter(x=self.X_variable, y=self.Y_variable, by='species')\n", + " return flowers.hvplot.scatter(x=self.X_variable, y=self.Y_variable, by='species').opts(height=600)\n", " \n", " def panel(self):\n", - " return pn.Row(self.param, self.plot)\n", + " return pn.Row(\n", + " pn.Param(self, width=300, name = \"Plot Settings\", sizing_mode=\"fixed\"), \n", + " self.plot\n", + " )\n", "\n", "dashboard = IrisDashboard(name='Iris_Dashboard')" ] @@ -82,7 +85,30 @@ "metadata": {}, "outputs": [], "source": [ - "dashboard.panel().servable()" + "component = dashboard.panel()\n", + "component" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve reactive_plots.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Machine Learning Data Visualization\", \n", + " main=[\n", + " \"The [iris dataset](https://en.wikipedia.org/wiki/Iris_flower_data_set) is a standard example used to illustrate **machine-learning and visualization techniques**.\\n\\nHere, we show how to use [Panel](http://panel.pyviz.org) to create a dashboard for visualizing the dataset. The Panel dashboard uses [hvPlot](http://hvplot.pyviz.org) to create plots and [Param](https://param.pyviz.org) objects to create options for selecting the `X` and `Y` axis for the plot.\",\n", + " component \n", + " ]).servable();" ] } ], @@ -93,5 +119,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/param/reactive_tables.ipynb b/examples/gallery/param/reactive_tables.ipynb index 5080fb96b2..f5aa6bddf1 100644 --- a/examples/gallery/param/reactive_tables.ipynb +++ b/examples/gallery/param/reactive_tables.ipynb @@ -13,7 +13,7 @@ "from bokeh.sampledata.autompg import autompg_clean\n", "from bokeh.sampledata.population import data\n", "\n", - "pn.extension()" + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { @@ -31,11 +31,9 @@ "source": [ "class ReactiveTables(param.Parameterized):\n", " \n", - " title = param.String(default='Data Summary')\n", - " \n", " dataset = param.ObjectSelector(default='iris', objects=['iris', 'autompg', 'population'])\n", " \n", - " rows = param.Integer(default=10, bounds=(0, 100))\n", + " rows = param.Integer(default=10, bounds=(0, 19))\n", " \n", " @param.depends('dataset')\n", " def data(self):\n", @@ -50,22 +48,40 @@ " def summary(self):\n", " return self.data().describe()\n", " \n", - " @param.depends('title')\n", - " def header(self):\n", - " return '##' + self.title\n", - " \n", " @param.depends('data', 'rows')\n", " def table(self):\n", " return self.data().iloc[:self.rows]\n", " \n", " def panel(self):\n", " return pn.Row(\n", - " self.param,\n", - " pn.Column(self.header, self.summary, self.table),\n", + " pn.Param(self, name=\"Settings\", width=300, sizing_mode=\"fixed\"),\n", + " pn.Column(\"## Description\", self.summary, \"## Table\", self.table),\n", " min_height=1000)\n", " \n", - "reactive = ReactiveTables()\n", - "reactive.panel().servable()" + "component = ReactiveTables().panel()\n", + "component" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve reactive_tables.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(site=\"Panel\", title=\"Reactive Data Tables\", \n", + " main=[\n", + " \"This example demonstrates [Panel's](https://panel.holoviz.org) reactive programming paradigm using the [Param](https://param.holoviz.org) library to express parameters, plus methods with computation depending on those parameters. \\n\\nThis pattern can be used to update the plots and tables whenever a parameter value changes, without re-running computations unnecessarily.\",\n", + " component \n", + " ]).servable();" ] } ], @@ -76,5 +92,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/simple/altair_choropleth.ipynb b/examples/gallery/simple/altair_choropleth.ipynb index 084a14b3cf..809bd75097 100644 --- a/examples/gallery/simple/altair_choropleth.ipynb +++ b/examples/gallery/simple/altair_choropleth.ipynb @@ -32,9 +32,6 @@ "source = 'https://raw.githubusercontent.com/vega/vega/master/docs/data/population_engineers_hurricanes.csv'\n", "variable_list = ['population', 'engineers', 'hurricanes']\n", "\n", - "variable = pn.widgets.Select(options=variable_list, name='Variable')\n", - "\n", - "@pn.depends(variable.param.value)\n", "def get_map(variable):\n", " return alt.Chart(states).mark_geoshape().encode(\n", " alt.Color(variable, type='quantitative')\n", @@ -42,18 +39,51 @@ " lookup='id',\n", " from_=alt.LookupData(source, 'id', [variable])\n", " ).properties(\n", - " width=500,\n", - " height=300\n", + " width=\"container\",\n", + " height=300,\n", " ).project(\n", " type='albersUsa'\n", " ).repeat(\n", " row=[variable]\n", " )\n", "\n", + "variable = pn.widgets.Select(options=variable_list, name='Variable', width=250)\n", + "logo = pn.panel(altair_logo, height=150, align=\"center\")\n", + "vega_panel = pn.pane.Vega(sizing_mode=\"stretch_width\", margin=(10,100,10,5))\n", + " \n", + "@pn.depends(variable.param.value, watch=True)\n", + "def update_vega_pane(variable):\n", + " vega_panel.object = get_map(variable)\n", + "\n", + "update_vega_pane(variable.value)\n", + " \n", "pn.Row(\n", - " pn.Column('# Altair Choropleth Maps', pn.panel(altair_logo, height=150), variable),\n", - " get_map\n", - ").servable()" + " pn.Column('# Altair Choropleth Maps', logo, variable),\n", + " vega_panel\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve altair_chropleth.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", \n", + " title=\"Altair Choropleth Maps\", \n", + " sidebar=[logo, variable], \n", + " main=[\"A simple example demonstrating **how to use a *reactive function* depending on a single widget**, to render Altair/Vega plots.\", vega_panel]\n", + ").servable();" ] } ], @@ -64,5 +94,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/simple/clifford_interact.ipynb b/examples/gallery/simple/clifford_interact.ipynb index 5857a02adf..eeff26cd12 100644 --- a/examples/gallery/simple/clifford_interact.ipynb +++ b/examples/gallery/simple/clifford_interact.ipynb @@ -15,7 +15,7 @@ "from datashader import transfer_functions as tf\n", "from colorcet import palette_n\n", "\n", - "pn.extension()" + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { @@ -49,14 +49,41 @@ " agg = cvs.points(df, 'x', 'y')\n", " return tf.shade(agg, cmap=cmap)\n", "\n", - "pane = pn.interact(clifford_plot, a=(0,2), b=(0,2), c=(0,2), d=(0,2), n=(1,2e7), cmap=ps)\n", + "pane = pn.interact(clifford_plot, a=(0,2), b=(0,2), c=(0,2), d=(0,2), n=(int(1),int(2e7)), cmap=ps)\n", + "\n", "logo = \"https://tinyurl.com/y9c2zn65/logo_stacked_s.png\"\n", - "text = \"\"\"Tap/click the microphone icon and say a color to change the background color of the app. Try {colors_html}\n", + "Please **use Chrome** as it has the best support for the Speech to Text Api.\n", "\"\"\"\n", "\n", - "content_panel = pn.pane.HTML(content_html, sizing_mode=\"stretch_width\")\n", - "\n", - "app = pn.Column(height=500, width=500, css_classes=[\"color-app\"])\n", + "content_panel = pn.pane.Markdown(content)\n", + "colors_panel = pn.pane.HTML(colors_html)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "app = pn.Column(height=700, css_classes=[\"color-app\"])\n", "style_panel = pn.pane.HTML(width=0, height=0, sizing_mode=\"fixed\")\n", "\n", - "result_panel = pn.pane.Markdown(sizing_mode=\"stretch_width\")\n", + "result_panel = pn.pane.Markdown()\n", "\n", "@pn.depends(speech_to_text_color, watch=True)\n", "def update_result_panel(results_last):\n", @@ -100,16 +115,32 @@ " result_panel.object = \"Result received: \" + results_last\n", " else:\n", " app.background = \"white\"\n", - " result_panel.object = \"Result received: \" + results_last + \" (Not recognized)\"\n", - "\n", + " result_panel.object = \"Result received: \" + results_last + \" (Not recognized)\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "app[:] = [\n", " style_panel,\n", " content_panel,\n", " speech_to_text_color,\n", " result_panel,\n", + " colors_html,\n", "]\n", + "app" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", "\n", - "app.servable()" + "Lets wrap it into nice template that can be served via `panel serve color_speech_recognition.ipynb`" ] }, { @@ -117,7 +148,13 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", \n", + " title=\"Speech Recognition - Color App\", \n", + " main=[app], main_max_width=\"768px\"\n", + ").servable();" + ] } ], "metadata": { diff --git a/examples/gallery/simple/deckgl_game_of_life.ipynb b/examples/gallery/simple/deckgl_game_of_life.ipynb index 13d3cf5641..d54649d8c5 100644 --- a/examples/gallery/simple/deckgl_game_of_life.ipynb +++ b/examples/gallery/simple/deckgl_game_of_life.ipynb @@ -11,7 +11,7 @@ "import pandas as pd\n", "import panel as pn\n", "\n", - "pn.extension('deckgl')" + "pn.extension('deckgl', sizing_mode=\"stretch_width\")" ] }, { @@ -172,11 +172,11 @@ "def toggle_periodic_callback(event):\n", " if event.new:\n", " periodic_toggle.name = 'Stop'\n", - " periodic_toggle.button_type = 'danger'\n", + " periodic_toggle.button_type = 'warning'\n", " periodic_cb.start()\n", " else:\n", " periodic_toggle.name = 'Run'\n", - " periodic_toggle.button_type = 'success'\n", + " periodic_toggle.button_type = 'primary'\n", " periodic_cb.stop()\n", " \n", "def update_period(event):\n", @@ -198,7 +198,7 @@ "source": [ "board = new_board(30, 30)\n", "\n", - "gol = pn.pane.DeckGL(board_json, width=600, height=600)\n", + "gol = pn.pane.DeckGL(board_json, height=400)\n", "\n", "run_gol()\n", "\n", @@ -216,11 +216,56 @@ "\n", "periodic_cb = pn.state.add_periodic_callback(run_gol, start=False, period=period.value)\n", "\n", + "settings = pn.Row(period, periodic_toggle, reset, width=400, sizing_mode=\"fixed\")\n", + "\n", "pn.Column(\n", " '## Game of Life (using Deck.GL)',\n", " gol,\n", - " pn.Row(period, periodic_toggle, reset)\n", - ").servable()" + " settings,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", + "\n", + "Lets wrap it into nice template that can be served via `panel serve deckgl_game_of_life.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "description = \"\"\"\n", + "**Conway's Game of Life** is a classic demonstration of *emergence*, where higher level patterns form from a few simple rules. Fantastic patterns emerge when the game is let to run long enough.\n", + "\n", + "The **rules** here, to borrow from [Wikipedia](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life), are as follows:\n", + "\n", + "- Any live cell with fewer than two live neighbours dies, as if by underpopulation.\n", + "- Any live cell with two or three live neighbours lives on to the next generation.\n", + "- Any live cell with more than three live neighbours dies, as if by overpopulation.\n", + "- Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.\n", + "\n", + "This demo was **adapted from [PyDeck's Conway Game of Life example](https://github.com/uber/deck.gl/blob/66c75051d5b385db31f0a4322dff054779824783/bindings/pydeck/examples/06%20-%20Conway's%20Game%20of%20Life.ipynb)**, full copyright lies with the original authors.\n", + "\n", + "This modified example demonstrates **how to display and update a `DeckGL` pane with a periodic callback** by modifying the JSON representation and triggering an update.\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", \n", + " title=\"Deck.gl - Game of Life\", \n", + " main=[ pn.Column(description, settings), gol, ], main_max_width=\"768px\",\n", + ").servable();" ] } ], diff --git a/examples/gallery/simple/defer_data_load.ipynb b/examples/gallery/simple/defer_data_load.ipynb index 429f671234..f8d49772c9 100644 --- a/examples/gallery/simple/defer_data_load.ipynb +++ b/examples/gallery/simple/defer_data_load.ipynb @@ -8,7 +8,10 @@ "source": [ "import panel as pn\n", "import pandas as pd\n", - "import hvplot.pandas" + "import hvplot.pandas\n", + "import time\n", + "\n", + "pn.extension(sizing_mode=\"stretch_width\")" ] }, { @@ -26,7 +29,7 @@ "source": [ "stocks_url = 'https://raw.githubusercontent.com/vega/datalib/master/test/data/stocks.csv'\n", "\n", - "select_ticker = pn.widgets.Select(name='Stock Ticker')\n", + "select_ticker = pn.widgets.Select(name='Stock Ticker', width=250, sizing_mode=\"fixed\")\n", "\n", "def load_data():\n", " if 'stocks' not in pn.state.cache: \n", @@ -57,9 +60,36 @@ "def plot_ticker(ticker):\n", " if 'stocks' not in pn.state.cache or not ticker:\n", " return pn.indicators.LoadingSpinner(value=True)\n", - " return pn.state.cache['stocks'].loc[ticker].hvplot.line('date', 'price')\n", + " time.sleep(0.5)\n", + " return pn.state.cache['stocks'].loc[ticker].hvplot.line('date', 'price', color=\"#C01754\", line_width=6)\n", + "\n", + "pn.Row(select_ticker, plot_ticker)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## App\n", "\n", - "pn.Row(select_ticker, plot_ticker).servable()" + "Lets wrap it into nice template that can be served via `panel serve defer_data_load.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", \n", + " title=\"Defer Data Load\", \n", + " sidebar=[select_ticker], \n", + " main=[\n", + " \"This app demonstrates how to **defer the loading** of the data and population of the widgets until the page is rendered\",\n", + " plot_ticker,\n", + " ]\n", + ").servable();" ] } ], diff --git a/examples/gallery/simple/file_download_examples.ipynb b/examples/gallery/simple/file_download_examples.ipynb index 2b70445cad..c396a96455 100644 --- a/examples/gallery/simple/file_download_examples.ipynb +++ b/examples/gallery/simple/file_download_examples.ipynb @@ -6,9 +6,7 @@ "source": [ "# File Download Example\n", "\n", - "The **purpose** of this notebook is to provide code examples and **code snippets** that enable you to quickly add FileDownload to your Panel dashboard or application.\n", - "\n", - "This notebook was originally contributed because I had problems creating the right code to enable downloading DataFrames in `xlsx` format. See [FileDownload widget produces empty file for dataframe](https://github.com/holoviz/panel/issues/1241)." + "The **purpose** of this notebook is to provide code examples and **code snippets** that enable you to quickly add FileDownload to your Panel dashboard or application." ] }, { @@ -17,32 +15,86 @@ "metadata": {}, "outputs": [], "source": [ + "import numpy as np\n", "import pandas as pd\n", "import panel as pn\n", "from io import BytesIO\n", "\n", - "pn.extension()" + "pn.extension(sizing_mode=\"stretch_width\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Source: Pandas DataFrame" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "data=pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Target: `.csv`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_csv():\n", + " return BytesIO(data.to_csv().encode())\n", + "\n", + "file_download_csv = pn.widgets.FileDownload(filename=\"data.csv\", callback=get_csv, button_type=\"primary\")\n", + "file_download_csv" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Source: DataFrame" + "### Target: `.csv.zip`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_csv_zip():\n", + " output = BytesIO()\n", + " output.name = \"data.csv\"\n", + " data.to_csv(output, compression=\"zip\")\n", + " output.seek(0)\n", + " return output\n", + "\n", + "file_download_csv_zip = pn.widgets.FileDownload(filename=\"data.csv.zip\", callback=get_csv_zip, button_type=\"primary\")\n", + "file_download_csv_zip" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### File: XLSX\n", + "### Target: `.xlsx`\n", "\n", - "Please note you need to have the packages\n", + "Please note you need to install one of the packages\n", "\n", - "- [XlsxWriter](https://xlsxwriter.readthedocs.io/index.html)\n", + "- [XlsxWriter](https://xlsxwriter.readthedocs.io/index.html) or\n", "- [OpenPyXL](https://openpyxl.readthedocs.io/en/stable/)\n", "\n", - "installed for being able to use the `.to_excel` method of a DataFrame." + "to be able to use the `.to_excel` method of a DataFrame." ] }, { @@ -51,9 +103,7 @@ "metadata": {}, "outputs": [], "source": [ - "data=pd.DataFrame({\"a\": [1]})\n", - "\n", - "def get_file():\n", + "def get_xlsx():\n", " output = BytesIO()\n", " writer = pd.ExcelWriter(output, engine='xlsxwriter')\n", " data.to_excel(writer, sheet_name=\"Data\")\n", @@ -61,8 +111,54 @@ " output.seek(0) # Important!\n", " return output\n", "\n", - "file_download = pn.widgets.FileDownload(filename=\"data.xlsx\", callback=get_file)\n", - "file_download" + "file_download_xlsx = pn.widgets.FileDownload(filename=\"data.xlsx\", callback=get_xlsx, button_type=\"primary\")\n", + "file_download_xlsx" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Target: `.json`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_json():\n", + " return BytesIO(data.to_json(orient=\"records\").encode())\n", + "\n", + "file_download_json = pn.widgets.FileDownload(filename=\"data.json\", callback=get_json, button_type=\"primary\")\n", + "file_download_json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Target: `.parquet`\n", + "\n", + "Please note you need to have the `pyarrow` package installed for this to work." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_parquet():\n", + " output = BytesIO()\n", + " output.name = \"data.parquet\"\n", + " data.to_parquet(output)\n", + " output.seek(0)\n", + " return output\n", + "\n", + "file_download_parquet = pn.widgets.FileDownload(filename=\"data.parquet\", callback=get_parquet, button_type=\"primary\")\n", + "file_download_parquet" ] }, { @@ -71,16 +167,34 @@ "source": [ "## Contributions\n", "\n", - "Example Contributions are very welcome. For example for `DataFrame` to `csv`, `parquet` and `json`." + "Example Contributions are very welcome. For example for `DataFrame` to `html` or `pdf`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Credits\n", + "## App\n", "\n", - "- [Marc Skov Madsen](https://datamodelsanalytics.com)" + "Lets wrap it into nice template that can be served via `panel serve file_download_examples.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pn.template.FastListTemplate(\n", + " site=\"Panel\", \n", + " title=\"File Download\", \n", + " main=[\n", + " \"This app demonstrates how to **download a Pandas DataFrame** using different formats.\",\n", + " pn.Column(\n", + " pn.pane.HTML(\"
This is a Panel app with a Material template allowing us to compose multiple Panel objects into a single HTML document.
This is a Panel app using a custom template based on Material Design. It works both in the Notebook and as a web app.