SimpleSearchWidget
This Not That (TNT) provides a simple search bar widget that can search through data in a dataframe for simple string based matches. We will outline the core functionality of the SimpleSearchWidget
and why and when it may be useful. Note that the SimpleSearchWidget
is relatively limited, and if you want a more featureful search you should use the SearchWidget
.
The first step is to load thisnotthat
and panel
.
[1]:
import thisnotthat as tnt
import panel as pn
To make Panel based objects interactive within a notebook we need to load the panel extension
.
[2]:
pn.extension()
Now we need some data to use as an example. In this case we’ll use the Palmer’s Penguins dataset, which we can get easy access to via seaborn; we will also clean up the data and rename the columns for ease of use.
[3]:
import seaborn as sns
penguins = (
sns.load_dataset('penguins')
.dropna()
.rename(
columns={
"bill_length_mm": "bill-length",
"bill_depth_mm": "bill-depth",
"flipper_length_mm": "flipper-length",
"body_mass_g": "body-mass"
}
)
)
The penguins dataset consists of a series of measurements relating to three species of penguins (Adelie, Chinstrap, and Gentoo) found in three different islands (Torgersen, Biscoe and Dream) in the Antarctic. We can glance at the first few rows to get a sense of the data.
[4]:
penguins.head()
[4]:
species | island | bill-length | bill-depth | flipper-length | body-mass | sex | |
---|---|---|---|---|---|---|---|
0 | Adelie | Torgersen | 39.1 | 18.7 | 181.0 | 3750.0 | Male |
1 | Adelie | Torgersen | 39.5 | 17.4 | 186.0 | 3800.0 | Female |
2 | Adelie | Torgersen | 40.3 | 18.0 | 195.0 | 3250.0 | Female |
4 | Adelie | Torgersen | 36.7 | 19.3 | 193.0 | 3450.0 | Female |
5 | Adelie | Torgersen | 39.3 | 20.6 | 190.0 | 3650.0 | Male |
Unlike the SearchWidget
the SimpleSearchWidget
needs to be instantiated with the BokehPlotPane
it will connect to, and can only be associated with a single BokehPlotPane
at a time. In contrast to the SearchWidget
, however, the SimpleSearchWidget
can link directly to the BokehPlotPane
via javascript and thus doesn’t need a python kernel or server to run. This can be a significant advantage if you wish to add search to a static HTML deployment.
Let’s make a data map of the penguins data. For that we’ll need some sklearn preprocessing (to get our numeric data all on the same scale) and UMAP.
[5]:
from sklearn.preprocessing import RobustScaler
import umap
Now we just apply UMAP to the rescaled numeric data from our penguins dataframe. We can pass that directly into a BokehPlotPane
(other PlotPane types are not supported by SimpleSearchWidget
at this time) to get a data map up and running
[6]:
data_for_umap = RobustScaler().fit_transform(penguins.select_dtypes(include="number"))
penguin_datamap = umap.UMAP(random_state=42).fit_transform(data_for_umap)
plot = tnt.BokehPlotPane(
penguin_datamap,
labels=penguins.species,
hover_text=penguins.island,
width=600,
height=600,
legend_location="top_right",
title="Penguins data map",
)
A quick visual check shows that our PlotPane data map looks like the sort of thing we want.
[7]:
plot.pane
[7]:
To create a SimpleSearchWidget
you need to pass it the BokehPlotPane
it will be connected to and (optionally) the dataframe it will ber performing searches over. The result is a simple search bar.
[8]:
search = tnt.SimpleSearchWidget(plot, raw_dataframe=penguins)
search
[8]:
With this done we can create a simple Column
layout of the BokehPlotPane
and our SimpleSearchWidget
. Typing in the search box will result in a live search on the plot running over all the columns in the dataframe. This should work even outside of a running notebook or web-app, unlike the more complex SearchWidget
.
[9]:
pn.Column(search, plot)
[9]:
If you have a lot of data and don’t want to search on every keypress you can use the option live_search=False
when creating the SimpleSearchWidget
and it will only run the search when the enter key is pressed.