Spaces:
Sleeping
Sleeping
cassiebuhler
commited on
Commit
·
b338fe9
1
Parent(s):
e6a4360
new layers, zonal stats
Browse files- app.py +194 -94
- requirements.txt +2 -1
app.py
CHANGED
@@ -53,7 +53,6 @@ ca = (con
|
|
53 |
.cast({"crop_expansion": "int64"})
|
54 |
)
|
55 |
|
56 |
-
|
57 |
private_access_color = "#DE881E" # orange
|
58 |
public_access_color = "#3388ff" # blue
|
59 |
tribal_color = "#BF40BF" # purple
|
@@ -78,57 +77,63 @@ from functools import reduce
|
|
78 |
def get_summary(ca, combined_filter, column, colors=None):
|
79 |
df = ca.filter(combined_filter)
|
80 |
|
81 |
-
if colors is not None and not colors.empty: # df used for chart.
|
82 |
-
|
83 |
|
84 |
df = (df
|
85 |
.group_by(*column) # unpack the list for grouping
|
86 |
.aggregate(percent_protected=100 * _.Acres.sum() / ca_area_acres,
|
87 |
-
|
88 |
mean_rsr = (_.rsr * _.Acres).sum() / _.Acres.sum(),
|
89 |
-
|
|
|
90 |
irrecoverable_carbon = (_.irrecoverable_carbon * _.Acres).sum() / _.Acres.sum(),
|
91 |
manageable_carbon = (_.manageable_carbon * _.Acres).sum() / _.Acres.sum(),
|
92 |
-
|
93 |
-
crop_expansion = (_.crop_expansion * _.Acres).sum() / _.Acres.sum(),
|
94 |
-
|
95 |
human_impact = (_.human_impact * _.Acres).sum() / _.Acres.sum(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
)
|
97 |
.mutate(percent_protected=_.percent_protected.round(1))
|
98 |
)
|
99 |
|
100 |
-
|
101 |
-
|
102 |
if colors is not None and not colors.empty: #
|
103 |
df = df.inner_join(colors, column) # chart colors
|
104 |
|
105 |
-
|
106 |
df = df.cast({col: "string" for col in column})
|
107 |
df = df.to_pandas()
|
108 |
return df
|
109 |
|
110 |
|
111 |
-
def summary_table(column, colors, filter_cols, filter_vals):
|
112 |
-
|
113 |
filters = []
|
114 |
-
|
115 |
if filter_cols and filter_vals: #if a filter is selected, add to list of filters
|
116 |
for filter_col, filter_val in zip(filter_cols, filter_vals):
|
117 |
if len(filter_val) > 1:
|
118 |
filters.append(getattr(_, filter_col).isin(filter_val))
|
119 |
else:
|
120 |
filters.append(getattr(_, filter_col) == filter_val[0])
|
121 |
-
|
|
|
|
|
|
|
|
|
122 |
combined_filter = reduce(lambda x, y: x & y, filters)
|
123 |
|
124 |
df = get_summary(ca, combined_filter, [column], colors) # df used for charts
|
125 |
df_tab = get_summary(ca, combined_filter, filter_cols, colors = None) #df used for printed table
|
126 |
-
|
127 |
return df, df_tab
|
128 |
|
129 |
|
130 |
-
|
131 |
-
|
132 |
def area_plot(df, column):
|
133 |
base = alt.Chart(df).encode(
|
134 |
alt.Theta("percent_protected:Q").stack(True),
|
@@ -167,7 +172,6 @@ def get_pmtiles_style(paint, alpha, cols, values):
|
|
167 |
"id": "ca30x30",
|
168 |
"source": "ca",
|
169 |
"source-layer": "layer",
|
170 |
-
|
171 |
# "source-layer": "ca202430m",
|
172 |
# "source-layer": "ca2024",
|
173 |
"type": "fill",
|
@@ -209,6 +213,12 @@ default_gap = {
|
|
209 |
2: True,
|
210 |
}
|
211 |
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
|
213 |
manager = {
|
214 |
'property': 'manager_type',
|
@@ -274,24 +284,24 @@ gap = {
|
|
274 |
}
|
275 |
|
276 |
|
277 |
-
area_type = {
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
|
286 |
|
287 |
style_options = {
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
|
296 |
|
297 |
|
@@ -321,6 +331,29 @@ justice40_style = {
|
|
321 |
|
322 |
|
323 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
|
325 |
st.set_page_config(layout="wide", page_title="CA Protected Areas Explorer", page_icon=":globe:")
|
326 |
|
@@ -333,9 +366,11 @@ m = leafmap.Map(style="positron")
|
|
333 |
filters = {}
|
334 |
|
335 |
with st.sidebar:
|
336 |
-
color_choice = st.radio("Color by:", style_options)
|
|
|
|
|
337 |
alpha = st.slider("transparency", 0.0, 1.0, 0.5)
|
338 |
-
|
339 |
"Filters:"
|
340 |
for label in style_options:
|
341 |
with st.expander(label):
|
@@ -357,85 +392,108 @@ with st.sidebar:
|
|
357 |
style = get_pmtiles_style(style_options[color_choice], alpha, filter_cols, filter_vals)
|
358 |
m.add_pmtiles(ca_pmtiles, style=style, visible=True, name="CA", opacity=alpha, tooltip=True)
|
359 |
|
|
|
360 |
"Data Layers:"
|
361 |
|
362 |
-
with st.expander("Justice40"):
|
363 |
-
justice40_toggle = st.toggle("Justice40")
|
364 |
-
if justice40_toggle:
|
365 |
-
m.add_pmtiles(justice40, style=justice40_style, visible=True, name="Justice40", opacity=alpha, tooltip=True)
|
366 |
-
|
367 |
with st.expander("🦜 Biodiversity"):
|
|
|
|
|
368 |
show_richness = st.toggle("Species Richness", False)
|
369 |
if show_richness:
|
370 |
-
m.add_tile_layer(
|
|
|
371 |
name="MOBI Species Richness",
|
372 |
-
opacity=
|
|
|
|
|
373 |
show_rsr = st.toggle("Range-Size Rarity")
|
374 |
if show_rsr:
|
375 |
-
m.add_tile_layer(
|
|
|
376 |
name="MOBI Range-Size Rarity",
|
377 |
-
opacity=
|
378 |
-
|
379 |
-
|
380 |
with st.expander("⛅ Carbon & Climate"):
|
381 |
-
|
382 |
-
|
383 |
-
m.add_tile_layer(url="https://huggingface.co/datasets/boettiger-lab/ca-30x30/resolve/main/deforest-carbon-ca/{z}/{x}/{y}.png",
|
384 |
-
name="Carbon Lost (2002-2022)",
|
385 |
-
opacity=0.9)
|
386 |
-
|
387 |
-
|
388 |
show_irrecoverable_carbon = st.toggle("Irrecoverable Carbon")
|
389 |
if show_irrecoverable_carbon:
|
390 |
-
m.add_cog_layer("https://
|
391 |
-
palette="
|
392 |
-
|
393 |
show_manageable_carbon = st.toggle("Manageable Carbon")
|
394 |
if show_manageable_carbon:
|
395 |
-
|
396 |
-
palette="
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
397 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
398 |
with st.expander("🚜 Human Impacts"):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
399 |
show_human_impact = st.toggle("Human Impact")
|
400 |
if show_human_impact:
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
show_crop_expansion = st.toggle("Cropland Expansion")
|
406 |
-
|
407 |
-
if show_crop_expansion:
|
408 |
-
m.add_cog_layer("https://data.source.coop/vizzuality/lg-land-carbon-data/natcrop_expansion_100m_cog.tif",
|
409 |
-
name="Cropland Expansion", transparent_bg=True, opacity = 0.5, fit_bounds=False)
|
410 |
-
show_biodiversity_inactness_loss = st.toggle("Biodiversity Intactness Loss")
|
411 |
-
if show_biodiversity_inactness_loss:
|
412 |
-
m.add_cog_layer("https://data.source.coop/vizzuality/lg-land-carbon-data/natcrop_bii_100m_cog.tif",
|
413 |
-
palette="reds", name="Biodiversity Intactness Loss", transparent_bg=True, opacity = 0.5, fit_bounds=False)
|
414 |
|
415 |
-
show_forest_integrity_loss = st.toggle("Forest Integrity Loss")
|
416 |
-
if show_forest_integrity_loss:
|
417 |
-
m.add_cog_layer("https://data.source.coop/vizzuality/lg-land-carbon-data/natcrop_fii_100m_cog.tif",
|
418 |
-
palette="reds", name="Forest Integrity Loss", transparent_bg=True, opacity = 0.5, fit_bounds=False)
|
419 |
|
420 |
|
421 |
select_column = {
|
|
|
422 |
"GAP Status Code": "reGAP",
|
423 |
"Manager Type": "manager_type",
|
424 |
"Easement": "Easement",
|
425 |
-
"Year": "established",
|
426 |
"Public Access": "access_type",
|
427 |
-
"Type": "type"
|
|
|
428 |
|
429 |
|
430 |
column = select_column[color_choice]
|
431 |
|
432 |
select_colors = {
|
|
|
|
|
433 |
"Manager Type": manager["stops"],
|
434 |
"Easement": easement["stops"],
|
435 |
"Public Access": access["stops"],
|
436 |
-
"
|
437 |
-
|
438 |
-
"Type": area_type["stops"]}
|
439 |
|
440 |
colors = (ibis
|
441 |
.memtable(select_colors[color_choice], columns = [column, "color"])
|
@@ -443,28 +501,46 @@ colors = (ibis
|
|
443 |
)
|
444 |
|
445 |
main = st.container()
|
446 |
-
|
|
|
447 |
with main:
|
448 |
map_col, stats_col = st.columns([2,1])
|
449 |
with map_col:
|
450 |
to_streamlit(m, height=700)
|
451 |
-
|
|
|
|
|
|
|
|
|
|
|
452 |
|
453 |
richness_chart = bar_chart(df, column, 'mean_richness')
|
454 |
rsr_chart = bar_chart(df, column, 'mean_rsr')
|
455 |
-
|
456 |
-
|
457 |
irrecoverable_carbon = bar_chart(df, column, 'irrecoverable_carbon')
|
|
|
|
|
458 |
human_impact = bar_chart(df, column, 'human_impact')
|
459 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
460 |
total_percent = df.percent_protected.sum().round(1)
|
461 |
with stats_col:
|
462 |
with st.container():
|
463 |
f"{total_percent}% CA Covered"
|
464 |
st.altair_chart(area_plot(df, column), use_container_width=True)
|
465 |
-
|
466 |
|
467 |
with st.container():
|
|
|
468 |
if show_richness:
|
469 |
"Species Richness"
|
470 |
st.altair_chart(richness_chart, use_container_width=True)
|
@@ -473,17 +549,38 @@ with main:
|
|
473 |
"Range-Size Rarity"
|
474 |
st.altair_chart(rsr_chart, use_container_width=True)
|
475 |
|
476 |
-
if show_carbon_lost:
|
477 |
-
"Carbon Lost ('02-'22)"
|
478 |
-
st.altair_chart(carbon_lost, use_container_width=True)
|
479 |
-
|
480 |
if show_irrecoverable_carbon:
|
481 |
"Irrecoverable Carbon"
|
482 |
st.altair_chart(irrecoverable_carbon, use_container_width=True)
|
483 |
|
484 |
-
if
|
485 |
-
"
|
486 |
-
st.altair_chart(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
487 |
|
488 |
if show_human_impact:
|
489 |
"Human Impact"
|
@@ -505,6 +602,10 @@ License: BSD-2-clause
|
|
505 |
### Data sources
|
506 |
- California Protected Areas Database by CA Nature. Data: https://www.californianature.ca.gov/datasets/CAnature::30x30-conserved-areas-terrestrial-2024/about. License: Public Domain
|
507 |
|
|
|
|
|
|
|
|
|
508 |
- Imperiled Species Richness and Range-Size-Rarity from NatureServe (2022). Data: https://beta.source.coop/repositories/cboettig/mobi. License CC-BY-NC-ND
|
509 |
|
510 |
- Carbon-loss and farming impact by Vizzuality, on https://beta.source.coop/repositories/vizzuality/lg-land-carbon-data. Citation: https://doi.org/10.1101/2023.11.01.565036, License: CC-BY
|
@@ -513,7 +614,6 @@ License: BSD-2-clause
|
|
513 |
|
514 |
- Irrecoverable Carbon from Conservation International, reprocessed to COG on https://beta.source.coop/cboettig/carbon, citation: https://doi.org/10.1038/s41893-021-00803-6, License: CC-BY-NC
|
515 |
|
516 |
-
- Climate and Economic Justice Screening Tool, US Council on Environmental Quality, Justice40, data: https://beta.source.coop/repositories/cboettig/justice40/description/, License: Public Domain
|
517 |
|
518 |
|
519 |
'''
|
|
|
53 |
.cast({"crop_expansion": "int64"})
|
54 |
)
|
55 |
|
|
|
56 |
private_access_color = "#DE881E" # orange
|
57 |
public_access_color = "#3388ff" # blue
|
58 |
tribal_color = "#BF40BF" # purple
|
|
|
77 |
def get_summary(ca, combined_filter, column, colors=None):
|
78 |
df = ca.filter(combined_filter)
|
79 |
|
80 |
+
# if colors is not None and not colors.empty: # df used for chart.
|
81 |
+
# df = df.filter(_.reGAP <3) # only show gaps 1 and 2 for chart.
|
82 |
|
83 |
df = (df
|
84 |
.group_by(*column) # unpack the list for grouping
|
85 |
.aggregate(percent_protected=100 * _.Acres.sum() / ca_area_acres,
|
86 |
+
mean_richness = (_.richness * _.Acres).sum() / _.Acres.sum(),
|
87 |
mean_rsr = (_.rsr * _.Acres).sum() / _.Acres.sum(),
|
88 |
+
all_rsr = (_.all_species_rwr * _.Acres).sum() / _.Acres.sum(),
|
89 |
+
all_richness = (_.all_species_richness * _.Acres).sum() / _.Acres.sum(),
|
90 |
irrecoverable_carbon = (_.irrecoverable_carbon * _.Acres).sum() / _.Acres.sum(),
|
91 |
manageable_carbon = (_.manageable_carbon * _.Acres).sum() / _.Acres.sum(),
|
92 |
+
carbon_lost = (_.deforest_carbon * _.Acres).sum() / _.Acres.sum(),
|
|
|
|
|
93 |
human_impact = (_.human_impact * _.Acres).sum() / _.Acres.sum(),
|
94 |
+
svi = (_.svi * _.Acres).sum() / _.Acres.sum(),
|
95 |
+
svi_socioeconomic_status = (_.svi_socioeconomic_status * _.Acres).sum() / _.Acres.sum(),
|
96 |
+
svi_household_char = (_.svi_household_char * _.Acres).sum() / _.Acres.sum(),
|
97 |
+
svi_racial_ethnic_minority = (_.svi_racial_ethnic_minority * _.Acres).sum() / _.Acres.sum(),
|
98 |
+
svi_housing_transit = (_.svi_housing_transit * _.Acres).sum() / _.Acres.sum(),
|
99 |
+
|
100 |
+
# biodiversity_intactness_loss = (_.biodiversity_intactness_loss * _.Acres).sum() / _.Acres.sum(),
|
101 |
+
# crop_reduction = (_.crop_reduction * _.Acres).sum() / _.Acres.sum(),
|
102 |
+
# crop_expansion = (_.crop_expansion * _.Acres).sum() / _.Acres.sum(),
|
103 |
+
# forest_loss = (_.forest_integrity_loss * _.Acres).sum() / _.Acres.sum(),
|
104 |
)
|
105 |
.mutate(percent_protected=_.percent_protected.round(1))
|
106 |
)
|
107 |
|
|
|
|
|
108 |
if colors is not None and not colors.empty: #
|
109 |
df = df.inner_join(colors, column) # chart colors
|
110 |
|
|
|
111 |
df = df.cast({col: "string" for col in column})
|
112 |
df = df.to_pandas()
|
113 |
return df
|
114 |
|
115 |
|
116 |
+
def summary_table(column, colors, filter_cols, filter_vals,colorby_vals):
|
|
|
117 |
filters = []
|
118 |
+
|
119 |
if filter_cols and filter_vals: #if a filter is selected, add to list of filters
|
120 |
for filter_col, filter_val in zip(filter_cols, filter_vals):
|
121 |
if len(filter_val) > 1:
|
122 |
filters.append(getattr(_, filter_col).isin(filter_val))
|
123 |
else:
|
124 |
filters.append(getattr(_, filter_col) == filter_val[0])
|
125 |
+
|
126 |
+
if column not in filter_cols: #show color_by variable in table
|
127 |
+
filter_cols.append(column)
|
128 |
+
filters.append(getattr(_, column).isin(colorby_vals[column]))
|
129 |
+
|
130 |
combined_filter = reduce(lambda x, y: x & y, filters)
|
131 |
|
132 |
df = get_summary(ca, combined_filter, [column], colors) # df used for charts
|
133 |
df_tab = get_summary(ca, combined_filter, filter_cols, colors = None) #df used for printed table
|
|
|
134 |
return df, df_tab
|
135 |
|
136 |
|
|
|
|
|
137 |
def area_plot(df, column):
|
138 |
base = alt.Chart(df).encode(
|
139 |
alt.Theta("percent_protected:Q").stack(True),
|
|
|
172 |
"id": "ca30x30",
|
173 |
"source": "ca",
|
174 |
"source-layer": "layer",
|
|
|
175 |
# "source-layer": "ca202430m",
|
176 |
# "source-layer": "ca2024",
|
177 |
"type": "fill",
|
|
|
213 |
2: True,
|
214 |
}
|
215 |
|
216 |
+
def getColorVals(style_options, style_choice): #adding "color by" values to table
|
217 |
+
column = style_options[style_choice]['property']
|
218 |
+
opts = [style[0] for style in style_options[style_choice]['stops']]
|
219 |
+
d = {}
|
220 |
+
d[column] = opts
|
221 |
+
return d
|
222 |
|
223 |
manager = {
|
224 |
'property': 'manager_type',
|
|
|
284 |
}
|
285 |
|
286 |
|
287 |
+
# area_type = {
|
288 |
+
# 'property': 'type',
|
289 |
+
# 'type': 'categorical',
|
290 |
+
# 'stops': [
|
291 |
+
# ["Land", "green"],
|
292 |
+
# ["Water", "blue"]
|
293 |
+
# ]
|
294 |
+
# }
|
295 |
|
296 |
|
297 |
style_options = {
|
298 |
+
"Year": year,
|
299 |
+
"GAP Status Code": gap,
|
300 |
+
"Manager Type": manager,
|
301 |
+
"Easement": easement,
|
302 |
+
"Public Access": access,
|
303 |
+
# "Type": area_type
|
304 |
+
}
|
305 |
|
306 |
|
307 |
|
|
|
331 |
|
332 |
|
333 |
|
334 |
+
|
335 |
+
sv_pmtiles = "https://data.source.coop/cboettig/social-vulnerability/svi2020_us_county.pmtiles"
|
336 |
+
def get_sv_style(column):
|
337 |
+
return {
|
338 |
+
"layers": [
|
339 |
+
{
|
340 |
+
"id": "SVI",
|
341 |
+
"source": "Social Vulnerability Index",
|
342 |
+
"source-layer": "SVI2020_US_county",
|
343 |
+
"filter": ["match", ["get", "STATE"], "California", True, False],
|
344 |
+
"type": "fill",
|
345 |
+
"paint": {
|
346 |
+
"fill-color":
|
347 |
+
["interpolate", ["linear"], ["get", column],
|
348 |
+
0, "#FFE6EE",
|
349 |
+
1, "#850101"]
|
350 |
+
|
351 |
+
}
|
352 |
+
}
|
353 |
+
]
|
354 |
+
}
|
355 |
+
|
356 |
+
|
357 |
|
358 |
st.set_page_config(layout="wide", page_title="CA Protected Areas Explorer", page_icon=":globe:")
|
359 |
|
|
|
366 |
filters = {}
|
367 |
|
368 |
with st.sidebar:
|
369 |
+
color_choice = st.radio("Color by:", style_options)
|
370 |
+
colorby_vals = getColorVals(style_options, color_choice)
|
371 |
+
|
372 |
alpha = st.slider("transparency", 0.0, 1.0, 0.5)
|
373 |
+
st.divider()
|
374 |
"Filters:"
|
375 |
for label in style_options:
|
376 |
with st.expander(label):
|
|
|
392 |
style = get_pmtiles_style(style_options[color_choice], alpha, filter_cols, filter_vals)
|
393 |
m.add_pmtiles(ca_pmtiles, style=style, visible=True, name="CA", opacity=alpha, tooltip=True)
|
394 |
|
395 |
+
st.divider()
|
396 |
"Data Layers:"
|
397 |
|
|
|
|
|
|
|
|
|
|
|
398 |
with st.expander("🦜 Biodiversity"):
|
399 |
+
alpha_bio = st.slider("transparency", 0.0, 1.0, 0.4, key = "biodiversity")
|
400 |
+
|
401 |
show_richness = st.toggle("Species Richness", False)
|
402 |
if show_richness:
|
403 |
+
m.add_tile_layer(
|
404 |
+
url = "https://huggingface.co/datasets/boettiger-lab/ca-30x30/resolve/main/species-richness-ca/{z}/{x}/{y}.png",
|
405 |
name="MOBI Species Richness",
|
406 |
+
opacity=alpha_bio
|
407 |
+
)
|
408 |
+
|
409 |
show_rsr = st.toggle("Range-Size Rarity")
|
410 |
if show_rsr:
|
411 |
+
m.add_tile_layer(
|
412 |
+
url="https://huggingface.co/datasets/boettiger-lab/ca-30x30/resolve/main/range-size-rarity/{z}/{x}/{y}.png",
|
413 |
name="MOBI Range-Size Rarity",
|
414 |
+
opacity=alpha_bio)
|
415 |
+
|
|
|
416 |
with st.expander("⛅ Carbon & Climate"):
|
417 |
+
alpha_climate = st.slider("transparency", 0.0, 1.0, 0.3, key = "climate")
|
418 |
+
|
|
|
|
|
|
|
|
|
|
|
419 |
show_irrecoverable_carbon = st.toggle("Irrecoverable Carbon")
|
420 |
if show_irrecoverable_carbon:
|
421 |
+
m.add_cog_layer("https://huggingface.co/datasets/boettiger-lab/ca-30x30/resolve/main/ca_irrecoverable_c_2018_cog.tif",
|
422 |
+
palette="reds", name="Irrecoverable Carbon", transparent_bg=True, opacity = alpha_climate, fit_bounds=False, bidx=[1])
|
423 |
+
|
424 |
show_manageable_carbon = st.toggle("Manageable Carbon")
|
425 |
if show_manageable_carbon:
|
426 |
+
m.add_cog_layer("https://huggingface.co/datasets/boettiger-lab/ca-30x30/resolve/main/ca_manageable_c_2018_cog.tif",
|
427 |
+
palette="purples", name="Manageable Carbon", transparent_bg=True, opacity = alpha_climate, fit_bounds=False)
|
428 |
+
|
429 |
+
with st.expander("Climate and Economic Justice"):
|
430 |
+
alpha_justice40 = st.slider("transparency", 0.0, 1.0, 0.3, key = "social justice")
|
431 |
+
|
432 |
+
show_justice40 = st.toggle("Justice40")
|
433 |
+
if show_justice40:
|
434 |
+
m.add_pmtiles(justice40, style=justice40_style, visible=True, name="Justice40", opacity=alpha_justice40, tooltip=False, fit_bounds = False)
|
435 |
+
|
436 |
+
with st.expander("Social Vulnerability"):
|
437 |
+
alpha_justice = st.slider("transparency", 0.0, 1.0, 0.3, key = "SVI")
|
438 |
+
|
439 |
+
show_sv = st.toggle("Social Vulnerability Index (SVI)")
|
440 |
+
if show_sv:
|
441 |
+
m.add_pmtiles(sv_pmtiles, style = get_sv_style("RPL_THEMES") ,visible=True, opacity=alpha_justice, tooltip=False, fit_bounds = False)
|
442 |
+
|
443 |
+
show_sv_socio = st.toggle("Socioeconomic Status")
|
444 |
+
if show_sv_socio:
|
445 |
+
m.add_pmtiles(sv_pmtiles, style = get_sv_style("RPL_THEME1") ,visible=True, opacity=alpha_justice, tooltip=False, fit_bounds = False)
|
446 |
+
|
447 |
+
show_sv_household = st.toggle("Household Characteristics")
|
448 |
+
if show_sv_household:
|
449 |
+
m.add_pmtiles(sv_pmtiles, style = get_sv_style("RPL_THEME2") ,visible=True, opacity=alpha_justice, tooltip=False, fit_bounds = False)
|
450 |
|
451 |
+
show_sv_minority = st.toggle("Racial & Ethnic Minority Status")
|
452 |
+
if show_sv_minority:
|
453 |
+
m.add_pmtiles(sv_pmtiles, style = get_sv_style("RPL_THEME3") ,visible=True, opacity=alpha_justice, tooltip=False, fit_bounds = False)
|
454 |
+
|
455 |
+
show_sv_housing = st.toggle("Housing Type & Transportation")
|
456 |
+
if show_sv_housing:
|
457 |
+
m.add_pmtiles(sv_pmtiles, style = get_sv_style("RPL_THEME4") ,visible=True, opacity=alpha_justice, tooltip=False, fit_bounds = False)
|
458 |
+
|
459 |
+
|
460 |
with st.expander("🚜 Human Impacts"):
|
461 |
+
alpha_hi = st.slider("transparency", 0.0, 1.0, 0.5, key = "hi")
|
462 |
+
|
463 |
+
show_carbon_lost = st.toggle("Carbon Lost (2002-2022)")
|
464 |
+
if show_carbon_lost:
|
465 |
+
m.add_tile_layer(
|
466 |
+
url="https://huggingface.co/datasets/boettiger-lab/ca-30x30/resolve/main/deforest-carbon-ca/{z}/{x}/{y}.png",
|
467 |
+
name="Carbon Lost (2002-2022)",
|
468 |
+
opacity = alpha_hi)
|
469 |
+
|
470 |
show_human_impact = st.toggle("Human Impact")
|
471 |
if show_human_impact:
|
472 |
+
m.add_cog_layer(
|
473 |
+
url = "https://huggingface.co/datasets/boettiger-lab/ca-30x30/resolve/main/ca_human_impact_cog.tif", name="Human Impact", transparent_bg=True, opacity = alpha_hi, fit_bounds=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
474 |
|
|
|
|
|
|
|
|
|
475 |
|
476 |
|
477 |
select_column = {
|
478 |
+
"Year": "established",
|
479 |
"GAP Status Code": "reGAP",
|
480 |
"Manager Type": "manager_type",
|
481 |
"Easement": "Easement",
|
|
|
482 |
"Public Access": "access_type",
|
483 |
+
# "Type": "type",
|
484 |
+
}
|
485 |
|
486 |
|
487 |
column = select_column[color_choice]
|
488 |
|
489 |
select_colors = {
|
490 |
+
"Year": year["stops"],
|
491 |
+
"GAP Status Code": gap["stops"],
|
492 |
"Manager Type": manager["stops"],
|
493 |
"Easement": easement["stops"],
|
494 |
"Public Access": access["stops"],
|
495 |
+
# "Type": area_type["stops"]
|
496 |
+
}
|
|
|
497 |
|
498 |
colors = (ibis
|
499 |
.memtable(select_colors[color_choice], columns = [column, "color"])
|
|
|
501 |
)
|
502 |
|
503 |
main = st.container()
|
504 |
+
df,df_tab = summary_table(column, colors, filter_cols, filter_vals, colorby_vals)
|
505 |
+
|
506 |
with main:
|
507 |
map_col, stats_col = st.columns([2,1])
|
508 |
with map_col:
|
509 |
to_streamlit(m, height=700)
|
510 |
+
st.dataframe(df_tab, use_container_width = True)
|
511 |
+
svi = bar_chart(df, column, 'svi')
|
512 |
+
svi_socioeconomic_status = bar_chart(df, column, 'svi_socioeconomic_status')
|
513 |
+
svi_household_char = bar_chart(df, column, 'svi_household_char')
|
514 |
+
svi_racial_ethnic_minority = bar_chart(df, column, 'svi_racial_ethnic_minority')
|
515 |
+
svi_housing_transit = bar_chart(df, column, 'svi_housing_transit')
|
516 |
|
517 |
richness_chart = bar_chart(df, column, 'mean_richness')
|
518 |
rsr_chart = bar_chart(df, column, 'mean_rsr')
|
519 |
+
# all_rsr = bar_chart(df, column, 'all_rsr')
|
520 |
+
# all_richness = bar_chart(df, column, 'all_richness')
|
521 |
irrecoverable_carbon = bar_chart(df, column, 'irrecoverable_carbon')
|
522 |
+
manageable_carbon = bar_chart(df, column, 'manageable_carbon')
|
523 |
+
carbon_lost = bar_chart(df, column, 'carbon_lost')
|
524 |
human_impact = bar_chart(df, column, 'human_impact')
|
525 |
|
526 |
+
# crop_expansion = bar_chart(df, column, 'crop_expansion')
|
527 |
+
# biodiversity_intactness_loss = bar_chart(df, column, biodiversity_intactness_loss')
|
528 |
+
# crop_reduction = bar_chart(df, column, 'crop_reduction')
|
529 |
+
# forest_loss = bar_chart(df, column, 'forest_loss')
|
530 |
+
|
531 |
+
|
532 |
+
|
533 |
+
|
534 |
+
|
535 |
total_percent = df.percent_protected.sum().round(1)
|
536 |
with stats_col:
|
537 |
with st.container():
|
538 |
f"{total_percent}% CA Covered"
|
539 |
st.altair_chart(area_plot(df, column), use_container_width=True)
|
540 |
+
|
541 |
|
542 |
with st.container():
|
543 |
+
|
544 |
if show_richness:
|
545 |
"Species Richness"
|
546 |
st.altair_chart(richness_chart, use_container_width=True)
|
|
|
549 |
"Range-Size Rarity"
|
550 |
st.altair_chart(rsr_chart, use_container_width=True)
|
551 |
|
|
|
|
|
|
|
|
|
552 |
if show_irrecoverable_carbon:
|
553 |
"Irrecoverable Carbon"
|
554 |
st.altair_chart(irrecoverable_carbon, use_container_width=True)
|
555 |
|
556 |
+
if show_manageable_carbon:
|
557 |
+
"Manageable Carbon"
|
558 |
+
st.altair_chart(manageable_carbon, use_container_width=True)
|
559 |
+
|
560 |
+
if show_sv:
|
561 |
+
"Social Vulnerability Index"
|
562 |
+
st.altair_chart(svi, use_container_width=True)
|
563 |
+
|
564 |
+
if show_sv_socio:
|
565 |
+
"SVI - Socioeconomic Status"
|
566 |
+
st.altair_chart(svi_socioeconomic_status, use_container_width=True)
|
567 |
+
|
568 |
+
if show_sv_household:
|
569 |
+
"SVI - Household Characteristics"
|
570 |
+
st.altair_chart(svi_household_char, use_container_width=True)
|
571 |
+
|
572 |
+
if show_sv_minority:
|
573 |
+
"SVI - Racial and Ethnic Minority"
|
574 |
+
st.altair_chart(svi_racial_ethnic_minority, use_container_width=True)
|
575 |
+
|
576 |
+
if show_sv_housing:
|
577 |
+
"SVI - Housing Type and Transit"
|
578 |
+
st.altair_chart(svi_housing_transit, use_container_width=True)
|
579 |
+
|
580 |
+
|
581 |
+
if show_carbon_lost:
|
582 |
+
"Carbon Lost ('02-'22)"
|
583 |
+
st.altair_chart(carbon_lost, use_container_width=True)
|
584 |
|
585 |
if show_human_impact:
|
586 |
"Human Impact"
|
|
|
602 |
### Data sources
|
603 |
- California Protected Areas Database by CA Nature. Data: https://www.californianature.ca.gov/datasets/CAnature::30x30-conserved-areas-terrestrial-2024/about. License: Public Domain
|
604 |
|
605 |
+
- Climate and Economic Justice Screening Tool, US Council on Environmental Quality, Justice40, data: https://beta.source.coop/repositories/cboettig/justice40/description/, License: Public Domain
|
606 |
+
|
607 |
+
- CDC 2020 Social Vulnerability Index by US Census Track. Data: https://source.coop/repositories/cboettig/social-vulnerability/description. License: Public Domain
|
608 |
+
|
609 |
- Imperiled Species Richness and Range-Size-Rarity from NatureServe (2022). Data: https://beta.source.coop/repositories/cboettig/mobi. License CC-BY-NC-ND
|
610 |
|
611 |
- Carbon-loss and farming impact by Vizzuality, on https://beta.source.coop/repositories/vizzuality/lg-land-carbon-data. Citation: https://doi.org/10.1101/2023.11.01.565036, License: CC-BY
|
|
|
614 |
|
615 |
- Irrecoverable Carbon from Conservation International, reprocessed to COG on https://beta.source.coop/cboettig/carbon, citation: https://doi.org/10.1038/s41893-021-00803-6, License: CC-BY-NC
|
616 |
|
|
|
617 |
|
618 |
|
619 |
'''
|
requirements.txt
CHANGED
@@ -9,4 +9,5 @@ rasterio==1.3.10
|
|
9 |
shapely==2.0.4
|
10 |
shiny==0.10.2
|
11 |
geoarrow-types
|
12 |
-
geoarrow-pandas
|
|
|
|
9 |
shapely==2.0.4
|
10 |
shiny==0.10.2
|
11 |
geoarrow-types
|
12 |
+
geoarrow-pandas
|
13 |
+
leafmap==0.38.12
|