Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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 @@ -5368,8 +5368,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 @@ -3799,8 +3799,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 @@ -3811,8 +3811,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 @@ -3827,8 +3827,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 @@ -4352,8 +4352,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 @@ -8199,8 +8199,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 @@ -8673,9 +8673,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 @@ -8688,9 +8688,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 @@ -9361,8 +9361,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 @@ -9371,8 +9371,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 @@ -116,7 +116,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
50 changes: 49 additions & 1 deletion xarray/tests/test_formatting_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,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 @@ -121,6 +121,43 @@ def test_repr_of_dataarray(dataarray: xr.DataArray) -> None:
)


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 @@ -160,6 +197,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