holoviz / holoviews

With Holoviews, your data visualizes itself.
https://holoviews.org
BSD 3-Clause "New" or "Revised" License
2.7k stars 403 forks source link

Prevent Dynamic Rasterization after `NaN` values are encountered in plot #5930

Open philipc2 opened 1 year ago

philipc2 commented 1 year ago

Is your feature request related to a problem? Please describe.

I am working on visualizing a high-resolution unstructured grid dataset (~40 million data points) using rasterization. Initially, I have explored using either polygon or trimesh methods, since we are interested in shading the data "between" points since it's an unstructured grid. However, converting our data in a format that is interpretable by datashader/holoviews is computationally expensive (i.e. conversion to a GeoDataFrame or running Delaunay Triangulation) .

With enough data points, we can represent our dataset using hv.Points and perform rasterization to get a pretty convincing looking plot

image

These plots look good at a global extent, however after zooming in enough, the density of points because too low and this leads to 'NaN' values showing up in our plot, up until the point that each "point" is rendered.

image

Describe the solution you'd like

Ideally, we would want to halt any rasterization once 'NaN' values are encountered in the output plot. The following is a zoomed in example using Dynamic=False . This would allow for re-rasterization to occur on zoom in, but would prevent any NaN values for showing up.

image

Describe alternatives you've considered

I have looked into using dynamic spreading, however I haven be able to find a good solution. Setting Dynamic=False and using a high-enough pixel_ratio does help in providing better zoomed in regional plots, however we loose the re-rasterization. Below is an example of why we would still want to keep Dyanmic=True for these interactive plots (I cropped the region of interested to better showcase what's happening)

image

image

Even for this example, we can see a few NaN values popping up after the initial zoom.

Additional context

Code used for data processing & visualuzation

def plot_point_spread_bokeh(pixel_ratio, width, height, dynamic, return_raster=False):
    opts_kwargs = {"title": "Relative humidity vertically interpolated to 200 hPa",
               "clabel":"relhum_200hPa (%)",
               "colorbar": True,
               "clim" : (vmin, vmax),
               "cmap" :cmap}

    raster = hd.rasterize(points, aggregator="mean", precompute=True, pixel_ratio=pixel_ratio, dynamic=dynamic)
    if return_raster:
        return raster.opts(**opts_kwargs, width=width, height=width)  * gf.coastline(projection=projection)
    point_dynspread = hd.dynspread(raster).opts(xaxis="bottom", yaxis="left", width=width, height=width)

    return point_dynspread.opts(**opts_kwargs) * gf.coastline(projection=projection)

def get_hv_points(projection, data_var):
    xPCS, yPCS, _ = projection.transform_points(ccrs.PlateCarree(), uxds.uxgrid.Mesh2_face_x.values, uxds.uxgrid.Mesh2_face_y.values).T
    point_dict = {"lon" : xPCS, "lat" : yPCS, "d_var" : uxds[data_var].sel(Time=0).values}
    point_ddf = dd.from_dict(data = point_dict, npartitions=10)
    points = hv.Points(point_ddf, ['lon', 'lat'])
    return points
plot_point_spread_bokeh(pixel_ratio=0.5, width=1000, height=500, return_raster=True, dynamic=True)
hoxbro commented 1 year ago

The figures are gorgeous.

Is it possible to get a working example to play around with?

philipc2 commented 1 year ago

The figures are gorgeous.

Is it possible to get a working example to play around with?

Thank you!! I can set up a minimal example with lat, lon, and data values for the dataset that I used.

philipc2 commented 1 year ago

@Hoxbro

Here's a notebook, I've also removed any uxarray (the package that we are developing these visualization for) requirements since I was working on a feature branch there.

I've also taken a subset of the 3.75km unstructured mesh and uploaded it to google drive. Is it okay if I share a link to that here?

hoxbro commented 1 year ago

Is it okay if I share a link to that here?

Yes.

philipc2 commented 1 year ago

Is it okay if I share a link to that here?

Yes.

Here's the dataset!

ahuang11 commented 1 year ago

Perhaps you could do something similar to this? https://discourse.holoviz.org/t/show-individual-points-when-zoomed-else-datashade/2204