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.")
---------------------------------------------------------------------------
SSLCertVerificationError Traceback (most recent call last)
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/connectionpool.py:464, in HTTPConnectionPool._make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)
463 try:
--> 464 self._validate_conn(conn)
465 except (SocketTimeout, BaseSSLError) as e:
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/connectionpool.py:1106, in HTTPSConnectionPool._validate_conn(self, conn)
1105 if conn.is_closed:
-> 1106 conn.connect()
1108 # TODO revise this, see https://github.com/urllib3/urllib3/issues/2791
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/connection.py:796, in HTTPSConnection.connect(self)
794 server_hostname_rm_dot = server_hostname.rstrip(".")
--> 796 sock_and_verified = _ssl_wrap_socket_and_match_hostname(
797 sock=sock,
798 cert_reqs=self.cert_reqs,
799 ssl_version=self.ssl_version,
800 ssl_minimum_version=self.ssl_minimum_version,
801 ssl_maximum_version=self.ssl_maximum_version,
802 ca_certs=self.ca_certs,
803 ca_cert_dir=self.ca_cert_dir,
804 ca_cert_data=self.ca_cert_data,
805 cert_file=self.cert_file,
806 key_file=self.key_file,
807 key_password=self.key_password,
808 server_hostname=server_hostname_rm_dot,
809 ssl_context=self.ssl_context,
810 tls_in_tls=tls_in_tls,
811 assert_hostname=self.assert_hostname,
812 assert_fingerprint=self.assert_fingerprint,
813 )
814 self.sock = sock_and_verified.socket
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/connection.py:975, in _ssl_wrap_socket_and_match_hostname(sock, cert_reqs, ssl_version, ssl_minimum_version, ssl_maximum_version, cert_file, key_file, key_password, ca_certs, ca_cert_dir, ca_cert_data, assert_hostname, assert_fingerprint, server_hostname, ssl_context, tls_in_tls)
973 server_hostname = normalized
--> 975 ssl_sock = ssl_wrap_socket(
976 sock=sock,
977 keyfile=key_file,
978 certfile=cert_file,
979 key_password=key_password,
980 ca_certs=ca_certs,
981 ca_cert_dir=ca_cert_dir,
982 ca_cert_data=ca_cert_data,
983 server_hostname=server_hostname,
984 ssl_context=context,
985 tls_in_tls=tls_in_tls,
986 )
988 try:
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/util/ssl_.py:433, in ssl_wrap_socket(sock, keyfile, certfile, cert_reqs, ca_certs, server_hostname, ssl_version, ciphers, ssl_context, ca_cert_dir, key_password, ca_cert_data, tls_in_tls)
431 context.set_alpn_protocols(ALPN_PROTOCOLS)
--> 433 ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
434 return ssl_sock
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/util/ssl_.py:477, in _ssl_wrap_socket_impl(sock, ssl_context, tls_in_tls, server_hostname)
475 return SSLTransport(sock, ssl_context, server_hostname)
--> 477 return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File ~/micromamba/envs/cookbook-dev/lib/python3.14/ssl.py:455, in SSLContext.wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, session)
449 def wrap_socket(self, sock, server_side=False,
450 do_handshake_on_connect=True,
451 suppress_ragged_eofs=True,
452 server_hostname=None, session=None):
453 # SSLSocket class handles server_hostname encoding before it calls
454 # ctx._wrap_socket()
--> 455 return self.sslsocket_class._create(
456 sock=sock,
457 server_side=server_side,
458 do_handshake_on_connect=do_handshake_on_connect,
459 suppress_ragged_eofs=suppress_ragged_eofs,
460 server_hostname=server_hostname,
461 context=self,
462 session=session
463 )
File ~/micromamba/envs/cookbook-dev/lib/python3.14/ssl.py:1076, in SSLSocket._create(cls, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, context, session)
1075 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
-> 1076 self.do_handshake()
1077 except:
File ~/micromamba/envs/cookbook-dev/lib/python3.14/ssl.py:1372, in SSLSocket.do_handshake(self, block)
1371 self.settimeout(None)
-> 1372 self._sslobj.do_handshake()
1373 finally:
SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1082)
During handling of the above exception, another exception occurred:
SSLError Traceback (most recent call last)
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/connectionpool.py:788, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)
787 # Make the request on the HTTPConnection object
--> 788 response = self._make_request(
789 conn,
790 method,
791 url,
792 timeout=timeout_obj,
793 body=body,
794 headers=headers,
795 chunked=chunked,
796 retries=retries,
797 response_conn=response_conn,
798 preload_content=preload_content,
799 decode_content=decode_content,
800 **response_kw,
801 )
803 # Everything went great!
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/connectionpool.py:488, in HTTPConnectionPool._make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)
487 new_e = _wrap_proxy_error(new_e, conn.proxy.scheme)
--> 488 raise new_e
490 # conn.request() calls http.client.*.request, not the method in
491 # urllib3.request. It also calls makefile (recv) on the socket.
SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1082)
The above exception was the direct cause of the following exception:
MaxRetryError Traceback (most recent call last)
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/requests/adapters.py:696, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies)
695 try:
--> 696 resp = conn.urlopen(
697 method=request.method,
698 url=url,
699 body=request.body, # type: ignore[arg-type] # urllib3 stubs don't accept Iterable[bytes | str]
700 headers=request.headers, # type: ignore[arg-type] # urllib3#3072
701 redirect=False,
702 assert_same_host=False,
703 preload_content=False,
704 decode_content=False,
705 retries=self.max_retries,
706 timeout=resolved_timeout,
707 chunked=chunked,
708 )
710 except (ProtocolError, OSError) as err:
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/connectionpool.py:842, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)
840 new_e = ProtocolError("Connection aborted.", new_e)
--> 842 retries = retries.increment(
843 method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2]
844 )
845 retries.sleep()
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/util/retry.py:543, in Retry.increment(self, method, url, response, error, _pool, _stacktrace)
542 reason = error or ResponseError(cause)
--> 543 raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
545 log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)
MaxRetryError: HTTPSConnectionPool(host='data.rda.ucar.edu', port=443): Max retries exceeded with url: /ds897.7/Katrina.zip (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1082)')))
During handling of the above exception, another exception occurred:
SSLError Traceback (most recent call last)
Cell In[1], line 12
8
9 # Check if the data file already exists
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.14/site-packages/requests/api.py:87, in get(url, params, **kwargs)
74 def get(
75 url: _t.UriType, params: _t.ParamsType = None, **kwargs: Unpack[_t.GetKwargs]
76 ) -> Response:
77 r"""Sends a GET request.
78
79 :param url: URL for the new :class:`Request` object.
(...) 84 :rtype: requests.Response
85 """
---> 87 return request("get", url, params=params, **kwargs)
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/requests/api.py:71, in request(method, url, **kwargs)
67 # By using the 'with' statement we are sure the session is closed, thus we
68 # avoid leaving sockets open which can trigger a ResourceWarning in some
69 # cases, and look like a memory leak in others.
70 with sessions.Session() as session:
---> 71 return session.request(method=method, url=url, **kwargs)
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/requests/sessions.py:651, in Session.request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
646 send_kwargs = {
647 "timeout": timeout,
648 "allow_redirects": allow_redirects,
649 }
650 send_kwargs.update(settings)
--> 651 resp = self.send(prep, **send_kwargs)
653 return resp
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/requests/sessions.py:784, in Session.send(self, request, **kwargs)
781 start = preferred_clock()
783 # Send the request
--> 784 r = adapter.send(request, **kwargs)
786 # Total elapsed time of the request (approximately)
787 elapsed = preferred_clock() - start
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/requests/adapters.py:727, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies)
723 raise ProxyError(e, request=request)
725 if isinstance(e.reason, _SSLError):
726 # This branch is for urllib3 v1.22 and later.
--> 727 raise SSLError(e, request=request)
729 raise ConnectionError(e, request=request)
731 except ClosedPoolError as e:
SSLError: HTTPSConnectionPool(host='data.rda.ucar.edu', port=443): Max retries exceeded with url: /ds897.7/Katrina.zip (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1082)')))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")
dsWe 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"]
U10In 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")
U10Now, 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()