I want to save the cross section data along a transect line between two coordinates as a netCDF file.
I'm following the example code described in Metpy's Cross Section Analysis:
Here's the modified code adding the remove crs command:
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import numpy as np
import xarray as xr
import metpy.calc as mpcalc
from metpy.interpolate import cross_section
#use xarray to read the data
data = xr.open_dataset('/home/rik/hrrr/gtgn/gtgn.t2215z.edr.f000.nc')
print(data)
<xarray.Dataset>
Dimensions: (alt: 52, time: 1, x: 451, y: 337)
Coordinates:
* time (time) datetime64[ns] 2020-06-18T22:15:00
* x (x) float64 0.0 1.355e+04 ... 6.082e+06 6.095e+06
* y (y) float64 0.0 1.355e+04 ... 4.538e+06 4.551e+06
* alt (alt) float64 0.0 30.0 304.0 ... 1.494e+04 1.524e+04
Data variables:
Lambert_Conformal int32 ...
param30.19.0 (time, alt, y, x) float32 ...
Attributes:
CDI: Climate Data Interface version 1.9.8 (https://mpimet.mpg.de...
Conventions: CF-1.6
history: Wed Oct 07 17:19:41 2020: cdo -f nc copy gtgn.t2215z.edr.f0...
institution: National Center for Atmospheric Research
CDO: Climate Data Operators version 1.9.8 (https://mpimet.mpg.de...
#parse the data and remove crs from coordinate
data = data.metpy.parse_cf().squeeze()
data.drop_vars('crs')
print(data)
<xarray.Dataset>
Dimensions: (alt: 52, x: 451, y: 337)
Coordinates:
time datetime64[ns] 2020-06-18T22:15:00
* x (x) float64 0.0 1.355e+04 ... 6.082e+06 6.095e+06
* y (y) float64 0.0 1.355e+04 ... 4.538e+06 4.551e+06
* alt (alt) float64 0.0 30.0 304.0 ... 1.494e+04 1.524e+04
crs object Projection: lambert_conformal_conic
Data variables:
Lambert_Conformal int32 ...
param30.19.0 (alt, y, x) float32 ...
Attributes:
CDI: Climate Data Interface version 1.9.8 (https://mpimet.mpg.de...
Conventions: CF-1.6
history: Wed Oct 07 17:19:41 2020: cdo -f nc copy gtgn.t2215z.edr.f0...
institution: National Center for Atmospheric Research
CDO: Climate Data Operators version 1.9.8 (https://mpimet.mpg.de...
#define start and end points
start = (37.0, -105.0)
end = (35.5, -90.0)
#get the cross section
cross = cross_section(data, start, end)
print(cross)
<xarray.Dataset>
Dimensions: (alt: 52, index: 100)
Coordinates:
time datetime64[ns] 2020-06-18T22:15:00
crs object Projection: lambert_conformal_conic
* alt (alt) float64 0.0 30.0 304.0 ... 1.494e+04 1.524e+04
x (index) float64 2.424e+06 2.438e+06 ... 3.793e+06
y (index) float64 1.967e+06 1.965e+06 ... 1.772e+06
* index (index) int64 0 1 2 3 4 5 6 7 ... 92 93 94 95 96 97 98 99
Data variables:
Lambert_Conformal int32 ...
param30.19.0 (alt, index) float64 0.3914 0.3687 ... 0.0605 0.0605
Attributes:
CDI: Climate Data Interface version 1.9.8 (https://mpimet.mpg.de...
Conventions: CF-1.6
history: Wed Oct 07 17:19:41 2020: cdo -f nc copy gtgn.t2215z.edr.f0...
institution: National Center for Atmospheric Research
CDO: Climate Data Operators version 1.9.8 (https://mpimet.mpg.de...
When I try to write/save the cross section xarray.dataset
as a netCDF file I get the following error message:
cross.to_netcdf('/home/rik/hrrr/gtgn/xarray_cross_section_data_to_netcdf.nc')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-12-0b4fce1219bd> in <module>
----> 1 cross.to_netcdf('/home/rik/hrrr/gtgn/xarray_cross_section_data_to_netcdf.nc')
~/miniconda3/envs/metpy/lib/python3.7/site-packages/xarray/core/dataset.py in to_netcdf(self, path, mode, format, group, engine, encoding, unlimited_dims, compute, invalid_netcdf)
1565 unlimited_dims=unlimited_dims,
1566 compute=compute,
-> 1567 invalid_netcdf=invalid_netcdf,
1568 )
1569
~/miniconda3/envs/metpy/lib/python3.7/site-packages/xarray/backends/api.py in to_netcdf(dataset, path_or_file, mode, format, group, engine, encoding, unlimited_dims, compute, multifile, invalid_netcdf)
1080 # to be parallelized with dask
1081 dump_to_store(
-> 1082 dataset, store, writer, encoding=encoding, unlimited_dims=unlimited_dims
1083 )
1084 if autoclose:
~/miniconda3/envs/metpy/lib/python3.7/site-packages/xarray/backends/api.py in dump_to_store(dataset, store, writer, encoder, encoding, unlimited_dims)
1126 variables, attrs = encoder(variables, attrs)
1127
-> 1128 store.store(variables, attrs, check_encoding, writer, unlimited_dims=unlimited_dims)
1129
1130
~/miniconda3/envs/metpy/lib/python3.7/site-packages/xarray/backends/common.py in store(self, variables, attributes, check_encoding_set, writer, unlimited_dims)
248 writer = ArrayWriter()
249
--> 250 variables, attributes = self.encode(variables, attributes)
251
252 self.set_attributes(attributes)
~/miniconda3/envs/metpy/lib/python3.7/site-packages/xarray/backends/common.py in encode(self, variables, attributes)
337 # All NetCDF files get CF encoded by default, without this attempting
338 # to write times, for example, would fail.
--> 339 variables, attributes = cf_encoder(variables, attributes)
340 variables = {k: self.encode_variable(v) for k, v in variables.items()}
341 attributes = {k: self.encode_attribute(v) for k, v in attributes.items()}
~/miniconda3/envs/metpy/lib/python3.7/site-packages/xarray/conventions.py in cf_encoder(variables, attributes)
771 _update_bounds_encoding(variables)
772
--> 773 new_vars = {k: encode_cf_variable(v, name=k) for k, v in variables.items()}
774
775 # Remove attrs from bounds variables (issue #2921)
~/miniconda3/envs/metpy/lib/python3.7/site-packages/xarray/conventions.py in <dictcomp>(.0)
771 _update_bounds_encoding(variables)
772
--> 773 new_vars = {k: encode_cf_variable(v, name=k) for k, v in variables.items()}
774
775 # Remove attrs from bounds variables (issue #2921)
~/miniconda3/envs/metpy/lib/python3.7/site-packages/xarray/conventions.py in encode_cf_variable(var, needs_copy, name)
256 var = maybe_default_fill_value(var)
257 var = maybe_encode_bools(var)
--> 258 var = ensure_dtype_not_object(var, name=name)
259 return var
260
~/miniconda3/envs/metpy/lib/python3.7/site-packages/xarray/conventions.py in ensure_dtype_not_object(var, name)
214 data[missing] = fill_value
215 else:
--> 216 data = _copy_with_dtype(data, dtype=_infer_dtype(data, name))
217
218 assert data.dtype.kind != "O" or data.dtype.metadata
~/miniconda3/envs/metpy/lib/python3.7/site-packages/xarray/conventions.py in _infer_dtype(array, name)
150 raise ValueError(
151 "unable to infer dtype on variable {!r}; xarray "
--> 152 "cannot serialize arbitrary Python objects".format(name)
153 )
154
ValueError: unable to infer dtype on variable 'crs'; xarray cannot serialize arbitrary Python objects
What am I doing wrong?
As @Robert Wilson suggested in the comments, you have to remove
crs
from your coordinates. However,drop_vars()
removes variables from a dataset. To remove a coordinate as in your case:Reference