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:470, in HTTPConnectionPool._make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)
469 try:
--> 470 self._validate_conn(conn)
471 except (SocketTimeout, BaseSSLError) as e:
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/connectionpool.py:1125, in HTTPSConnectionPool._validate_conn(self, conn)
1124 if conn.is_closed:
-> 1125 conn.connect()
1127 # TODO revise this, see https://github.com/urllib3/urllib3/issues/2791
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/connection.py:878, in HTTPSConnection.connect(self)
877 else:
--> 878 wrapped_socket, is_verified = _ssl_wrap_socket_and_match_hostname(
879 sock=sock,
880 cert_reqs=self.cert_reqs,
881 ssl_version=self.ssl_version,
882 ssl_minimum_version=self.ssl_minimum_version,
883 ssl_maximum_version=self.ssl_maximum_version,
884 ca_certs=self.ca_certs,
885 ca_cert_dir=self.ca_cert_dir,
886 ca_cert_data=self.ca_cert_data,
887 cert_file=self.cert_file,
888 key_file=self.key_file,
889 key_password=self.key_password,
890 server_hostname=server_hostname_rm_dot,
891 ssl_context=self.ssl_context,
892 tls_in_tls=tls_in_tls,
893 assert_hostname=self.assert_hostname,
894 assert_fingerprint=self.assert_fingerprint,
895 )
896 self.sock = wrapped_socket
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/connection.py:1080, 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)
1078 server_hostname = normalized
-> 1080 ssl_sock = ssl_wrap_socket(
1081 sock=sock,
1082 keyfile=key_file,
1083 certfile=cert_file,
1084 key_password=key_password,
1085 ca_certs=ca_certs,
1086 ca_cert_dir=ca_cert_dir,
1087 ca_cert_data=ca_cert_data,
1088 server_hostname=server_hostname,
1089 ssl_context=context,
1090 tls_in_tls=tls_in_tls,
1091 )
1093 try:
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/util/ssl_.py:437, 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)
435 context.set_alpn_protocols(ALPN_PROTOCOLS)
--> 437 ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
438 return ssl_sock
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/util/ssl_.py:481, in _ssl_wrap_socket_impl(sock, ssl_context, tls_in_tls, server_hostname)
479 return SSLTransport(sock, ssl_context, server_hostname)
--> 481 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:793, 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)
792 # Make the request on the HTTPConnection object
--> 793 response = self._make_request(
794 conn,
795 method,
796 url,
797 timeout=timeout_obj,
798 body=body,
799 headers=headers,
800 chunked=chunked,
801 retries=retries,
802 response_conn=response_conn,
803 preload_content=preload_content,
804 decode_content=decode_content,
805 **response_kw,
806 )
808 # Everything went great!
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/connectionpool.py:494, in HTTPConnectionPool._make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)
493 new_e = _wrap_proxy_error(new_e, conn.proxy.scheme)
--> 494 raise new_e
496 # conn.request() calls http.client.*.request, not the method in
497 # 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:847, 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)
845 new_e = ProtocolError("Connection aborted.", new_e)
--> 847 retries = retries.increment(
848 method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2]
849 )
850 retries.sleep()
File ~/micromamba/envs/cookbook-dev/lib/python3.14/site-packages/urllib3/util/retry.py:555, in Retry.increment(self, method, url, response, error, _pool, _stacktrace)
554 reason = error or ResponseError(cause)
--> 555 raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
557 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()