On this page
_images/logo_stacked.png

Overview#

A high-level app and dashboarding solution for Python

Attractors
https://assets.holoviews.org/panel/thumbnails/index/attractors.png
Gapminders
https://assets.holoviews.org/panel/thumbnails/index/gapminders.png
Penguins
https://assets.holoviews.org/panel/thumbnails/index/penguins.png
Glaciers
https://assets.holoviews.org/panel/thumbnails/index/glaciers.png
Portfolio Optimizer
https://assets.holoviews.org/panel/thumbnails/index/portfolio_optimizer.png

Panel is an open-source Python library that lets you create custom interactive web apps and dashboards by connecting user-defined widgets to plots, images, tables, or text.

import panel as pn

import pandas as pd
import holoviews as hv

from sklearn.cluster import KMeans

penguins = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv')
cols = list(penguins.columns)[:-1]

pn.extension('ace')

import hvplot.pandas
slider = pn.widgets.IntSlider(start=0, end=10)

img = pn.pane.JPG(f"https://picsum.photos/800/300?image=0", embed=False, height=300)

slider.jscallback(args={'img': img}, value="""
img.text = '<img src="https://picsum.photos/800/300?image='+cb_obj.value+'" width=800 height=300></img>'
""")

app = pn.Column(slider, img)

ace = pn.widgets.Ace(readonly=True, width=800, height=200, language='python', theme='monokai', value=\
"""slider = pn.widgets.IntSlider(start=0, end=10)

def slideshow(index):
    url = f"https://picsum.photos/800/300?image={index}"
    return pn.pane.JPG(url)

output = pn.bind(slideshow, slider)

app = pn.Column(slider, output)""")

app1 = pn.Tabs(('Output', app), ('Code', ace))

penguins = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv').dropna()
cols = list(penguins.columns)[2:6]

x = pn.widgets.Select(name='x', options=cols)
y = pn.widgets.Select(name='y', options=cols, value='bill_depth_mm')
n_clusters = pn.widgets.IntSlider(name='n_clusters', start=2, end=5, value=3)

def cluster(data, n_clusters):
    kmeans = KMeans(n_clusters=n_clusters)
    est = kmeans.fit(data)
    return est.labels_.astype('str')

def plot(x, y, n_clusters):
    penguins['labels'] = cluster(penguins.iloc[:, 2:6].values, n_clusters)
    centers = penguins.groupby('labels').mean()
    return (penguins.sort_values('labels').hvplot.scatter(
        x, y, c='labels', hover_cols=['species'], line_width=1, size=60, frame_width=400, frame_height=400
    ).opts(marker=hv.dim('species').categorize({'Adelie': 'square', 'Chinstrap': 'circle', 'Gentoo': 'triangle'})) * centers.hvplot.scatter(
        x, y, marker='x', color='black', size=400, padding=0.1, line_width=5
    ))

explanation = pn.pane.Markdown("""
This app applies k-means clustering on the Palmer Penguins dataset using scikit-learn, parameterizing the number of clusters and the variables to plot.
<br><br>
Each cluster is denoted by one color while the penguin species is indicated using markers: 
<br><br>
● - Adelie, ▲ - Gentoo, ■ - Chinstrap
<br><br>
By comparing the two we can assess the performance of the clustering algorithm.
<br><br>
""")

code = pn.widgets.Ace(language='python', theme='monokai', height=360, value=\
"""x = pn.widgets.Select(name='x', options=cols)
y = pn.widgets.Select(name='y', options=cols, value='bill_depth_mm')
n_clusters = pn.widgets.IntSlider(name='n_clusters', start=2, end=5, value=3)
explanation = pn.pane.Markdown(...)

def plot_clusters(x, y, n_clusters):
    ...
    
pn.Row(
    pn.WidgetBox(x, y, n_clusters, explanation),  
    pn.bind(plot, x, y, n_clusters)
)""", width=800)

app2 = pn.Tabs(
    ('Output', pn.Column(
        pn.Row(
            pn.WidgetBox(x, y, n_clusters, explanation),  
            pn.bind(plot, x, y, n_clusters)
        )
    )),
    ('Code', code)
)

pn.Row(pn.layout.HSpacer(), pn.Tabs(
  ('Penguin K-Means Clustering', app2),
  ('Slideshow', app1)
), pn.layout.HSpacer(), sizing_mode='stretch_width').embed(max_opts=4, json=True, json_prefix='json')

Compared to other approaches, Panel is novel in that it supports nearly all plotting libraries, works just as well in a Jupyter notebook as on a standalone secure web server, uses the same code for both those cases, supports both Python-backed and static HTML/JavaScript exported applications, and can be used to develop rich interactive applications without tying your domain-specific code to any particular GUI or web tools.

Panel makes it simple to:

  • Use the PyData tools and plotting libraries that you know and love

  • Develop in your favorite editor or notebook environment and seamlessly deploy the resulting application

  • Iterate quickly to prototype apps and dashboards while offering polished templates for your final deployment

  • Support deep interactivity by communicating client-side interactions and events to Python

  • Stream data large and small to the frontend

  • Add authentication to your application using the inbuilt OAuth providers

Usage#

Core Concepts

Introduces you to some of the core concepts behind Panel, how to develop Panel applications effectively both in your IDE and in the notebook and some of the core features that make Panel such a powerful library.

Installation

Walks you through setting up your Python environment, installing Panel into it and how to configure your editor, IDE or notebook environment appropriately.

Build an app

A more hands on tour taking you through the process of loading some data, displaying it and then building an application around it with some of the rich features that Panel supports.

User Guide

For a more in-depth guide through a range of topics, starting from the various APIs of Panel, through to building custom components and authentication visit our user guide.

For usage questions or technical assistance, please head over to Discourse. If you have any issues or wish to contribute code, you can visit our GitHub site.

Sponsors#

The Panel project is grateful for the sponsorship by the organizations and companies below:

Anaconda Logo
Blackstone Logo