Package: geovista
Cartographic rendering and mesh analytics powered byPyVista⚙️ CI💬 Community📈 Health✨ Meta📦 Package🧰 Repo🛡️ StatusMotivationThe goal of GeoVista is simple; to complementPyVistawith a convenient
cartographic capability.In this regard, from a design perspective we aim to keep GeoVista aspureto PyVista as possible i.e.,minimise specialisationas far as practically possible in order tomaximise native compatibilitywithin the
PyVista andVTKecosystems.We intend GeoVista to be a cartographic gateway into the powerful world of PyVista, and all that it offers.GeoVista is intentionally agnostic to packages such asgeopandas,iris,xarrayet al, which specialise in preparing your spatial data for visualisation. Rather, we delegate that responsibility and
choice of tool to you the user, as we want GeoVista to remain as flexible and open-ended as possible to the entire
Scientific Python community.Simply put, "GeoVista is to PyVista", as "Cartopy is to Matplotlib". Well, that's the aspiration.InstallationGeoVista is available on bothconda-forgeandPyPI.We recommend usingmambato install GeoVista 👍MambaGeoVista is available onconda-forge, and can be easily installed withmamba:mambainstall-cconda-forgegeovistaor alternatively withconda:condainstall-cconda-forgegeovistaFor more information see ourconda-forge feedstockandprefix.dev dashboard.PipGeoVista is also available onPyPI:pipinstallgeovistaCheckout out ourPyPI Download Stats, if you like that kinda thing.DeveloperIf you simply can't wait for the next release to play with the latest hot features, then you can easily
install themaindevelopment branch from GitHub:pipinstallgit+https://github.com/bjlittle/geovista@mainAlternatively, to configure a full developer environment, first clone the GeoVista GitHub repository:gitclonegit@github.com:bjlittle/geovista.gitChange to the root directory:cdgeovistaCreate thegeovista-devconda development environment:mambaenvcreate--filerequirements/geovista.ymlNow activate the environment and install themaindevelopment branch of GeoVista:condaactivategeovista-dev
pipinstall--no-deps--editable.Finally, you're good to roll 🥳And for extra credit, install our developerpre-commitgit-hooks:pre-commitinstallQuick StartGeoVista comes with various pre-canned resources to help get you started on your visualisation journey.ResourcesGeoVista makes use of various resources, such as rasters, VTK meshes,Natural Earthfeatures, and sample model data.If you want to download and cache all registered GeoVista resources to make them available offline, simply:geovistadownload--allAlternatively, just leave GeoVista to download resources on-the-fly, as and when she needs them.To view the list of registered resources, simply:geovistadownload--listWant to know more?geovistadownload--helpPlotting ExamplesLet's explore a sample of various oceanographic and atmospheric model data using GeoVista.WAVEWATCH IIIFirst, let's render aWAVEWATCH III(WW3)unstructuredtriangular mesh, with10m Natural Earth coastlines, a1:50m Natural Earth Cross-Blended Hypsometric Tintsbase layer, and the gorgeous perceptually uniformcmocean balancediverging
colormap.🗒importgeovistaasgvfromgeovista.pantryimportww3_global_triimportgeovista.theme# Load the sample data.sample=ww3_global_tri()# Create the mesh from the sample data.mesh=gv.Transform.from_unstructured(sample.lons,sample.lats,connectivity=sample.connectivity,data=sample.data)# Plot the mesh.plotter=gv.GeoPlotter()sargs={"title":f"{sample.name}/{sample.units}"}plotter.add_mesh(mesh,show_edges=True,scalar_bar_args=sargs)plotter.add_base_layer(texture=gv.natural_earth_hypsometric())plotter.add_coastlines(resolution="10m")plotter.add_graticule()plotter.view_xy(negative=True)plotter.add_axes()plotter.show()Finite Volume Community Ocean ModelNow, let's visualise the bathymetry of thePlymouth Sound and Tamar Riverfrom anFVCOMunstructuredmesh, as kindly provided by thePlymouth Marine Laboratoryusing the lushcmocean deepcolormap.🗒importgeovistaasgvfromgeovista.pantryimportfvcom_tamarimportgeovista.theme# Load the sample data.sample=fvcom_tamar()# Create the mesh from the sample data.mesh=gv.Transform.from_unstructured(sample.lons,sample.lats,connectivity=sample.connectivity,data=sample.face,name="face",)# Warp the mesh nodes by the bathymetry.mesh.point_data["node"]=sample.nodemesh.compute_normals(cell_normals=False,point_normals=True,inplace=True)mesh.warp_by_scalar(scalars="node",inplace=True,factor=2e-5)# Plot the mesh.plotter=gv.GeoPlotter()sargs={"title":f"{sample.name}/{sample.units}"}plotter.add_mesh(mesh,cmap="deep",scalar_bar_args=sargs)plotter.add_axes()plotter.show()CF UGRIDLocal Area ModelInitial projection support is available within GeoVista forCylindricalandPseudo-Cylindricalprojections. As
GeoVista matures and stabilises, we'll aim to complement this capability with other classes of projections, such asAzimuthalandConic.In the meantime, let's showcase our basic projection support with some high-resolutionunstructuredLocal Area Model
(LAM) data reprojected toMollweideusing aPROJstring, with10m Natural Earth coastlinesand a1:50m Natural Earth Cross-Blended Hypsometric Tintsbase layer.🗒importgeovistaasgvfromgeovista.pantryimportlam_pacificimportgeovista.theme# Load the sample data.sample=lam_pacific()# Create the mesh from the sample data.mesh=gv.Transform.from_unstructured(sample.lons,sample.lats,connectivity=sample.connectivity,data=sample.data,)# Plot the mesh on a mollweide projection using a Proj string.plotter=gv.GeoPlotter(crs="+proj=moll")sargs={"title":f"{sample.name}/{sample.units}"}plotter.add_mesh(mesh,scalar_bar_args=sargs)plotter.add_coastlines()plotter.add_base_layer(texture=gv.natural_earth_hypsometric())plotter.add_graticule()plotter.add_axes()plotter.view_xy()plotter.show()Using the sameunstructuredLAM data, reproject toEquidistant Cylindricalbut this time using aCartopy Plate Carrée CRS,
also with10m Natural Earth coastlinesand a1:50m Natural Earth Cross-Blended Hypsometric Tintsbase layer.🗒importcartopy.crsasccrsimportgeovistaasgvfromgeovista.pantryimportlam_pacificimportgeovista.theme# Load the sample data.sample=lam_pacific()# Create the mesh from the sample data.mesh=gv.Transform.from_unstructured(sample.lons,sample.lats,connectivity=sample.connectivity,data=sample.data,)# Plot the mesh on a Plate Carrée projection using a cartopy CRS.plotter=gv.GeoPlotter(crs=ccrs.PlateCarree(central_longitude=180))sargs={"title":f"{sample.name}/{sample.units}"}plotter.add_mesh(mesh,scalar_bar_args=sargs)plotter.add_coastlines()plotter.add_base_layer(texture=gv.natural_earth_hypsometric())plotter.add_graticule()plotter.add_axes()plotter.view_xy()plotter.show()LFRic Cube-SphereNow render aMet Office LFRicC48 cube-sphereunstructuredmesh of Sea Surface Temperature data on aRobinsonprojection using an ESRI SRID, with10m Natural Earth coastlinesand acmocean thermalcolormap.🗒importgeovistaasgvfromgeovista.pantryimportlfric_sstimportgeovista.theme# Load the sample data.sample=lfric_sst()# Create the mesh from the sample data.mesh=gv.Transform.from_unstructured(sample.lons,sample.lats,connectivity=sample.connectivity,data=sample.data,)# Plot the mesh on a Robinson projection using an ESRI spatial reference identifier.plotter=gv.GeoPlotter(crs="ESRI:54030")sargs={"title":f"{sample.name}/{sample.units}"}plotter.add_mesh(mesh,cmap="thermal",show_edges=True,scalar_bar_args=sargs)plotter.add_coastlines()plotter.view_xy()plotter.add_axes()plotter.show()UM ORCA2So far we've demonstrated GeoVista's ability to cope withunstructureddata. Now let's plot acurvilinearmesh
using Met Office Unified Model (UM) ORCA2 Sea Water Potential Temperature data, with10m Natural Earth coastlinesand a1:50m Natural Earth Ibase layer.🗒importgeovistaasgvfromgeovista.pantryimportum_orca2importgeovista.theme# Load sample data.sample=um_orca2()# Create the mesh from the sample data.mesh=gv.Transform.from_2d(sample.lons,sample.lats,data=sample.data)# Remove cells from the mesh with NaN values.mesh=mesh.threshold()# Plot the mesh.plotter=gv.GeoPlotter()sargs={"title":f"{sample.name}/{sample.units}"}plotter.add_mesh(mesh,show_edges=True,scalar_bar_args=sargs)plotter.add_base_layer(texture=gv.natural_earth_1())plotter.add_coastlines(resolution="10m")plotter.view_xy()plotter.add_axes()plotter.show()OISST AVHRRNow let's render aNOAA/NCEI Optimum Interpolation SST(OISST) Advanced Very High Resolution Radiometer (AVHRR)rectilinearmesh, with10m Natural Earth coastlinesand aNASA Blue Marblebase layer.🗒importgeovistaasgvfromgeovista.pantryimportoisst_avhrr_sstimportgeovista.theme# Load sample data.sample=oisst_avhrr_sst()# Create the mesh from the sample data.mesh=gv.Transform.from_1d(sample.lons,sample.lats,data=sample.data)# Remove cells from the mesh with NaN values.mesh=mesh.threshold()# Plot the mesh.plotter=gv.GeoPlotter()sargs={"title":f"{sample.name}/{sample.units}"}plotter.add_mesh(mesh,scalar_bar_args=sargs)plotter.add_base_layer(texture=gv.blue_marble())plotter.add_coastlines()plotter.view_xz()plotter.add_axes()plotter.show()DYNAMICO IcosahedralFinally, to demonstrate support for non-traditional cell geometries i.e., not triangles or quadrilaterals, we plot
theunstructuredicosahedral mesh from theDYNAMICOproject. This model uses hexagonal cells and is a new dynamical core forLMD-Z, the atmospheric General Circulation Model (GCM) part of theIPSL-CMEarth System Model. The render also contains10m Natural Earth coastlines.🗒importgeovistaasgvfromgeovista.pantryimporticosahedralimportgeovista.theme# Load sample data.sample=icosahedral()# Create the mesh from the sample data.mesh=gv.Transform.from_unstructured(sample.lons,sample.lats,data=sample.data)# Plot the mesh.plotter=gv.GeoPlotter()sargs={"title":f"{sample.name}/{sample.units}"}plotter.add_mesh(mesh,scalar_bar_args=sargs)plotter.add_coastlines()plotter.add_axes()plotter.show()Unreal ReelsGeoVista is built on the shoulders of giants, namelyPyVistaandVTK, thus allowing it to easily leverage the power of the GPU.As a result, it offers a paradigm shift in rendering performance and interactive user experience, as demonstrated by
this realtime, time-series animation of WAVEWATCH III® third-generation wave model (WAVE-height,WATer depth
andCurrentHindcasting), developed atNOAA/NCEP,
quasi-unstructured Spherical Multi-Cell (SMC) grid data of Sea Surface Wave Significant Height located on cell faces.🎥 WW3 SMC time-seriesFurther Examples"Please, sir, I want some more", Charles Dickens, Oliver Twist, 1838.Certainly, our pleasure! From the command line, simply:geovistaexamples--runall--verboseWant to know more?geovistaexamples--helpEcosystemWhilst you're here, why not hop on over to thepyvista-xarrayproject and
check it out!It's aiming to providexarray DataArray accessors for PyVista to visualize datasets in 3Dfor thexarraycommunity, and will be building on top of GeoVista 🎉SupportNeed help? 😢Why not check out ourexisting GitHub issues. See something similar?
Well, give it a 👍 to raise its priority and feel free to chip in on the conversation. Otherwise, don't hesitate to
create anew GitHub issueinstead.However, if you'd rather have a natter, then head on over to ourGitHub Discussions. That's definitely the place to wax lyrical all
things GeoVista!LicenseGeoVista is distributed under the terms of theBSD-3-Clauselicense.#ShowYourStripesGraphics and Lead Scientist:Ed Hawkins, National Centre for Atmospheric Science, University of Reading.Data: Berkeley Earth, NOAA, UK Met Office, MeteoSwiss, DWD, SMHI, UoR, Meteo France & ZAMG.#ShowYourStripesis distributed under aCreative Commons Attribution 4.0 International License