landvote / app.py
cassiebuhler's picture
adding layers to pmtiles
7d06004
raw
history blame
7.51 kB
import ibis
from ibis import _
import streamlit as st
st.set_page_config(layout="wide",
page_title="TPL LandVote",
page_icon=":globe:")
'''
# LandVote Prototype
An experimental platform for visualizing data on ballot measures for conservation, based on data from <https://landvote.org/> curated by the Trust for Public Land.
'''
## Chatbot
import os
import pandas as pd
import matplotlib.pyplot as plt
from pandasai.llm.openai import OpenAI
from pandasai import Agent
from pandasai.responses.streamlit_response import StreamlitResponse
llm = OpenAI(api_token=st.secrets["OPENAI_API_KEY"])
df1 = pd.read_csv("data.csv")
agent = Agent(
[df1],
config={"verbose": True, "response_parser": StreamlitResponse, "llm": llm},
)
with st.sidebar:
'''
## Data Assistant (experimental)
Ask questions about the landvote data, like:
- What are the top states for approved conservation funds?
- Plot the total funds spent in conservation each year.
- What city has approved the most funds in a single measure? What was the description of that vote?
- Which state has had largest number measures fail? What is that as a fraction of it's total measures?
'''
prompt = st.chat_input("Ask about the data")
if prompt:
with st.spinner():
resp = agent.chat(prompt)
if os.path.isfile('exports/charts/temp_chart.png'):
im = plt.imread('exports/charts/temp_chart.png')
st.image(im)
os.remove('exports/charts/temp_chart.png')
st.write(resp)
# year = st.slider("Select a year", min_value=1988, max_value=2024, value=2022, step=2)
year = st.slider("Select a year", min_value=1988, max_value=2024, value=2022, step=1)
import leafmap.maplibregl as leafmap
m = leafmap.Map(style="positron", center=(-100, 40), zoom=3)
url = "https://huggingface.co/datasets/boettiger-lab/landvote/resolve/main/landvote.pmtiles"
dark_orange = 'rgba(171, 86, 1, 1)' # dark orange - min value
light_orange = 'rgba(243, 211, 177, 1)' # light orange
grey = 'rgba(211, 211, 211, 1)' # grey
light_green = 'rgba(195, 219, 195, 1)' # light green
dark_green = 'rgba(65, 125, 65, 1)' # dark green - max value
style_municipals = {
"layers": [
{
"id": "municipals",
"source": "municipal",
"source-layer": "municipal",
"type": "fill-extrusion",
"filter": [
"==",
["get", "year"],
year,
],
"paint": {
"fill-extrusion-color": [
"case",
# if passed, color green
["==", ["get", "Status"], "Pass"],
[
"interpolate", ["linear"], [
"to-number", ["slice", ["get", "yes"], 0, -1] # convert 'yes' string to number
],
50, grey,
55, light_green, # higher yes % -> darker green
100, dark_green # 100 is the max of data
],
# if failed, color orange
["==", ["get", "Status"], "Fail"],
[
"interpolate", ["linear"], [
"to-number", ["slice", ["get", "yes"], 0, -1] # convert 'yes' string to number
],
0, dark_orange, # higher yes % -> lighter orange
50, light_orange,
67, grey # 67 is the max of data.
],
grey # if no match
],
"fill-extrusion-height": ["*", ["get", "log_amount"], 5000],
}
},
],
}
style_counties = {
"layers": [
{
"id": "counties",
"source": "county",
"source-layer": "county",
"type": "fill-extrusion",
"filter": [
"==",
["get", "year"],
year,
],
"paint": {
"fill-extrusion-color": [
"case",
# if passed, color green
["==", ["get", "Status"], "Pass"],
[
"interpolate", ["linear"], [
"to-number", ["slice", ["get", "yes"], 0, -1] # convert 'yes' string to number
],
50, grey,
55, light_green, # higher yes % -> darker green
100, dark_green # 100 is the max of data
],
# if failed, color orange
["==", ["get", "Status"], "Fail"],
[
"interpolate", ["linear"], [
"to-number", ["slice", ["get", "yes"], 0, -1] # convert 'yes' string to number
],
0, dark_orange, # higher yes % -> lighter orange
50, light_orange,
67, grey # 67 is the max of data.
],
grey # if no match
],
"fill-extrusion-height": ["*", ["get", "log_amount"], 5000],
}
},
],
}
style_states = {
"layers": [
{
"id": "states",
"source": "state",
"source-layer": "state",
"type": "fill",
"filter": [
"==",
["get", "year"],
year,
],
"paint": {
"fill-color": [
"case",
# if passed, color green
["==", ["get", "Status"], "Pass"],
[
"interpolate", ["linear"], [
"to-number", ["slice", ["get", "yes"], 0, -1] # convert 'yes' string to number
],
50, grey,
55, light_green, # higher yes % -> darker green
100, dark_green # 100 is the max of data
],
# if failed, color orange
["==", ["get", "Status"], "Fail"],
[
"interpolate", ["linear"], [
"to-number", ["slice", ["get", "yes"], 0, -1] # convert 'yes' string to number
],
0, dark_orange, # higher yes % -> lighter orange
50, light_orange,
67, grey # 67 is the max of data.
],
grey # if no match
]
}
},
],
}
#states are 2D and transparent, thus added separately.
m.add_pmtiles(
url,
style=style_states,
visible=True,
opacity=0.6,
tooltip=True,
fit_bounds=False
)
#states are 2D and transparent, thus added separately.
m.add_pmtiles(
url,
style=style_counties,
visible=True,
opacity=0.6,
tooltip=True,
fit_bounds=False
)
m.add_pmtiles(
url,
style=style_municipals,
visible=True,
opacity=1.0,
tooltip=True,
fit_bounds=False
)
m.add_layer_control()
m.to_streamlit()