# -*- 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 os # + import altair as alt import numpy as np import pandas as pd 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=":butterfly:") # + @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() ) @st.cache_data def load_class(df, taxa="Amphibia", 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() ) # - 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="h3z6", # set by zoom get_fill_color="[color, 30, color]", get_line_color=[255, 255, 255], line_width_min_pixels=2, ), ], ) ) # CALCULATE MIDPOINT FOR GIVEN SET OF DATA @st.cache_data def mpoint(lat, lon): return (np.average(lat), np.average(lon)) # LAYING OUT THE TOP SECTION OF THE APP row1_1, row1_2 = st.columns((2, 3)) # SEE IF THERE'S A QUERY PARAM IN THE URL (e.g. ?pickup_hour=2) # THIS ALLOWS YOU TO PASS A STATEFUL URL TO SOMEONE WITH A SPECIFIC HOUR SELECTED, # E.G. https://share.streamlit.io/streamlit/demo-uber-nyc-pickups/main?pickup_hour=2 if not st.session_state.get("url_synced", False): try: year = int(st.query_params["year"][0]) st.session_state["year"] = year st.session_state["url_synced"] = True except KeyError: pass # IF THE SLIDER CHANGES, UPDATE THE QUERY PARAM def update_query_params(): year_selected = st.session_state["year"] st.query_params["year"]=year_selected with row1_1: st.title("GBIF Species Richness") taxa = st.text_input('taxonomic class (Chordates only)') zoom = st.slider( "Select hex resolution", 4, 7, key="zoom" ) with row1_2: st.write( """ ## Testing """ ) # + # 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 data = load_data() # + row2_1, row2_2, row2_3, row2_4 = st.columns((2, 1, 1, 1)) with row2_1: st.write( f"""**All**""" ) map(filterdata(data, taxa), midpoint[0], midpoint[1], 10) with row2_2: st.write("**Amphibians**") map(load_class(df, taxa="Amphibia", zoom=7), midpoint[0], midpoint[1], 11) with row2_3: st.write("**Mammals**") map(filterdata(data, "Mammalia"), midpoint[0], midpoint[1], 9) with row2_4: st.write("**Birds**") map(filterdata(data, "Aves"), midpoint[0], midpoint[1], 11)