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.