Hvplot Explorer#
This example demonstrates how to leverage the hvPlot explorer functionality when combined with a FileInput widget to allow users to explore their own data. When a user uploads their own data it gets added to the list of datasets the user can select from.
import io
import hvplot.pandas # noqa: F401
import pandas as pd
import panel as pn
pn.extension()
Datasets#
Uploaded files are stored as raw bytes, so a dataset can be selected again after it has been read once.
SEABORN = 'https://raw.githubusercontent.com/mwaskom/seaborn-data/master'
upload = pn.ui.FileInput(label='Upload file', accept='.csv')
select = pn.ui.Select(label='Dataset', options={
'Penguins': f'{SEABORN}/penguins.csv',
'Diamonds': f'{SEABORN}/diamonds.csv',
'Titanic': f'{SEABORN}/titanic.csv',
'MPG': f'{SEABORN}/mpg.csv',
})
def add_data(value):
if not value:
return
name = upload.filename.rsplit('.', 1)[0]
select.options = {**select.options, name: value}
select.value = value
pn.bind(add_data, upload.param.value, watch=True);
Explorer#
A new explorer is created whenever the dataset changes. Its code parameter tracks the plot settings, and .rx.resolve() follows it across explorer instances so the code pane stays in sync.
def make_explorer(source):
data = io.BytesIO(source) if isinstance(source, bytes) else source
return hvplot.explorer(pd.read_csv(data))
def code_md(code):
return f'```python\n{code}\n```'
explorer = pn.rx(make_explorer)(select)
code = explorer.rx.pipe(lambda e: e.param.code).rx.resolve()
widgets = pn.ui.Column(
pn.ui.Markdown("Select an existing dataset or upload one of your own CSV files and start exploring your data."),
pn.ui.Row(select, upload),
)
output = pn.ui.Column(
pn.ui.ParamRef(explorer),
pn.ui.Markdown('**Code**:'),
pn.ui.Markdown(code.rx.pipe(code_md)),
)
page = pn.ui.Page(title="hvPlot Explorer", main=[widgets, output])
page
Served App#
if pn.state.served:
page.servable()