Repository: Unidata/MetPy

Issue:
mpcalc.isentropic_interpolation_as_dataset "vertical attribute is not available."
I get an error "vertical attribute is not available." when interpolating bitwise vortices to isentropic surfaces using the mpcalc.isentropic_interpolation_as_dataset function.Here's the code and the specifics of the error reported：

```python
f=xr.open_dataset(r'H:\data\dust\daily_atmosphere_data\daily_mean_era5_pv0.5_198604.nc')
f_1=xr.open_dataset(r'H:\data\dust\daily_atmosphere_data\daily_mean_era5_t0.5_198604.nc')
pv=f.pv.loc['1986-04-01',100000:20000,20:60,30:150] # （level，lat，lon）
t=f_1.t.loc['1986-04-01',100000:20000,20:60,30:150]# （level，lat，lon）
print(t,pv)
isentlevs = [345.] * units.kelvin
print(isen_lev)
isent_data = mpcalc.isentropic_interpolation_as_dataset(isentlevs, t, pv)
```
```
C:\Users\Administrator\AppData\Local\Temp\ipykernel_8224\906077059.py:12: UserWarning: More than one vertical coordinate present for variable  "t".
  isent_data = mpcalc.isentropic_interpolation_as_dataset(isentlevs, t, pv)
```

```pytb
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Input In [20], in <cell line: 12>()
     10 print(isen_lev)
     11 # 调用 isentropic_interpolation_as_dataset 函数
---> 12 isent_data = mpcalc.isentropic_interpolation_as_dataset(isentlevs, t, pv)

File G:\Anaconda\lib\site-packages\metpy\calc\thermo.py:2761, in isentropic_interpolation_as_dataset(levels, temperature, max_iters, eps, bottom_up_search, *args)
   2756 all_args = xr.broadcast(temperature, *args)
   2758 # Obtain result as list of Quantities
   2759 ret = isentropic_interpolation(
   2760     levels,
-> 2761     all_args[0].metpy.vertical,
   2762     all_args[0].metpy.unit_array,
   2763     *(arg.metpy.unit_array for arg in all_args[1:]),
   2764     vertical_dim=all_args[0].metpy.find_axis_number('vertical'),
   2765     temperature_out=True,
   2766     max_iters=max_iters,
   2767     eps=eps,
   2768     bottom_up_search=bottom_up_search
   2769 )
   2771 # Reconstruct coordinates and dims (add isentropic levels, remove isobaric levels)
   2772 vertical_dim = all_args[0].metpy.find_axis_name('vertical')

File G:\Anaconda\lib\site-packages\metpy\xarray.py:486, in MetPyDataArrayAccessor.vertical(self)
    483 @property
    484 def vertical(self):
    485     """Return the vertical coordinate."""
--> 486     return self._axis('vertical')

File G:\Anaconda\lib\site-packages\metpy\xarray.py:418, in MetPyDataArrayAccessor._axis(self, axis)
    416 coord_var = self._metpy_axis_search(axis)
    417 if coord_var is None:
--> 418     raise AttributeError(axis + ' attribute is not available.')
    419 else:
    420     return coord_var

AttributeError: vertical attribute is not available.
```


Comments:

Patch:
diff --git a/ci/extra_requirements.txt b/ci/extra_requirements.txt
index 70a45f6230..590f2f0b2f 100644
--- a/ci/extra_requirements.txt
+++ b/ci/extra_requirements.txt
@@ -1,3 +1,3 @@
 cartopy==0.22.0
-dask==2024.3.0
+dask==2024.3.1
 shapely==2.0.3
diff --git a/ci/linting_requirements.txt b/ci/linting_requirements.txt
index a67d1f70f0..1d739578d5 100644
--- a/ci/linting_requirements.txt
+++ b/ci/linting_requirements.txt
@@ -1,4 +1,4 @@
-ruff==0.3.2
+ruff==0.3.3
 
 flake8==7.0.0
 pycodestyle==2.11.1
diff --git a/src/metpy/calc/basic.py b/src/metpy/calc/basic.py
index 0e164e1b04..a290e3df12 100644
--- a/src/metpy/calc/basic.py
+++ b/src/metpy/calc/basic.py
@@ -52,6 +52,13 @@ def wind_speed(u, v):
     --------
     wind_components
 
+    Examples
+    --------
+    >>> from metpy.calc import wind_speed
+    >>> from metpy.units import units
+    >>> wind_speed(10. * units('m/s'), 10. * units('m/s'))
+    <Quantity(14.1421356, 'meter / second')>
+
     """
     return np.hypot(u, v)
 
@@ -88,6 +95,13 @@ def wind_direction(u, v, convention='from'):
     In the case of calm winds (where `u` and `v` are zero), this function returns a direction
     of 0.
 
+    Examples
+    --------
+    >>> from metpy.calc import wind_direction
+    >>> from metpy.units import units
+    >>> wind_direction(10. * units('m/s'), 10. * units('m/s'))
+    <Quantity(225.0, 'degree')>
+
     """
     wdir = units.Quantity(90., 'deg') - np.arctan2(-v, -u)
     origshape = wdir.shape
@@ -141,7 +155,7 @@ def wind_components(speed, wind_direction):
     >>> from metpy.calc import wind_components
     >>> from metpy.units import units
     >>> wind_components(10. * units('m/s'), 225. * units.deg)
-     (<Quantity(7.07106781, 'meter / second')>, <Quantity(7.07106781, 'meter / second')>)
+    (<Quantity(7.07106781, 'meter / second')>, <Quantity(7.07106781, 'meter / second')>)
 
     .. versionchanged:: 1.0
        Renamed ``wdir`` parameter to ``wind_direction``
diff --git a/src/metpy/calc/tools.py b/src/metpy/calc/tools.py
index c34453c8f3..12640a6561 100644
--- a/src/metpy/calc/tools.py
+++ b/src/metpy/calc/tools.py
@@ -1825,6 +1825,13 @@ def angle_to_direction(input_angle, full=False, level=3):
     direction
         The directional text
 
+    Examples
+    --------
+    >>> from metpy.calc import angle_to_direction
+    >>> from metpy.units import units
+    >>> angle_to_direction(225. * units.deg)
+    'SW'
+
     """
     try:  # strip units temporarily
         origin_units = input_angle.units
diff --git a/src/metpy/xarray.py b/src/metpy/xarray.py
index 2ccb36ce0a..ab16f76802 100644
--- a/src/metpy/xarray.py
+++ b/src/metpy/xarray.py
@@ -338,15 +338,16 @@ class MetPyDataArrayAccessor:
     def _generate_coordinate_map(self):
         """Generate a coordinate map via CF conventions and other methods."""
         coords = self._data_array.coords.values()
-        # Parse all the coordinates, attempting to identify x, longitude, y, latitude,
-        # vertical, time
-        coord_lists = {'time': [], 'vertical': [], 'y': [], 'latitude': [], 'x': [],
-                       'longitude': []}
+        # Parse all the coordinates, attempting to identify longitude, latitude, x, y,
+        # time, vertical, in that order.
+        coord_lists = {'longitude': [], 'latitude': [], 'x': [], 'y': [], 'time': [],
+                       'vertical': []}
         for coord_var in coords:
             # Identify the coordinate type using check_axis helper
             for axis in coord_lists:
                 if check_axis(coord_var, axis):
                     coord_lists[axis].append(coord_var)
+                    break  # Ensure a coordinate variable only goes to one axis
 
         # Fill in x/y with longitude/latitude if x/y not otherwise present
         for geometric, graticule in (('y', 'latitude'), ('x', 'longitude')):


Test patch:
diff --git a/ci/test_requirements.txt b/ci/test_requirements.txt
index 4302ff9e96..61b6ff44b9 100644
--- a/ci/test_requirements.txt
+++ b/ci/test_requirements.txt
@@ -2,4 +2,4 @@ packaging==24.0
 pytest==8.1.1
 pytest-mpl==0.17.0
 netCDF4==1.6.5
-coverage==7.4.3
+coverage==7.4.4
diff --git a/tests/test_xarray.py b/tests/test_xarray.py
index a5364f327b..2571944f80 100644
--- a/tests/test_xarray.py
+++ b/tests/test_xarray.py
@@ -273,6 +273,14 @@ def test_missing_grid_mapping_invalid(test_var_multidim_no_xy):
     assert 'metpy_crs' not in data_var.coords
 
 
+def test_xy_not_vertical(test_ds):
+    """Test not detecting x/y as a vertical coordinate based on metadata."""
+    test_ds.x.attrs['positive'] = 'up'
+    test_ds.y.attrs['positive'] = 'up'
+    data_var = test_ds.metpy.parse_cf('Temperature')
+    assert data_var.metpy.vertical.identical(data_var.coords['isobaric'])
+
+
 def test_missing_grid_mapping_var(caplog):
     """Test behavior when we can't find the variable pointed to by grid_mapping."""
     x = xr.DataArray(np.arange(3),