Create an app showing an interactive Shibuya map visualization. Mock data: - Nursery schools locations (25 points) * with business hours * with a number of children * with a type of school (public or private) - Elementary schools locations (20 points) - Bus stops (100 points) and Bus routes Features: - Interactive map centered on Shibuya, Tokyo - Toggle layers: * Nursery schools with popups * Elementary schools * Bus stops * Animated Bus routes Controls: - Time slider - Borough filters - Color schemes - Map style (street/satellite) Include zoom/pan and stats panel showing data summaries.
To upload files, please first save the app
import streamlit as st
import pandas as pd
import numpy as np
import pydeck as pdk
import plotly.express as px
from datetime import datetime, time
import json
st.set_page_config(layout="wide", page_title="Shibuya Education Map")
# Generate mock data
@st.cache_data
def generate_mock_data():
# Shibuya coordinates
SHIBUYA_LAT = 35.6580
SHIBUYA_LON = 139.7016
# Nursery schools
np.random.seed(42)
n_nurseries = 25
nurseries = pd.DataFrame({
'name': [f'Nursery School {i+1}' for i in range(n_nurseries)],
'lat': SHIBUYA_LAT + np.random.normal(0, 0.01, n_nurseries),
'lon': SHIBUYA_LON + np.random.normal(0, 0.01, n_nurseries),
'children': np.random.randint(20, 100, n_nurseries),
'type': np.random.choice(['Public', 'Private'], n_nurseries),
'opening_time': [time(7, 0) for _ in range(n_nurseries)],
'closing_time': [time(18, 0) for _ in range(n_nurseries)],
'borough': np.random.choice(['Shibuya', 'Harajuku', 'Ebisu', 'Daikanyama'], n_nurseries)
})
# Elementary schools
n_elementary = 20
elementary = pd.DataFrame({
'name': [f'Elementary School {i+1}' for i in range(n_elementary)],
'lat': SHIBUYA_LAT + np.random.normal(0, 0.015, n_elementary),
'lon': SHIBUYA_LON + np.random.normal(0, 0.015, n_elementary),
'students': np.random.randint(200, 800, n_elementary),
'borough': np.random.choice(['Shibuya', 'Harajuku', 'Ebisu', 'Daikanyama'], n_elementary)
})
# Bus stops
n_stops = 100
bus_stops = pd.DataFrame({
'name': [f'Bus Stop {i+1}' for i in range(n_stops)],
'lat': SHIBUYA_LAT + np.random.normal(0, 0.02, n_stops),
'lon': SHIBUYA_LON + np.random.normal(0, 0.02, n_stops),
'borough': np.random.choice(['Shibuya', 'Harajuku', 'Ebisu', 'Daikanyama'], n_stops)
})
# Generate bus routes
n_routes = 5
routes = []
for i in range(n_routes):
n_points = np.random.randint(10, 20)
route = pd.DataFrame({
'path_lat': SHIBUYA_LAT + np.random.normal(0, 0.02, n_points),
'path_lon': SHIBUYA_LON + np.random.normal(0, 0.02, n_points),
'route_id': i
})
routes.append(route)
bus_routes = pd.concat(routes)
return nurseries, elementary, bus_stops, bus_routes
nurseries, elementary, bus_stops, bus_routes = generate_mock_data()
# Sidebar controls
st.sidebar.title("Map Controls")
# Borough filter
boroughs = ['All'] + sorted(nurseries['borough'].unique().tolist())
selected_borough = st.sidebar.selectbox('Select Borough', boroughs)
# Layer toggles
show_nurseries = st.sidebar.checkbox('Show Nursery Schools', True)
show_elementary = st.sidebar.checkbox('Show Elementary Schools', True)
show_bus_stops = st.sidebar.checkbox('Show Bus Stops', True)
show_bus_routes = st.sidebar.checkbox('Show Bus Routes', True)
# Time slider
time_range = st.sidebar.slider(
"Time of Day",
min_value=time(6, 0),
max_value=time(20, 0),
value=time(12, 0),
format="HH:mm"
)
# Map style
map_style = st.sidebar.selectbox(
'Map Style',
['mapbox://styles/mapbox/light-v9', 'mapbox://styles/mapbox/satellite-v9']
)
# Color scheme
color_scheme = st.sidebar.selectbox(
'Color Scheme',
['default', 'viridis', 'plasma']
)
# Filter data based on borough selection
if selected_borough != 'All':
nurseries = nurseries[nurseries['borough'] == selected_borough]
elementary = elementary[elementary['borough'] == selected_borough]
bus_stops = bus_stops[bus_stops['borough'] == selected_borough]
# Create layers
layers = []
if show_nurseries:
nursery_layer = pdk.Layer(
'ScatterplotLayer',
nurseries,
get_position=['lon', 'lat'],
get_radius=100,
get_fill_color=[255, 0, 0, 140],
pickable=True
)
layers.append(nursery_layer)
if show_elementary:
elementary_layer = pdk.Layer(
'ScatterplotLayer',
elementary,
get_position=['lon', 'lat'],
get_radius=150,
get_fill_color=[0, 0, 255, 140],
pickable=True
)
layers.append(elementary_layer)
if show_bus_stops:
bus_stop_layer = pdk.Layer(
'ScatterplotLayer',
bus_stops,
get_position=['lon', 'lat'],
get_radius=50,
get_fill_color=[0, 255, 0, 140],
pickable=True
)
layers.append(bus_stop_layer)
if show_bus_routes:
bus_route_layer = pdk.Layer(
'PathLayer',
bus_routes,
get_path=['path_lon', 'path_lat'],
get_width=20,
get_color=[255, 255, 0, 80],
pickable=True
)
layers.append(bus_route_layer)
# Create the map
st.title("Shibuya Education Map")
col1, col2 = st.columns([3, 1])
with col1:
view_state = pdk.ViewState(
latitude=35.6580,
longitude=139.7016,
zoom=13,
pitch=45
)
deck = pdk.Deck(
map_style=map_style,
initial_view_state=view_state,
layers=layers,
tooltip={
"html": "<b>Name:</b> {name}<br/>"
"<b>Borough:</b> {borough}<br/>"
"<b>Type:</b> {type}<br/>"
"<b>Children:</b> {children}"
}
)
st.pydeck_chart(deck)
# Stats panel
with col2:
st.subheader("Statistics")
# Nursery schools stats
st.write("**Nursery Schools**")
st.write(f"Total: {len(nurseries)}")
st.write(f"Total children: {nurseries['children'].sum()}")
# Plot nursery types distribution
fig = px.pie(nurseries, names='type', title='Nursery Types')
st.plotly_chart(fig, use_container_width=True)
# Elementary schools stats
st.write("**Elementary Schools**")
st.write(f"Total: {len(elementary)}")
st.write(f"Total students: {elementary['students'].sum()}")
# Bus infrastructure
st.write("**Bus Infrastructure**")
st.write(f"Bus stops: {len(bus_stops)}")
st.write(f"Bus routes: {len(bus_routes['route_id'].unique())}")
# Borough distribution
if selected_borough == 'All':
st.write("**Facilities by Borough**")
borough_counts = pd.concat([
nurseries['borough'].value_counts(),
elementary['borough'].value_counts(),
bus_stops['borough'].value_counts()
]).reset_index()
borough_counts.columns = ['Borough', 'Count']
fig = px.bar(borough_counts, x='Borough', y='Count', title='Facilities by Borough')
st.plotly_chart(fig, use_container_width=True)
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?