pyvista / pyvista-xarray

xarray DataArray accessors for PyVista
Apache License 2.0
98 stars 6 forks source link

Nodata issue #34

Closed giswqs closed 1 year ago

giswqs commented 2 years ago

I am trying to display an elevation dataset, but it seems pyvista-xarray somehow uses the nodata value as the minimum value to render the data, making it look like a long vertical column. Is it possible to specify a minimum value to prevent pyxarray from using the nodata value for rendering?

import rioxarray

da = rioxarray.open_rasterio("madison.tif")
da = da.rio.reproject("EPSG:3857")

# Grab the mesh object for use with PyVista
mesh = da[dict(band=0)].pyvista.mesh(x="x", y="y")

# plot in 3D
mesh.warp_by_scalar().plot()

image

Rendering the original lidar point cloud

import leafmap
leafmap.view_lidar('madison.las', cmap='terrain')

image

giswqs commented 2 years ago

The minimum and maximum values of the GeoTIFF are recognized by QGIS correctly. Not sure why pyxarray does not recognize them.

image

banesullivan commented 2 years ago

Take a look at #35 and try the following now:

import rioxarray

da = rioxarray.open_rasterio("madison.tif")
da = da.rio.reproject("EPSG:3857")

# Grab the mesh object for use with PyVista
mesh = da[dict(band=0)].pyvista.mesh(x="x", y="y", nodata=da.rio.nodata)

# plot in 3D
mesh.warp_by_scalar().plot()

35 is a half-baked solution that I'd like to hold off on merging

banesullivan commented 2 years ago

The minimum and maximum values of the GeoTIFF are recognized by QGIS correctly. Not sure why pyxarray does not recognize them.

The nodata value is in the metadata of the geotiff itself. If you have rioxarray installed, we could use that accessor to get the nodata value programmatically (as I do above)

This is actually a bit of a nuanced issue, and my exhausted brain doesn't have a great solution for you at the moment... the solution I provide in #35 has what could be serious side effects by modifying the data inplace or copying the values (converting int to float and thus blowing up memory usage for large datasets)

giswqs commented 2 years ago

Thanks for looking into it. The issue seems a bit more complicated than I expected. da.rio.nodata can indeed get the nodata value. -32768.0 seems quite commonly used for nodata. Can we modify the GeoTIFF nodata value to zero or a value slighly smaller than the minimum value? This can potentially create new GeoTIFF that works with pvxarray. What I meant is to prepare an input file that will works with pvxarray rather than asking pvxarray to deal with such nodata issue.

image