|
19 | 19 | import cf_xarray # noqa |
20 | 20 | import numpy as np |
21 | 21 | import xarray as xr |
22 | | -from IPython.display import display_html |
23 | 22 | from xarray.core.coordinates import DatasetCoordinates |
24 | 23 | from xarray.core.dataset import DataVariables |
25 | 24 | from xarray.core.formatting_html import dataset_repr |
@@ -109,86 +108,39 @@ def _display_metadata(self) -> str: |
109 | 108 | >>> hindcast = climpred.HindcastEnsemble(init) |
110 | 109 | >>> print(hindcast) |
111 | 110 | <climpred.HindcastEnsemble> |
112 | | - Initialized Ensemble: |
| 111 | + Initialized: |
113 | 112 | SST (init, lead, member) float64 -0.2404 -0.2085 ... 0.7442 0.7384 |
114 | | - Observations: |
115 | | - None |
116 | 113 | Uninitialized: |
117 | 114 | None |
| 115 | + Observations: |
| 116 | + None |
118 | 117 |
|
119 | 118 | """ |
120 | 119 | SPACE = " " |
121 | | - header = f"<climpred.{type(self).__name__}>" |
122 | | - summary = header + "\nInitialized Ensemble:\n" |
123 | | - summary += SPACE + str(self._datasets["initialized"].data_vars)[18:].strip() + "\n" |
124 | | - if isinstance(self, HindcastEnsemble): |
125 | | - # Prints out observations and associated variables if they exist. |
126 | | - # If not, just write "None". |
127 | | - summary += "Observations:\n" |
128 | | - if any(self._datasets["observations"]): |
129 | | - num_obs = len(self._datasets["observations"].data_vars) |
130 | | - for i in range(1, num_obs + 1): |
131 | | - summary += ( |
132 | | - SPACE |
133 | | - + str(self._datasets["observations"].data_vars) |
134 | | - .split("\n")[i] |
135 | | - .strip() |
136 | | - + "\n" |
137 | | - ) |
138 | | - else: |
139 | | - summary += SPACE + "None\n" |
140 | | - elif isinstance(self, PerfectModelEnsemble): |
141 | | - summary += "Control:\n" |
142 | | - # Prints out control variables if a control is appended. If not, |
143 | | - # just write "None". |
144 | | - if any(self._datasets["control"]): |
145 | | - num_ctrl = len(self._datasets["control"].data_vars) |
146 | | - for i in range(1, num_ctrl + 1): |
147 | | - summary += ( |
148 | | - SPACE |
149 | | - + str(self._datasets["control"].data_vars).split("\n")[i].strip() |
150 | | - + "\n" |
| 120 | + summary = f"<climpred.{type(self).__name__}>\n" |
| 121 | + |
| 122 | + for k in self._datasets.keys(): |
| 123 | + if self._datasets[k]: |
| 124 | + summary += ( |
| 125 | + str(self._datasets[k].data_vars).replace( |
| 126 | + "Data variables", k.capitalize() |
151 | 127 | ) |
152 | | - else: |
153 | | - summary += SPACE + "None\n" |
154 | | - if any(self._datasets["uninitialized"]): |
155 | | - summary += "Uninitialized:\n" |
156 | | - summary += SPACE + str(self._datasets["uninitialized"].data_vars)[18:].strip() |
157 | | - else: |
158 | | - summary += "Uninitialized:\n" |
159 | | - summary += SPACE + "None" |
160 | | - return summary |
161 | | - |
162 | | - |
163 | | -def _display_metadata_html(self) -> str: |
164 | | - """Print contents of :py:class:`.PredictionEnsemble` as html.""" |
165 | | - header = f"<h4>climpred.{type(self).__name__}</h4>" |
166 | | - display_html(header, raw=True) |
167 | | - init_repr_str = dataset_repr(self._datasets["initialized"]) |
168 | | - init_repr_str = init_repr_str.replace("xarray.Dataset", "Initialized Ensemble") |
169 | | - display_html(init_repr_str, raw=True) |
170 | | - |
171 | | - if isinstance(self, HindcastEnsemble): |
172 | | - if any(self._datasets["observations"]): |
173 | | - obs_repr_str = dataset_repr(self._datasets["observations"]) |
174 | | - obs_repr_str = obs_repr_str.replace("xarray.Dataset", "Observations") |
175 | | - display_html(obs_repr_str, raw=True) |
176 | | - elif isinstance(self, PerfectModelEnsemble): |
177 | | - if any(self._datasets["control"]): |
178 | | - control_repr_str = dataset_repr(self._datasets["control"]) |
179 | | - control_repr_str = control_repr_str.replace( |
180 | | - "xarray.Dataset", "Control Simulation" |
| 128 | + + "\n" |
181 | 129 | ) |
182 | | - display_html(control_repr_str, raw=True) |
| 130 | + else: |
| 131 | + summary += f"{k.capitalize()}:\n{SPACE}None\n" |
| 132 | + return summary.strip("\n") |
183 | 133 |
|
184 | | - if any(self._datasets["uninitialized"]): |
185 | | - uninit_repr_str = dataset_repr(self._datasets["uninitialized"]) |
186 | | - uninit_repr_str = uninit_repr_str.replace("xarray.Dataset", "Uninitialized") |
187 | | - display_html(uninit_repr_str, raw=True) |
188 | | - # better would be to aggregate repr_strs and then all return but this fails |
189 | | - # TypeError: __repr__ returned non-string (type NoneType) |
190 | | - # workaround return empty string |
191 | | - return "" |
| 134 | + |
| 135 | +def _display_metadata_html(self): |
| 136 | + """Show contents of :py:class:`.PredictionEnsemble` as html.""" |
| 137 | + html_str = f"<h4>climpred.{type(self).__name__}</h4>" |
| 138 | + for k in self._datasets.keys(): |
| 139 | + if self._datasets[k]: |
| 140 | + html_str += dataset_repr(self._datasets[k]).replace( |
| 141 | + "xarray.Dataset", k.capitalize() |
| 142 | + ) |
| 143 | + return html_str |
192 | 144 |
|
193 | 145 |
|
194 | 146 | class PredictionEnsemble: |
@@ -377,14 +329,17 @@ def data_vars(self) -> DataVariables: |
377 | 329 | varlist = list(varset) |
378 | 330 | return self.get_initialized()[varlist].data_vars |
379 | 331 |
|
380 | | - # when you just print it interactively |
381 | | - # https://stackoverflow.com/questions/1535327/how-to-print-objects-of-class-using-print |
| 332 | + def _repr_html_(self): |
| 333 | + """Return for :py:class:`.PredictionEnsemble` in html.""" |
| 334 | + from html import escape |
| 335 | + |
| 336 | + if XR_OPTIONS["display_style"] == "text": |
| 337 | + return f"<pre>{escape(repr(self))}</pre>" |
| 338 | + return _display_metadata_html(self) |
| 339 | + |
382 | 340 | def __repr__(self) -> str: |
383 | | - """Return for print(PredictionEnsemble).""" |
384 | | - if XR_OPTIONS["display_style"] == "html": |
385 | | - return _display_metadata_html(self) |
386 | | - else: |
387 | | - return _display_metadata(self) |
| 341 | + """Return for print(:py:class:`.PredictionEnsemble`).""" |
| 342 | + return _display_metadata(self) |
388 | 343 |
|
389 | 344 | def __len__(self) -> int: |
390 | 345 | """Return number of all variables :py:class:`.PredictionEnsemble`.""" |
@@ -658,6 +613,8 @@ def __getattr__( |
658 | 613 | Args: |
659 | 614 | * name: str of xarray function, e.g., ``.isel()`` or ``.sum()``. |
660 | 615 | """ |
| 616 | + if name == "_ipython_canary_method_should_not_exist_": |
| 617 | + raise AttributeError(name) |
661 | 618 |
|
662 | 619 | def wrapper(*args, **kwargs): |
663 | 620 | """Apply arbitrary function to all datasets in ``PerfectModelEnsemble``. |
@@ -809,12 +766,12 @@ def smooth( |
809 | 766 |
|
810 | 767 | >>> HindcastEnsemble_3D.smooth({"lon": 1, "lat": 1}) |
811 | 768 | <climpred.HindcastEnsemble> |
812 | | - Initialized Ensemble: |
| 769 | + Initialized: |
813 | 770 | SST (init, lead, lat, lon) float32 -0.3236 -0.3161 -0.3083 ... 0.0 0.0 |
814 | | - Observations: |
815 | | - SST (time, lat, lon) float32 0.002937 0.001561 0.002587 ... 0.0 0.0 0.0 |
816 | 771 | Uninitialized: |
817 | 772 | None |
| 773 | + Observations: |
| 774 | + SST (time, lat, lon) float32 0.002937 0.001561 0.002587 ... 0.0 0.0 0.0 |
818 | 775 |
|
819 | 776 | ``smooth`` simultaneously aggregates spatially listening to ``lon`` and |
820 | 777 | ``lat`` and temporally listening to ``lead`` or ``time``. |
@@ -924,21 +881,21 @@ def remove_seasonality( |
924 | 881 | Examples: |
925 | 882 | >>> HindcastEnsemble |
926 | 883 | <climpred.HindcastEnsemble> |
927 | | - Initialized Ensemble: |
| 884 | + Initialized: |
928 | 885 | SST (init, lead, member) float64 -0.2392 -0.2203 ... 0.618 0.6136 |
929 | | - Observations: |
930 | | - SST (time) float32 -0.4015 -0.3524 -0.1851 ... 0.2481 0.346 0.4502 |
931 | 886 | Uninitialized: |
932 | 887 | SST (time, member) float64 -0.1969 -0.01221 -0.275 ... 0.4179 0.3974 |
| 888 | + Observations: |
| 889 | + SST (time) float32 -0.4015 -0.3524 -0.1851 ... 0.2481 0.346 0.4502 |
933 | 890 | >>> # example already effectively without seasonal cycle |
934 | 891 | >>> HindcastEnsemble.remove_seasonality(seasonality="month") |
935 | 892 | <climpred.HindcastEnsemble> |
936 | | - Initialized Ensemble: |
| 893 | + Initialized: |
937 | 894 | SST (init, lead, member) float64 -0.2349 -0.216 ... 0.6476 0.6433 |
938 | | - Observations: |
939 | | - SST (time) float32 -0.3739 -0.3248 -0.1575 ... 0.2757 0.3736 0.4778 |
940 | 895 | Uninitialized: |
941 | 896 | SST (time, member) float64 -0.1789 0.005732 -0.257 ... 0.4359 0.4154 |
| 897 | + Observations: |
| 898 | + SST (time) float32 -0.3739 -0.3248 -0.1575 ... 0.2757 0.3736 0.4778 |
942 | 899 | """ |
943 | 900 |
|
944 | 901 | def _remove_seasonality(ds, initialized_dim="init", seasonality=None): |
@@ -1797,21 +1754,21 @@ def generate_uninitialized( |
1797 | 1754 | Example: |
1798 | 1755 | >>> HindcastEnsemble # uninitialized from historical simulations |
1799 | 1756 | <climpred.HindcastEnsemble> |
1800 | | - Initialized Ensemble: |
| 1757 | + Initialized: |
1801 | 1758 | SST (init, lead, member) float64 -0.2392 -0.2203 ... 0.618 0.6136 |
1802 | | - Observations: |
1803 | | - SST (time) float32 -0.4015 -0.3524 -0.1851 ... 0.2481 0.346 0.4502 |
1804 | 1759 | Uninitialized: |
1805 | 1760 | SST (time, member) float64 -0.1969 -0.01221 -0.275 ... 0.4179 0.3974 |
| 1761 | + Observations: |
| 1762 | + SST (time) float32 -0.4015 -0.3524 -0.1851 ... 0.2481 0.346 0.4502 |
1806 | 1763 |
|
1807 | 1764 | >>> HindcastEnsemble.generate_uninitialized() # newly generated from initialized |
1808 | 1765 | <climpred.HindcastEnsemble> |
1809 | | - Initialized Ensemble: |
| 1766 | + Initialized: |
1810 | 1767 | SST (init, lead, member) float64 -0.2392 -0.2203 ... 0.618 0.6136 |
1811 | | - Observations: |
1812 | | - SST (time) float32 -0.4015 -0.3524 -0.1851 ... 0.2481 0.346 0.4502 |
1813 | 1768 | Uninitialized: |
1814 | 1769 | SST (time, member) float64 0.04868 0.07173 0.09435 ... 0.4158 0.418 |
| 1770 | + Observations: |
| 1771 | + SST (time) float32 -0.4015 -0.3524 -0.1851 ... 0.2481 0.346 0.4502 |
1815 | 1772 | """ |
1816 | 1773 | uninit = resample_uninitialized_from_initialized( |
1817 | 1774 | self._datasets["initialized"], resample_dim=resample_dim |
|
0 commit comments