Skip to content

Commit cfaa72f

Browse files
authored
Update Datatree html repr to indicate inheritance (#9633)
* _inherited_vars -> inherited_vars * implementation using Coordinates * datatree.DataTree -> xarray.DataTree * only show inherited coordinates on root * test that there is an Inherited coordinates header
1 parent e58edcc commit cfaa72f

File tree

3 files changed

+53
-10
lines changed

3 files changed

+53
-10
lines changed

xarray/core/formatting.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ def coords_repr(coords: AbstractCoordinates, col_width=None, max_rows=None):
447447

448448

449449
def inherited_coords_repr(node: DataTree, col_width=None, max_rows=None):
450-
coords = _inherited_vars(node._coord_variables)
450+
coords = inherited_vars(node._coord_variables)
451451
if col_width is None:
452452
col_width = _calculate_col_width(coords)
453453
return _mapping_repr(
@@ -1075,7 +1075,7 @@ def diff_datatree_repr(a: DataTree, b: DataTree, compat):
10751075
return "\n\n".join(summary)
10761076

10771077

1078-
def _inherited_vars(mapping: ChainMap) -> dict:
1078+
def inherited_vars(mapping: ChainMap) -> dict:
10791079
return {k: v for k, v in mapping.parents.items() if k not in mapping.maps[0]}
10801080

10811081

@@ -1085,7 +1085,7 @@ def _datatree_node_repr(node: DataTree, show_inherited: bool) -> str:
10851085
col_width = _calculate_col_width(node.variables)
10861086
max_rows = OPTIONS["display_max_rows"]
10871087

1088-
inherited_coords = _inherited_vars(node._coord_variables)
1088+
inherited_coords = inherited_vars(node._coord_variables)
10891089

10901090
# Only show dimensions if also showing a variable or coordinates section.
10911091
show_dims = (

xarray/core/formatting_html.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from typing import TYPE_CHECKING
1010

1111
from xarray.core.formatting import (
12+
inherited_vars,
1213
inline_index_repr,
1314
inline_variable_array_repr,
1415
short_data_repr,
@@ -248,7 +249,6 @@ def array_section(obj) -> str:
248249
expand_option_name="display_expand_coords",
249250
)
250251

251-
252252
datavar_section = partial(
253253
_mapping_section,
254254
name="Data variables",
@@ -382,16 +382,40 @@ def summarize_datatree_children(children: Mapping[str, DataTree]) -> str:
382382
expand_option_name="display_expand_groups",
383383
)
384384

385+
inherited_coord_section = partial(
386+
_mapping_section,
387+
name="Inherited coordinates",
388+
details_func=summarize_coords,
389+
max_items_collapse=25,
390+
expand_option_name="display_expand_coords",
391+
)
392+
393+
394+
def datatree_node_repr(group_title: str, node: DataTree, show_inherited=False) -> str:
395+
from xarray.core.coordinates import Coordinates
385396

386-
def datatree_node_repr(group_title: str, dt: DataTree) -> str:
387397
header_components = [f"<div class='xr-obj-type'>{escape(group_title)}</div>"]
388398

389-
ds = dt._to_dataset_view(rebuild_dims=False, inherit=True)
399+
ds = node._to_dataset_view(rebuild_dims=False, inherit=True)
400+
node_coords = node.to_dataset(inherit=False).coords
401+
402+
# use this class to get access to .xindexes property
403+
inherited_coords = Coordinates(
404+
coords=inherited_vars(node._coord_variables),
405+
indexes=inherited_vars(node._indexes),
406+
)
390407

391408
sections = [
392-
children_section(dt.children),
409+
children_section(node.children),
393410
dim_section(ds),
394-
coord_section(ds.coords),
411+
coord_section(node_coords),
412+
]
413+
414+
# only show inherited coordinates on the root
415+
if show_inherited:
416+
sections.append(inherited_coord_section(inherited_coords))
417+
418+
sections += [
395419
datavar_section(ds.data_vars),
396420
attr_section(ds.attrs),
397421
]
@@ -470,5 +494,5 @@ def _wrap_datatree_repr(r: str, end: bool = False) -> str:
470494

471495

472496
def datatree_repr(dt: DataTree) -> str:
473-
obj_type = f"datatree.{type(dt).__name__}"
474-
return datatree_node_repr(obj_type, dt)
497+
obj_type = f"xarray.{type(dt).__name__}"
498+
return datatree_node_repr(obj_type, dt, show_inherited=True)

xarray/tests/test_formatting_html.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,25 @@ def test_two_children(
320320
)
321321

322322

323+
class TestDataTreeInheritance:
324+
def test_inherited_section_present(self) -> None:
325+
dt = xr.DataTree.from_dict(
326+
{
327+
"/": None,
328+
"a": None,
329+
}
330+
)
331+
with xr.set_options(display_style="html"):
332+
html = dt._repr_html_().strip()
333+
# checks that the section appears somewhere
334+
assert "Inherited coordinates" in html
335+
336+
# TODO how can we assert that the Inherited coordinates section does not appear in the child group?
337+
# with xr.set_options(display_style="html"):
338+
# child_html = dt["a"]._repr_html_().strip()
339+
# assert "Inherited coordinates" not in child_html
340+
341+
323342
class Test__wrap_datatree_repr:
324343
"""
325344
Unit tests for _wrap_datatree_repr.

0 commit comments

Comments
 (0)