cboettig's picture
tickle
6c6695e
# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""An example of showing species richness from GBIF data."""
import pydeck as pdk
import streamlit as st
import ibis
from ibis import _
# SETTING PAGE CONFIG TO WIDE MODE AND ADDING A TITLE AND FAVICON
st.set_page_config(layout="wide", page_title="GBIF Biodiversity Demo", page_icon=":globe:")
# +
@st.cache_data
def load_data(zoom=7):
con = ibis.duckdb.connect()
path = "gbif-vert-gb-h3z" + str(zoom) + ".csv"
df_all = (
con.
read_csv(path).
group_by(_.h3).
aggregate(n = _.n.sum()).
mutate(color = 255 * _.n / _.n.max()).
to_pandas()
)
return df_all
@st.cache_data
def load_class(taxa, zoom=7):
con = ibis.duckdb.connect()
path = "gbif-vert-gb-h3z" + str(zoom) + ".csv"
df = (con.
read_csv(path).
filter(_['class']==taxa).
mutate(color = 255 * _.n / _.n.max()).
to_pandas()
)
return df
# -
def map(data, lat, lon, zoom):
st.write(
pdk.Deck(
map_style="mapbox://styles/mapbox/light-v9",
initial_view_state={
"latitude": lat,
"longitude": lon,
"zoom": zoom,
"pitch": 50,
},
layers=[
pdk.Layer(
"H3HexagonLayer",
data,
pickable=True,
stroked=True,
filled=True,
extruded=True,
elevation_scale=200,
get_elevation='color',
get_hexagon="h3", # set by zoom
get_fill_color="[color, 30, 255 - color, 160]",
get_line_color=[255, 255, 255],
line_width_min_pixels=2,
),
],
)
)
# LAYING OUT THE TOP SECTION OF THE APP
row1_1, row1_2 = st.columns((2, 3))
## Interactive elements, see https://docs.streamlit.io/library/api-reference/widgets
with row1_1:
st.title("GBIF Species Richness")
taxa = st.text_input('taxonomic class (Chordates only)', value = "Amphibia")
zoom = st.slider("Select hex resolution", 4, 7, key="zoom", value = 5)
with row1_2:
st.write(
"""
## GBIF Streamlit demo
This shows a simple interactive demonstration using a series of [pydeck maps](https://deckgl.readthedocs.io/) overlaid with
[h3 hexagons](https://h3geo.org/) whose height and color indicate species richness of the group.
Adjust the [h3 hexagon size](https://h3geo.org/docs/core-library/restable/) to increase the geographic area over which richness coordinates are aggregated. Select a focal taxonomic group to compare, zoom in and out of maps.
Data derived from GBIF 2024-02-01 and h3 aggregations are pre-computed for cell sizes 1-7 across the UK using [duckdb-hs](https://github.com/isaacbrodsky/h3-duckdb)
"""
)
# +
# LAYING OUT THE MIDDLE SECTION OF THE APP WITH THE MAPS
# -
# SETTING THE ZOOM LOCATIONS
midpoint = (52.0, -1.0) #mpoint(data["lat"], data["lon"])
# STREAMLIT APP LAYOUT
# +
row2_1, row2_2, row2_3, row2_4 = st.columns((2, 1, 1, 1))
with row2_1:
st.write(
f"""**All**"""
)
map(load_data(zoom=zoom), midpoint[0], midpoint[1], 3)
with row2_2:
st.write(f"Selected class is {taxa}")
map(load_class(taxa=taxa, zoom=zoom), midpoint[0], midpoint[1], 3)
with row2_3:
st.write("**Mammals**")
map(load_class("Mammalia", zoom=zoom), midpoint[0], midpoint[1], 4)
with row2_4:
st.write("**Birds**")
map(load_class("Aves", zoom=zoom), midpoint[0], midpoint[1], 4)