From 6b5b5e3c4cfeb940c8ba5c33fd2599b88093a69f Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 26 Jun 2025 16:16:40 +0200 Subject: [PATCH 1/2] add error when plotting cftime --- ultraplot/internals/inputs.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/ultraplot/internals/inputs.py b/ultraplot/internals/inputs.py index 6b61dbc2b..710a4b47e 100644 --- a/ultraplot/internals/inputs.py +++ b/ultraplot/internals/inputs.py @@ -139,24 +139,42 @@ def _to_duck_array(data, strip_units=False): def _to_numpy_array(data, strip_units=False): """ - Convert arbitrary input to numpy array. Preserve masked arrays and unit arrays. + Convert arbitrary input to a numpy array. Preserve masked arrays and unit arrays. + If the array contains cftime objects, require nc-time-axis to be installed. """ _load_objects() if data is None: raise ValueError("Invalid data None.") + if isinstance(data, ndarray): pass elif isinstance(data, DataArray): data = data.data # support pint quantities that get unit-stripped later elif isinstance(data, (DataFrame, Series, Index)): data = data.values + if Quantity is not ndarray and isinstance(data, Quantity): if strip_units: - return np.atleast_1d(data.magnitude) + result = np.atleast_1d(data.magnitude) else: - return np.atleast_1d(data.magnitude) * data.units + result = np.atleast_1d(data.magnitude) * data.units else: - return np.atleast_1d(data) # natively preserves masked arrays + result = np.atleast_1d(data) # natively preserves masked arrays + + # If the array contains cftime objects, ensure nc-time-axis is available. + if result.size: + first_elem = result.flat[0] + if hasattr( + first_elem, "__class__" + ) and first_elem.__class__.__module__.startswith("cftime"): + try: + import nc_time_axis # This module registers its converter automatically. + except ImportError: + raise ImportError( + "The input data contains cftime objects, but nc_time_axis is not available. " + "Please install nc_time_axis to handle these dates correctly." + ) + return result def _to_masked_array(data, *, copy=False): From 00eb243776e1d05bb1153ca2635dfc2d958a2c8b Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 26 Jun 2025 16:30:23 +0200 Subject: [PATCH 2/2] make explicit flat --- ultraplot/internals/inputs.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ultraplot/internals/inputs.py b/ultraplot/internals/inputs.py index 710a4b47e..41baa7ea2 100644 --- a/ultraplot/internals/inputs.py +++ b/ultraplot/internals/inputs.py @@ -160,10 +160,9 @@ def _to_numpy_array(data, strip_units=False): result = np.atleast_1d(data.magnitude) * data.units else: result = np.atleast_1d(data) # natively preserves masked arrays - # If the array contains cftime objects, ensure nc-time-axis is available. if result.size: - first_elem = result.flat[0] + first_elem = result.flatten()[0] if hasattr( first_elem, "__class__" ) and first_elem.__class__.__module__.startswith("cftime"):