Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ New Features
(:pull:`10624`).
By `Stephan Hoyer <https://github.com/shoyer>`_.

- Coordinates are ordered to match dims when displaying Xarray objects. (:pull:`10778`).
By `Julia Signell <https://github.com/jsignell>`_.

Breaking changes
~~~~~~~~~~~~~~~~

Expand Down
4 changes: 2 additions & 2 deletions xarray/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -619,9 +619,9 @@ def assign_coords(
<xarray.Dataset> Size: 360B
Dimensions: (x: 2, y: 2, time: 4)
Coordinates:
* time (time) datetime64[ns] 32B 2014-09-06 ... 2014-09-09
lon (x, y) float64 32B 260.2 260.7 260.2 260.8
lat (x, y) float64 32B 42.25 42.21 42.63 42.59
* time (time) datetime64[ns] 32B 2014-09-06 ... 2014-09-09
reference_time datetime64[ns] 8B 2014-09-05
Dimensions without coordinates: x, y
Data variables:
Expand All @@ -633,9 +633,9 @@ def assign_coords(
<xarray.Dataset> Size: 360B
Dimensions: (x: 2, y: 2, time: 4)
Coordinates:
* time (time) datetime64[ns] 32B 2014-09-06 ... 2014-09-09
lon (x, y) float64 32B -99.83 -99.32 -99.79 -99.23
lat (x, y) float64 32B 42.25 42.21 42.63 42.59
* time (time) datetime64[ns] 32B 2014-09-06 ... 2014-09-09
reference_time datetime64[ns] 8B 2014-09-05
Dimensions without coordinates: x, y
Data variables:
Expand Down
16 changes: 8 additions & 8 deletions xarray/core/dataarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,9 @@ class DataArray(
[[22.60070734, 13.78914233, 14.17424919],
[18.28478802, 16.15234857, 26.63418806]]])
Coordinates:
* time (time) datetime64[ns] 24B 2014-09-06 2014-09-07 2014-09-08
lon (x, y) float64 32B -99.83 -99.32 -99.79 -99.23
lat (x, y) float64 32B 42.25 42.21 42.63 42.59
* time (time) datetime64[ns] 24B 2014-09-06 2014-09-07 2014-09-08
reference_time datetime64[ns] 8B 2014-09-05
Dimensions without coordinates: x, y
Attributes:
Expand Down Expand Up @@ -2139,17 +2139,17 @@ def reindex_like(
<xarray.DataArray (y: 3)> Size: 24B
array([3, 4, 5])
Coordinates:
x int64 8B 20
* y (y) int64 24B 70 80 90
x int64 8B 20

...so ``b`` in not added here:

>>> da1.sel(x=20).reindex_like(da1)
<xarray.DataArray (y: 3)> Size: 24B
array([3, 4, 5])
Coordinates:
x int64 8B 20
* y (y) int64 24B 70 80 90
x int64 8B 20

See Also
--------
Expand Down Expand Up @@ -2363,8 +2363,8 @@ def interp(
[3. , nan, 5.75, nan],
[5. , nan, 5.25, nan]])
Coordinates:
* y (y) int64 32B 10 12 14 16
* x (x) float64 32B 0.0 0.75 1.25 1.75
* y (y) int64 32B 10 12 14 16

1D nearest interpolation:

Expand All @@ -2375,8 +2375,8 @@ def interp(
[ 2., 7., 6., nan],
[ 6., nan, 5., 8.]])
Coordinates:
* y (y) int64 32B 10 12 14 16
* x (x) float64 32B 0.0 0.75 1.25 1.75
* y (y) int64 32B 10 12 14 16

1D linear extrapolation:

Expand All @@ -2391,8 +2391,8 @@ def interp(
[ 8. , nan, 4.5, nan],
[12. , nan, 3.5, nan]])
Coordinates:
* y (y) int64 32B 10 12 14 16
* x (x) float64 32B 1.0 1.5 2.5 3.5
* y (y) int64 32B 10 12 14 16

2D linear interpolation:

Expand Down Expand Up @@ -2639,8 +2639,8 @@ def swap_dims(
<xarray.DataArray (y: 2)> Size: 16B
array([0, 1])
Coordinates:
x (y) <U1 8B 'a' 'b'
* y (y) int64 16B 0 1
x (y) <U1 8B 'a' 'b'

>>> arr.swap_dims({"x": "z"})
<xarray.DataArray (z: 2)> Size: 16B
Expand Down Expand Up @@ -5369,8 +5369,8 @@ def quantile(
[3.6 , 5.75, 6. , 1.7 ],
[6.5 , 7.3 , 9.4 , 1.9 ]])
Coordinates:
* y (y) float64 32B 1.0 1.5 2.0 2.5
* quantile (quantile) float64 24B 0.0 0.5 1.0
* y (y) float64 32B 1.0 1.5 2.0 2.5

References
----------
Expand Down
24 changes: 12 additions & 12 deletions xarray/core/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,10 @@ class Dataset(
<xarray.Dataset> Size: 552B
Dimensions: (loc: 2, instrument: 3, time: 4)
Coordinates:
lon (loc) float64 16B -99.83 -99.32
lat (loc) float64 16B 42.25 42.21
* instrument (instrument) <U8 96B 'manufac1' 'manufac2' 'manufac3'
* time (time) datetime64[ns] 32B 2014-09-06 ... 2014-09-09
lon (loc) float64 16B -99.83 -99.32
lat (loc) float64 16B 42.25 42.21
reference_time datetime64[ns] 8B 2014-09-05
Dimensions without coordinates: loc
Data variables:
Expand Down Expand Up @@ -1806,8 +1806,8 @@ def set_coords(self, names: Hashable | Iterable[Hashable]) -> Self:
<xarray.Dataset> Size: 48B
Dimensions: (time: 3)
Coordinates:
pressure (time) float64 24B 1.013 1.2 3.5
* time (time) datetime64[ns] 24B 2023-01-01 2023-01-02 2023-01-03
pressure (time) float64 24B 1.013 1.2 3.5
Data variables:
*empty*

Expand Down Expand Up @@ -3800,8 +3800,8 @@ def interp(
<xarray.Dataset> Size: 224B
Dimensions: (x: 4, y: 4)
Coordinates:
* y (y) int64 32B 10 12 14 16
* x (x) float64 32B 0.0 0.75 1.25 1.75
* y (y) int64 32B 10 12 14 16
Data variables:
a (x) float64 32B 5.0 6.5 6.25 4.75
b (x, y) float64 128B 1.0 4.0 2.0 nan 1.75 ... nan 5.0 nan 5.25 nan
Expand All @@ -3812,8 +3812,8 @@ def interp(
<xarray.Dataset> Size: 224B
Dimensions: (x: 4, y: 4)
Coordinates:
* y (y) int64 32B 10 12 14 16
* x (x) float64 32B 0.0 0.75 1.25 1.75
* y (y) int64 32B 10 12 14 16
Data variables:
a (x) float64 32B 5.0 7.0 7.0 4.0
b (x, y) float64 128B 1.0 4.0 2.0 9.0 2.0 7.0 ... nan 6.0 nan 5.0 8.0
Expand All @@ -3828,8 +3828,8 @@ def interp(
<xarray.Dataset> Size: 224B
Dimensions: (x: 4, y: 4)
Coordinates:
* y (y) int64 32B 10 12 14 16
* x (x) float64 32B 1.0 1.5 2.5 3.5
* y (y) int64 32B 10 12 14 16
Data variables:
a (x) float64 32B 7.0 5.5 2.5 -0.5
b (x, y) float64 128B 2.0 7.0 6.0 nan 4.0 ... nan 12.0 nan 3.5 nan
Expand Down Expand Up @@ -4353,8 +4353,8 @@ def swap_dims(
<xarray.Dataset> Size: 56B
Dimensions: (y: 2)
Coordinates:
x (y) <U1 8B 'a' 'b'
* y (y) int64 16B 0 1
x (y) <U1 8B 'a' 'b'
Data variables:
a (y) int64 16B 5 7
b (y) float64 16B 0.1 2.4
Expand Down Expand Up @@ -8203,8 +8203,8 @@ def quantile(
<xarray.Dataset> Size: 152B
Dimensions: (quantile: 3, y: 4)
Coordinates:
* y (y) float64 32B 1.0 1.5 2.0 2.5
* quantile (quantile) float64 24B 0.0 0.5 1.0
* y (y) float64 32B 1.0 1.5 2.0 2.5
Data variables:
a (quantile, y) float64 96B 0.7 4.2 2.6 1.5 3.6 ... 6.5 7.3 9.4 1.9

Expand Down Expand Up @@ -8677,9 +8677,9 @@ def filter_by_attrs(self, **kwargs) -> Self:
<xarray.Dataset> Size: 192B
Dimensions: (x: 2, y: 2, time: 3)
Coordinates:
* time (time) datetime64[ns] 24B 2014-09-06 2014-09-07 2014-09-08
lon (x, y) float64 32B -99.83 -99.32 -99.79 -99.23
lat (x, y) float64 32B 42.25 42.21 42.63 42.59
* time (time) datetime64[ns] 24B 2014-09-06 2014-09-07 2014-09-08
reference_time datetime64[ns] 8B 2014-09-05
Dimensions without coordinates: x, y
Data variables:
Expand All @@ -8692,9 +8692,9 @@ def filter_by_attrs(self, **kwargs) -> Self:
<xarray.Dataset> Size: 288B
Dimensions: (x: 2, y: 2, time: 3)
Coordinates:
* time (time) datetime64[ns] 24B 2014-09-06 2014-09-07 2014-09-08
lon (x, y) float64 32B -99.83 -99.32 -99.79 -99.23
lat (x, y) float64 32B 42.25 42.21 42.63 42.59
* time (time) datetime64[ns] 24B 2014-09-06 2014-09-07 2014-09-08
reference_time datetime64[ns] 8B 2014-09-05
Dimensions without coordinates: x, y
Data variables:
Expand Down Expand Up @@ -9365,8 +9365,8 @@ def argmin(self, dim: Hashable | None = None, **kwargs) -> Self:
<xarray.DataArray 'student' (test: 3)> Size: 84B
array(['Bob', 'Bob', 'Alice'], dtype='<U7')
Coordinates:
student (test) <U7 84B 'Bob' 'Bob' 'Alice'
* test (test) <U6 72B 'Test 1' 'Test 2' 'Test 3'
student (test) <U7 84B 'Bob' 'Bob' 'Alice'

>>> min_score_in_english = dataset["student"].isel(
... student=argmin_indices["english_scores"]
Expand All @@ -9375,8 +9375,8 @@ def argmin(self, dim: Hashable | None = None, **kwargs) -> Self:
<xarray.DataArray 'student' (test: 3)> Size: 84B
array(['Charlie', 'Bob', 'Charlie'], dtype='<U7')
Coordinates:
student (test) <U7 84B 'Charlie' 'Bob' 'Charlie'
* test (test) <U6 72B 'Test 1' 'Test 2' 'Test 3'
student (test) <U7 84B 'Charlie' 'Bob' 'Charlie'

See Also
--------
Expand Down
6 changes: 5 additions & 1 deletion xarray/core/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,12 @@ def _mapping_repr(
def coords_repr(coords: AbstractCoordinates, col_width=None, max_rows=None):
if col_width is None:
col_width = _calculate_col_width(coords)
dims = tuple(coords._data.dims)
dim_ordered_coords = sorted(
coords.items(), key=lambda x: dims.index(x[0]) if x[0] in dims else len(dims)
)
return _mapping_repr(
coords,
dict(dim_ordered_coords),
title="Coordinates",
summarizer=summarize_variable,
expand_option_name="display_expand_coords",
Expand Down
6 changes: 5 additions & 1 deletion xarray/core/formatting_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ def summarize_variable(name, var, is_index=False, dtype=None) -> str:

def summarize_coords(variables) -> str:
li_items = []
for k, v in variables.items():
dims = tuple(variables._data.dims)
dim_ordered_coords = sorted(
variables.items(), key=lambda x: dims.index(x[0]) if x[0] in dims else len(dims)
)
for k, v in dim_ordered_coords:
li_content = summarize_variable(k, v, is_index=k in variables.xindexes)
li_items.append(f"<li class='xr-var-item'>{li_content}</li>")

Expand Down
10 changes: 5 additions & 5 deletions xarray/core/groupby.py
Original file line number Diff line number Diff line change
Expand Up @@ -750,8 +750,8 @@ def shuffle_to_chunks(self, chunks: T_Chunks = None) -> T_Xarray:
<xarray.DataArray 'a' (x: 4)> Size: 32B
array([9., 3., 4., 5.])
Coordinates:
quantile float64 8B 0.5
* x (x) int64 32B 0 1 2 3
quantile float64 8B 0.5

See Also
--------
Expand Down Expand Up @@ -1313,15 +1313,15 @@ def quantile(
array([[0.7, 4.2, 0.7, 1.5],
[6.5, 7.3, 2.6, 1.9]])
Coordinates:
* x (x) int64 16B 0 1
* y (y) int64 32B 1 1 2 2
quantile float64 8B 0.0
* x (x) int64 16B 0 1
>>> ds.groupby("y").quantile(0, dim=...)
<xarray.Dataset> Size: 40B
Dimensions: (y: 2)
Coordinates:
quantile float64 8B 0.0
* y (y) int64 16B 1 2
quantile float64 8B 0.0
Data variables:
a (y) float64 16B 0.7 0.7
>>> da.groupby("x").quantile([0, 0.5, 1])
Expand All @@ -1336,15 +1336,15 @@ def quantile(
[2.6 , 2.6 , 2.6 ],
[1.9 , 1.9 , 1.9 ]]])
Coordinates:
* x (x) int64 16B 0 1
* y (y) int64 32B 1 1 2 2
* quantile (quantile) float64 24B 0.0 0.5 1.0
* x (x) int64 16B 0 1
>>> ds.groupby("y").quantile([0, 0.5, 1], dim=...)
<xarray.Dataset> Size: 88B
Dimensions: (y: 2, quantile: 3)
Coordinates:
* quantile (quantile) float64 24B 0.0 0.5 1.0
* y (y) int64 16B 1 2
* quantile (quantile) float64 24B 0.0 0.5 1.0
Data variables:
a (y, quantile) float64 48B 0.7 5.35 8.4 0.7 2.25 9.4

Expand Down
6 changes: 3 additions & 3 deletions xarray/structure/concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ def concat(
array([[0, 1, 2],
[3, 4, 5]])
Coordinates:
x (new_dim) <U1 8B 'a' 'b'
* y (y) int64 24B 10 20 30
x (new_dim) <U1 8B 'a' 'b'
Dimensions without coordinates: new_dim

>>> xr.concat(
Expand All @@ -237,9 +237,9 @@ def concat(
array([[0, 1, 2],
[3, 4, 5]])
Coordinates:
x (new_dim) <U1 8B 'a' 'b'
* y (y) int64 24B 10 20 30
* new_dim (new_dim) int64 16B -90 -100
* y (y) int64 24B 10 20 30
x (new_dim) <U1 8B 'a' 'b'

# Concatenate a scalar variable along a new dimension of the same name with and without creating a new index

Expand Down
40 changes: 39 additions & 1 deletion xarray/tests/test_formatting_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def dataset() -> xr.Dataset:
"tmin": (("time", "location"), tmin_values),
"tmax": (("time", "location"), tmax_values),
},
{"time": times, "location": ["<IA>", "IN", "IL"]},
{"location": ["<IA>", "IN", "IL"], "time": times},
attrs={"description": "Test data."},
)

Expand Down Expand Up @@ -186,6 +186,33 @@ def test_repr_of_dataarray() -> None:
assert "Attributes" not in formatted


def test_repr_coords_order_of_datarray() -> None:
da1 = xr.DataArray(
np.empty((2, 2)),
coords={"foo": [0, 1], "bar": [0, 1]},
dims=["foo", "bar"],
)
da2 = xr.DataArray(
np.empty((2, 2)),
coords={"bar": [0, 1], "foo": [0, 1]},
dims=["bar", "foo"],
)
ds = xr.Dataset({"da1": da1, "da2": da2})

bar_line = (
"<span class='xr-has-index'>bar</span></div><div class='xr-var-dims'>(bar)"
)
foo_line = (
"<span class='xr-has-index'>foo</span></div><div class='xr-var-dims'>(foo)"
)

formatted_da1 = fh.array_repr(ds.da1)
assert formatted_da1.index(foo_line) < formatted_da1.index(bar_line)

formatted_da2 = fh.array_repr(ds.da2)
assert formatted_da2.index(bar_line) < formatted_da2.index(foo_line)


def test_repr_of_multiindex(multiindex: xr.Dataset) -> None:
formatted = fh.dataset_repr(multiindex)
assert "(x)" in formatted
Expand Down Expand Up @@ -231,6 +258,17 @@ def test_repr_text_fallback(dataset: xr.Dataset) -> None:
assert "<pre class='xr-text-repr-fallback'>" in formatted


def test_repr_coords_order_of_dataset() -> None:
ds = xr.Dataset()
ds.coords["as"] = 10
ds["var"] = xr.DataArray(np.ones((10,)), dims="x", coords={"x": np.arange(10)})
formatted = fh.dataset_repr(ds)

x_line = "<span class='xr-has-index'>x</span></div><div class='xr-var-dims'>(x)"
as_line = "<span>as</span></div><div class='xr-var-dims'>()"
assert formatted.index(x_line) < formatted.index(as_line)


def test_variable_repr_html() -> None:
v = xr.Variable(["time", "x"], [[1, 2, 3], [4, 5, 6]], {"foo": "bar"})
assert hasattr(v, "_repr_html_")
Expand Down
Loading