Skip to article frontmatterSkip to article content

Rendering XArray data with Vapor

While it is recommended to import data into Vapor using session.LoadDataset(), Vapor also supports importing data from XArray datasets.

The following cell will download sample data from NCAR’s Research Data Archives.

import os
import requests
import zipfile
url = 'https://data.rda.ucar.edu/ds897.7/Katrina.zip'
extract_to = './data'
zip_name = "Katrina.zip"
data_file = './data/wrfout_d02_2005-08-29_02.nc'

# Check if the data file already exists
if not os.path.exists(data_file):
    # Download zip
    with requests.get(url, stream=True) as r:
        r.raise_for_status()
        with open(zip_name, 'wb') as f:
            for chunk in r.iter_content(chunk_size=8192):
                f.write(chunk)
    # Extract the file
    with zipfile.ZipFile(zip_name, 'r') as zip_ref:
        zip_ref.extractall(extract_to)

    # Clean up the zip file
    os.remove(zip_name)

    print(f"Data downloaded and extracted to {data_file}")
else:
    print(f"Data file already exists at {data_file}, skipping download and extraction.")
---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
Cell In[1], line 13
     10 if not os.path.exists(data_file):
     11     # Download zip
     12     with requests.get(url, stream=True) as r:
---> 13         r.raise_for_status()
     14         with open(zip_name, 'wb') as f:
     15             for chunk in r.iter_content(chunk_size=8192):

File ~/micromamba/envs/cookbook-dev/lib/python3.13/site-packages/requests/models.py:1026, in Response.raise_for_status(self)
   1021     http_error_msg = (
   1022         f"{self.status_code} Server Error: {reason} for url: {self.url}"
   1023     )
   1025 if http_error_msg:
-> 1026     raise HTTPError(http_error_msg, response=self)

HTTPError: 404 Client Error: Not Found for url: https://data.rda.ucar.edu/ds897.7/Katrina.zip

In order to pass XArray data to Vapor, create a data set within your vapor session using Session.CreatePythonDataset().

from vapor import session, renderer, dataset, camera
import xarray as xr

ses = session.Session()
data = ses.CreatePythonDataset()

First we will load the dataset with XArray

ds = xr.open_dataset("data/wrfout_d02_2005-08-29_02.nc")
ds

We can add variables from our XArray dataset to our Vapor dataset using dataset.AddXarrayDataset(). We should be careful though -- once the data is loaded with XArray, Vapor cannot determine if a dimension is spatial or temporal. Because of this, we should make sure the data array we pass contains only spatial dimensions.

U10 = ds["U10"]
U10

In this case, U10 should be a two dimensional variable (longitude and latitude). But notice that in the DataArray we just created we still have a time dimension. Because of this, Vapor will incorrectly treat it as a 3 dimensional variable. Before passing the DataArray to Vapor, we should remove the temporal dimension.

U10 = ds["U10"].squeeze("Time")
U10

Now, we can add this variable to our Vapor dataset with dataset.AddXArrayData(). The first parameter will be the variable name that we want to appear in our Vapor dataset, while the second parameter is the XArray DataArray.

data.AddXArrayData("U10", U10)

Now, we can render our data using any of Vapor’s renderers.

# Create a renderer for the data
ren = data.NewRenderer(renderer.WireFrameRenderer)
ren.SetVariableName("U10")
# Show the rendering
ses.GetCamera().ViewAll()
ses.Show()
ses.DeleteRenderer(ren)

The same process can be used to render a 3D variable

data.AddXArrayData("U", ds["U"].squeeze("Time"))
ren = data.NewRenderer(renderer.WireFrameRenderer)
ren.SetVariableName("U")
ses.GetCamera().LookAt([ 138.64364963, -213.94716727,  293.46022828],
                       [157., 154.,   0.],
                       [0.04815987, 0.62133843, 0.78206086])
ses.Show()