Spaces:
Sleeping
Sleeping
cassiebuhler
commited on
Commit
•
b18f1b3
1
Parent(s):
d9b3bb0
description and sources
Browse files
app.py
CHANGED
@@ -19,9 +19,18 @@ st.set_page_config(layout="wide",
|
|
19 |
# LandVote Prototype
|
20 |
|
21 |
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.
|
22 |
-
|
23 |
'''
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
COLORS = {
|
26 |
"dark_orange": "#ab5601",
|
27 |
"light_orange": "#f3d3b1",
|
@@ -52,16 +61,17 @@ votes = (con
|
|
52 |
.cast({"geometry": "geometry"})
|
53 |
)
|
54 |
|
55 |
-
|
56 |
-
# generate altair chart with df
|
57 |
-
def create_chart(df, y_column, ylab, title, color):
|
58 |
# color encoding - color is a list or single value
|
59 |
color_encoding = (
|
60 |
alt.Color('party:N', scale=alt.Scale(domain=["DEMOCRAT", "REPUBLICAN"], range=color))
|
61 |
if isinstance(color, list) else alt.value(color)
|
62 |
)
|
|
|
|
|
|
|
63 |
|
64 |
-
return
|
65 |
x=alt.X('year:N', title='Year'),
|
66 |
y=alt.Y(f'{y_column}:Q', title=ylab),
|
67 |
color=color_encoding
|
@@ -200,6 +210,34 @@ def get_style_party(jurisdiction):
|
|
200 |
}
|
201 |
|
202 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
203 |
sv_pmtiles = "https://data.source.coop/cboettig/social-vulnerability/svi2020_us_county.pmtiles"
|
204 |
sv_style = {
|
205 |
"layers": [
|
@@ -250,15 +288,19 @@ party_style = {
|
|
250 |
with st.sidebar:
|
251 |
color_choice = st.radio("Color by:", ["Measure Status", "Political Party"])
|
252 |
st.divider()
|
|
|
253 |
|
254 |
-
|
|
|
|
|
255 |
party_toggle = st.toggle("Political Parties")
|
|
|
256 |
st.divider()
|
257 |
|
258 |
'''
|
259 |
## Data Assistant (experimental)
|
260 |
|
261 |
-
Ask questions about the
|
262 |
|
263 |
- What are the top states for approved conservation funds?
|
264 |
- Plot the total funds spent in conservation each year.
|
@@ -286,10 +328,24 @@ if social_toggle:
|
|
286 |
if party_toggle:
|
287 |
m.add_pmtiles(party_pmtiles, style = party_style ,visible=True, opacity=0.3, tooltip=True)
|
288 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
289 |
passed = votes.filter(_.Status.isin(["Pass","Pass*"])).count().execute()
|
290 |
total = votes.count().execute()
|
291 |
overall_passed = (passed/total*100).round(2)
|
292 |
-
f"{overall_passed}% Measures Passed"
|
|
|
|
|
293 |
|
294 |
if color_choice == "Measure Status":
|
295 |
m.add_pmtiles(votes_pmtiles, style=get_style_status("State"), visible=True, opacity=0.8, tooltip=True)
|
@@ -309,8 +365,32 @@ m.to_streamlit()
|
|
309 |
|
310 |
# display charts
|
311 |
df_passes = get_passes(votes)
|
312 |
-
st.altair_chart(create_chart(df_passes, "percent_passed", "Percent Passed","% of Measures Passed", [COLORS["dem_blue"], COLORS["rep_red"]]), use_container_width=True)
|
313 |
|
314 |
df_funding = funding_chart(votes)
|
315 |
-
st.altair_chart(create_chart(df_funding, "cumulative_funding", "Billions of Dollars", "Cumulative Funding", COLORS["dark_green"]), use_container_width=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
316 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
# LandVote Prototype
|
20 |
|
21 |
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.
|
|
|
22 |
'''
|
23 |
|
24 |
+
st.caption("We visualize each voting jurisdiction with green if a conservation measure passed and orange if it failed. The intensity of green or orange reflects the level of support or opposition, with darker green representing stronger support for passed measures and darker orange representing lower support for failed measures. Areas with more balanced outcomes appear in shades of grey. Additionally, the height of county and city jurisdictions represents the amount of funding proposed by the measure.")
|
25 |
+
|
26 |
+
st.caption("Political affiliation is determined by the party that received the majority vote in the most recent presidential election for each jurisdiction. For counties and states, this reflects the majority vote in that area. For cities, affiliation is based on the party of the county in which the city is located.")
|
27 |
+
|
28 |
+
|
29 |
+
|
30 |
+
|
31 |
+
|
32 |
+
|
33 |
+
|
34 |
COLORS = {
|
35 |
"dark_orange": "#ab5601",
|
36 |
"light_orange": "#f3d3b1",
|
|
|
61 |
.cast({"geometry": "geometry"})
|
62 |
)
|
63 |
|
64 |
+
def create_chart(df, y_column, ylab, title, color, chart_type="line"):
|
|
|
|
|
65 |
# color encoding - color is a list or single value
|
66 |
color_encoding = (
|
67 |
alt.Color('party:N', scale=alt.Scale(domain=["DEMOCRAT", "REPUBLICAN"], range=color))
|
68 |
if isinstance(color, list) else alt.value(color)
|
69 |
)
|
70 |
+
|
71 |
+
# Set the mark type based on chart_type
|
72 |
+
mark = alt.Chart(df).mark_line(strokeWidth=3) if chart_type == "line" else alt.Chart(df).mark_bar()
|
73 |
|
74 |
+
return mark.encode(
|
75 |
x=alt.X('year:N', title='Year'),
|
76 |
y=alt.Y(f'{y_column}:Q', title=ylab),
|
77 |
color=color_encoding
|
|
|
210 |
}
|
211 |
|
212 |
|
213 |
+
|
214 |
+
justice40 = "https://data.source.coop/cboettig/justice40/disadvantaged-communities.pmtiles"
|
215 |
+
justice40_fill = {
|
216 |
+
'property': 'Disadvan',
|
217 |
+
'type': 'categorical',
|
218 |
+
'stops': [
|
219 |
+
[0, "rgba(255, 255, 255, 0)"],
|
220 |
+
[1, "rgba(0, 0, 139, 1)"]]}
|
221 |
+
justice40_style = {
|
222 |
+
"version": 8,
|
223 |
+
"sources": {
|
224 |
+
"source1": {
|
225 |
+
"type": "vector",
|
226 |
+
"url": "pmtiles://" + justice40,
|
227 |
+
"attribution": "Justice40"}
|
228 |
+
},
|
229 |
+
"layers": [{
|
230 |
+
"id": "Justice40",
|
231 |
+
"source": "source1",
|
232 |
+
"source-layer": "DisadvantagedCommunitiesCEJST",
|
233 |
+
"type": "fill",
|
234 |
+
"paint": {"fill-color": justice40_fill, "fill-opacity": 0.6}}]
|
235 |
+
}
|
236 |
+
|
237 |
+
|
238 |
+
|
239 |
+
|
240 |
+
|
241 |
sv_pmtiles = "https://data.source.coop/cboettig/social-vulnerability/svi2020_us_county.pmtiles"
|
242 |
sv_style = {
|
243 |
"layers": [
|
|
|
288 |
with st.sidebar:
|
289 |
color_choice = st.radio("Color by:", ["Measure Status", "Political Party"])
|
290 |
st.divider()
|
291 |
+
with st.expander("Social Justice"):
|
292 |
|
293 |
+
social_toggle = st.toggle("Social Vulnerability Index")
|
294 |
+
justice_toggle = st.toggle("Justice 40")
|
295 |
+
|
296 |
party_toggle = st.toggle("Political Parties")
|
297 |
+
|
298 |
st.divider()
|
299 |
|
300 |
'''
|
301 |
## Data Assistant (experimental)
|
302 |
|
303 |
+
Ask questions about the LandVote data, like:
|
304 |
|
305 |
- What are the top states for approved conservation funds?
|
306 |
- Plot the total funds spent in conservation each year.
|
|
|
328 |
if party_toggle:
|
329 |
m.add_pmtiles(party_pmtiles, style = party_style ,visible=True, opacity=0.3, tooltip=True)
|
330 |
|
331 |
+
if justice_toggle:
|
332 |
+
m.add_pmtiles(justice40, style=justice40_style, visible=True, name="Justice40", opacity=0.3, tooltip=True)
|
333 |
+
|
334 |
+
|
335 |
+
|
336 |
+
#compute percentage passed in given year
|
337 |
+
passed_year = votes.filter(_.year == year).filter(_.Status.isin(["Pass","Pass*"])).count().execute()
|
338 |
+
total_year= votes.filter(_.year == year).count().execute()
|
339 |
+
year_passed = (passed_year/total_year*100).round(2)
|
340 |
+
f"{year_passed}% Measures Passed in {year}"
|
341 |
+
|
342 |
+
#compute percentage passed over entire dataset
|
343 |
passed = votes.filter(_.Status.isin(["Pass","Pass*"])).count().execute()
|
344 |
total = votes.count().execute()
|
345 |
overall_passed = (passed/total*100).round(2)
|
346 |
+
f"{overall_passed}% Measures Passed from 1988 - 2024 \n"
|
347 |
+
|
348 |
+
|
349 |
|
350 |
if color_choice == "Measure Status":
|
351 |
m.add_pmtiles(votes_pmtiles, style=get_style_status("State"), visible=True, opacity=0.8, tooltip=True)
|
|
|
365 |
|
366 |
# display charts
|
367 |
df_passes = get_passes(votes)
|
368 |
+
st.altair_chart(create_chart(df_passes, "percent_passed", "Percent Passed","% of Measures Passed", [COLORS["dem_blue"], COLORS["rep_red"]], chart_type="line"), use_container_width=True)
|
369 |
|
370 |
df_funding = funding_chart(votes)
|
371 |
+
st.altair_chart(create_chart(df_funding, "cumulative_funding", "Billions of Dollars", "Cumulative Funding", COLORS["dark_green"], chart_type="bar"), use_container_width=True)
|
372 |
+
|
373 |
+
st.divider()
|
374 |
+
footer = st.container()
|
375 |
+
|
376 |
+
'''
|
377 |
+
# Credits
|
378 |
+
Authors: Cassie Buhler & Carl Boettiger, UC Berkeley License: BSD-2-clause
|
379 |
+
|
380 |
+
## Data sources
|
381 |
|
382 |
+
- TPL LandVote Database by Trust for Public Land. Data: https://tpl.quickbase.com/db/bbqna2qct?a=dbpage&pageID=8. Citation: The Trust for Public Land, LandVote®, 2024, www.landvote.org., License: Public Domain
|
383 |
+
|
384 |
+
- County Presidential Election Returns 2000-2020 by MIT Election Data and Science Lab. Citation: https://doi.org/10.7910/DVN/VOQCHQ. License: Public Domain.
|
385 |
+
|
386 |
+
- U.S. President 1976–2020 by MIT Election Data and Science Lab. Citation: https://doi.org/10.7910/DVN/42MVDX. License: Public Domain.
|
387 |
+
|
388 |
+
- Dave Leip's Atlas of U.S. Presidential Elections. Citation: http://uselectionatlas.org.
|
389 |
+
|
390 |
+
|
391 |
+
- Climate and Economic Justice Screening Tool, US Council on Environmental Quality, Justice40, Data: https://beta.source.coop/repositories/cboettig/justice40/description/. License: Public Domain
|
392 |
+
|
393 |
+
|
394 |
+
- CDC 2020 Social Vulnerability Index by US Census Track. Data: https://source.coop/repositories/cboettig/social-vulnerability/description. License: Public Domain
|
395 |
+
|
396 |
+
'''
|