drguilhermeapolinario commited on
Commit
9a51b58
·
verified ·
1 Parent(s): 95c0b72

Update views/maps.py

Browse files
Files changed (1) hide show
  1. views/maps.py +1022 -477
views/maps.py CHANGED
@@ -1,19 +1,16 @@
1
  import folium
2
  import geopandas as gpd
 
3
  import plotly.express as px
 
 
4
  from branca.colormap import LinearColormap
5
  from folium.plugins import HeatMap
6
- from streamlit_folium import folium_static
7
-
8
- import streamlit as st
9
- from streamlit_extras.stylable_container import stylable_container
10
  from streamlit_extras.add_vertical_space import add_vertical_space
11
- #import streamlit_shadcn_ui as ui
 
12
  from streamlit_option_menu import option_menu
13
- import pandas as pd
14
- import plotly.graph_objects as go
15
 
16
- with stylable_container(
17
  key="banner",
18
  css_styles="""
19
  img {
@@ -24,338 +21,932 @@ with stylable_container(
24
  object-fit: cover;
25
  border-radius: 20px; /* Adiciona bordas arredondadas */
26
  mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
27
- -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); /* For Safari */
 
28
  }
29
  """,
30
  ):
31
  st.image("src/Images/mp.jpg")
32
 
33
- st.title("Mapas da área")
34
  add_vertical_space(2)
35
  st.markdown(""" ### :world_map: **UBS Flamengo: (IBGE 2022)** """)
36
 
 
37
  @st.cache_resource
38
  def load_data():
 
 
 
39
  """
40
- A function that loads and reads geojson data for UBS Flamengo and converts it to the specified coordinate reference system.
41
- """
42
- return gpd.read_file("flamengo_ibge2022.geojson").to_crs(epsg=4326)
43
 
44
  gdf = load_data()
45
- LATITUDE = -19.971591804
46
  LONGITUDE = -44.057912815
47
  lat = -19.96214
48
  long = -44.05603
49
 
50
- total_pop = gdf["POP"].sum()
 
 
51
  col1, col2, col3 = st.columns([1, 1, 5])
52
 
53
  STYLE = "static/style.css"
54
  STYLES = "static/styles.html"
55
  with open(STYLE, "r", encoding="utf-8") as f:
56
- st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
57
 
58
  with open(STYLES, "r", encoding="utf-8") as f:
59
- st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
60
 
61
- @st.cache_resource
62
- def load_data():
63
- """
64
- A function that loads and reads geojson data for UBS Flamengo and converts it to the specified coordinate reference system.
65
- """
66
- return gpd.read_file("views/flamengo_ibge2022.geojson").to_crs(epsg=4326)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
- gdf = load_data()
69
- LATITUDE = -19.971591804
70
- LONGITUDE = -44.057912815
71
- lat = -19.96214
72
- long = -44.05603
 
 
 
73
 
74
- total_pop = gdf["POP"].sum()
75
- num_setores = len(gdf)
76
 
77
- with st.expander("Visualização", expanded=True):
78
- selected_tab = option_menu(
79
- menu_title=None,
80
- options=[
81
- "Mapa IBGE",
82
- "Área",
83
- "População",
84
- ],
85
- icons=[
86
- "person",
87
- "geo-alt",
88
- "capsule-pill"
89
- ],
90
- menu_icon="cast",
91
- default_index=0,
92
- orientation="horizontal",
93
- styles={
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  "container": {
95
- "padding": "5px",
96
- "background-color": "#1E1E28",
97
- "border-radius": "8px",
 
 
98
  },
99
  "icon": {
100
- "color": "#64B5F6",
101
- "font-size": "20px",
102
- "padding-right": "8px",
103
  },
104
  "nav-link": {
105
- "font-size": "16px",
106
  "text-align": "center",
107
  "margin": "5px",
108
- "padding": "12px",
109
- "background-color": "#2A2B3D",
110
- "--hover-color": "#4B4B4B",
111
- "color": "#FFFFFF",
112
- "border-radius": "4px",
113
  },
114
  "nav-link-selected": {
115
- "background-color": "#007BB5",
116
- "color": "#FFFFFF",
117
- "font-weight": "bold",
 
118
  },
119
  "separator": {
120
- "border-color": "#303030",
121
- "margin": "0 10px",
122
- },
123
  },
124
- )
125
- if selected_tab == "Mapa IBGE":
126
- col1, col2, col3, col4, col5 = st.columns([1.5, 1.5, 0.8, 5, 0.5])
127
- with col1:
128
- st.metric(label="👪 População Total", value=f"{total_pop:,} habitantes", help="Dados do Censo 2022 IBGE")
129
- map_type = st.selectbox("Tipo de mapa", ["População", "Densidade", "Heatmap"])
130
- with col2:
131
- st.metric(label="🗺️ Número de Setores Censitários", value=f"{num_setores}", help="Dados do Censo 2022 IBGE")
132
- base_map = st.selectbox("Mapa base", ["Cartodb Positron", "OpenStreetMap"])
133
- with col4:
134
- with st.container(border=False, height=400):
135
- row1, row2, row3 = st.columns([0.5, 3, 0.9])
136
- with row1:
137
- st.write('')
138
- with row2:
139
- st.write("""
140
- ### Definição de Setor Censitário
141
- Um **setor censitário** é a menor unidade territorial utilizada pelo
142
- IBGE para a coleta de dados em censos demográficos.
143
-
144
- Cada setor censitário é uma área contínua dentro de um município, delimitado
145
- por características físicas e populacionais. Geralmente contém entre 250 e
146
- 350 domicílios.
147
-
148
- Os setores censitários são fundamentais em pesquisas mais elaboradas.
149
- Permitem uma análise granular da distribuição populacional, socioeconômica
150
- e das condições de moradia em diferentes regiões do país. Essa unidade de
151
- medida é fundamental para a elaboração de políticas públicas, planejamento
152
- urbano, e outras atividades que dependem de informações demográficas precisas.
153
- """)
154
- with row3:
155
- st.write('')
156
-
157
- col1, col2 = st.columns(2)
158
-
159
- with col1:
160
- m = folium.Map(
161
- location=[LATITUDE, LONGITUDE], tiles=base_map, zoom_start=15
162
- )
163
- dns_p = "Densidade pop. (hab/km²) UBS Flamengo - IBGE 2022"
164
- if map_type in ["População", "Densidade"]:
165
- if map_type == "População":
166
- column = "POP"
167
- caption = "Pop. residente UBS Flamengo IBGE 2022"
168
- else:
169
- gdf["DENSIDADE"] = gdf["POP"] / gdf["AREA_KM2"]
170
- column = "DENSIDADE"
171
- caption = dns_p
172
- colorscale = px.colors.sequential.Viridis
173
- colormap = LinearColormap(
174
- colors=colorscale,
175
- vmin=gdf[column].min(),
176
- vmax=gdf[column].max(),
177
- caption=caption,
178
- )
179
- folium.GeoJson(
180
- gdf,
181
- style_function=lambda feature: {
182
- "fillColor": colormap(feature["properties"][column]),
183
- "color": "black",
184
- "weight": 1,
185
- "fillOpacity": 0.7,
186
- },
187
- highlight_function=lambda feature: {
188
- "fillColor": "#ffaf00",
189
- "color": "green",
190
- "weight": 3,
191
- "fillOpacity": 0.9,
192
- },
193
- tooltip=folium.features.GeoJsonTooltip(
194
- fields=["CD_SETOR", column, "AREA_KM2"],
195
- aliases=[
196
- "Setor Censitário:",
197
- f"{caption}:",
198
- "Área (km²):",
199
- ],
200
- style=(
201
- "background-color: white; color: #333333;"
202
- "font-family: calibri; font-size: 12px;"
203
- "padding: 10px;"
204
- ),
205
- ),
206
- ).add_to(m)
207
- colormap.add_to(m)
208
-
209
- elif map_type == "Heatmap":
210
- heat_data = [
211
- [
212
- row["geometry"].centroid.y,
213
- row["geometry"].centroid.x,
214
- row["POP"],
215
- ]
216
- for idx, row in gdf.iterrows()
217
- ]
218
- HeatMap(heat_data).add_to(m)
219
- folium.Marker(
220
- [lat, long],
221
- popup="UBS Flamengo",
222
- tooltip="UBS Flamengo",
223
- icon=folium.Icon(color="red", icon="info-sign"),
224
- ).add_to(m)
225
-
226
- STYLE_STATEMENT = (
227
- "<style>.leaflet-control-layers"
228
- "{ position: fixed; top: 10px; left: 50px; } </style>"
229
- )
230
- m.get_root().html.add_child(folium.Element(STYLE_STATEMENT))
231
- folium_static(m)
232
- with col2:
233
- fig = px.bar(
234
- gdf,
235
- x="CD_SETOR",
236
- y="POP",
237
- title="Distribuição da População por Setor Censitário",
238
- color="POP",
239
- color_continuous_scale=px.colors.sequential.Viridis,
240
- )
241
- st.plotly_chart(fig)
242
-
243
- age_columns = [
244
- "POP_0A4", "POP_5A9", "POP_10A14", "POP_15A19", "POP_20A24",
245
- "POP_25A29", "POP_30A34", "POP_35A39", "POP_40A44", "POP_45A49",
246
- "POP_50A54", "POP_55A59", "POP_60A64", "POP_65A69", "POP_70A74",
247
- "POP_75A79", "POP_80A84", "POP_85A89", "POP_90A94", "POP_95A99",
248
- "POP_100OUMAIS",
249
- ]
250
-
251
- fig = px.bar()
252
-
253
- elif selected_tab == "Área":
254
- st.subheader("Crescimento populacional - UBS Flamengo")
255
- with stylable_container(
256
- key="banner",
257
- css_styles="""
258
  img {
259
- width: 1800px;
260
- height: 340px;
261
  overflow: hidden;
262
  position: relative;
263
  object-fit: cover;
264
  border-radius: 20px; /* Adiciona bordas arredondadas */
265
- mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
266
- -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); /* For Safari */
 
 
267
  }
268
  """,
269
- ):
270
- st.image("src/Images/pop.jpg")
271
- st.title("Crescimento populacional - UBS Flamengo")
272
-
273
- raw_data = [
274
- {"Mês": "mai-21", "Usuários": 3402, "Domicílios": 1440, "Famílias": 1269},
275
- {"Mês": "jun-21", "Usuários": 3503, "Domicílios": 1462, "Famílias": 1304},
276
- {"Mês": "jul-21", "Usuários": 3559, "Domicílios": 1478, "Famílias": 1323},
277
- {"Mês": "ago-21", "Usuários": 3592, "Domicílios": 1490, "Famílias": 1338},
278
- {"Mês": "set-21", "Usuários": 3755, "Domicílios": 1573, "Famílias": 1380},
279
- {"Mês": "out-21", "Usuários": 3776, "Domicílios": 1533, "Famílias": 1384},
280
- {"Mês": "nov-21", "Usuários": 3839, "Domicílios": 1553, "Famílias": 1397},
281
- {"Mês": "dez-21", "Usuários": 3926, "Domicílios": 1581, "Famílias": 1423},
282
- {"Mês": "jan-22", "Usuários": 3951, "Domicílios": 1596, "Famílias": 1437},
283
- {"Mês": "fev-22", "Usuários": 4035, "Domicílios": 1638, "Famílias": 1465},
284
- {"Mês": "mar-22", "Usuários": 4131, "Domicílios": 1672, "Famílias": 1500},
285
- {"Mês": "abr-22", "Usuários": 4306, "Domicílios": 1723, "Famílias": 1555},
286
- {"Mês": "mai-22", "Usuários": 4553, "Domicílios": 1795, "Famílias": 1625},
287
- {"Mês": "jun-22", "Usuários": 4639, "Domicílios": 1817, "Famílias": 1653},
288
- {"Mês": "jul-22", "Usuários": 4719, "Domicílios": 1848, "Famílias": 1676},
289
- {"Mês": "ago-22", "Usuários": 4776, "Domicílios": 1869, "Famílias": 1687},
290
- {"Mês": "set-22", "Usuários": 4831, "Domicílios": 1883, "Famílias": 1699},
291
- {"Mês": "out-22", "Usuários": 4871, "Domicílios": 1900, "Famílias": 1709},
292
- {"Mês": "nov-22", "Usuários": 4874, "Domicílios": 1906, "Famílias": 1708},
293
- {"Mês": "dez-22", "Usuários": 4920, "Domicílios": 1914, "Famílias": 1720},
294
- {"Mês": "jan-23", "Usuários": 5135, "Domicílios": 2006, "Famílias": 1776},
295
- {"Mês": "fev-23", "Usuários": 5396, "Domicílios": 2084, "Famílias": 1848},
296
- {"Mês": "mar-23", "Usuários": 5544, "Domicílios": 2127, "Famílias": 1893},
297
- {"Mês": "abr-23", "Usuários": 5546, "Domicílios": 2140, "Famílias": 1910},
298
- {"Mês": "mai-23", "Usuários": 5579, "Domicílios": 2164, "Famílias": 1920},
299
- {"Mês": "jun-23", "Usuários": 5642, "Domicílios": 2181, "Famílias": 1946},
300
- {"Mês": "jul-23", "Usuários": 5681, "Domicílios": 2200, "Famílias": 1961},
301
- {"Mês": "ago-23", "Usuários": 5728, "Domicílios": 2208, "Famílias": 1972},
302
- {"Mês": "set-23", "Usuários": 5774, "Domicílios": 2228, "Famílias": 1983},
303
- {"Mês": "out-23", "Usuários": 5841, "Domicílios": 2245, "Famílias": 2007},
304
- {"Mês": "nov-23", "Usuários": 5891, "Domicílios": 2297, "Famílias": 2027},
305
- {"Mês": "dez-23", "Usuários": 5933, "Domicílios": 2281, "Famílias": 2036},
306
- {"Mês": "jan-24", "Usuários": 5982, "Domicílios": 2307, "Famílias": 2050},
307
- {"Mês": "fev-24", "Usuários": 6005, "Domicílios": 2333, "Famílias": 2057},
308
- {"Mês": "mar-24", "Usuários": 6020, "Domicílios": 2327, "Famílias": 2070},
309
- {"Mês": "abr-24", "Usuários": 6074, "Domicílios": 2370, "Famílias": 2095},
310
- ]
311
-
312
- df = pd.DataFrame(raw_data)
313
-
314
- @st.cache_data
315
- def processar_dados(dados, intervalo):
316
- """
317
- Process data based on the specified interval and return the aggregated data.
318
- Parameters:
319
- - dados: List of dictionaries containing data for each month.
320
- - intervalo: String indicating the interval for data aggregation.
321
-
322
- Returns:
323
- - List of dictionaries with aggregated data based on the specified interval.
324
- """
325
- if intervalo == "Mensal":
326
- return dados
327
- agrupamentos = {"Trimestral": 3, "Semestral": 6, "Anual": 12}
328
- dados_agrupados = []
329
- for i in range(0, len(dados), agrupamentos[intervalo]):
330
- grupo = dados[i : i + agrupamentos[intervalo]]
331
- ultimo_Mês = grupo[-1]["Mês"]
332
- dados_agrupados.append(
333
- {
334
- "Mês": ultimo_Mês,
335
- "Usuários": max(d["Usuários"] for d in grupo),
336
- "Domicílios": max(d["Domicílios"] for d in grupo),
337
- "Famílias": max(d["Famílias"] for d in grupo),
338
- }
339
- )
340
- return dados_agrupados
341
-
342
- @st.cache_data
343
- def formatar_data(Mês):
344
- """
345
- A function that formats the data based on the input Mês parameter.
346
-
347
- Parameters:
348
- - Mês (str): A string containing the month and year separated by a hyphen.
349
-
350
- Returns:
351
- - str: A formatted string in the format "month/year".
352
- """
353
- m, a = Mês.split("-")
354
- return f"{m}/{a}"
355
-
356
- # Adicionando estilo personalizado
357
- st.markdown(
358
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
  <style>
360
  .stSelectbox [data-baseweb="select"] {
361
  max-width: 300px;
@@ -367,194 +958,148 @@ with st.expander("Visualização", expanded=True):
367
  }
368
  </style>
369
  """,
370
- unsafe_allow_html=True,
371
- )
372
-
373
- # Criando duas colunas para os menus de opções
374
- col1, col2, col3 = st.columns([3, 2, 2])
375
-
376
- with col1:
377
- st.dataframe(df, use_container_width=True, height=250, hide_index=True)
378
-
379
- with col2:
380
- intervalo = option_menu(
381
- "Intervalo de Tempo",
382
- ["Mensal", "Trimestral", "Semestral", "Anual"],
383
- icons=["calendar-month", "calendar-quarter", "calendar-half", "calendar-year"],
384
- menu_icon="cast",
385
- default_index=0,
386
- styles={
387
- "container": {"padding": "0!important", "background-color": "#f0f0f3", "border-radius": "15px", "box-shadow": "5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff"},
388
- "icon": {"color": "#007bff", "font-size": "18px"},
389
- "nav-link": {
390
- "font-size": "14px",
391
- "text-align": "center",
392
- "margin": "5px",
393
- "padding": "10px",
394
- "--hover-color": "#e6e6e9",
395
- "color": "#333333",
396
- "border-radius": "10px",
397
- "transition": "all 0.3s ease",
398
- },
399
- "nav-link-selected": {"background-color": "#ffffff", "box-shadow": "inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff"},
400
- "separator": {"border-color": "#e0e0e3"},
401
- },
402
- )
403
-
404
- with col3:
405
- metrica = option_menu(
406
- "Métrica",
407
- ["Todos", "Usuários", "Domicílios", "Famílias"],
408
- icons=["list", "person", "house", "people"],
409
- menu_icon="cast",
410
- default_index=0,
411
- styles={
412
- "container": {"padding": "0!important", "background-color": "#f0f0f3", "border-radius": "15px", "box-shadow": "5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff"},
413
- "icon": {"color": "#007bff", "font-size": "18px"},
414
- "nav-link": {
415
- "font-size": "14px",
416
- "text-align": "center",
417
- "margin": "5px",
418
- "padding": "10px",
419
- "--hover-color": "#e6e6e9",
420
- "color": "#333333",
421
- "border-radius": "10px",
422
- "transition": "all 0.3s ease",
423
- },
424
- "nav-link-selected": {"background-color": "#ffffff", "box-shadow": "inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff"},
425
- "separator": {"border-color": "#e0e0e3"},
426
- },
427
- )
428
-
429
- dados_processados = processar_dados(raw_data, intervalo)
430
-
431
- # Switch para mostrar valores nos pontos
432
- mostrar_valores = st.checkbox("Mostrar valores nos pontos", value=True)
433
-
434
- # Criação do gráfico
435
- fig = go.Figure()
436
-
437
- metricas = ["Usuários", "Domicílios", "Famílias"] if metrica == "Todos" else [metrica]
438
- cores = {"Usuários": "#007bff", "Domicílios": "#28a745", "Famílias": "#ffc107"}
439
-
440
- # Slider Component
441
- # st.sidebar.header("Ajustes dos Balões")
442
- # balloon_positions = {}
443
- # for m in metricas:
444
- # balloon_positions[m] = st.sidebar.slider(
445
- # f"Posição do balão para {m}", min_value=-100, max_value=0, value=-40, step=5
446
- # )
447
-
448
- annotations = []
449
- for m in metricas:
450
- x_data = [formatar_data(d["Mês"]) for d in dados_processados]
451
- y_data = [d[m] for d in dados_processados]
452
-
453
- fig.add_trace(
454
- go.Scatter(
455
- x=x_data,
456
- y=y_data,
457
- mode="lines+markers",
458
- name=m,
459
- line=dict(color=cores[m], width=3),
460
- marker=dict(size=10, symbol="circle", line=dict(width=2, color="white")),
461
- )
462
- )
463
- if mostrar_valores:
464
- for i, (x, y) in enumerate(zip(x_data, y_data)):
465
- annotations.append(
466
- dict(
467
- x=x,
468
- y=y,
469
- xref="x",
470
- yref="y",
471
- text=f"{y:,.0f}",
472
- showarrow=True,
473
- arrowhead=2,
474
- ax=0,
475
- ay=balloon_positions[m],
476
- bgcolor=cores[m],
477
- opacity=0.8,
478
- bordercolor="white",
479
- borderwidth=2,
480
- borderpad=4,
481
- font=dict(color="white", size=10),
482
- boxshadow=dict(x=2, y=2, blur=3, color='rgba(0,0,0,0.3)'),
483
- )
484
- )
485
- fig.update_layout(
486
- title={
487
- "text": "Crescimento na Área de Saúde",
488
- "y": 0.95,
489
- "x": 0.5,
490
- "xanchor": "center",
491
- "yanchor": "top",
492
- "font": dict(size=24, color="#333333"),
493
  },
494
- xaxis_title="Mês",
495
- yaxis_title="Quantidade",
496
- legend_title="Métricas",
497
- template="plotly_white",
498
- plot_bgcolor="#f0f0f3",
499
- paper_bgcolor="#f0f0f3",
500
- font=dict(color="#333333"),
501
- xaxis=dict(showgrid=True, gridcolor="#e0e0e3", tickangle=45),
502
- yaxis=dict(showgrid=True, gridcolor="#e0e0e3"),
503
- legend=dict(
504
- bgcolor="rgba(255,255,255,0.8)",
505
- bordercolor="#e0e0e3",
506
- borderwidth=1,
507
- font=dict(size=12, color="#333333"),
508
- ),
509
- margin=dict(l=50, r=50, t=80, b=50),
510
- annotations=annotations,
511
- shapes=[
512
- dict(
513
- type="rect",
514
- xref="paper", yref="paper",
515
- x0=0, y0=0, x1=1, y1=1,
516
- line=dict(color="#e0e0e3", width=2),
517
- fillcolor="#f0f0f3",
518
- layer="below"
519
- )
520
- ]
521
- )
522
- fig.add_shape(
523
- type="rect",
524
- xref="paper", yref="paper",
525
- x0=-0.05, y0=-0.05, x1=1.05, y1=1.05,
526
- line=dict(color="rgba(0,0,0,0.1)", width=5),
527
- fillcolor="rgba(0,0,0,0)",
528
- layer="below"
529
  )
530
- fig.update_layout(
531
- updatemenus=[
532
- dict(
533
- type="buttons",
534
- direction="left",
535
- buttons=[
536
- dict(args=[{"visible": [True, True, True]}], label="Mostrar Tudo", method="restyle"),
537
- dict(args=[{"visible": [True, False, False]}], label="Usuários", method="restyle"),
538
- dict(args=[{"visible": [False, True, False]}], label="Domicílios", method="restyle"),
539
- dict(args=[{"visible": [False, False, True]}], label="Famílias", method="restyle")
540
- ],
541
- pad={"r": 10, "t": 10},
542
- showactive=True,
543
- x=0.1,
544
- xanchor="left",
545
- y=1.1,
546
- yanchor="top",
547
- bgcolor="#ffffff",
548
- bordercolor="#e0e0e3",
549
- borderwidth=1,
550
- font=dict(color="#333333"),
551
- ),
552
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
553
  )
554
 
555
- st.plotly_chart(fig, use_container_width=True)
556
-
557
- add_vertical_space(10)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
558
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
559
 
560
  st.write('----')
 
1
  import folium
2
  import geopandas as gpd
3
+ import pandas as pd
4
  import plotly.express as px
5
+ import plotly.graph_objects as go
6
+ import streamlit as st
7
  from branca.colormap import LinearColormap
8
  from folium.plugins import HeatMap
 
 
 
 
9
  from streamlit_extras.add_vertical_space import add_vertical_space
10
+ from streamlit_extras.stylable_container import stylable_container
11
+ from streamlit_folium import folium_static
12
  from streamlit_option_menu import option_menu
 
 
13
 
 
14
  key="banner",
15
  css_styles="""
16
  img {
 
21
  object-fit: cover;
22
  border-radius: 20px; /* Adiciona bordas arredondadas */
23
  mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
24
+ -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0,
25
+ 0)); /* For Safari */
26
  }
27
  """,
28
  ):
29
  st.image("src/Images/mp.jpg")
30
 
 
31
  add_vertical_space(2)
32
  st.markdown(""" ### :world_map: **UBS Flamengo: (IBGE 2022)** """)
33
 
34
+
35
  @st.cache_resource
36
  def load_data():
37
+ """
38
+ A function that loads and reads geojson data for UBS Flamengo and
39
+ converts it to the specified coordinate reference system.
40
  """
41
+ return gpd.read_file("views/flamengo_ibge2022.geojson").to_crs(epsg=4326)
42
+
 
43
 
44
  gdf = load_data()
45
+ LATITUDE = -19.965591804
46
  LONGITUDE = -44.057912815
47
  lat = -19.96214
48
  long = -44.05603
49
 
50
+ total_pop = gdf["População"].sum()
51
+ num_setores = len(gdf)
52
+
53
  col1, col2, col3 = st.columns([1, 1, 5])
54
 
55
  STYLE = "static/style.css"
56
  STYLES = "static/styles.html"
57
  with open(STYLE, "r", encoding="utf-8") as f:
58
+ st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
59
 
60
  with open(STYLES, "r", encoding="utf-8") as f:
61
+ st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
62
 
63
+ with st.expander("Visualização", expanded=True):
64
+ selected_tab = option_menu(
65
+ menu_title=None,
66
+ options=[
67
+ "Mapa IBGE",
68
+ "Equipe Azul",
69
+ "Equipe Vermelha",
70
+ ],
71
+ icons=["person", "geo-alt", "capsule-pill"],
72
+ menu_icon="cast",
73
+ default_index=0,
74
+ orientation="horizontal",
75
+ styles={
76
+ "container": {
77
+ "padding": "5px",
78
+ "background-color": "#1E1E28",
79
+ "border-radius": "8px",
80
+ },
81
+ "icon": {
82
+ "color": "#64B5F6",
83
+ "font-size": "20px",
84
+ "padding-right": "8px",
85
+ },
86
+ "nav-link": {
87
+ "font-size": "16px",
88
+ "text-align": "center",
89
+ "margin": "5px",
90
+ "padding": "12px",
91
+ "background-color": "#2A2B3D",
92
+ "--hover-color": "#4B4B4B",
93
+ "color": "#FFFFFF",
94
+ "border-radius": "4px",
95
+ },
96
+ "nav-link-selected": {
97
+ "background-color": "#007BB5",
98
+ "color": "#FFFFFF",
99
+ "font-weight": "bold",
100
+ },
101
+ "separator": {
102
+ "border-color": "#303030",
103
+ "margin": "0 10px",
104
+ },
105
+ },
106
+ )
107
+ if selected_tab == "Mapa IBGE":
108
+ col1, col2, col3, col4, col5 = st.columns([1.5, 1.5, 0.8, 5, 0.5])
109
+ with col1:
110
+ st.metric(label="👪 População Total",
111
+ value=f"{total_pop:,} habitantes",
112
+ help="Dados do Censo 2022 IBGE")
113
+ map_type = st.selectbox("Tipo de mapa",
114
+ ["População", "Densidade", "Heatmap"])
115
+ with col2:
116
+ st.metric(label="🗺️ Número de Setores Censitários",
117
+ value=f"{num_setores}",
118
+ help="Dados do Censo 2022 IBGE")
119
+ base_map = st.selectbox("Mapa base",
120
+ ["Cartodb Positron", "OpenStreetMap"])
121
+ with col4, st.container(border=False, height=400):
122
+ row1, row2, row3 = st.columns([0.5, 3, 0.9])
123
+ with row1:
124
+ st.write('')
125
+ with row2:
126
+ st.write("""
127
+ ### Definição de Setor Censitário
128
+ É a menor unidade territorial utilizada pelo IBGE para a coleta de dados em censos
129
+ demográficos. Cada setor é delimitado por características físicas e populacionais.
130
+ Geralmente contém entre 250 e 350 domicílios.
131
 
132
+ Fundamentais em pesquisas, elaboração de políticas públicas, planejamento urbano,
133
+ e atividades que dependem de informações demográficas precisas.
134
+
135
+ Permitem uma análise granular da distribuição populacional, socioeconômica e das
136
+ condições de moradia. É fundamental .
137
+ """)
138
+ with row3:
139
+ st.write('')
140
 
141
+ add_vertical_space(3)
 
142
 
143
+ col1, col2 = st.columns(2)
144
+
145
+ with col1:
146
+ m = folium.Map(location=[LATITUDE, LONGITUDE],
147
+ tiles=base_map,
148
+ zoom_start=15)
149
+ dns_p = "Densidade pop. (hab/km²) UBS Flamengo - IBGE 2022"
150
+ if map_type in ["População", "Densidade"]:
151
+ if map_type == "População":
152
+ column = "População"
153
+ caption = "Pop. residente UBS Flamengo IBGE 2022"
154
+ else:
155
+ gdf["DENSIDADE"] = gdf["População"] / gdf["Área em km²"]
156
+ column = "DENSIDADE"
157
+ caption = dns_p
158
+ colorscale = px.colors.sequential.Viridis
159
+ colormap = LinearColormap(
160
+ colors=colorscale,
161
+ vmin=gdf[column].min(),
162
+ vmax=gdf[column].max(),
163
+ caption=caption,
164
+ )
165
+ folium.GeoJson(
166
+ gdf,
167
+ style_function=lambda feature: {
168
+ "fillColor": colormap(feature["properties"][column]),
169
+ "color": "black",
170
+ "weight": 1,
171
+ "fillOpacity": 0.6,
172
+ },
173
+ highlight_function=lambda feature: {
174
+ "fillColor": "#ffaf00",
175
+ "color": "green",
176
+ "weight": 3,
177
+ "fillOpacity": 0.9,
178
+ } if feature else {},
179
+ tooltip=folium.GeoJsonTooltip(
180
+ fields=["Setor", column, "Área em km²"],
181
+ aliases=[
182
+ "Setor Censitário:",
183
+ f"{caption}:",
184
+ "Área (km²):",
185
+ ],
186
+ style=("background-color: white; color: #333333;"
187
+ "font-family: calibri; font-size: 12px;"
188
+ "padding: 10px;"),
189
+ ),
190
+ ).add_to(m)
191
+ colormap.add_to(m)
192
+
193
+ elif map_type == "Heatmap":
194
+ heat_data = [[
195
+ row["geometry"].centroid.y,
196
+ row["geometry"].centroid.x,
197
+ row["População"],
198
+ ] for idx, row in gdf.iterrows()]
199
+ HeatMap(heat_data).add_to(m)
200
+ folium.Marker(
201
+ [lat, long],
202
+ popup="UBS Flamengo",
203
+ tooltip="UBS Flamengo",
204
+ icon=folium.Icon(color="red", icon="info-sign"),
205
+ ).add_to(m)
206
+
207
+ STYLE_STATEMENT = (
208
+ "<style>.leaflet-control-layers"
209
+ "{ position: fixed; top: 10px; left: 50px; } </style>")
210
+
211
+ # folium.LayerControl().add_to(m) # Adding Layer Control is good practice.
212
+ # Display the map
213
+ folium_static(m)
214
+
215
+ # m.get_root().html.add_child(folium.Element(STYLE_STATEMENT))
216
+ # folium_static(m)
217
+ with col2:
218
+ fig = px.bar(
219
+ gdf,
220
+ x="Setor",
221
+ y="População",
222
+ title="Distribuição da População por Setor Censitário",
223
+ color="População",
224
+ color_continuous_scale=px.colors.sequential.Viridis,
225
+ )
226
+ st.plotly_chart(fig)
227
+
228
+ age_columns = [
229
+ "População_0A4",
230
+ "População_5A9",
231
+ "População_10A14",
232
+ "População_15A19",
233
+ "População_20A24",
234
+ "População_25A29",
235
+ "População_30A34",
236
+ "População_35A39",
237
+ "População_40A44",
238
+ "População_45A49",
239
+ "População_50A54",
240
+ "População_55A59",
241
+ "População_60A64",
242
+ "População_65A69",
243
+ "População_70A74",
244
+ "População_75A79",
245
+ "População_80A84",
246
+ "População_85A89",
247
+ "População_90A94",
248
+ "População_95A99",
249
+ "População_100OUMAIS",
250
+ ]
251
+
252
+ fig = px.bar()
253
+
254
+ elif selected_tab == "Equipe Azul":
255
+ st.subheader("Crescimento populacional - UBS Flamengo - Equipe Azul")
256
+
257
+ with stylable_container(
258
+ key="exp1",
259
+ css_styles="""
260
+ img {
261
+ width: 200px;
262
+ height: 200px;
263
+ overflow: hidden;
264
+ position: relative;
265
+ object-fit: cover;
266
+ border-radius: 20px; /* Adiciona bordas arredondadas */
267
+ mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1),
268
+ rgba(0, 0, 0, 0));
269
+ -webkit-mask-image: linear-gradient(to bottom,
270
+ rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); /* For Safari */
271
+ }
272
+ """,
273
+ ):
274
+ st.image("src/Images/blue.png", caption='Equipe Azul')
275
+ # st.image("src/Images/pop.jpg")
276
+
277
+ raw_data = [
278
+ {
279
+ "Mês": "set-21",
280
+ "Usuários": 3755,
281
+ "Domicílios": 1573,
282
+ "Famílias": 1380
283
+ },
284
+ {
285
+ "Mês": "out-21",
286
+ "Usuários": 3776,
287
+ "Domicílios": 1533,
288
+ "Famílias": 1384
289
+ },
290
+ {
291
+ "Mês": "nov-21",
292
+ "Usuários": 3839,
293
+ "Domicílios": 1553,
294
+ "Famílias": 1397
295
+ },
296
+ {
297
+ "Mês": "dez-21",
298
+ "Usuários": 3926,
299
+ "Domicílios": 1581,
300
+ "Famílias": 1423
301
+ },
302
+ {
303
+ "Mês": "jan-22",
304
+ "Usuários": 3951,
305
+ "Domicílios": 1596,
306
+ "Famílias": 1437
307
+ },
308
+ {
309
+ "Mês": "fev-22",
310
+ "Usuários": 4035,
311
+ "Domicílios": 1638,
312
+ "Famílias": 1465
313
+ },
314
+ {
315
+ "Mês": "mar-22",
316
+ "Usuários": 4131,
317
+ "Domicílios": 1672,
318
+ "Famílias": 1500
319
+ },
320
+ {
321
+ "Mês": "abr-22",
322
+ "Usuários": 4306,
323
+ "Domicílios": 1723,
324
+ "Famílias": 1555
325
+ },
326
+ {
327
+ "Mês": "mai-22",
328
+ "Usuários": 4553,
329
+ "Domicílios": 1795,
330
+ "Famílias": 1625
331
+ },
332
+ {
333
+ "Mês": "jun-22",
334
+ "Usuários": 4639,
335
+ "Domicílios": 1817,
336
+ "Famílias": 1653
337
+ },
338
+ {
339
+ "Mês": "jul-22",
340
+ "Usuários": 4719,
341
+ "Domicílios": 1848,
342
+ "Famílias": 1676
343
+ },
344
+ {
345
+ "Mês": "ago-22",
346
+ "Usuários": 4776,
347
+ "Domicílios": 1869,
348
+ "Famílias": 1687
349
+ },
350
+ {
351
+ "Mês": "set-22",
352
+ "Usuários": 4831,
353
+ "Domicílios": 1883,
354
+ "Famílias": 1699
355
+ },
356
+ {
357
+ "Mês": "out-22",
358
+ "Usuários": 4871,
359
+ "Domicílios": 1900,
360
+ "Famílias": 1709
361
+ },
362
+ {
363
+ "Mês": "nov-22",
364
+ "Usuários": 4874,
365
+ "Domicílios": 1906,
366
+ "Famílias": 1708
367
+ },
368
+ {
369
+ "Mês": "dez-22",
370
+ "Usuários": 4920,
371
+ "Domicílios": 1914,
372
+ "Famílias": 1720
373
+ },
374
+ {
375
+ "Mês": "jan-23",
376
+ "Usuários": 5135,
377
+ "Domicílios": 2006,
378
+ "Famílias": 1776
379
+ },
380
+ {
381
+ "Mês": "fev-23",
382
+ "Usuários": 5396,
383
+ "Domicílios": 2084,
384
+ "Famílias": 1848
385
+ },
386
+ {
387
+ "Mês": "mar-23",
388
+ "Usuários": 5544,
389
+ "Domicílios": 2127,
390
+ "Famílias": 1893
391
+ },
392
+ {
393
+ "Mês": "abr-23",
394
+ "Usuários": 5546,
395
+ "Domicílios": 2140,
396
+ "Famílias": 1910
397
+ },
398
+ {
399
+ "Mês": "mai-23",
400
+ "Usuários": 5579,
401
+ "Domicílios": 2164,
402
+ "Famílias": 1920
403
+ },
404
+ {
405
+ "Mês": "jun-23",
406
+ "Usuários": 5642,
407
+ "Domicílios": 2181,
408
+ "Famílias": 1946
409
+ },
410
+ {
411
+ "Mês": "jul-23",
412
+ "Usuários": 5680,
413
+ "Domicílios": 2200,
414
+ "Famílias": 1961
415
+ },
416
+ {
417
+ "Mês": "ago-23",
418
+ "Usuários": 5727,
419
+ "Domicílios": 2208,
420
+ "Famílias": 1972
421
+ },
422
+ {
423
+ "Mês": "set-23",
424
+ "Usuários": 5772,
425
+ "Domicílios": 2228,
426
+ "Famílias": 1983
427
+ },
428
+ {
429
+ "Mês": "out-23",
430
+ "Usuários": 5839,
431
+ "Domicílios": 2245,
432
+ "Famílias": 2007
433
+ },
434
+ {
435
+ "Mês": "nov-23",
436
+ "Usuários": 5889,
437
+ "Domicílios": 2297,
438
+ "Famílias": 2027
439
+ },
440
+ {
441
+ "Mês": "dez-23",
442
+ "Usuários": 5932,
443
+ "Domicílios": 2281,
444
+ "Famílias": 2036
445
+ },
446
+ {
447
+ "Mês": "jan-24",
448
+ "Usuários": 5980,
449
+ "Domicílios": 2307,
450
+ "Famílias": 2050
451
+ },
452
+ {
453
+ "Mês": "fev-24",
454
+ "Usuários": 6003,
455
+ "Domicílios": 2333,
456
+ "Famílias": 2057
457
+ },
458
+ {
459
+ "Mês": "mar-24",
460
+ "Usuários": 6018,
461
+ "Domicílios": 2327,
462
+ "Famílias": 2070
463
+ },
464
+ {
465
+ "Mês": "abr-24",
466
+ "Usuários": 6072,
467
+ "Domicílios": 2370,
468
+ "Famílias": 2095
469
+ },
470
+ {
471
+ "Mês": "mai-24",
472
+ "Usuários": 6080,
473
+ "Domicílios": 2357,
474
+ "Famílias": 2097
475
+ },
476
+ {
477
+ "Mês": "jun-24",
478
+ "Usuários": 6112,
479
+ "Domicílios": 2372,
480
+ "Famílias": 2108
481
+ },
482
+ {
483
+ "Mês": "jul-24",
484
+ "Usuários": 6130,
485
+ "Domicílios": 2413,
486
+ "Famílias": 2110
487
+ },
488
+ {
489
+ "Mês": "ago-24",
490
+ "Usuários": 6169,
491
+ "Domicílios": 2397,
492
+ "Famílias": 2118
493
+ },
494
+ ]
495
+
496
+ df = pd.DataFrame(raw_data)
497
+
498
+ @st.cache_data
499
+ def processar_dados(dados, intervalo):
500
+ """
501
+ Process data based on the specified interval and return the aggregated data.
502
+ Parameters:
503
+ - dados: List of dictionaries containing data for each month.
504
+ - intervalo: String indicating the interval for data aggregation.
505
+
506
+ Returns:
507
+ - List of dictionaries with aggregated data based on the specified interval.
508
+ """
509
+ if intervalo == "Mensal":
510
+ return dados
511
+ agrupamentos = {"Trimestral": 3, "Semestral": 6, "Anual": 12}
512
+ dados_agrupados = []
513
+ for i in range(0, len(dados), agrupamentos[intervalo]):
514
+ grupo = dados[i:i + agrupamentos[intervalo]]
515
+ ultimo_Mês = grupo[-1]["Mês"]
516
+ dados_agrupados.append({
517
+ "Mês":
518
+ ultimo_Mês,
519
+ "Usuários":
520
+ max(d["Usuários"] for d in grupo),
521
+ "Domicílios":
522
+ max(d["Domicílios"] for d in grupo),
523
+ "Famílias":
524
+ max(d["Famílias"] for d in grupo),
525
+ })
526
+ return dados_agrupados
527
+
528
+ @st.cache_data
529
+ def formatar_data(Mês):
530
+ """
531
+ A function that formats the data based on the input Mês parameter.
532
+ Parameters:
533
+ - Mês (str): A string containing the month and year separated by a hyphen.
534
+ Returns:
535
+ - str: A formatted string in the format "month/year".
536
+ """
537
+ m, a = Mês.split("-")
538
+ return f"{m}/{a}"
539
+
540
+ # Adicionando estilo personalizado
541
+ st.markdown(
542
+ """
543
+ <style>
544
+ .stSelectbox [data-baseweb="select"] {
545
+ max-width: 300px;
546
+ }
547
+ .st-emotion-cache-16idsys p {
548
+ font-size: 20px;
549
+ font-weight: bold;
550
+ color: #4FCBFC;
551
+ }
552
+ </style>
553
+ """,
554
+ unsafe_allow_html=True,
555
+ )
556
+
557
+ # Criando duas colunas para os menus de opções
558
+ col1, col2, col3 = st.columns([3, 2, 2])
559
+
560
+ with col1:
561
+ st.dataframe(df, use_container_width=True, height=250, hide_index=True)
562
+
563
+ with col2:
564
+ intervalo = option_menu(
565
+ "Intervalo de Tempo",
566
+ ["Mensal", "Trimestral", "Semestral", "Anual"],
567
+ icons=[
568
+ "calendar-month", "calendar-quarter", "calendar-half",
569
+ "calendar-year"
570
+ ],
571
+ menu_icon="cast",
572
+ default_index=0,
573
+ styles={
574
+ "container": {
575
+ "padding": "0!important",
576
+ "background-color": "#f0f0f3",
577
+ "border-radius": "15px",
578
+ "box-shadow":
579
+ "5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff"
580
+ },
581
+ "icon": {
582
+ "color": "#007bff",
583
+ "font-size": "18px"
584
+ },
585
+ "nav-link": {
586
+ "font-size": "14px",
587
+ "text-align": "center",
588
+ "margin": "5px",
589
+ "padding": "10px",
590
+ "--hover-color": "#e6e6e9",
591
+ "color": "#333333",
592
+ "border-radius": "10px",
593
+ "transition": "all 0.3s ease",
594
+ },
595
+ "nav-link-selected": {
596
+ "background-color":
597
+ "#ffffff",
598
+ "box-shadow":
599
+ "inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff"
600
+ },
601
+ "separator": {
602
+ "border-color": "#e0e0e3"
603
+ },
604
+ },
605
+ )
606
+
607
+ with col3:
608
+ metrica = option_menu(
609
+ "Métrica",
610
+ ["Todos", "Usuários", "Domicílios", "Famílias"],
611
+ icons=["list", "person", "house", "people"],
612
+ menu_icon="cast",
613
+ default_index=0,
614
+ styles={
615
  "container": {
616
+ "padding": "0!important",
617
+ "background-color": "#f0f0f3",
618
+ "border-radius": "15px",
619
+ "box-shadow":
620
+ "5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff"
621
  },
622
  "icon": {
623
+ "color": "#007bff",
624
+ "font-size": "18px"
 
625
  },
626
  "nav-link": {
627
+ "font-size": "14px",
628
  "text-align": "center",
629
  "margin": "5px",
630
+ "padding": "10px",
631
+ "--hover-color": "#e6e6e9",
632
+ "color": "#333333",
633
+ "border-radius": "10px",
634
+ "transition": "all 0.3s ease",
635
  },
636
  "nav-link-selected": {
637
+ "background-color":
638
+ "#ffffff",
639
+ "box-shadow":
640
+ "inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff"
641
  },
642
  "separator": {
643
+ "border-color": "#e0e0e3"
644
+ },
 
645
  },
646
+ )
647
+
648
+ dados_processados = processar_dados(raw_data, intervalo)
649
+
650
+ # Criação do gráfico
651
+ fig = go.Figure()
652
+
653
+ metricas = ["Usuários", "Domicílios", "Famílias"
654
+ ] if metrica == "Todos" else [metrica]
655
+ cores = {
656
+ "Usuários": "#007bff",
657
+ "Domicílios": "#28a745",
658
+ "Famílias": "#ffc107"
659
+ }
660
+
661
+ annotations = []
662
+ for m in metricas:
663
+ x_data = [formatar_data(d["Mês"]) for d in dados_processados]
664
+ y_data = [d[m] for d in dados_processados]
665
+
666
+ fig.add_trace(
667
+ go.Scatter(
668
+ x=x_data,
669
+ y=y_data,
670
+ mode="lines+markers",
671
+ name=m,
672
+ line={
673
+ "color": cores[m],
674
+ "width": 3
675
+ },
676
+ marker={
677
+ "size": 12,
678
+ "symbol": "circle",
679
+ "line": {
680
+ "width": 2,
681
+ "color": "white"
682
+ }
683
+ },
684
+ ))
685
+ fig.update_layout(
686
+ hoverlabel={
687
+ "bgcolor": "white",
688
+ "font_size": 16,
689
+ "font_family": "Arial",
690
+ },
691
+ hovermode="x unified",
692
+ )
693
+ fig.update_traces(hovertemplate="<b>%{y}</b><br>%{x}<extra></extra>")
694
+ st.plotly_chart(fig, use_container_width=True)
695
+
696
+ elif selected_tab == "Equipe Vermelha":
697
+ st.subheader("Crescimento populacional - UBS Flamengo - Equipe Vermelha")
698
+
699
+ with stylable_container(
700
+ key="exp1",
701
+ css_styles="""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
702
  img {
703
+ width: 200px;
704
+ height: 200px;
705
  overflow: hidden;
706
  position: relative;
707
  object-fit: cover;
708
  border-radius: 20px; /* Adiciona bordas arredondadas */
709
+ mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1),
710
+ rgba(0, 0, 0, 0));
711
+ -webkit-mask-image: linear-gradient(to bottom,
712
+ rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); /* For Safari */
713
  }
714
  """,
715
+ ):
716
+ st.image("src/Images/red.png", caption='Equipe Vermelha')
717
+ # st.image("src/Images/pop.jpg")
718
+
719
+ raw_red = [{
720
+ "Mês": "set-21",
721
+ "Usuários": 3542,
722
+ "Domicílios": 1243,
723
+ "Famílias": 1191
724
+ }, {
725
+ "Mês": "out-21",
726
+ "Usuários": 3647,
727
+ "Domicílios": 1240,
728
+ "Famílias": 1204
729
+ }, {
730
+ "Mês": "nov-21",
731
+ "Usuários": 3730,
732
+ "Domicílios": 1267,
733
+ "Famílias": 1227
734
+ }, {
735
+ "Mês": "dez-21",
736
+ "Usuários": 3847,
737
+ "Domicílios": 1307,
738
+ "Famílias": 1267
739
+ }, {
740
+ "Mês": "jan-22",
741
+ "Usuários": 3895,
742
+ "Domicílios": 1328,
743
+ "Famílias": 1284
744
+ }, {
745
+ "Mês": "fev-22",
746
+ "Usuários": 3937,
747
+ "Domicílios": 1342,
748
+ "Famílias": 1297
749
+ }, {
750
+ "Mês": "mar-22",
751
+ "Usuários": 4082,
752
+ "Domicílios": 1393,
753
+ "Famílias": 1348
754
+ }, {
755
+ "Mês": "abr-22",
756
+ "Usuários": 4248,
757
+ "Domicílios": 1434,
758
+ "Famílias": 1375
759
+ }, {
760
+ "Mês": "mai-22",
761
+ "Usuários": 4440,
762
+ "Domicílios": 1509,
763
+ "Famílias": 1442
764
+ }, {
765
+ "Mês": "jun-22",
766
+ "Usuários": 4646,
767
+ "Domicílios": 1575,
768
+ "Famílias": 1499
769
+ }, {
770
+ "Mês": "jul-22",
771
+ "Usuários": 4783,
772
+ "Domicílios": 1616,
773
+ "Famílias": 1539
774
+ }, {
775
+ "Mês": "ago-22",
776
+ "Usuários": 4909,
777
+ "Domicílios": 1670,
778
+ "Famílias": 1567
779
+ }, {
780
+ "Mês": "set-22",
781
+ "Usuários": 5008,
782
+ "Domicílios": 1720,
783
+ "Famílias": 1609
784
+ }, {
785
+ "Mês": "out-22",
786
+ "Usuários": 5017,
787
+ "Domicílios": 1721,
788
+ "Famílias": 1610
789
+ }, {
790
+ "Mês": "nov-22",
791
+ "Usuários": 5037,
792
+ "Domicílios": 1742,
793
+ "Famílias": 1613
794
+ }, {
795
+ "Mês": "dez-22",
796
+ "Usuários": 5060,
797
+ "Domicílios": 1742,
798
+ "Famílias": 1615
799
+ }, {
800
+ "Mês": "jan-23",
801
+ "Usuários": 5107,
802
+ "Domicílios": 1708,
803
+ "Famílias": 1563
804
+ }, {
805
+ "Mês": "fev-23",
806
+ "Usuários": 5127,
807
+ "Domicílios": 1631,
808
+ "Famílias": 1496
809
+ }, {
810
+ "Mês": "mar-23",
811
+ "Usuários": 5262,
812
+ "Domicílios": 1667,
813
+ "Famílias": 1533
814
+ }, {
815
+ "Mês": "abr-23",
816
+ "Usuários": 5279,
817
+ "Domicílios": 1682,
818
+ "Famílias": 1545
819
+ }, {
820
+ "Mês": "mai-23",
821
+ "Usuários": 5361,
822
+ "Domicílios": 1719,
823
+ "Famílias": 1575
824
+ }, {
825
+ "Mês": "jun-23",
826
+ "Usuários": 5381,
827
+ "Domicílios": 1728,
828
+ "Famílias": 1591
829
+ }, {
830
+ "Mês": "jul-23",
831
+ "Usuários": 5429,
832
+ "Domicílios": 1766,
833
+ "Famílias": 1609
834
+ }, {
835
+ "Mês": "ago-23",
836
+ "Usuários": 5417,
837
+ "Domicílios": 1743,
838
+ "Famílias": 1618
839
+ }, {
840
+ "Mês": "set-23",
841
+ "Usuários": 5447,
842
+ "Domicílios": 1748,
843
+ "Famílias": 1632
844
+ }, {
845
+ "Mês": "out-23",
846
+ "Usuários": 5495,
847
+ "Domicílios": 1772,
848
+ "Famílias": 1646
849
+ }, {
850
+ "Mês": "nov-23",
851
+ "Usuários": 5496,
852
+ "Domicílios": 1775,
853
+ "Famílias": 1650
854
+ }, {
855
+ "Mês": "dez-23",
856
+ "Usuários": 5519,
857
+ "Domicílios": 1767,
858
+ "Famílias": 1657
859
+ }, {
860
+ "Mês": "jan-24",
861
+ "Usuários": 5560,
862
+ "Domicílios": 1793,
863
+ "Famílias": 1673
864
+ }, {
865
+ "Mês": "fev-24",
866
+ "Usuários": 5574,
867
+ "Domicílios": 1795,
868
+ "Famílias": 1679
869
+ }, {
870
+ "Mês": "mar-24",
871
+ "Usuários": 5576,
872
+ "Domicílios": 1789,
873
+ "Famílias": 1676
874
+ }, {
875
+ "Mês": "abr-24",
876
+ "Usuários": 5624,
877
+ "Domicílios": 1824,
878
+ "Famílias": 1696
879
+ }, {
880
+ "Mês": "mai-24",
881
+ "Usuários": 5699,
882
+ "Domicílios": 1827,
883
+ "Famílias": 1713
884
+ }, {
885
+ "Mês": "jun-24",
886
+ "Usuários": 5739,
887
+ "Domicílios": 1843,
888
+ "Famílias": 1733
889
+ }, {
890
+ "Mês": "jul-24",
891
+ "Usuários": 5739,
892
+ "Domicílios": 1877,
893
+ "Famílias": 1742
894
+ }, {
895
+ "Mês": "ago-24",
896
+ "Usuários": 5760,
897
+ "Domicílios": 1881,
898
+ "Famílias": 1757
899
+ }]
900
+
901
+ df = pd.DataFrame(raw_red)
902
+
903
+ @st.cache_data
904
+ def processar_dados(dados, intervalo):
905
+ """
906
+ Process data based on the specified interval and return the aggregated data.
907
+ Parameters:
908
+ - dados: List of dictionaries containing data for each month.
909
+ - intervalo: String indicating the interval for data aggregation.
910
+
911
+ Returns:
912
+ - List of dictionaries with aggregated data based on the specified interval.
913
+ """
914
+ if intervalo == "Mensal":
915
+ return dados
916
+ agrupamentos = {"Trimestral": 3, "Semestral": 6, "Anual": 12}
917
+ dados_agrupados = []
918
+ for i in range(0, len(dados), agrupamentos[intervalo]):
919
+ grupo = dados[i:i + agrupamentos[intervalo]]
920
+ ultimo_Mês = grupo[-1]["Mês"]
921
+ dados_agrupados.append({
922
+ "Mês":
923
+ ultimo_Mês,
924
+ "Usuários":
925
+ max(d["Usuários"] for d in grupo),
926
+ "Domicílios":
927
+ max(d["Domicílios"] for d in grupo),
928
+ "Famílias":
929
+ max(d["Famílias"] for d in grupo),
930
+ })
931
+ return dados_agrupados
932
+
933
+ @st.cache_data
934
+ def formatar_data(Mês):
935
+ """
936
+ A function that formats the data based on the input Mês parameter.
937
+
938
+ Parameters:
939
+ - Mês (str): A string containing the month and year separated by a hyphen.
940
+
941
+ Returns:
942
+ - str: A formatted string in the format "month/year".
943
+ """
944
+ m, a = Mês.split("-")
945
+ return f"{m}/{a}"
946
+
947
+ # Adicionando estilo personalizado
948
+ st.markdown(
949
+ """
950
  <style>
951
  .stSelectbox [data-baseweb="select"] {
952
  max-width: 300px;
 
958
  }
959
  </style>
960
  """,
961
+ unsafe_allow_html=True,
962
+ )
963
+
964
+ # Criando duas colunas para os menus de opções
965
+ col1, col2, col3 = st.columns([3, 2, 2])
966
+
967
+ with col1:
968
+ st.dataframe(df, use_container_width=True, height=250, hide_index=True)
969
+
970
+ with col2:
971
+ intervalo = option_menu(
972
+ "Intervalo de Tempo",
973
+ ["Mensal", "Trimestral", "Semestral", "Anual"],
974
+ icons=[
975
+ "calendar-month", "calendar-quarter", "calendar-half",
976
+ "calendar-year"
977
+ ],
978
+ menu_icon="cast",
979
+ default_index=0,
980
+ styles={
981
+ "container": {
982
+ "padding": "0!important",
983
+ "background-color": "#f0f0f3",
984
+ "border-radius": "15px",
985
+ "box-shadow":
986
+ "5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff"
987
+ },
988
+ "icon": {
989
+ "color": "#007bff",
990
+ "font-size": "18px"
991
+ },
992
+ "nav-link": {
993
+ "font-size": "14px",
994
+ "text-align": "center",
995
+ "margin": "5px",
996
+ "padding": "10px",
997
+ "--hover-color": "#e6e6e9",
998
+ "color": "#333333",
999
+ "border-radius": "10px",
1000
+ "transition": "all 0.3s ease",
1001
+ },
1002
+ "nav-link-selected": {
1003
+ "background-color":
1004
+ "#ffffff",
1005
+ "box-shadow":
1006
+ "inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1007
  },
1008
+ "separator": {
1009
+ "border-color": "#e0e0e3"
1010
+ },
1011
+ },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1012
  )
1013
+
1014
+ with col3:
1015
+ metrica = option_menu(
1016
+ "Métrica",
1017
+ ["Todos", "Usuários", "Domicílios", "Famílias"],
1018
+ icons=["list", "person", "house", "people"],
1019
+ menu_icon="cast",
1020
+ default_index=0,
1021
+ styles={
1022
+ "container": {
1023
+ "padding": "0!important",
1024
+ "background-color": "#f0f0f3",
1025
+ "border-radius": "15px",
1026
+ "box-shadow":
1027
+ "5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff"
1028
+ },
1029
+ "icon": {
1030
+ "color": "#007bff",
1031
+ "font-size": "18px"
1032
+ },
1033
+ "nav-link": {
1034
+ "font-size": "14px",
1035
+ "text-align": "center",
1036
+ "margin": "5px",
1037
+ "padding": "10px",
1038
+ "--hover-color": "#e6e6e9",
1039
+ "color": "#333333",
1040
+ "border-radius": "10px",
1041
+ "transition": "all 0.3s ease",
1042
+ },
1043
+ "nav-link-selected": {
1044
+ "background-color":
1045
+ "#ffffff",
1046
+ "box-shadow":
1047
+ "inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff"
1048
+ },
1049
+ "separator": {
1050
+ "border-color": "#e0e0e3"
1051
+ },
1052
+ },
1053
  )
1054
 
1055
+ dados_processados = processar_dados(raw_red, intervalo)
1056
+
1057
+ # Criação do gráfico
1058
+ fig = go.Figure()
1059
+
1060
+ metricas = ["Usuários", "Domicílios", "Famílias"
1061
+ ] if metrica == "Todos" else [metrica]
1062
+ cores = {
1063
+ "Usuários": "#007bff",
1064
+ "Domicílios": "#28a745",
1065
+ "Famílias": "#ffc107"
1066
+ }
1067
+
1068
+ annotations = []
1069
+ for m in metricas:
1070
+ x_data = [formatar_data(d["Mês"]) for d in dados_processados]
1071
+ y_data = [d[m] for d in dados_processados]
1072
 
1073
+ fig.add_trace(
1074
+ go.Scatter(
1075
+ x=x_data,
1076
+ y=y_data,
1077
+ mode="lines+markers",
1078
+ name=m,
1079
+ line={
1080
+ "color": cores[m],
1081
+ "width": 3
1082
+ },
1083
+ marker={
1084
+ "size": 12,
1085
+ "symbol": "circle",
1086
+ "line": {
1087
+ "width": 2,
1088
+ "color": "white"
1089
+ }
1090
+ },
1091
+ ))
1092
+ fig.update_layout(
1093
+ hoverlabel={
1094
+ "bgcolor": "white",
1095
+ "font_size": 16,
1096
+ "font_family": "Arial",
1097
+ },
1098
+ hovermode="x unified",
1099
+ )
1100
+ fig.update_traces(hovertemplate="<b>%{y}</b><br>%{x}<extra></extra>")
1101
+ st.plotly_chart(fig, use_container_width=True)
1102
+
1103
+ add_vertical_space(10)
1104
 
1105
  st.write('----')