xarray
xarray copied to clipboard
Plotting empty DataArray oddly raises ImportError
What happened?
When calling the xarray.DataArray.plot() method on empty DataArrays raises an ImportError about a required, but missing, nc-time-axis package. This is at least confusing.
What did you expect to happen?
Either a more appropriate exception (to the effect of "don't try to plot nothing plz"). Or just get an empty plot returned.
Minimal Complete Verifiable Example
>>> import xarray as xr
>>> xr.DataArray([])
<xarray.DataArray (dim_0: 0)>
array([], dtype=float64)
Dimensions without coordinates: dim_0
>>> xr.DataArray([]).plot()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "foo/env/lib/python3.9/site-packages/xarray/plot/plot.py", line 866, in __call__
return plot(self._da, **kwargs)
File "foo/env/lib/python3.9/site-packages/xarray/plot/plot.py", line 332, in plot
return plotfunc(darray, **kwargs)
File "foo/env/lib/python3.9/site-packages/xarray/plot/plot.py", line 438, in line
_ensure_plottable(xplt_val, yplt_val)
File "foo/env/lib/python3.9/site-packages/xarray/plot/utils.py", line 648, in _ensure_plottable
raise ImportError(
ImportError: Plotting of arrays of cftime.datetime objects or arrays indexed by cftime.datetime objects requires the optional `nc-time-axis` (v1.2.0 or later) package.
MVCE confirmation
- [X] Minimal example — the example is as focused as reasonably possible to demonstrate the underlying issue in xarray.
- [X] Complete example — the example is self-contained, including all data and the text of any traceback.
- [ ] Verifiable example — the example copy & pastes into an IPython prompt or Binder notebook, returning the result.
- [X] New issue — a search of GitHub Issues suggests this is not a duplicate.
Relevant log output
No response
Anything else we need to know?
No response
Environment
xarray: 0.21.1 pandas: 1.4.0 numpy: 1.21.5 scipy: 1.8.1 netCDF4: 1.5.8 pydap: None h5netcdf: None h5py: None Nio: None zarr: None cftime: 1.5.2 nc_time_axis: None PseudoNetCDF: None rasterio: None cfgrib: None iris: None bottleneck: None dask: None distributed: None matplotlib: 3.5.1 cartopy: None seaborn: None numbagg: None fsspec: None cupy: None pint: None sparse: None setuptools: 49.2.1 pip: 22.2.2 conda: None pytest: 7.1.2 IPython: 8.0.1 sphinx: None
👁️ @headtr1ck
Thanks for the bug report @derhintze !
I'm confused as to why this wasn't caught by our tests - I thought we had a minimum-dependencies test run in our suite :confused:
the issue is that we only have a minimum dependencies CI (i.e. pandas and numpy but not matplotlib) and one that tests all dependencies with minimum versions. This means that we don't have an environment could have caught this (we'd need one with matplotlib but not nc-time-axis). This case is one of the issues we run into with so many optional dependencies: we can't just test every combination of them (the "all but dask" CI is an exception).
I don't think we have a test for plotting empty DataArrays, so no combination of dependencies would've picked that up?
We should just explicitly check for da.size > 0 before trying anything in .plot
pandas raises an error when plotting an empty dataframe:
import pandas as pd
a = pd.DataFrame()
a.plot()
Traceback (most recent call last):
File "C:\Users\J.W\AppData\Local\Temp\ipykernel_14580\3422621525.py", line 1, in <cell line: 1>
a.plot()
File "C:\Users\J.W\anaconda3\envs\xarray-tests\lib\site-packages\pandas\plotting\_core.py", line 1001, in __call__
return plot_backend.plot(data, kind=kind, **kwargs)
File "C:\Users\J.W\anaconda3\envs\xarray-tests\lib\site-packages\pandas\plotting\_matplotlib\__init__.py", line 71, in plot
plot_obj.generate()
File "C:\Users\J.W\anaconda3\envs\xarray-tests\lib\site-packages\pandas\plotting\_matplotlib\core.py", line 451, in generate
self._compute_plot_data()
File "C:\Users\J.W\anaconda3\envs\xarray-tests\lib\site-packages\pandas\plotting\_matplotlib\core.py", line 636, in _compute_plot_data
raise TypeError("no numeric data to plot")
TypeError: no numeric data to plot
pandas raises an error when plotting an empty dataframe:
... TypeError: no numeric data to plot
Not sure if TypeError is correct? Should it not be a ValueError?
This is raised by matplotlib, not pandas. Personally, I prefer aligning with upstream projects, so I'd pick that very same error.
One could argue that it's a ValueError in the sense that there's no data to plot, which is like an invalid value. But I also could see why they picked TypeError, because one could have non-numeric (but not empty) data. But yeah, this is nitpicking, I suppose 😆