Search code examples
python-xarraymetpy

Cause of ValueError while plotting Cross Section Analysis on Metpy


I get the example code from this website: https://unidata.github.io/MetPy/latest/examples/cross_section.html#sphx-glr-examples-cross-section-py

I wonder why the example programs can't work on my computer with either xarray-0.15.0 or with xarray-0.15.1.

the original code is below

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.cbook import get_test_data
from metpy.interpolate import cross_section

data = xr.open_dataset(get_test_data('narr_example.nc', False))
data = data.metpy.parse_cf().squeeze()
print(data)

start = (37.0, -105.0)
end = (35.5, -65.0)

cross = cross_section(data, start, end).set_coords(('lat', 'lon'))
print(cross)

temperature, pressure, specific_humidity = xr.broadcast(cross['Temperature'],
                                                        cross['isobaric'],
                                                        cross['Specific_humidity'])

theta = mpcalc.potential_temperature(pressure, temperature)
rh = mpcalc.relative_humidity_from_specific_humidity(pressure, temperature, specific_humidity)

# These calculations return unit arrays, so put those back into DataArrays in our Dataset
cross['Potential_temperature'] = xr.DataArray(theta,
                                              coords=temperature.coords,
                                              dims=temperature.dims,
                                              attrs={'units': theta.units})
cross['Relative_humidity'] = xr.DataArray(rh,
                                          coords=specific_humidity.coords,
                                          dims=specific_humidity.dims,
                                          attrs={'units': rh.units})

cross['u_wind'].metpy.convert_units('knots')
cross['v_wind'].metpy.convert_units('knots')
cross['t_wind'], cross['n_wind'] = mpcalc.cross_section_components(cross['u_wind'],
                                                                   cross['v_wind'])

print(cross)

the error information is below (with xarray-0.15.1)

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-506a7aabdc3e> in <module>
      1 data = xr.open_dataset(get_test_data('narr_example.nc', False))
----> 2 data = data.metpy.parse_cf().squeeze()
      3 print(data)

/opt/anaconda3/lib/python3.7/site-packages/metpy/xarray.py in parse_cf(self, varname, coordinates)
    502             # If non-string iterable is given, apply recursively across the varnames
    503             subset = xr.merge([self.parse_cf(single_varname, coordinates=coordinates)
--> 504                                for single_varname in varname])
    505             subset.attrs = self._dataset.attrs
    506             return subset

/opt/anaconda3/lib/python3.7/site-packages/metpy/xarray.py in <listcomp>(.0)
    502             # If non-string iterable is given, apply recursively across the varnames
    503             subset = xr.merge([self.parse_cf(single_varname, coordinates=coordinates)
--> 504                                for single_varname in varname])
    505             subset.attrs = self._dataset.attrs
    506             return subset

/opt/anaconda3/lib/python3.7/site-packages/metpy/xarray.py in parse_cf(self, varname, coordinates)
    518                 var.coords['crs'] = CFProjection(proj_var.attrs)
    519 
--> 520         self._fixup_coords(var)
    521 
    522         # Trying to guess whether we should be adding a crs to this variable's coordinates

/opt/anaconda3/lib/python3.7/site-packages/metpy/xarray.py in _fixup_coords(self, var)
    547                     and not check_axis(data_array, 'longitude', 'latitude')):
    548                 try:
--> 549                     var.coords[coord_name].metpy.convert_units('meters')
    550                 except DimensionalityError:  # Radians!
    551                     if 'crs' in var.coords:

/opt/anaconda3/lib/python3.7/site-packages/metpy/xarray.py in convert_units(self, units)
    143     def convert_units(self, units):
    144         """Convert the data values to different units in-place."""
--> 145         self.unit_array = self.unit_array.to(units)
    146 
    147     @property

/opt/anaconda3/lib/python3.7/site-packages/metpy/xarray.py in unit_array(self, values)
    138     def unit_array(self, values):
    139         """Set data values from a `pint.Quantity`."""
--> 140         self._data_array.values = values.magnitude
    141         self._units = self._data_array.attrs['units'] = str(values.units)
    142 

/opt/anaconda3/lib/python3.7/site-packages/xarray/core/common.py in __setattr__(self, name, value)
    260         """
    261         try:
--> 262             object.__setattr__(self, name, value)
    263         except AttributeError as e:
    264             # Don't accidentally shadow custom AttributeErrors, e.g.

/opt/anaconda3/lib/python3.7/site-packages/xarray/core/dataarray.py in values(self, value)
    560     @values.setter
    561     def values(self, value: Any) -> None:
--> 562         self.variable.values = value
    563 
    564     @property

/opt/anaconda3/lib/python3.7/site-packages/xarray/core/variable.py in values(self, values)
   2113     def values(self, values):
   2114         raise ValueError(
-> 2115             f"Cannot assign to the .values attribute of dimension coordinate a.k.a IndexVariable {self.name!r}. "
   2116             f"Please use DataArray.assign_coords, Dataset.assign_coords or Dataset.assign as appropriate."
   2117         )

ValueError: Cannot assign to the .values attribute of dimension coordinate a.k.a IndexVariable 'y'. Please use DataArray.assign_coords, Dataset.assign_coords or Dataset.assign as appropriate.

the error information is below (with xarray-0.15.0)

Traceback (most recent call last):
  File "cross_section.py", line 57, in <module>
    rh = mpcalc.relative_humidity_from_specific_humidity(pressure, temperature, specific_humidity)
  File "/opt/anaconda3/lib/python3.7/site-packages/metpy/xarray.py", line 655, in wrapper
    return func(*args, **kwargs)
  File "/opt/anaconda3/lib/python3.7/site-packages/metpy/units.py", line 319, in wrapper
    raise ValueError(msg)
ValueError: `relative_humidity_from_specific_humidity` given arguments with incorrect units: `specific_humidity` requires "[dimensionless]" but given "hectopascal", `pressure` requires "[pressure]" but given "dimensionless".


Solution

  • The problem with xarray 0.15.1 is a known issue that should be fixed in the next release.

    The error you get with 0.15.0 is certainly confusing. The problem is that the example code you're using is from the docs, which were pointing to the docs for 1.0, which is currently in release candidate status--which means you're most likely not running it, but MetPy 0.12. The problem is that MetPy 1.0 changes the order of arguments to the relative_humidity_from_specific_humidity. So the example code you downloaded wasn't appropriate for the version of MetPy you're running.

    I have updated the MetPy docs to point the latest docs to the 0.12 release docs. You should now be able to download the correct example code for your version.