Skip to content

Commit 5a6dea4

Browse files
neishmJoe Hamman
authored and
Joe Hamman
committed
Fix multidimensional coordinates (#1768)
* Add test case for 1763. * Add whitespace and wrap long lines to pass flake8 tests. * Fix test case - time should not be a coordinate! * When encoding coordinates, change the criteria so that the dimensions of the coordinate must be a subset (or equal to) the dimensions of the variable. * Add note about bug fix (#1763) to the docs.
1 parent 50b0a69 commit 5a6dea4

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

doc/whats-new.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ Enhancements
5656

5757
Bug fixes
5858
~~~~~~~~~
59+
- Fixed encoding of multi-dimensional coordinates in
60+
:py:meth:`~Dataset.to_netcdf` (:issue:`1763`).
61+
By `Mike Neish <https://github.com/neishm>`_.
5962

6063
- Bug fix in open_dataset(engine='pydap') (:issue:`1775`)
6164
By `Keisuke Fujii <https://github.com/fujiisoup>`_.

xarray/conventions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ def _encode_coordinates(variables, attributes, non_dim_coord_names):
663663
target_dims = variables[coord_name].dims
664664
for k, v in variables.items():
665665
if (k not in non_dim_coord_names and k not in v.dims and
666-
any(d in target_dims for d in v.dims)):
666+
set(target_dims) <= set(v.dims)):
667667
variable_coordinates[k].add(coord_name)
668668
global_coordinates.discard(coord_name)
669669

xarray/tests/test_conventions.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,41 @@ def test_missing_fillvalue(self):
200200
with self.assertWarns('floating point data as an integer'):
201201
conventions.encode_cf_variable(v)
202202

203+
def test_multidimensional_coordinates(self):
204+
# regression test for GH1763
205+
# Set up test case with coordinates that have overlapping (but not
206+
# identical) dimensions.
207+
zeros1 = np.zeros((1, 5, 3))
208+
zeros2 = np.zeros((1, 6, 3))
209+
zeros3 = np.zeros((1, 5, 4))
210+
orig = Dataset({
211+
'lon1': (['x1', 'y1'], zeros1.squeeze(0), {}),
212+
'lon2': (['x2', 'y1'], zeros2.squeeze(0), {}),
213+
'lon3': (['x1', 'y2'], zeros3.squeeze(0), {}),
214+
'lat1': (['x1', 'y1'], zeros1.squeeze(0), {}),
215+
'lat2': (['x2', 'y1'], zeros2.squeeze(0), {}),
216+
'lat3': (['x1', 'y2'], zeros3.squeeze(0), {}),
217+
'foo1': (['time', 'x1', 'y1'], zeros1,
218+
{'coordinates': 'lon1 lat1'}),
219+
'foo2': (['time', 'x2', 'y1'], zeros2,
220+
{'coordinates': 'lon2 lat2'}),
221+
'foo3': (['time', 'x1', 'y2'], zeros3,
222+
{'coordinates': 'lon3 lat3'}),
223+
'time': ('time', [0.], {'units': 'hours since 2017-01-01'}),
224+
})
225+
orig = conventions.decode_cf(orig)
226+
# Encode the coordinates, as they would be in a netCDF output file.
227+
enc, attrs = conventions.encode_dataset_coordinates(orig)
228+
# Make sure we have the right coordinates for each variable.
229+
foo1_coords = enc['foo1'].attrs.get('coordinates', '')
230+
foo2_coords = enc['foo2'].attrs.get('coordinates', '')
231+
foo3_coords = enc['foo3'].attrs.get('coordinates', '')
232+
assert set(foo1_coords.split()) == set(['lat1', 'lon1'])
233+
assert set(foo2_coords.split()) == set(['lat2', 'lon2'])
234+
assert set(foo3_coords.split()) == set(['lat3', 'lon3'])
235+
# Should not have any global coordinates.
236+
assert 'coordinates' not in attrs
237+
203238

204239
@requires_netCDF4
205240
class TestDecodeCF(TestCase):

0 commit comments

Comments
 (0)