Using Kepler.GL in Jupyter

In this note I would like to briefly introduce the possibility of using [Kepler.GL](https://kepler.gl/) in
Jupyter notebooks. To cite the official webpage,

```
Kepler.gl is a powerful open source geospatial analysis tool for *large-scale* data sets.
```

## Intro: Why use Kepler.GL in Jupyter?

To my knowledge, the standard GeoVisualization solution for use in Jupyter is 
[folium](https://qiita.com/hotoku/items/0d9ddbd24568c1a07f9f).

I think that using Kepler.GL instead of folium can not only be interesting for the sake of variety, but also due to following
reasons:

* Kepler.GL is high-performant, i.e. it can load big chunks of geodata and still remain responsive;
* Kepler.GL has rich interface: one can easily add/remove datasets and/or layers so to create rich interactive maps, which
can then be exported to JSON or stand-alone HTML;

## Installing Kepler.GL widget

### Prerequisites

Note that more detailed [instructions](https://github.com/keplergl/kepler.gl/blob/master/docs/keplergl-jupyter/README.md#install) 
are given at [references](#references)

* Python 3
* Mac OS (I have tried these intsructions on Mac OS only)
* [Homebrew](https://brew.sh/)

### Installation

```sh
pip3 install keplergl 
pip3 install ipywidgets
brew install node@10
jupyter labextension install @jupyter-widgets/jupyterlab-manager keplergl-jupyter
jupyter notebook
```

## Displaying the widget

Once you have installed the widget, using it is pretty easy:

![screen_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588288/188205d2-e2d2-f476-797d-5b4f85f3ef3d.png)

As mentioned before, widget is fully interactive. At every point, however, one can dump the widget's internal state as

![screen_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588288/168d6f41-7357-5c90-d74c-0576d22abf4d.png)

To load the saved internal state into a freshly-created widget, one can do as follows

```py
w = kepler.KeplerGl()
w.config = config
# or directly at the construction
w = kepler.KeplerGl(config=config)
```

Note that datasets are **not** included into config (i.e. they have to be passed at creation).

## Loading data into widget

### Data Sources

In principle, you can use multiple sources to load data into Kepler.GL widget:

* `GeoJSON` (passed to widget object as a string);
* [geopandas](https://geopandas.org/) `GeoDataFrame`;
* [pandas](https://pandas.pydata.org/pandas-docs/stable/) `DataFrame`.

I will concentrate on the latter one. However, for the completeness, here are the
demo notebooks from the official documentation corresponding to first two items: 
[geojson](https://github.com/keplergl/kepler.gl/blob/master/bindings/kepler.gl-jupyter/notebooks/GeoJSON.ipynb), 
[geopandas](https://github.com/keplergl/kepler.gl/blob/master/bindings/kepler.gl-jupyter/notebooks/GeoDataFrame.ipynb).

### A Few Concepts

Before we begin, a word about terminology. While working with Kepler.GL, one distinguishes 

datasets
: which are the chunks of raw
data one wants to analyze (think of them as tables), and 

layers
: which are layers of data visualization.
Kepler.GL comes with following layer types out-of-the-box: Point, Arc, Cluster, Line, Grid, Polygon, Icon, Heatmap and Hexbin.

The relationship between *datasets* and *layers* is one-to-many, that is one can create several layers from one dataset. The
relationship between two is further guided by

filters
: which allow to have only subset of data being visualized.

In principle, after datasets are added, one has to create layers and filters manually, either by using Kepler.GL's UI interface,
or by interacting with widget through the Python API. However, Kepler.GL is 
smart enough
to automatically add layers and filters based on dataset in 
[some cases](https://github.com/keplergl/kepler.gl/blob/master/docs/user-guides/b-kepler-gl-workflow/a-add-data-to-the-map.md#2-layer-detection-based-on-column-names).

For simplicity, I will never add layers manually in examples below, relying instead on Kepler.GL's built-ins.

### Adding Point layers

![screen_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588288/521cf83f-62f4-41b2-f886-0625f34e01fe.png)

Note that `Kepler.GL` automatically created `Point` layer and filter for `Time`.

### Adding Arc and Line layers

![screen_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588288/6032675d-5af3-add9-a390-5863d8544b25.png)

Note that although Arc and Line layers were automatically created, there are hidden by default, so I had to show them
via Kepler.GL's UI.

### Adding H3 layer

![screen_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588288/dfe2a74b-a318-f82e-3c3c-3a4d69715fb7.png)

## References

1. [installation instructions](https://github.com/keplergl/kepler.gl/blob/master/docs/keplergl-jupyter/README.md#install)
1. [using folium in GeoVisualization (jap.)](https://qiita.com/hotoku/items/0d9ddbd24568c1a07f9f)
1. [other demo notebooks](https://docs.kepler.gl/docs/keplergl-jupyter)