2222
2323from __future__ import annotations
2424
25- import cubedynamics .viz as viz
2625import matplotlib .pyplot as plt
2726import numpy as np
28- import xarray as xr
2927from IPython .display import display
3028
3129from ..config import TIME_DIM , X_DIM , Y_DIM
5755from .stats import anomaly , mean , rolling_tail_dep_vs_center , variance , zscore
5856
5957
58+ def _import_xarray ():
59+ """Import xarray lazily to avoid import-time hard dependency failures."""
60+
61+ import xarray as xr
62+
63+ return xr
64+
65+
6066def _unwrap_dataarray (
61- obj : xr . DataArray | VirtualCube | None ,
62- ) -> tuple [ xr . DataArray , xr . DataArray | VirtualCube ] :
67+ obj ,
68+ ):
6369 """
6470 Normalize a verb input to an (xarray.DataArray, original_obj) pair.
6571
@@ -73,6 +79,8 @@ def _unwrap_dataarray(
7379 if obj is None :
7480 raise ValueError ("extract() requires an input cube/DataArray; got None." )
7581
82+ xr = _import_xarray ()
83+
7684 if isinstance (obj , VirtualCube ):
7785 base_da = obj .materialize ()
7886 if not isinstance (base_da , xr .DataArray ):
@@ -154,6 +162,8 @@ def show_cube_lexcube(**kwargs):
154162 """
155163
156164 def _op (obj ):
165+ xr = _import_xarray ()
166+
157167 # normalize to DataArray if needed (Dataset with 1 var)
158168 if isinstance (obj , xr .Dataset ):
159169 if len (obj .data_vars ) != 1 :
@@ -173,6 +183,8 @@ def _op(obj):
173183 )
174184
175185 da = da .transpose (TIME_DIM , Y_DIM , X_DIM )
186+ import cubedynamics .viz as viz
187+
176188 widget = viz .show_cube_lexcube (da , ** kwargs )
177189 display (widget )
178190
0 commit comments