dea-tools 0.3.6.dev1__tar.gz → 0.3.6.dev31__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dea_tools-0.3.6.dev1/dea_tools.egg-info → dea_tools-0.3.6.dev31}/PKG-INFO +14 -3
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/datahandling.py +29 -11
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/landcover.py +260 -69
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31/dea_tools.egg-info}/PKG-INFO +14 -3
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools.egg-info/requires.txt +1 -1
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/setup.py +1 -1
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/.gitignore +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/LICENSE +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/MANIFEST.in +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/README.rst +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/__init__.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/__main__.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/app/__init__.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/app/animations.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/app/changefilmstrips.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/app/crophealth.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/app/deacoastlines.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/app/geomedian.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/app/imageexport.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/app/miningrehab.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/app/widgetconstructors.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/bandindices.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/bom.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/classification.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/climate.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/coastal.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/dask.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/maps.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/plotting.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/pyfes_model.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/spatial.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/temporal.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/validation.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/waterbodies.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools/wetlands.py +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools.egg-info/SOURCES.txt +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools.egg-info/dependency_links.txt +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/dea_tools.egg-info/top_level.txt +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/index.rst +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/mock_imports.txt +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/pyproject.toml +0 -0
- {dea_tools-0.3.6.dev1 → dea_tools-0.3.6.dev31}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: dea-tools
|
|
3
|
-
Version: 0.3.6.
|
|
3
|
+
Version: 0.3.6.dev31
|
|
4
4
|
Summary: Functions and algorithms for analysing Digital Earth Australia data.
|
|
5
5
|
Home-page: https://github.com/GeoscienceAustralia/dea-notebooks
|
|
6
6
|
Author: Geoscience Australia
|
|
@@ -44,7 +44,7 @@ Requires-Dist: pyproj
|
|
|
44
44
|
Requires-Dist: pystac-client
|
|
45
45
|
Requires-Dist: planetary-computer
|
|
46
46
|
Requires-Dist: python-dateutil
|
|
47
|
-
Requires-Dist: pyTMD
|
|
47
|
+
Requires-Dist: pyTMD!=2.1.7
|
|
48
48
|
Requires-Dist: pytz
|
|
49
49
|
Requires-Dist: rasterio
|
|
50
50
|
Requires-Dist: rasterstats
|
|
@@ -65,6 +65,17 @@ Provides-Extra: dask-gateway
|
|
|
65
65
|
Requires-Dist: dask_gateway; extra == "dask-gateway"
|
|
66
66
|
Provides-Extra: otps
|
|
67
67
|
Requires-Dist: otps; extra == "otps"
|
|
68
|
+
Dynamic: author
|
|
69
|
+
Dynamic: author-email
|
|
70
|
+
Dynamic: classifier
|
|
71
|
+
Dynamic: description
|
|
72
|
+
Dynamic: description-content-type
|
|
73
|
+
Dynamic: home-page
|
|
74
|
+
Dynamic: license
|
|
75
|
+
Dynamic: provides-extra
|
|
76
|
+
Dynamic: requires-dist
|
|
77
|
+
Dynamic: requires-python
|
|
78
|
+
Dynamic: summary
|
|
68
79
|
|
|
69
80
|
|
|
70
81
|
dea-tools package
|
|
@@ -17,7 +17,7 @@ here: https://gis.stackexchange.com/questions/tagged/open-data-cube).
|
|
|
17
17
|
If you would like to report an issue with this script, you can file one
|
|
18
18
|
on GitHub (https://github.com/GeoscienceAustralia/dea-notebooks/issues/new).
|
|
19
19
|
|
|
20
|
-
Last modified:
|
|
20
|
+
Last modified: February 2025
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
import datetime
|
|
@@ -112,7 +112,7 @@ def load_ard(
|
|
|
112
112
|
):
|
|
113
113
|
"""
|
|
114
114
|
Load multiple Geoscience Australia Landsat or Sentinel 2
|
|
115
|
-
Collection 3 products (e.g. Landsat 5, 7, 8, 9; Sentinel 2A
|
|
115
|
+
Collection 3 Analysis Ready Data products (e.g. Landsat 5, 7, 8, 9; Sentinel 2A, 2B, 2C),
|
|
116
116
|
optionally apply pixel quality/cloud masking and contiguity masks,
|
|
117
117
|
and drop time steps that contain greater than a minimum proportion
|
|
118
118
|
of good quality (e.g. non-cloudy or shadowed) pixels.
|
|
@@ -126,13 +126,14 @@ def load_ard(
|
|
|
126
126
|
And Sentinel-2 products:
|
|
127
127
|
* ga_s2am_ard_3
|
|
128
128
|
* ga_s2bm_ard_3
|
|
129
|
+
* ga_s2cm_ard_3
|
|
129
130
|
|
|
130
131
|
Cloud masking can be performed using the Fmask (Function of Mask)
|
|
131
132
|
cloud mask for Landsat and Sentinel-2, and the s2cloudless
|
|
132
133
|
(Sentinel Hub cloud detector for Sentinel-2 imagery) cloud mask for
|
|
133
134
|
Sentinel-2.
|
|
134
135
|
|
|
135
|
-
Last modified:
|
|
136
|
+
Last modified: February 2025
|
|
136
137
|
|
|
137
138
|
Parameters
|
|
138
139
|
----------
|
|
@@ -142,7 +143,8 @@ def load_ard(
|
|
|
142
143
|
products : list
|
|
143
144
|
A list of product names to load. Valid options are
|
|
144
145
|
['ga_ls5t_ard_3', 'ga_ls7e_ard_3', 'ga_ls8c_ard_3', 'ga_ls9c_ard_3']
|
|
145
|
-
for Landsat, ['ga_s2am_ard_3', 'ga_s2bm_ard_3']
|
|
146
|
+
for Landsat, ['ga_s2am_ard_3', 'ga_s2bm_ard_3', 'ga_s2cm_ard_3']
|
|
147
|
+
for Sentinel 2.
|
|
146
148
|
cloud_mask : string, optional
|
|
147
149
|
The cloud mask used by the function. This is used for both
|
|
148
150
|
masking out poor quality pixels (e.g. clouds) if
|
|
@@ -256,21 +258,27 @@ def load_ard(
|
|
|
256
258
|
# Setup #
|
|
257
259
|
#########
|
|
258
260
|
|
|
261
|
+
# Convert products to a list if it is passed as a string
|
|
262
|
+
products = [products] if isinstance(products, str) else products
|
|
263
|
+
|
|
264
|
+
# Valid Landsat products
|
|
265
|
+
valid_ls = ["ga_ls5t_ard_3", "ga_ls7e_ard_3", "ga_ls8c_ard_3", "ga_ls9c_ard_3"]
|
|
266
|
+
valid_s2 = ["ga_s2am_ard_3", "ga_s2bm_ard_3", "ga_s2cm_ard_3"]
|
|
267
|
+
|
|
259
268
|
# Verify that products were provided
|
|
260
269
|
if not products:
|
|
261
270
|
raise ValueError(
|
|
262
|
-
"Please provide a list of
|
|
263
|
-
"Valid options are:
|
|
264
|
-
"
|
|
265
|
-
"['ga_s2am_ard_3', 'ga_s2bm_ard_3'] for Sentinel 2."
|
|
271
|
+
f"Please provide a list of Landsat or Sentinel-2 Analysis Ready Data "
|
|
272
|
+
f"product names to load data from. Valid options are: "
|
|
273
|
+
f"{valid_ls + valid_s2}."
|
|
266
274
|
)
|
|
267
275
|
|
|
268
276
|
# Determine whether products are all Landsat, all S2, or mixed
|
|
269
|
-
elif all([
|
|
277
|
+
elif all([product in valid_ls for product in products]):
|
|
270
278
|
product_type = "ls"
|
|
271
|
-
elif all([
|
|
279
|
+
elif all([product in valid_s2 for product in products]):
|
|
272
280
|
product_type = "s2"
|
|
273
|
-
|
|
281
|
+
elif all([product in valid_s2 + valid_ls for product in products]):
|
|
274
282
|
product_type = "mixed"
|
|
275
283
|
|
|
276
284
|
warnings.warn(
|
|
@@ -280,6 +288,16 @@ def load_ard(
|
|
|
280
288
|
"(e.g. Landsat and Sentinel-2's 'nbart_swir_2'); use with "
|
|
281
289
|
"caution."
|
|
282
290
|
)
|
|
291
|
+
else:
|
|
292
|
+
# If an invalid product is passed, raise error
|
|
293
|
+
invalid_products = [
|
|
294
|
+
product for product in products if product not in valid_s2 + valid_ls
|
|
295
|
+
]
|
|
296
|
+
raise ValueError(
|
|
297
|
+
f"The `load_ard` function only supports Landsat and "
|
|
298
|
+
f"Sentinel-2 Analysis Ready Data products; {invalid_products} is not supported. "
|
|
299
|
+
f"Valid options are: {valid_ls + valid_s2}."
|
|
300
|
+
)
|
|
283
301
|
|
|
284
302
|
# Set contiguity band depending on `mask_contiguity`;
|
|
285
303
|
# "oa_nbart_contiguity" if True, False or "nbart",
|
|
@@ -34,13 +34,13 @@ from matplotlib.animation import FuncAnimation
|
|
|
34
34
|
|
|
35
35
|
# Define colour schemes for each land cover measurement
|
|
36
36
|
lc_colours = {
|
|
37
|
-
'level3': {
|
|
38
|
-
111: (172, 188, 45, 255, "Cultivated Terrestrial\n Vegetation"),
|
|
37
|
+
'level3': {111: (172, 188, 45, 255, "Cultivated Terrestrial\n Vegetation"),
|
|
39
38
|
112: (14, 121, 18, 255, "Natural Terrestrial\n Vegetation"),
|
|
40
39
|
124: (30, 191, 121, 255, "Natural Aquatic\n Vegetation"),
|
|
41
40
|
215: (218, 92, 105, 255, "Artificial Surface"),
|
|
42
41
|
216: (243, 171, 105, 255, "Natural Bare\n Surface"),
|
|
43
|
-
220: (77, 159, 220, 255, "Water")
|
|
42
|
+
220: (77, 159, 220, 255, "Water"),
|
|
43
|
+
255: (255, 255, 255, 255, "No Data")},
|
|
44
44
|
|
|
45
45
|
'level3_change_colour_scheme': {0: (255, 255, 255, 255, "No Change"),
|
|
46
46
|
111112: (14, 121, 18, 255, "CTV -> NTV"),
|
|
@@ -61,49 +61,51 @@ lc_colours = {
|
|
|
61
61
|
216215: (218, 92, 105, 255, "BS -> AS"),
|
|
62
62
|
216220: (77, 159, 220, 255, "BS -> Water"),
|
|
63
63
|
220112: (14, 121, 18, 255, "Water -> NTV"),
|
|
64
|
-
220216: (243, 171, 105, 255, "Water -> BS")
|
|
64
|
+
220216: (243, 171, 105, 255, "Water -> BS"),
|
|
65
|
+
},
|
|
65
66
|
|
|
66
|
-
'level3_change_colour_bar': {
|
|
67
|
-
111: (172, 188, 45, 255, "Changed to Cultivated\n Terrestrial Vegetation"),
|
|
67
|
+
'level3_change_colour_bar': {111: (172, 188, 45, 255, "Changed to Cultivated\n Terrestrial Vegetation"),
|
|
68
68
|
112: (14, 121, 18, 255, "Changed to Natural\n Terrestrial Vegetation"),
|
|
69
69
|
124: (30, 191, 121, 255, "Changed to Natural\n Aquatic Vegetation"),
|
|
70
70
|
215: (218, 92, 105, 255, "Changed to Artificial\n Surface"),
|
|
71
71
|
216: (243, 171, 105, 255, "Changed to Natural\n Bare Surface"),
|
|
72
|
-
220: (77, 159, 220, 255, "Changed to Water")
|
|
72
|
+
220: (77, 159, 220, 255, "Changed to Water"),
|
|
73
|
+
0: (255, 255, 255, 255, "No Change")},
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
'lifeform_veg_cat_l4a': {1: (14, 121, 18, 255, "Woody Vegetation"),
|
|
76
|
+
2: (172, 188, 45, 255, "Herbaceous\n Vegetation"),
|
|
77
|
+
255: (255, 255, 255, 255, "No Data /\n Not vegetated")},
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
|
|
80
|
+
'canopyco_veg_cat_l4d': {10: (14, 121, 18, 255, "> 65 % cover"),
|
|
80
81
|
12: (45, 141, 47, 255, "40 to 65 % cover"),
|
|
81
82
|
13: (80, 160, 82, 255, "15 to 40 % cover"),
|
|
82
83
|
15: (117, 180, 118, 255, "4 to 15 % cover"),
|
|
83
|
-
16: (154, 199, 156, 255, "1 to 4 % cover")
|
|
84
|
+
16: (154, 199, 156, 255, "1 to 4 % cover"),
|
|
85
|
+
255: (255, 255, 255, 255, "No Data /\n Not vegetated")},
|
|
84
86
|
|
|
85
|
-
'waterstt_wat_cat_l4a': {
|
|
86
|
-
|
|
87
|
+
'waterstt_wat_cat_l4a': {1: (77, 159, 220, 255, "Water"),
|
|
88
|
+
255: (255, 255, 255, 255, "No Data /\n Not water")},
|
|
87
89
|
|
|
88
|
-
'watersea_veg_cat_l4a_au': {
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
'watersea_veg_cat_l4a_au': {1: (25, 173, 109, 255, "> 3 months"),
|
|
91
|
+
2: (176, 218, 201, 255, "< 3 months"),
|
|
92
|
+
255: (255, 255, 255, 255, "No data /\n Not aquatic vegetation")},
|
|
91
93
|
|
|
92
|
-
'inttidal_wat_cat_l4a': {
|
|
93
|
-
|
|
94
|
+
'inttidal_wat_cat_l4a': {3: (77, 159, 220, 255, "Intertidal"),
|
|
95
|
+
255: (255, 255, 255, 255, "No data /\n Not intertidal")},
|
|
94
96
|
|
|
95
|
-
'waterper_wat_cat_l4d_au': {
|
|
96
|
-
1: (27, 85, 186, 255, "> 9 months"),
|
|
97
|
+
'waterper_wat_cat_l4d_au': {1: (27, 85, 186, 255, "> 9 months"),
|
|
97
98
|
7: (52, 121, 201, 255, "7 to 9 months"),
|
|
98
99
|
8: (79, 157, 217, 255, "4 to 6 months"),
|
|
99
|
-
9: (113, 202, 253, 255, "1 to 3 months")
|
|
100
|
+
9: (113, 202, 253, 255, "1 to 3 months"),
|
|
101
|
+
255: (255, 255, 255, 255, "No data /\n Not water")},
|
|
100
102
|
|
|
101
|
-
'baregrad_phy_cat_l4d_au': {
|
|
102
|
-
10: (255, 230, 140, 255, "Sparsely vegetated\n (< 20% bare)"),
|
|
103
|
+
'baregrad_phy_cat_l4d_au': {10: (255, 230, 140, 255, "Sparsely vegetated\n (< 20% bare)"),
|
|
103
104
|
12: (250, 210, 110, 255, "Very sparsely\n vegetated (20 to 60% bare)"),
|
|
104
|
-
15: (243, 171, 105, 255, "Bare areas,\n unvegetated (> 60% bare)")
|
|
105
|
+
15: (243, 171, 105, 255, "Bare areas,\n unvegetated (> 60% bare)"),
|
|
106
|
+
255: (255, 255, 255, 255, "No data /\n Not bare")},
|
|
105
107
|
|
|
106
|
-
'level4': {
|
|
108
|
+
'level4': {
|
|
107
109
|
1: (151, 187, 26, 255, 'Cultivated Terrestrial\n Vegetated:'),
|
|
108
110
|
2: (151, 187, 26, 255, 'Cultivated Terrestrial\n Vegetated: Woody'),
|
|
109
111
|
3: (209, 224, 51, 255, 'Cultivated Terrestrial\n Vegetated: Herbaceous'),
|
|
@@ -112,11 +114,11 @@ lc_colours = {
|
|
|
112
114
|
6: (213, 193, 79, 255, 'Cultivated Terrestrial\n Vegetated: Open\n (15 to 40 %)'),
|
|
113
115
|
7: (228, 210, 108, 255, 'Cultivated Terrestrial\n Vegetated: Sparse\n (4 to 15 %)'),
|
|
114
116
|
8: (242, 227, 138, 255, 'Cultivated Terrestrial\n Vegetated: Scattered\n (1 to 4 %)'),
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
9: (197, 168, 71, 255, 'Cultivated Terrestrial\n Vegetated: Woody Closed\n (> 65 %)'),
|
|
118
|
+
10: (205, 181, 75, 255, 'Cultivated Terrestrial\n Vegetated: Woody Open\n (40 to 65 %)'),
|
|
119
|
+
11: (213, 193, 79, 255, 'Cultivated Terrestrial\n Vegetated: Woody Open\n (15 to 40 %)'),
|
|
120
|
+
12: (228, 210, 108, 255, 'Cultivated Terrestrial\n Vegetated: Woody Sparse\n (4 to 15 %)'),
|
|
121
|
+
13: (242, 227, 138, 255, 'Cultivated Terrestrial\n Vegetated: Woody Scattered\n (1 to 4 %)'),
|
|
120
122
|
14: (228, 224, 52, 255, 'Cultivated Terrestrial\n Vegetated: Herbaceous Closed\n (> 65 %)'),
|
|
121
123
|
15: (235, 232, 84, 255, 'Cultivated Terrestrial\n Vegetated: Herbaceous Open\n (40 to 65 %)'),
|
|
122
124
|
16: (242, 240, 127, 255, 'Cultivated Terrestrial\n Vegetated: Herbaceous Open\n (15 to 40 %)'),
|
|
@@ -140,24 +142,24 @@ lc_colours = {
|
|
|
140
142
|
34: (153, 196, 80, 255, 'Natural Terrestrial Vegetated: Herbaceous Open (15 to 40 %)'),
|
|
141
143
|
35: (170, 212, 113, 255, 'Natural Terrestrial Vegetated: Herbaceous Sparse (4 to 15 %)'),
|
|
142
144
|
36: (186, 226, 146, 255, 'Natural Terrestrial Vegetated: Herbaceous Scattered (1 to 4 %)'),
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
145
|
+
37: (86, 236, 231, 255, 'Cultivated Aquatic Vegetated:'),
|
|
146
|
+
38: (61, 170, 140, 255, 'Cultivated Aquatic Vegetated: Woody'),
|
|
147
|
+
39: (82, 231, 172, 255, 'Cultivated Aquatic Vegetated: Herbaceous'),
|
|
148
|
+
40: (43, 210, 203, 255, 'Cultivated Aquatic Vegetated: Closed (> 65 %)'),
|
|
149
|
+
41: (73, 222, 216, 255, 'Cultivated Aquatic Vegetated: Open (40 to 65 %)'),
|
|
150
|
+
42: (110, 233, 228, 255, 'Cultivated Aquatic Vegetated: Open (15 to 40 %)'),
|
|
151
|
+
43: (149, 244, 240, 255, 'Cultivated Aquatic Vegetated: Sparse (4 to 15 %)'),
|
|
152
|
+
44: (187, 255, 252, 255, 'Cultivated Aquatic Vegetated: Scattered (1 to 4 %)'),
|
|
151
153
|
# 45: (43, 210, 203, 255, 'Cultivated Aquatic Vegetated: Woody Closed (> 65 %)'),
|
|
152
154
|
# 46: (73, 222, 216, 255, 'Cultivated Aquatic Vegetated: Woody Open (40 to 65 %)'),
|
|
153
155
|
# 47: (110, 233, 228, 255, 'Cultivated Aquatic Vegetated: Woody Open (15 to 40 %)'),
|
|
154
156
|
# 48: (149, 244, 240, 255, 'Cultivated Aquatic Vegetated: Woody Sparse (4 to 15 %)'),
|
|
155
157
|
# 49: (187, 255, 252, 255, 'Cultivated Aquatic Vegetated: Woody Scattered (1 to 4 %)'),
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
158
|
+
50: (82, 231, 196, 255, 'Cultivated Aquatic Vegetated: Herbaceous Closed (> 65 %)'),
|
|
159
|
+
51: (113, 237, 208, 255, 'Cultivated Aquatic Vegetated: Herbaceous Open (40 to 65 %)'),
|
|
160
|
+
52: (144, 243, 220, 255, 'Cultivated Aquatic Vegetated: Herbaceous Open (15 to 40 %)'),
|
|
161
|
+
53: (175, 249, 232, 255, 'Cultivated Aquatic Vegetated: Herbaceous Sparse (4 to 15 %)'),
|
|
162
|
+
54: (207, 255, 244, 255, 'Cultivated Aquatic Vegetated: Herbaceous Scattered (1 to 4 %)'),
|
|
161
163
|
55: (30, 191, 121, 255, 'Natural Aquatic Vegetated:'),
|
|
162
164
|
56: (18, 142, 148, 255, 'Natural Aquatic Vegetated: Woody'),
|
|
163
165
|
57: (112, 234, 134, 255, 'Natural Aquatic Vegetated: Herbaceous'),
|
|
@@ -209,9 +211,14 @@ lc_colours = {
|
|
|
209
211
|
103: (79, 157, 217, 255, 'Water: (Water) Non-perennial (4 to 6 months)'),
|
|
210
212
|
104: (133, 202, 253, 255, 'Water: (Water) Non-perennial (1 to 3 months)'),
|
|
211
213
|
# 105: (250, 250, 250, 255, 'Water: (Snow)')
|
|
214
|
+
255: (255, 255, 255, 255, "No Data")
|
|
212
215
|
},
|
|
213
216
|
|
|
214
|
-
'level4_colourbar_labels': {
|
|
217
|
+
'level4_colourbar_labels': {9: (197, 168, 71, 255, 'Cultivated Terrestrial Vegetated: Woody Closed (> 65 %)'),
|
|
218
|
+
10: (205, 181, 75, 255, 'Cultivated Terrestrial Vegetated: Woody Open (40 to 65 %)'),
|
|
219
|
+
11: (213, 193, 79, 255, 'Cultivated Terrestrial Vegetated: Woody Open (15 to 40 %)'),
|
|
220
|
+
12: (228, 210, 108, 255, 'Cultivated Terrestrial Vegetated: Woody Sparse (4 to 15 %)'),
|
|
221
|
+
13: (242, 227, 138, 255, 'Cultivated Terrestrial Vegetated: Woody Scattered (1 to 4 %)'),
|
|
215
222
|
14: (228, 224, 52, 255, 'Cultivated Terrestrial Vegetated: Herbaceous Closed (> 65 %)'),
|
|
216
223
|
15: (235, 232, 84, 255, 'Cultivated Terrestrial Vegetated: Herbaceous Open (40 to 65 %)'),
|
|
217
224
|
16: (242, 240, 127, 255, 'Cultivated Terrestrial Vegetated: Herbaceous Open (15 to 40 %)'),
|
|
@@ -245,10 +252,41 @@ lc_colours = {
|
|
|
245
252
|
101: (27, 85, 186, 255, 'Water: (Water) Perennial (> 9 months)'),
|
|
246
253
|
102: (52, 121, 201, 255, 'Water: (Water) Non-perennial (7 to 9 months)'),
|
|
247
254
|
103: (79, 157, 217, 255, 'Water: (Water) Non-perennial (4 to 6 months)'),
|
|
248
|
-
104: (133, 202, 253, 255, 'Water: (Water) Non-perennial (1 to 3 months)')
|
|
255
|
+
104: (133, 202, 253, 255, 'Water: (Water) Non-perennial (1 to 3 months)'),
|
|
256
|
+
255: (255, 255, 255, 255, "No Data")
|
|
257
|
+
},
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
# dictionary needed to generate colour schemes of descriptors from the level 4 colour scheme. The structure is as follow:
|
|
261
|
+
# long_descriptor_name[string]: {keyword_for_finding_classes_in_level4_colourscheme[string] : (RGB_colourscheme[4 integers], label_of_descriptor[string])}
|
|
262
|
+
lc_colours_mapping = {
|
|
263
|
+
'lifeform_veg_cat_l4a': {'Woody': (14, 121,18, 255, 'Woody Vegetation'),
|
|
264
|
+
'Herbaceous': (172, 188, 45, 255, 'Herbaceous\n Vegetation')},
|
|
265
|
+
'canopyco_veg_cat_l4d': {'> 65 %': (14, 121, 18, 255, '> 65 % cover'),
|
|
266
|
+
'40 to 65 %': (45, 141, 47, 255, '40 to 65 % cover'),
|
|
267
|
+
'15 to 40 %': (80, 160, 82, 255, '15 to 40 % cover'),
|
|
268
|
+
'4 to 15 %': (117, 180, 118, 255, '4 to 15 % cover'),
|
|
269
|
+
'1 to 4 %': (154, 199, 156, 255, '1 to 4 % cover')},
|
|
270
|
+
'watersea_veg_cat_l4a_au': {'(semi-) permenant': (25, 173, 109, 255, '> 3 months'),
|
|
271
|
+
'(temporary or seasonal)': (176, 218, 201, 255, '< 3 months')},
|
|
272
|
+
'waterstt_wat_cat_l4a': {'Water: (Water)': (77, 159, 220, 255, 'Water')},
|
|
273
|
+
'inttidal_wat_cat_l4a': {'Tidal area': (77, 159, 220, 255, 'Water: (Water) Tidal area')},
|
|
274
|
+
'waterper_wat_cat_l4d_au': {'> 9 months': (27, 85, 186, 255, '> 9 months'),
|
|
275
|
+
'7 to 9 months': (52, 121, 201, 255, '7 to 9 months'),
|
|
276
|
+
'4 to 6 months': (79, 157, 217, 255, '4 to 6 months'),
|
|
277
|
+
'1 to 3 months': (113, 202, 253, 255, '1 to 3 months')},
|
|
278
|
+
'baregrad_phy_cat_l4d_au': {'Sparsely vegetated': (255, 230, 140, 255, 'Sparsely vegetated\n (< 20% bare)'),
|
|
279
|
+
'Very sparesely': (250, 210, 110, 255, 'Very sparsely\n vegetated (20 to 60% bare)'),
|
|
280
|
+
'Bare areas': (243, 171, 105, 255, 'Bare areas,\n unvegetated (> 60% bare)')},
|
|
281
|
+
|
|
249
282
|
}
|
|
250
283
|
|
|
251
284
|
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
252
290
|
def get_layer_name(measurement, da):
|
|
253
291
|
aliases = {
|
|
254
292
|
'lifeform': 'lifeform_veg_cat_l4a',
|
|
@@ -287,6 +325,7 @@ def make_colorbar(fig, ax, measurement, horizontal=False, animation=False):
|
|
|
287
325
|
Land cover measurement to use for colour map and labels.
|
|
288
326
|
|
|
289
327
|
"""
|
|
328
|
+
|
|
290
329
|
# Create new axis object for colorbar
|
|
291
330
|
# parameters for add_axes are [left, bottom, width, height], in
|
|
292
331
|
# fractions of total plot
|
|
@@ -298,12 +337,12 @@ def make_colorbar(fig, ax, measurement, horizontal=False, animation=False):
|
|
|
298
337
|
orient = 'vertical'
|
|
299
338
|
|
|
300
339
|
# get level 4 colour bar colour map ect
|
|
301
|
-
cb_cmap, cb_norm, cb_labels, cb_ticks =
|
|
340
|
+
cb_cmap, cb_norm, cb_labels, cb_ticks = lc_colourmap_colourbar('level4_colourbar_labels',
|
|
302
341
|
colour_bar=True)
|
|
303
342
|
elif measurement == 'level4' and animation == False:
|
|
304
343
|
|
|
305
344
|
# get level 4 colour bar colour map ect
|
|
306
|
-
cb_cmap, cb_norm, cb_labels, cb_ticks =
|
|
345
|
+
cb_cmap, cb_norm, cb_labels, cb_ticks = lc_colourmap_colourbar('level4_colourbar_labels',
|
|
307
346
|
colour_bar=True)
|
|
308
347
|
#move plot over to make room for colourbar
|
|
309
348
|
fig.subplots_adjust(right=0.825)
|
|
@@ -327,7 +366,7 @@ def make_colorbar(fig, ax, measurement, horizontal=False, animation=False):
|
|
|
327
366
|
orient = 'vertical'
|
|
328
367
|
|
|
329
368
|
# get measurement colour bar colour map ect
|
|
330
|
-
cb_cmap, cb_norm, cb_labels, cb_ticks =
|
|
369
|
+
cb_cmap, cb_norm, cb_labels, cb_ticks = lc_colourmap_colourbar(measurement,
|
|
331
370
|
colour_bar=True)
|
|
332
371
|
|
|
333
372
|
img = ax.imshow([cb_ticks], cmap=cb_cmap, norm=cb_norm)
|
|
@@ -339,6 +378,59 @@ def make_colorbar(fig, ax, measurement, horizontal=False, animation=False):
|
|
|
339
378
|
|
|
340
379
|
|
|
341
380
|
|
|
381
|
+
|
|
382
|
+
def descriptors_colours(lc_colours, lc_colours_mapping, descriptor):
|
|
383
|
+
"""
|
|
384
|
+
Generates a sorted dictionary of colours based on a given descriptor.
|
|
385
|
+
|
|
386
|
+
This function takes in a dictionary of Land Cover classes, a mapping of descriptors to colours,
|
|
387
|
+
and a specific descriptor. It returns a dictionary where the keys are sorted and the values are
|
|
388
|
+
the corresponding colours and labels from the descriptor mapping.
|
|
389
|
+
|
|
390
|
+
Parameters
|
|
391
|
+
----------
|
|
392
|
+
lc_colours : dict
|
|
393
|
+
Dictionary containing colour schemes for all Land Cover classes.
|
|
394
|
+
|
|
395
|
+
lc_colours_mapping : dict
|
|
396
|
+
Dictionary mapping descriptors (e.g., lifeform) to their corresponding colours and labels.
|
|
397
|
+
|
|
398
|
+
descriptor : str
|
|
399
|
+
The descriptor to be used for mapping colours.
|
|
400
|
+
|
|
401
|
+
Returns
|
|
402
|
+
-------
|
|
403
|
+
sorted_colours_dict : dict
|
|
404
|
+
Sorted dictionary with class values as keys and colour tuples as values.
|
|
405
|
+
"""
|
|
406
|
+
|
|
407
|
+
# get the level 4 colour scheme from the lc_colours dictionary
|
|
408
|
+
level4_colours = lc_colours['level4']
|
|
409
|
+
|
|
410
|
+
# get the descriptor dictionary from the lc_colours_mapping
|
|
411
|
+
descriptor_dict = lc_colours_mapping[descriptor]
|
|
412
|
+
|
|
413
|
+
# create a new colours dictionary with all level 4 values set to white colour
|
|
414
|
+
# based on the descriptor, the values of interest will be filled with the pre-defined colours (all the rest will stay white)
|
|
415
|
+
colours_dict = level4_colours.copy()
|
|
416
|
+
for key in colours_dict:
|
|
417
|
+
colours_dict[key] = (255, 255, 255, 255, "No Data")
|
|
418
|
+
|
|
419
|
+
# update the colours dictionary with the descriptor-specific colours
|
|
420
|
+
for class_keyword, colour_n_label in descriptor_dict.items():
|
|
421
|
+
|
|
422
|
+
for class_value, lvl4_scheme in level4_colours.items():
|
|
423
|
+
label_lvl4 = lvl4_scheme[4]
|
|
424
|
+
|
|
425
|
+
if class_keyword in label_lvl4:
|
|
426
|
+
colours_dict[class_value] = colour_n_label
|
|
427
|
+
|
|
428
|
+
# sort the colours dictionary by keys
|
|
429
|
+
sorted_colours_dict = {key: colours_dict[key] for key in sorted(colours_dict.keys())}
|
|
430
|
+
|
|
431
|
+
return sorted_colours_dict
|
|
432
|
+
|
|
433
|
+
|
|
342
434
|
def lc_colourmap(colour_scheme, colour_bar=False):
|
|
343
435
|
"""
|
|
344
436
|
Returns colour map and normalisation for the provided DEA Land Cover
|
|
@@ -371,6 +463,85 @@ def lc_colourmap(colour_scheme, colour_bar=False):
|
|
|
371
463
|
in the chosen DEA Land Cover measurement.
|
|
372
464
|
"""
|
|
373
465
|
|
|
466
|
+
|
|
467
|
+
colour_scheme = colour_scheme.lower()
|
|
468
|
+
|
|
469
|
+
# if a descriptor colour scheme is required, use the descriptors_colours function
|
|
470
|
+
if colour_scheme in lc_colours_mapping:
|
|
471
|
+
lc_colour_scheme=descriptors_colours(lc_colours,lc_colours_mapping, colour_scheme)
|
|
472
|
+
|
|
473
|
+
else: # standard colours scheme
|
|
474
|
+
lc_colour_scheme = lc_colours[colour_scheme]
|
|
475
|
+
# Ensure a valid colour scheme was requested
|
|
476
|
+
assert (colour_scheme in lc_colours.keys(
|
|
477
|
+
)), f'colour scheme must be one of [{lc_colours.keys()}] (got "{colour_scheme}")'
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
# Create colour map
|
|
481
|
+
colour_arr = []
|
|
482
|
+
for key, value in lc_colour_scheme.items():
|
|
483
|
+
colour_arr.append(np.array(value[:-2]) / 255)
|
|
484
|
+
|
|
485
|
+
cmap = mcolours.ListedColormap(colour_arr)
|
|
486
|
+
bounds = list(lc_colour_scheme)
|
|
487
|
+
|
|
488
|
+
if colour_bar == True:
|
|
489
|
+
if colour_scheme == 'level4':
|
|
490
|
+
# Set colour labels to shortened level 4 list
|
|
491
|
+
lc_colour_scheme = lc_colours['level4_colourbar_labels']
|
|
492
|
+
cb_ticks = list(lc_colour_scheme)
|
|
493
|
+
#print(f'CB_TICKS {cb_ticks}')
|
|
494
|
+
cb_labels = []
|
|
495
|
+
for x in cb_ticks:
|
|
496
|
+
cb_labels.append(lc_colour_scheme[x][4])
|
|
497
|
+
|
|
498
|
+
bounds.append(bounds[-1]+1)
|
|
499
|
+
|
|
500
|
+
# shift all back by 0.5 to make sure level4 values are within bounds and not mathcing exactly one bound
|
|
501
|
+
bounds = [i-0.5 for i in bounds]
|
|
502
|
+
|
|
503
|
+
norm = mcolours.BoundaryNorm(np.array(bounds), cmap.N)
|
|
504
|
+
|
|
505
|
+
if colour_bar == False:
|
|
506
|
+
return (cmap, norm)
|
|
507
|
+
else:
|
|
508
|
+
return (cmap, norm, cb_labels, cb_ticks)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
def lc_colourmap_colourbar(colour_scheme, colour_bar=False):
|
|
513
|
+
"""
|
|
514
|
+
Returns colour map and normalisation for the provided DEA Land Cover
|
|
515
|
+
measurement, for use in plotting with Matplotlib library
|
|
516
|
+
|
|
517
|
+
Parameters
|
|
518
|
+
----------
|
|
519
|
+
colour_scheme : string
|
|
520
|
+
Name of land cover colour scheme to use
|
|
521
|
+
Valid options: 'level3', 'level4', 'lifeform_veg_cat_l4a',
|
|
522
|
+
'canopyco_veg_cat_l4d', 'watersea_veg_cat_l4a_au',
|
|
523
|
+
'waterstt_wat_cat_l4a', 'inttidal_wat_cat_l4a',
|
|
524
|
+
'waterper_wat_cat_l4d_au', 'baregrad_phy_cat_l4d_au'.
|
|
525
|
+
colour_bar : bool, optional
|
|
526
|
+
Controls if colour bar labels are returned as a list for
|
|
527
|
+
plotting a colour bar. Default: False.
|
|
528
|
+
|
|
529
|
+
Returns
|
|
530
|
+
---------
|
|
531
|
+
cmap : matplotlib colormap
|
|
532
|
+
Matplotlib colormap containing the colour scheme for the
|
|
533
|
+
specified DEA Land Cover measurement.
|
|
534
|
+
norm : matplotlib colormap index
|
|
535
|
+
Matplotlib colormap index based on the discrete intervals of the
|
|
536
|
+
classes in the specified DEA Land Cover measurement. Ensures the
|
|
537
|
+
colormap maps the colours to the class numbers correctly.
|
|
538
|
+
cblables : array
|
|
539
|
+
A two dimentional array containing the numerical class values
|
|
540
|
+
(first dim) and string labels (second dim) of the classes found
|
|
541
|
+
in the chosen DEA Land Cover measurement.
|
|
542
|
+
"""
|
|
543
|
+
|
|
544
|
+
|
|
374
545
|
colour_scheme = colour_scheme.lower()
|
|
375
546
|
# Ensure a valid colour scheme was requested
|
|
376
547
|
# try:
|
|
@@ -380,9 +551,9 @@ def lc_colourmap(colour_scheme, colour_bar=False):
|
|
|
380
551
|
# ('The dataset provided does not have a valid '
|
|
381
552
|
# 'name. Please specify which DEA Landcover measurement is being plotted '
|
|
382
553
|
# 'by providing the name using the "measurement" variable. For example (measurement = "full_classification")')
|
|
383
|
-
|
|
554
|
+
|
|
384
555
|
# Get colour definitions
|
|
385
|
-
lc_colour_scheme = lc_colours[colour_scheme]
|
|
556
|
+
lc_colour_scheme = lc_colours[colour_scheme]
|
|
386
557
|
|
|
387
558
|
# Create colour map
|
|
388
559
|
colour_arr = []
|
|
@@ -397,6 +568,7 @@ def lc_colourmap(colour_scheme, colour_bar=False):
|
|
|
397
568
|
# Set colour labels to shortened level 4 list
|
|
398
569
|
lc_colour_scheme = lc_colours['level4_colourbar_labels']
|
|
399
570
|
cb_ticks = list(lc_colour_scheme)
|
|
571
|
+
#print(f'CB_TICKS {cb_ticks}')
|
|
400
572
|
cb_labels = []
|
|
401
573
|
for x in cb_ticks:
|
|
402
574
|
cb_labels.append(lc_colour_scheme[x][4])
|
|
@@ -410,6 +582,7 @@ def lc_colourmap(colour_scheme, colour_bar=False):
|
|
|
410
582
|
return (cmap, norm, cb_labels, cb_ticks)
|
|
411
583
|
|
|
412
584
|
|
|
585
|
+
|
|
413
586
|
def plot_land_cover(data, year=None, measurement=None, out_width=15, cols=4,):
|
|
414
587
|
"""
|
|
415
588
|
Plot a single land cover measurement with appropriate colour scheme.
|
|
@@ -437,30 +610,33 @@ def plot_land_cover(data, year=None, measurement=None, out_width=15, cols=4,):
|
|
|
437
610
|
f'DataArray name {measurement}. Please specify which '
|
|
438
611
|
'DEA Landcover measurement is being plotted by providing'
|
|
439
612
|
'the name using the "measurement" variable For example'
|
|
440
|
-
'(measurement = "
|
|
613
|
+
'(measurement = "level4")')
|
|
441
614
|
|
|
442
615
|
height, width = data.geobox.shape
|
|
443
616
|
scale = out_width / width
|
|
444
617
|
|
|
445
618
|
if year:
|
|
446
|
-
#plotting
|
|
447
|
-
|
|
448
|
-
|
|
619
|
+
#plotting protocol if 'year' variable is passed
|
|
620
|
+
if int(year) not in pd.to_datetime(data.time.values).year: # check if year selecte is in the datacube
|
|
621
|
+
raise ValueError(f'Year {year} is not in the data array.')
|
|
622
|
+
|
|
623
|
+
year_string = f"{year}-07-01" # LC collection 3 dates are in July
|
|
624
|
+
data = data.sel(time=year_string, method='nearest')
|
|
449
625
|
|
|
450
626
|
fig, ax = plt.subplots()
|
|
451
627
|
fig.set_size_inches(width * scale, height * scale)
|
|
452
628
|
make_colorbar(fig, ax, measurement)
|
|
453
|
-
im = ax.imshow(data, cmap=cmap, norm=norm, interpolation="nearest")
|
|
629
|
+
im = ax.imshow(data.values, cmap=cmap, norm=norm, interpolation="nearest")
|
|
454
630
|
|
|
455
631
|
|
|
456
632
|
elif len(data.time) == 1:
|
|
457
|
-
#plotting
|
|
633
|
+
#plotting protocol if only one timestep is passed and not a year variable
|
|
458
634
|
fig, ax = plt.subplots()
|
|
459
635
|
fig.set_size_inches(width * scale, height * scale)
|
|
460
636
|
make_colorbar(fig, ax, measurement)
|
|
461
637
|
im = ax.imshow(data.isel(time=0), cmap=cmap, norm=norm, interpolation="nearest")
|
|
462
638
|
else:
|
|
463
|
-
#plotting
|
|
639
|
+
#plotting protocol if multible time steps are passed to plot
|
|
464
640
|
if cols > len(data.time):
|
|
465
641
|
cols = len(data.time)
|
|
466
642
|
rows = int((len(data.time) + cols-1)/cols)
|
|
@@ -489,7 +665,8 @@ def lc_animation(
|
|
|
489
665
|
width_pixels=10,
|
|
490
666
|
dpi=150,
|
|
491
667
|
font_size=15,
|
|
492
|
-
label_ax=True
|
|
668
|
+
label_ax=True,
|
|
669
|
+
):
|
|
493
670
|
"""
|
|
494
671
|
Creates an animation of DEA Landcover though time beside
|
|
495
672
|
corresponding stacked plots of the landcover classes. Saves the
|
|
@@ -531,19 +708,21 @@ def lc_animation(
|
|
|
531
708
|
label_ax : boolean, optional
|
|
532
709
|
Determines if animation plot should have tick marks and numbers
|
|
533
710
|
on axes. Also removes white space around plot. default: True
|
|
711
|
+
|
|
534
712
|
|
|
535
713
|
Returns
|
|
536
714
|
-------
|
|
537
715
|
A GIF (.gif) animation file.
|
|
538
716
|
"""
|
|
539
717
|
|
|
540
|
-
def calc_class_ratio(da):
|
|
718
|
+
def calc_class_ratio(da, measurement):
|
|
541
719
|
"""
|
|
542
720
|
Creates a table listing year by year what percentage of the
|
|
543
721
|
total area is taken up by each class.
|
|
544
722
|
Parameters
|
|
545
723
|
----------
|
|
546
724
|
da : xarray.DataArray with time dimension
|
|
725
|
+
measurement: string with name of descriptor/measurement
|
|
547
726
|
Returns
|
|
548
727
|
-------
|
|
549
728
|
Pandas Dataframe : containing class percentages per year
|
|
@@ -551,13 +730,24 @@ def lc_animation(
|
|
|
551
730
|
|
|
552
731
|
# list all class codes in dataset
|
|
553
732
|
list_classes = (np.unique(da, return_counts=False)).tolist()
|
|
554
|
-
|
|
733
|
+
|
|
734
|
+
# if a descriptor colour scheme is required, list_classes need to be chnaged to contain only classes of that descriptor
|
|
735
|
+
# the following code uses the descriptors_colours function to get the colours scheme and then the values of the descriptor of interest
|
|
736
|
+
if measurement in lc_colours_mapping:
|
|
737
|
+
lc_colour_scheme=descriptors_colours(lc_colours,lc_colours_mapping, measurement)
|
|
738
|
+
# sort based on first RGB colour, so stack plot will show same colours next to each other
|
|
739
|
+
lc_colour_scheme= dict(sorted(lc_colour_scheme.items(), key=lambda item: item[1][0]))
|
|
740
|
+
# create list of values
|
|
741
|
+
all_classes_descriptor = list(lc_colour_scheme.keys())
|
|
742
|
+
# out of all possible classes of that descriptor, keep only the ones actually in the data array
|
|
743
|
+
list_classes = [i for i in all_classes_descriptor if i in list_classes] # the order of all_classes_descriptor and list_classes is important: the correct sorting order is the one of all_classes_descriptor
|
|
744
|
+
|
|
555
745
|
# create empty dataframe & dictionary
|
|
556
746
|
ratio_table = pd.DataFrame(data=None, columns=list_classes)
|
|
557
747
|
date_line = {}
|
|
558
748
|
|
|
559
749
|
# count all pixels, should be consistent
|
|
560
|
-
total_pix =
|
|
750
|
+
total_pix = da.isel(time=1).size
|
|
561
751
|
|
|
562
752
|
# iterate through each year in dataset
|
|
563
753
|
for i in range(0, len(da.time)):
|
|
@@ -572,7 +762,6 @@ def lc_animation(
|
|
|
572
762
|
|
|
573
763
|
# add each year's counts to dataframe
|
|
574
764
|
ratio_table.loc[date] = date_line
|
|
575
|
-
|
|
576
765
|
return ratio_table
|
|
577
766
|
|
|
578
767
|
def rgb_to_hex(r, g, b):
|
|
@@ -596,7 +785,7 @@ def lc_animation(
|
|
|
596
785
|
f'DataArray name {measurement}. Please specify which '
|
|
597
786
|
'DEA Landcover measurement is being plotted by providing '
|
|
598
787
|
'the name using the "measurement" variable For example '
|
|
599
|
-
'(measurement = "
|
|
788
|
+
'(measurement = "level4")')
|
|
600
789
|
|
|
601
790
|
# Prepare variables needed
|
|
602
791
|
# Get info on dataset dimensions
|
|
@@ -626,14 +815,16 @@ def lc_animation(
|
|
|
626
815
|
|
|
627
816
|
if stacked_plot == True:
|
|
628
817
|
|
|
629
|
-
|
|
630
|
-
|
|
631
818
|
# Create table for stacked plot
|
|
632
|
-
stacked_plot_table = calc_class_ratio(da)
|
|
819
|
+
stacked_plot_table = calc_class_ratio(da, measurement)
|
|
633
820
|
|
|
634
821
|
# Build colour list of hex vals for stacked plot
|
|
635
822
|
hex_colour_list = []
|
|
636
|
-
|
|
823
|
+
|
|
824
|
+
if measurement in lc_colours_mapping: # if descriptor
|
|
825
|
+
colour_def=descriptors_colours(lc_colours,lc_colours_mapping, measurement)
|
|
826
|
+
else: # if level 3 or 4
|
|
827
|
+
colour_def = lc_colours[measurement]
|
|
637
828
|
|
|
638
829
|
# Custom error message to help if user puts incorrect measurement name
|
|
639
830
|
for val in list(stacked_plot_table):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: dea-tools
|
|
3
|
-
Version: 0.3.6.
|
|
3
|
+
Version: 0.3.6.dev31
|
|
4
4
|
Summary: Functions and algorithms for analysing Digital Earth Australia data.
|
|
5
5
|
Home-page: https://github.com/GeoscienceAustralia/dea-notebooks
|
|
6
6
|
Author: Geoscience Australia
|
|
@@ -44,7 +44,7 @@ Requires-Dist: pyproj
|
|
|
44
44
|
Requires-Dist: pystac-client
|
|
45
45
|
Requires-Dist: planetary-computer
|
|
46
46
|
Requires-Dist: python-dateutil
|
|
47
|
-
Requires-Dist: pyTMD
|
|
47
|
+
Requires-Dist: pyTMD!=2.1.7
|
|
48
48
|
Requires-Dist: pytz
|
|
49
49
|
Requires-Dist: rasterio
|
|
50
50
|
Requires-Dist: rasterstats
|
|
@@ -65,6 +65,17 @@ Provides-Extra: dask-gateway
|
|
|
65
65
|
Requires-Dist: dask_gateway; extra == "dask-gateway"
|
|
66
66
|
Provides-Extra: otps
|
|
67
67
|
Requires-Dist: otps; extra == "otps"
|
|
68
|
+
Dynamic: author
|
|
69
|
+
Dynamic: author-email
|
|
70
|
+
Dynamic: classifier
|
|
71
|
+
Dynamic: description
|
|
72
|
+
Dynamic: description-content-type
|
|
73
|
+
Dynamic: home-page
|
|
74
|
+
Dynamic: license
|
|
75
|
+
Dynamic: provides-extra
|
|
76
|
+
Dynamic: requires-dist
|
|
77
|
+
Dynamic: requires-python
|
|
78
|
+
Dynamic: summary
|
|
68
79
|
|
|
69
80
|
|
|
70
81
|
dea-tools package
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|