map / pages /2_↔️_Comparision.py
interactive-crime's picture
Duplicate from yunusserhat/Crime-Map
c6b286b
raw
history blame
5.52 kB
import streamlit as st
import leafmap.foliumap as leafmap
import json
import requests
# Functions to dynamically fetch columns
def get_columns_from_geojson(geojson_data):
"""Retrieve column names from a GeoJSON data."""
if "features" in geojson_data:
properties = geojson_data["features"][0]["properties"]
return list(properties.keys())
return []
def get_columns_from_url(url):
"""Retrieve column names from a GeoJSON URL."""
response = requests.get(url)
geojson_data = response.json()
return get_columns_from_geojson(geojson_data)
st.set_page_config(layout="wide")
# Sidebar Information
st.sidebar.info(
'''
- Web App URL: <https://interactive-crime-map.hf.space/>
- HuggingFace repository: <https://huggingface.co/spaces/interactive-crime/map/tree/main>
'''
)
st.sidebar.title("Contact")
st.sidebar.info(
'''
Yunus Serhat Bıçakçı at [yunusserhat.com](https://yunusserhat.com) | [GitHub](https://github.com/yunusserhat) | [Twitter](https://twitter.com/yunusserhat) | [LinkedIn](https://www.linkedin.com/in/yunusserhat)
'''
)
# Title and Description
st.title("Interactive Analysis of Hate Metrics in London & Custom Dataset Visualization")
st.markdown(
'''
Dive into an interactive analysis of hate metrics in London, exploring the disparities and correlations between hate-related tweets and reported crimes in boroughs. This platform offers a comparative visualization based on data from X and the London Metropolitan Police Service as of December 2022.
Additionally, users can upload and visualize their own GeoJSON datasets, facilitating personalized analysis and insights. Delve deeper into the patterns of hate sentiment, understand how online behavior might mirror real-world incidents, or uncover patterns in your own data.
'''
)
# File Uploader
uploaded_file = st.file_uploader("Upload a GeoJSON file", type=["geojson"])
uploaded_geojson = None
# Map URLs
map_1 = "https://raw.githubusercontent.com/yunusserhat/data/main/data/boroughs_count_df_2022_dec.geojson"
map_2 = "https://raw.githubusercontent.com/yunusserhat/data/main/data/mps_hate_2022_dec_count.geojson"
map_3 = "https://raw.githubusercontent.com/yunusserhat/data/main/data/mps2022dec_count.geojson"
if uploaded_file:
try:
uploaded_geojson = json.load(uploaded_file)
if "features" not in uploaded_geojson:
st.warning("The uploaded file does not seem to be a valid GeoJSON format.")
uploaded_geojson = None
else:
st.success("GeoJSON file uploaded successfully!")
except json.JSONDecodeError:
st.error("Failed to decode the uploaded file. Please ensure it's a valid GeoJSON format.")
# Map Selection
map_choices = ["Hate Tweets", "MPS Hate Crime Data", "MPS All Crime Data"]
if uploaded_geojson:
map_choices.append("Uploaded GeoJSON")
selected_map_1 = st.selectbox("Select data for Map 1", map_choices)
# Determine the columns based on the selected dataset for Map 1
if selected_map_1 == "Uploaded GeoJSON" and uploaded_geojson:
available_columns_1 = get_columns_from_geojson(uploaded_geojson)
elif selected_map_1 == "Hate Tweets":
available_columns_1 = get_columns_from_url(map_1)
elif selected_map_1 == "MPS Hate Crime Data":
available_columns_1 = get_columns_from_url(map_2)
elif selected_map_1 == "MPS All Crime Data":
available_columns_1 = get_columns_from_url(map_3)
selected_column_1 = st.selectbox("Select column for Map 1 visualization", available_columns_1)
selected_map_2 = st.selectbox("Select data for Map 2", map_choices)
# Determine the columns based on the selected dataset for Map 2
if selected_map_2 == "Uploaded GeoJSON" and uploaded_geojson:
available_columns_2 = get_columns_from_geojson(uploaded_geojson)
elif selected_map_2 == "Hate Tweets":
available_columns_2 = get_columns_from_url(map_1)
elif selected_map_2 == "MPS Hate Crime Data":
available_columns_2 = get_columns_from_url(map_2)
elif selected_map_2 == "MPS All Crime Data":
available_columns_2 = get_columns_from_url(map_3)
selected_column_2 = st.selectbox("Select column for Map 2 visualization", available_columns_2)
# Display Maps
row1_col1, row1_col2 = st.columns([1, 1])
with row1_col1:
m1 = leafmap.Map(center=[51.50, -0.1], zoom=10)
if selected_map_1 == "Uploaded GeoJSON":
m1.add_data(uploaded_geojson, column=selected_column_1)
elif selected_map_1 == "Hate Tweets":
m1.add_data(map_1, column=selected_column_1)
elif selected_map_1 == "MPS Hate Crime Data":
m1.add_data(map_2, column=selected_column_1)
else:
m1.add_data(map_3, column=selected_column_1)
with row1_col2:
m2 = leafmap.Map(center=[51.50, -0.1], zoom=10)
if selected_map_2 == "Uploaded GeoJSON":
m2.add_data(uploaded_geojson, column=selected_column_2)
elif selected_map_2 == "Hate Tweets":
m2.add_data(map_1, column=selected_column_2)
elif selected_map_2 == "MPS Hate Crime Data":
m2.add_data(map_2, column=selected_column_2)
else:
m2.add_data(map_3, column=selected_column_2)
# Zoom
longitude = -0.1
latitude = 51.50
zoomlevel = st.number_input("Zoom", 0, 20, 10)
row2_col1, row2_col2 = st.columns([1, 1])
with row2_col1:
m1.set_center(longitude, latitude, zoomlevel)
with row2_col2:
m2.set_center(longitude, latitude, zoomlevel)
row3_col1, row3_col2 = st.columns([1, 1])
with row3_col1:
m1.to_streamlit()
with row3_col2:
m2.to_streamlit()