Iris Kmeans#
This app provides an example of building a simple dashboard using Panel. It demonstrates how to take the output of k-means clustering on the Iris dataset (performed using scikit-learn), parameterizing the number of clusters and the x and y variables to plot. The entire clustering and plotting pipeline is expressed as a single reactive function that returns a plot that responsively updates when one of the widgets changes.
import hvplot.pandas # noqa: F401
import panel as pn
from bokeh.sampledata import iris
from sklearn.cluster import KMeans
pn.extension(sizing_mode='stretch_width')
Clustering#
get_clusters returns a labelled copy of the data instead of mutating it, so it can be cached on n_clusters and shared between sessions.
FLOWERS = iris.flowers
COLS = list(FLOWERS.columns)[:-1]
@pn.cache
def get_clusters(n_clusters):
est = KMeans(n_clusters=n_clusters, n_init='auto').fit(FLOWERS[COLS].values)
return FLOWERS.assign(labels=est.labels_.astype('str')).sort_values('labels')
def plot_clusters(x, y, n_clusters):
flowers = get_clusters(n_clusters)
centers = flowers.groupby('labels')[[x] if x == y else [x, y]].mean()
return (
flowers.hvplot.scatter(
x, y, c='labels', size=100, height=500, responsive=True
) *
centers.hvplot.scatter(
x, y, marker='x', c='black', size=400, padding=0.1, line_width=5,
height=500, responsive=True
)
)
App#
x = pn.ui.Select(label='x', options=COLS)
y = pn.ui.Select(label='y', options=COLS, value='sepal_width')
n_clusters = pn.ui.IntSlider(label='n_clusters', start=1, end=5, value=3)
widgets = pn.ui.Column(
pn.ui.Markdown(
"This app provides an example of **building a simple dashboard using Panel**.\n\n"
"It demonstrates how to take the output of **k-means clustering on the Iris dataset** "
"using scikit-learn, parameterizing the number of clusters and the variables to plot.\n\n"
"The entire clustering and plotting pipeline is expressed as a **single reactive function** "
"that responsively returns an updated plot when one of the widgets changes.\n\n"
"The **`x` marks the center** of the cluster."
),
x, y, n_clusters,
)
plot = pn.ui.HoloViews(pn.bind(plot_clusters, x, y, n_clusters))
page = pn.ui.Page(
main=[plot],
sidebar=[widgets],
title='Iris K-Means Clustering'
)
page
Served App#
if pn.state.served:
page.servable()