Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plotting using lonboard #11

Open
benbovy opened this issue Nov 8, 2023 · 10 comments
Open

Plotting using lonboard #11

benbovy opened this issue Nov 8, 2023 · 10 comments

Comments

@benbovy
Copy link
Member

benbovy commented Nov 8, 2023

lonboard is a new tool for efficient and interactive plotting of (vector) geospatial data in Jupyter.

It would be nice to leverage it for plotting DGGS data.

Lonboard uses deck.gl in the front-end. Although this is not (yet) available in lonboard, Deck.gl has specific layers for H3 and S2 so for those two grids this could potentially be very efficient as we would only need to transfer cell ids and cell values (colors) to the front-end and let deck.gl compute and render the cells.

For the other grids, we could fallback to transfer the grid cell geometries as polygons (see #10) and use lonboard's SolidPolygonLayers.

cc @kylebarron

@kylebarron
Copy link
Contributor

kylebarron commented Nov 8, 2023

I think you probably want the H3HexagonLayer instead of the clustering variant. The main annoyance with the h3 layer is that h3-js doesn't support the uint64 representation of an h3 index, so you either have to transmit the data to JS as strings or convert the uint64 to a hex string once you get there. Are s2 tokens always strings?

Either way, they're relatively layers easy to wrap, at least putting off h3 integers for later

@benbovy
Copy link
Member Author

benbovy commented Nov 9, 2023

The main annoyance with the h3 layer is that h3-js doesn't support the uint64 representation of an h3 index, so you either have to transmit the data to JS as strings or convert the uint64 to a hex string once you get there. Are s2 tokens always strings?

Yes I guess we'd have to do the same for converting s2 cell (uint64) ids to s2 tokens.

@keewis
Copy link
Collaborator

keewis commented Sep 30, 2024

I just tried to use lonboard to visualize model data on a healpix grid: https://gist.github.com/keewis/a72329adffa96a8e47bacb43d8255831 The data I'm using for this is from the ICON ocean model, which is already on the healpix grid but unfortunately not public... we really have to put some example data somewhere. The model is global with level=10, which means that it has 12 * 4**level=12582912 cells and thus polygons. This takes a while to render on my laptop, but after that is pretty fast to explore.

The only issue I had is that I couldn't yet figure out how to zoom in on polygons in the range of 180° to 360° longitude, the map always snaps back to -180° to 0°, which does not have any data.

That issue aside this has been pleasant to work with, so I wonder how much would it take to add sliders for time / depth. As far as I can tell, as long as we don't change the polygons lonboard is very fast changing colors / values, so all that's left is figuring out how to actually wire everything up.

@kylebarron
Copy link
Contributor

The only issue I had is that I couldn't yet figure out how to zoom in on polygons in the range of 180° to 360° longitude, the map always snaps back to -180° to 0°, which does not have any data.

Not sure I fully understand, but maybe we need to enable map-repeating? https://deck.gl/docs/whats-new#world-repeating-in-web-mercator-maps

@keewis
Copy link
Collaborator

keewis commented Sep 30, 2024

that could be it. Let me try to create a dummy dataset so you can see what I'm talking about.

@keewis
Copy link
Collaborator

keewis commented Sep 30, 2024

If you want to try reproducing, you'll need to have an environment with xdggs installed from main. Something like this, if you use mamba / conda:

channels:
- conda-forge
dependencies:
- python=3.12
- jupyterlab
- geopandas
- xarray
- numpy<2.1
- lonboard
- matplotlib
- pip
- pip:
  - git+https://github.com/xarray-contrib/xdggs.git

and here's the code:

import geopandas as gpd
import lonboard
import numpy as np
import xarray as xr
import xdggs
from lonboard.colormap import apply_continuous_cmap
from matplotlib import colormaps
from matplotlib.colors import CenteredNorm, Colormap

resolution = 5

ds = (
    xr.Dataset(
        coords={
            "cell_ids": (
                "cells",
                np.arange(12 * 4**resolution),
                {
                    "grid_name": "healpix",
                    "resolution": resolution,
                    "indexing_scheme": "nested",
                },
            )
        }
    )
    .pipe(xdggs.decode)
    .pipe(lambda ds: ds.merge(ds.dggs.cell_centers()))
    .assign(data=lambda ds: np.sin(np.radians(ds["latitude"])))
    .assign_coords(cell_boundaries=lambda ds: ds.dggs.cell_boundaries())
)

gdf = ds.to_pandas().pipe(gpd.GeoDataFrame, geometry="cell_boundaries", crs=4326)

data = gdf["data"].to_numpy()
normalizer = CenteredNorm(vcenter=0, halfrange=1)
normalized_data = normalizer(data)

cmap = colormaps["coolwarm"]
colors = apply_continuous_cmap(normalized_data, cmap)

layer = lonboard.SolidPolygonLayer.from_geopandas(
    gdf, filled=True, get_fill_color=colors
)
map = lonboard.Map(layer)
map

@kylebarron
Copy link
Contributor

Are you able to post a screenshot/screencast of the issue?

@keewis
Copy link
Collaborator

keewis commented Sep 30, 2024

I can try to create a screencast, yes (I just need to figure out how to do that on my OS)

@keewis
Copy link
Collaborator

keewis commented Sep 30, 2024

screencast demonstrating the issue

snapping-map

@kylebarron
Copy link
Contributor

I haven't seen that behavior before. Perhaps it is somehow related to deck.gl not sure which side of the earth to draw on, but that would seem weird because it's split by 0 latitude and not -180

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants