Skip to content

Commit fb0668e

Browse files
committed
feat: Add simple São Paulo demo
- Create demo_sp.ipynb with simple EHSA example - Create demo_sao_paulo.py script version - Use synthetic grid data in central São Paulo - Show hotspot detection and visualization - Functional import from source code
1 parent 526281d commit fb0668e

3 files changed

Lines changed: 248 additions & 0 deletions

File tree

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,4 @@ For more information:
7070
- 📖 Check the main README.md
7171
- 🐛 Report issues on GitHub
7272
- 💡 See docstrings in the code for detailed parameter explanations
73+

examples/demo_sao_paulo.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Demo simples do PyEhsa - Análise de Hotspots em São Paulo
4+
"""
5+
6+
import sys
7+
import os
8+
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src'))
9+
10+
import pandas as pd
11+
import geopandas as gpd
12+
import numpy as np
13+
from shapely.geometry import Point
14+
from datetime import datetime, timedelta
15+
import folium
16+
17+
# Importar PyEhsa do código fonte
18+
from pyehsa.emerging_hotspot_analysis import EmergingHotspotAnalysis
19+
20+
# Configurar seed
21+
np.random.seed(42)
22+
23+
# 1. Criar dados sintéticos - Grid 5x5 no centro de SP
24+
center_lat, center_lon = -23.5489, -46.6388
25+
step = 0.01 # ~1.1km
26+
27+
data = []
28+
for i in range(5):
29+
for j in range(5):
30+
lat = center_lat + (i - 2) * step
31+
lon = center_lon + (j - 2) * step
32+
location_id = f'SP_{i}_{j}'
33+
34+
# 6 meses de dados
35+
for month in range(6):
36+
time_period = datetime(2024, 1, 1) + timedelta(days=30*month)
37+
38+
# Valor base
39+
value = np.random.poisson(10)
40+
41+
# Simular hotspot emergente no canto superior direito
42+
if i >= 3 and j >= 3 and month >= 2:
43+
value += (month - 1) * 8
44+
45+
# Ruído
46+
value += np.random.normal(0, 2)
47+
value = max(0, value)
48+
49+
data.append({
50+
'location_id': location_id,
51+
'time_period': time_period,
52+
'value': value,
53+
'geometry': Point(lon, lat)
54+
})
55+
56+
# Criar GeoDataFrame
57+
gdf = gpd.GeoDataFrame(data, geometry='geometry', crs='EPSG:4326')
58+
59+
print(f"Dataset: {len(gdf)} observações, {gdf['location_id'].nunique()} locais")
60+
61+
# 2. Executar análise EHSA
62+
results = EmergingHotspotAnalysis.emerging_hotspot_analysis(
63+
gdf,
64+
region_id_field='location_id',
65+
time_period_field='time_period',
66+
value='value',
67+
k=1,
68+
nsim=99
69+
)
70+
71+
# 3. Mostrar resultados
72+
print(f"\nResultados:")
73+
print(results['classification'].value_counts())
74+
75+
# 4. Criar mapa simples
76+
locations = gdf[['location_id', 'geometry']].drop_duplicates()
77+
viz_data = results.merge(locations, left_on='region_id', right_on='location_id')
78+
79+
m = folium.Map(location=[center_lat, center_lon], zoom_start=13)
80+
81+
color_map = {
82+
'no pattern detected': 'gray',
83+
'new hotspot': 'red',
84+
'consecutive hotspot': 'darkred',
85+
'sporadic hotspot': 'orange'
86+
}
87+
88+
for _, row in viz_data.iterrows():
89+
color = color_map.get(row['classification'], 'gray')
90+
91+
folium.CircleMarker(
92+
location=[row['geometry'].y, row['geometry'].x],
93+
radius=8,
94+
popup=f"{row['region_id']}: {row['classification']}",
95+
color='black',
96+
fillColor=color,
97+
fillOpacity=0.7
98+
).add_to(m)
99+
100+
# Salvar mapa
101+
m.save('hotspots_sao_paulo.html')
102+
print(f"\nMapa salvo em: hotspots_sao_paulo.html")

examples/demo_sp.ipynb

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# PyEhsa Demo - São Paulo\n"
8+
]
9+
},
10+
{
11+
"cell_type": "code",
12+
"execution_count": null,
13+
"metadata": {},
14+
"outputs": [],
15+
"source": [
16+
"import sys\n",
17+
"import os\n",
18+
"sys.path.append(os.path.join(os.path.dirname(''), '..', 'src'))\n",
19+
"\n",
20+
"import pandas as pd\n",
21+
"import geopandas as gpd\n",
22+
"import numpy as np\n",
23+
"from shapely.geometry import Point\n",
24+
"from datetime import datetime, timedelta\n",
25+
"\n",
26+
"from pyehsa.emerging_hotspot_analysis import EmergingHotspotAnalysis\n",
27+
"\n",
28+
"np.random.seed(42)\n"
29+
]
30+
},
31+
{
32+
"cell_type": "code",
33+
"execution_count": null,
34+
"metadata": {},
35+
"outputs": [],
36+
"source": [
37+
"# Criar dados sintéticos - Grid 5x5 no centro de SP\n",
38+
"center_lat, center_lon = -23.5489, -46.6388\n",
39+
"step = 0.01\n",
40+
"\n",
41+
"data = []\n",
42+
"for i in range(5):\n",
43+
" for j in range(5):\n",
44+
" lat = center_lat + (i - 2) * step\n",
45+
" lon = center_lon + (j - 2) * step\n",
46+
" location_id = f'SP_{i}_{j}'\n",
47+
" \n",
48+
" for month in range(6):\n",
49+
" time_period = datetime(2024, 1, 1) + timedelta(days=30*month)\n",
50+
" \n",
51+
" value = np.random.poisson(10)\n",
52+
" \n",
53+
" # Hotspot emergente no canto superior direito\n",
54+
" if i >= 3 and j >= 3 and month >= 2:\n",
55+
" value += (month - 1) * 8\n",
56+
" \n",
57+
" value += np.random.normal(0, 2)\n",
58+
" value = max(0, value)\n",
59+
" \n",
60+
" data.append({\n",
61+
" 'location_id': location_id,\n",
62+
" 'time_period': time_period,\n",
63+
" 'value': value,\n",
64+
" 'geometry': Point(lon, lat)\n",
65+
" })\n",
66+
"\n",
67+
"gdf = gpd.GeoDataFrame(data, geometry='geometry', crs='EPSG:4326')\n",
68+
"print(f\"Dataset: {len(gdf)} observações, {gdf['location_id'].nunique()} locais\")\n"
69+
]
70+
},
71+
{
72+
"cell_type": "code",
73+
"execution_count": null,
74+
"metadata": {},
75+
"outputs": [],
76+
"source": [
77+
"# Executar análise EHSA\n",
78+
"results = EmergingHotspotAnalysis.emerging_hotspot_analysis(\n",
79+
" gdf,\n",
80+
" region_id_field='location_id',\n",
81+
" time_period_field='time_period', \n",
82+
" value='value',\n",
83+
" k=1,\n",
84+
" nsim=99\n",
85+
")\n"
86+
]
87+
},
88+
{
89+
"cell_type": "code",
90+
"execution_count": null,
91+
"metadata": {},
92+
"outputs": [],
93+
"source": [
94+
"# Mostrar resultados\n",
95+
"print(\"Padrões identificados:\")\n",
96+
"print(results['classification'].value_counts())\n",
97+
"print(\"\\nPrimeiros resultados:\")\n",
98+
"results[['region_id', 'classification', 'tau', 'p_value']].head()\n"
99+
]
100+
},
101+
{
102+
"cell_type": "code",
103+
"execution_count": null,
104+
"metadata": {},
105+
"outputs": [],
106+
"source": [
107+
"# Criar mapa\n",
108+
"import folium\n",
109+
"\n",
110+
"locations = gdf[['location_id', 'geometry']].drop_duplicates()\n",
111+
"viz_data = results.merge(locations, left_on='region_id', right_on='location_id')\n",
112+
"\n",
113+
"m = folium.Map(location=[center_lat, center_lon], zoom_start=13)\n",
114+
"\n",
115+
"color_map = {\n",
116+
" 'no pattern detected': 'gray',\n",
117+
" 'new hotspot': 'red',\n",
118+
" 'consecutive hotspot': 'darkred',\n",
119+
" 'sporadic hotspot': 'orange'\n",
120+
"}\n",
121+
"\n",
122+
"for _, row in viz_data.iterrows():\n",
123+
" color = color_map.get(row['classification'], 'gray')\n",
124+
" \n",
125+
" folium.CircleMarker(\n",
126+
" location=[row['geometry'].y, row['geometry'].x],\n",
127+
" radius=8,\n",
128+
" popup=f\"{row['region_id']}: {row['classification']}\",\n",
129+
" color='black',\n",
130+
" fillColor=color,\n",
131+
" fillOpacity=0.7\n",
132+
" ).add_to(m)\n",
133+
"\n",
134+
"m\n"
135+
]
136+
}
137+
],
138+
"metadata": {
139+
"language_info": {
140+
"name": "python"
141+
}
142+
},
143+
"nbformat": 4,
144+
"nbformat_minor": 2
145+
}

0 commit comments

Comments
 (0)