Skip to content

Commit ac30c96

Browse files
authored
Merge pull request #113 from aaronspring/add-gcb
Add Global Carbon Budget to climate catalog
2 parents 2c47284 + b215179 commit ac30c96

4 files changed

Lines changed: 132 additions & 4 deletions

File tree

README.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ atmosphere:
6464
climate:
6565
- NOAA_correlation
6666
- NOAA_correlation_xr
67+
- Global_Carbon_Budget_2025
68+
- Global_Carbon_Budget_2021
6769
6870
shapefiles:
6971
- Countries
@@ -93,8 +95,28 @@ import intake
9395
cat = intake.open_catalog('https://raw.githubusercontent.com/aaronspring/remote_climate_data/master/master.yaml')
9496
cat.atmosphere.HadCRUT5.to_dask()
9597
```
98+
```
99+
<xarray.Dataset> Size: 42MB
100+
Dimensions: (time: 2028, latitude: 36, longitude: 72, bnds: 2)
101+
...
102+
```
103+
104+
```python
105+
import hvplot.pandas
106+
gcb = cat.climate().Global_Carbon_Budget_2025.read()
107+
gcb.hvplot(y=['fossil emissions excluding carbonation', 'land-use change emissions',
108+
'atmospheric growth', 'ocean sink', 'land sink'],
109+
title='Global Carbon Budget 2025')
110+
gcb
111+
fossil emissions excluding carbonation ... budget imbalance
112+
Year
113+
1959 2.416788 ... 1.168380
114+
...
115+
2024 10.534546 ... -1.691863
116+
[66 rows x 7 columns]
117+
```
96118

97-
To explore the whole catalog, you can try:
119+
Explore the whole catalog:
98120
```python
99121
cat.walk()
100122
```
@@ -115,7 +137,7 @@ Make data access for climate data easy:
115137
- [`intake_xarray`](https://intake-xarray.readthedocs.io/en/latest/) for:
116138
- `nc` using [`netcdf4`](https://github.com/Unidata/netcdf4-python) [[example](https://github.com/aaronspring/remote_climate_data/blob/1209c5ebf5877b09b4403ea60da6d97b374b7b5c/catalogs/atmosphere.yaml#L64)]
117139
- `tif` using [`rioxarray`](https://github.com/corteva/rioxarray) [[example](https://github.com/aaronspring/remote_climate_data/blob/1209c5ebf5877b09b4403ea60da6d97b374b7b5c/catalogs/humans.yaml#L42)]
118-
- [`intake_excel`](https://github.com/edjdavid/intake-excel) for Excel `xls` and `xlsx` [[example](https://github.com/aaronspring/remote_climate_data/blob/1209c5ebf5877b09b4403ea60da6d97b374b7b5c/catalogs/climate.yaml#L35)]
140+
- [`intake_excel`](https://github.com/edjdavid/intake-excel) for Excel `xls` and `xlsx` [[example](https://github.com/aaronspring/remote_climate_data/blob/1209c5ebf5877b09b4403ea60da6d97b374b7b5c/catalogs/climate.yaml#L35)] (see [`excel_source.py`](remote_climate_data/excel_source.py) for custom driver if package unavailable)
119141
- [`intake_geopandas`](https://github.com/intake/intake_geopandas) for shapefiles `shp` [[example](https://github.com/aaronspring/remote_climate_data/blob/1209c5ebf5877b09b4403ea60da6d97b374b7b5c/catalogs/shapefiles.yaml#L11)], GeoJSON `geo.json` [[example](https://github.com/aaronspring/remote_climate_data/blob/1209c5ebf5877b09b4403ea60da6d97b374b7b5c/catalogs/shapefiles.yaml#L57)], GeoParquet `parquet`, `PostGIS` databases, `Spatialite` databases
120142
- [`regionmask`](https://regionmask.readthedocs.io/) for aggregating over geoshapes
121143

catalogs/climate.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,38 @@
22
plugins:
33
source:
44
- module: intake_xarray
5+
- module: remote_climate_data
56
sources:
7+
Global_Carbon_Budget_2025:
8+
description: Global Carbon Budget 2025
9+
metadata:
10+
url: https://globalcarbonbudget.org/
11+
doi:
12+
- https://doi.org/10.5194/essd-2025-659
13+
- https://doi.org/10.18160/gcp-2025
14+
driver: excel_url
15+
args:
16+
urlpath: simplecache::https://data.icos-cp.eu/licence_accept?ids=%5B%22UtUDiUg-PuYWkAiHoUNn83e0%22%5D
17+
sheet_name: Global Carbon Budget
18+
header: 21
19+
index_col: Year
20+
skipfooter: 0
21+
22+
Global_Carbon_Budget_2021:
23+
description: Global Carbon Budget 2021
24+
metadata:
25+
url: https://www.globalcarbonproject.org/carbonbudget/
26+
doi:
27+
- https://doi.org/10.5194/essd-2021-386
28+
- https://doi.org/10.18160/gcp-2021
29+
driver: excel_url
30+
args:
31+
urlpath: simplecache::https://data.icos-cp.eu/licence_accept?ids=%5B%220ST81nXCND5VfAQdOCSJDveT%22%5D
32+
sheet_name: Global Carbon Budget
33+
header: 20
34+
index_col: Year
35+
skipfooter: 0
36+
637
NOAA_correlation:
738
description: climate indices from psl.noaa.gov/data/correlation
839
metadata:

remote_climate_data/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import intake
22

3+
from remote_climate_data import excel_source # noqa: F401
4+
35

46
def cmor_cat(cat="../master.yml", keyword="cmor", depth=3):
57
if isinstance(cat, str):
68
cat = intake.open_catalog(cat)
7-
assert isinstance(cat, intake.catalog.local.YAMLFileCatalog) # type: ignore[attr-defined]
8-
return intake.Catalog.from_dict(cat.search(keyword, depth=depth).walk()) # type: ignore[call-arg, union-attr]
9+
assert isinstance(cat, intake.catalog.local.YAMLFileCatalog)
10+
return intake.Catalog.from_dict(cat.search(keyword, depth=depth).walk())
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import io
2+
3+
import intake
4+
import intake.source
5+
6+
7+
class ExcelSource(intake.source.base.DataSource):
8+
"""Intake source for reading Excel files from URLs.
9+
10+
Supports simplecache:: prefix for caching.
11+
"""
12+
13+
container = "dataframe"
14+
name = "excel_url"
15+
version = "0.0.1"
16+
17+
def __init__(
18+
self,
19+
urlpath,
20+
sheet_name="Global Carbon Budget",
21+
header=21,
22+
index_col="Year",
23+
skipfooter=4,
24+
metadata=None,
25+
):
26+
"""Initialize Excel source.
27+
28+
Args:
29+
urlpath: URL or simplecache path to Excel file
30+
sheet_name: Name of sheet to read
31+
header: Row number to use as header (0-indexed)
32+
index_col: Column to use as index
33+
skipfooter: Number of rows to skip at end
34+
metadata: Additional metadata
35+
"""
36+
super().__init__(metadata=metadata)
37+
self.urlpath = urlpath
38+
self.sheet_name = sheet_name
39+
self.header = header
40+
self.index_col = index_col
41+
self.skipfooter = skipfooter
42+
43+
def _get_schema(self):
44+
return intake.source.base.Schema(
45+
datatypes={"_": "python"},
46+
shape=(None, None),
47+
npartitions=1,
48+
metadata=self.metadata,
49+
)
50+
51+
def _load(self):
52+
import fsspec
53+
import pandas as pd
54+
55+
fs, _token, paths = fsspec.get_fs_token_paths(self.urlpath)
56+
path = paths[0]
57+
with fs.open(path, "rb") as f:
58+
return pd.read_excel(
59+
io.BytesIO(f.read()),
60+
sheet_name=self.sheet_name,
61+
header=self.header,
62+
index_col=self.index_col,
63+
skipfooter=self.skipfooter,
64+
)
65+
66+
def read(self):
67+
return self._load()
68+
69+
def _close(self):
70+
pass
71+
72+
73+
intake.source.register_driver("excel_url", ExcelSource)

0 commit comments

Comments
 (0)