holoviz / holoviz/hvplot

Goal of simplifying multi-color rasterize analysis into one line in hvplot?

Open
#1,376 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
1.4k
Forks
124
Avg merge
1d 18h
Merged PRs (30d)
1

Description

image

I want to simplify this workflow down to a single call in hvplot.

```python
df.hvplot(
"LON",
"LAT",
groupby="BaseDateTime",
geo=True,
tiles=True,
datashade=True,
dynspread=True,
by="VesselType",
aggregator=ds.count_cat,
cmap="glasbey_bw_minc_20_minl_30",
)
```

I think it's doable, but hvplot is missing a few features, so this issue is kind of like an epic

1. Automatic lon/lat to easting/northing https://github.com/holoviz/hvplot/issues/1375
2. Map categorical strings to color given a cmap (or default cmap) and use as color_key in datashade
3. Create legend based on the categories https://github.com/holoviz/holoviews/issues/6320

For 2, I think rather than having a column be the actual color, `color=["red", "green", "blue"]`, if it detects non-valid colors, it would automatically use a cmap to map categories to color (I always find that tedious) https://holoviews.org/user_guide/Style_Mapping.html#styling-mapping

To reproduce:
Data download: https://coast.noaa.gov/htdata/CMSP/AISDataHandler/2020/index.html

```python
import pandas as pd
import hvplot.pandas
import geoviews as gv
import pandas as pd
import datashader as ds
import colorcet as cc
import holoviews as hv
import holoviews.operation.datashader as hd
from holoviews.util.transform import lon_lat_to_easting_northing

df = pd.read_csv("AIS_2020_01_01.csv", parse_dates=True, index_col="BaseDateTime")
df = df.assign(
**pd.concat(lon_lat_to_easting_northing(df["LON"], df["LAT"]), axis=1).rename(
{"LON": "EASTING", "LAT": "NORTHING"}, axis=1
)
)

df.index = df.index.round("1Min")
df = df.sort_index()
df.index = df.index.astype(str)

vessel_types = pd.read_csv("AIS_categories.csv")

categories = {
r.num: r.category if r.category in [0, 2, 3, 6, 7, 16, 14, 19, 12, 18] else 21
for i, r in vessel_types.iterrows()
}

def category_desc(val):
"""Return description for the category with the indicated integer value"""
return vessel_types[vessel_types.category == val].iloc[0].category_desc

groups = {categories[i]: category_desc(categories[i]) for i in categories.keys()}
colors = cc.glasbey_bw_minc_20_minl_30
color_key = {
list(groups.keys())[i]: tuple(int(e * 255.0) for e in v)
for i, v in enumerate(colors[: (len(groups))][::-1])
}
legend = hv.NdOverlay(
{
groups[k]: hv.Points([0, 0], label=str(groups[k])).opts(
color=cc.rgb_to_hex(*v), size=0
)
for k, v in color_key.items()
}
)

df = df.loc[df["VesselType"].isin(color_key)]

pts = hv.Dataset(df, kdims=["EASTING", "NORTHING"], vdims=["VesselType"]).to(
hv.Points, groupby=["BaseDateTime"]
)
points = hd.dynspread(
hd.datashade(pts, aggregator=ds.count_cat("VesselType"), color_key=color_key)
)

tiles = (
hv.element.tiles.ESRI()
.opts(alpha=0.4, bgcolor="black")
.opts(responsive=True, min_height=600)
)
labels = hv.element.tiles.CartoDark().opts(alpha=0.7, level="glyph")
display(
tiles
* labels
* points.opts(show_legend=False)
* legend.opts(xaxis="bare", yaxis="bare", title="")
)
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.