Hexadron grid
PBrockmann opened this issue · comments
I like to display a mesh of hexaedron cells with geovista to have all projections available.
Here is the mesh I can create and display with pyvista.
import numpy as np
import xarray as xr
import pyvista as pv
ds = xr.open_dataset("https://thredds-su.ipsl.fr/thredds/dodsC/ipsl_thredds/brocksce/ICO/ICO.79.1jour.native.1_19790101_19790101_1D_inca_ges.nc")
blon = ds['bounds_lon'].to_numpy()
blat = ds['bounds_lat'].to_numpy()
nvertex = blon.shape[-1]
blon = blon.reshape(-1, nvertex)
blat = blat.reshape(-1, nvertex)
arr = ds['bounds_lon'].to_numpy()
blon = arr.reshape(-1, arr.shape[-1])
arr = ds['bounds_lat'].to_numpy()
blat = arr.reshape(-1, arr.shape[-1])
deg2rad = np.pi/180.
x = np.cos(blat*deg2rad)*np.cos(blon*deg2rad)
y = np.cos(blat*deg2rad)*np.sin(blon*deg2rad)
z = np.sin(blat*deg2rad)
points = np.stack((x,y,z), axis=2).reshape(x.size, 3)
faces = np.arange(x.shape[0] * nvertex).reshape(x.shape[0], nvertex)
faces = np.insert(faces, 0, nvertex, axis=1)
points = np.stack((x,y,z), axis=2).reshape(x.size, 3)
faces = np.arange(x.shape[0] * nvertex).reshape(x.shape[0], nvertex)
faces = np.insert(faces, 0, nvertex, axis=1)
mesh = pv.PolyData(points, faces)
pl = pv.Plotter()
pl.add_mesh(mesh, show_edges=True)
pl.show()
Now if I use geovista with this mesh that is in my understanding the same object as what gv.Transform.from_unstructured
returns I do not get the expected projected mesh.
plotter = gv.GeoPlotter(crs="ESRI:54030")
plotter.add_mesh(mesh, show_edges=True)
plotter.view_xy()
plotter.add_axes()
plotter.show()
What do I have missed ?
Ok it works by using indeed gv.Transform.from_unstructured
that defines additionnal parameters.
import numpy as np
import xarray as xr
import geovista as gv
ds = xr.open_dataset("https://thredds-su.ipsl.fr/thredds/dodsC/ipsl_thredds/brocksce/ICO/ICO.79.1jour.native.1_19790101_19790101_1D_inca_ges.nc")
blon = ds['bounds_lon'].to_numpy()
blat = ds['bounds_lat'].to_numpy()
nvertex = blon.shape[-1]
blon = blon.reshape(-1, nvertex)
blat = blat.reshape(-1, nvertex)
arr = ds['bounds_lon'].to_numpy()
blon = arr.reshape(-1, arr.shape[-1])
arr = ds['bounds_lat'].to_numpy()
blat = arr.reshape(-1, arr.shape[-1])
faces = np.arange(blon.shape[0] * nvertex).reshape(blon.shape[0], nvertex)
mesh = gv.Transform.from_unstructured(
blon.ravel(),
blat.ravel(),
connectivity = faces,
data = ds['temp'][0,0]
)
then
plotter = gv.GeoPlotter(crs="ESRI:54030")
plotter.add_mesh(mesh, cmap="thermal", show_edges=True, edge_color="black")
plotter.add_coastlines(resolution="50m", color="black")
plotter.view_xy()
plotter.add_axes()
plotter.show()
@PBrockmann Neat! Love it!
The geovista.bridge
is getting quite sophisticated, which means you can simply boil it down to the following...
import geovista as gv
import geovista.theme
import xarray as xr
ds = xr.open_dataset("ICO.79.1jour.native.1_19790101_19790101_1D_inca_ges.nc")
blon = ds['bounds_lon'].to_numpy()
blat = ds['bounds_lat'].to_numpy()
data = ds["ps"]
mesh = gv.Transform.from_unstructured(blon, blat, data=data[0].to_numpy())
pl = gv.GeoPlotter()
sargs = {"title": f"{data.long_name} / {data.units}", "shadow": True}
pl.add_mesh(mesh, show_edges=True, scalar_bar_args=sargs)
pl.add_coastlines()
pl.add_axes()
pl.show()
Yes indeed much more simpler.
No need of faces connectivity either.
Nice !
I dream about being able to update efficiently the data for each time step. Or vertical levels. To produce a kind of animation. Using ipywidgets.
I have made some prototype with this idea available from: https://github.com/PBrockmann/LSCE_notebooks/blob/main/pyvista_DYNAMICO_orthographic_trame.ipynb
See also discussion from: pyvista/pyvista#2567
It would be nice to share experience on this.