Spaces:
Running
Running
import folium | |
import geopandas as gpd | |
import pandas as pd | |
import plotly.express as px | |
import plotly.graph_objects as go | |
import streamlit as st | |
from branca.colormap import LinearColormap | |
from folium.plugins import HeatMap | |
from streamlit_extras.add_vertical_space import add_vertical_space | |
from streamlit_extras.stylable_container import stylable_container | |
from streamlit_folium import folium_static | |
from streamlit_option_menu import option_menu | |
with stylable_container( | |
key="banner", | |
css_styles=""" | |
img { | |
width: 1800px; | |
height: 250px; | |
overflow: hidden; | |
position: relative; | |
object-fit: cover; | |
border-radius: 20px; /* Adiciona bordas arredondadas */ | |
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); | |
-webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, | |
0)); /* For Safari */ | |
} | |
""", | |
): | |
st.image("src/Images/mp.jpg") | |
add_vertical_space(2) | |
st.markdown(""" ### :world_map: **UBS Flamengo: (IBGE 2022)** """) | |
def load_data(): | |
""" | |
A function that loads and reads geojson data for UBS Flamengo and | |
converts it to the specified coordinate reference system. | |
""" | |
return gpd.read_file("views/flamengo_ibge2022.geojson").to_crs(epsg=4326) | |
gdf = load_data() | |
LATITUDE = -19.965591804 | |
LONGITUDE = -44.057912815 | |
lat = -19.96214 | |
long = -44.05603 | |
total_pop = gdf["População"].sum() | |
num_setores = len(gdf) | |
col1, col2, col3 = st.columns([1, 1, 5]) | |
STYLE = "static/style.css" | |
STYLES = "static/styles.html" | |
with open(STYLE, "r", encoding="utf-8") as f: | |
st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True) | |
with open(STYLES, "r", encoding="utf-8") as f: | |
st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True) | |
with st.expander("Visualização", expanded=True): | |
selected_tab = option_menu( | |
menu_title=None, | |
options=[ | |
"Mapa IBGE", | |
"Equipe Azul", | |
"Equipe Vermelha", | |
], | |
icons=["person", "geo-alt", "capsule-pill"], | |
menu_icon="cast", | |
default_index=0, | |
orientation="horizontal", | |
styles={ | |
"container": { | |
"padding": "5px", | |
"background-color": "#1E1E28", | |
"border-radius": "8px", | |
}, | |
"icon": { | |
"color": "#64B5F6", | |
"font-size": "20px", | |
"padding-right": "8px", | |
}, | |
"nav-link": { | |
"font-size": "16px", | |
"text-align": "center", | |
"margin": "5px", | |
"padding": "12px", | |
"background-color": "#2A2B3D", | |
"--hover-color": "#4B4B4B", | |
"color": "#FFFFFF", | |
"border-radius": "4px", | |
}, | |
"nav-link-selected": { | |
"background-color": "#007BB5", | |
"color": "#FFFFFF", | |
"font-weight": "bold", | |
}, | |
"separator": { | |
"border-color": "#303030", | |
"margin": "0 10px", | |
}, | |
}, | |
) | |
if selected_tab == "Mapa IBGE": | |
col1, col2, col3, col4, col5 = st.columns([1.5, 1.5, 0.8, 5, 0.5]) | |
with col1: | |
st.metric(label="👪 População Total", | |
value=f"{total_pop:,} habitantes", | |
help="Dados do Censo 2022 IBGE") | |
map_type = st.selectbox("Tipo de mapa", | |
["População", "Densidade", "Heatmap"]) | |
with col2: | |
st.metric(label="🗺️ Número de Setores Censitários", | |
value=f"{num_setores}", | |
help="Dados do Censo 2022 IBGE") | |
base_map = st.selectbox("Mapa base", | |
["Cartodb Positron", "OpenStreetMap"]) | |
with col4, st.container(border=False, height=400): | |
row1, row2, row3 = st.columns([0.5, 3, 0.9]) | |
with row1: | |
st.write('') | |
with row2: | |
st.write(""" | |
### Definição de Setor Censitário | |
É a menor unidade territorial utilizada pelo IBGE para a coleta de dados em censos | |
demográficos. Cada setor é delimitado por características físicas e populacionais. | |
Geralmente contém entre 250 e 350 domicílios. | |
Fundamentais em pesquisas, elaboração de políticas públicas, planejamento urbano, | |
e atividades que dependem de informações demográficas precisas. | |
Permitem uma análise granular da distribuição populacional, socioeconômica e das | |
condições de moradia. É fundamental . | |
""") | |
with row3: | |
st.write('') | |
add_vertical_space(3) | |
col1, col2 = st.columns(2) | |
with col1: | |
m = folium.Map(location=[LATITUDE, LONGITUDE], | |
tiles=base_map, | |
zoom_start=15) | |
dns_p = "Densidade pop. (hab/km²) UBS Flamengo - IBGE 2022" | |
if map_type in ["População", "Densidade"]: | |
if map_type == "População": | |
column = "População" | |
caption = "Pop. residente UBS Flamengo IBGE 2022" | |
else: | |
gdf["DENSIDADE"] = gdf["População"] / gdf["Área em km²"] | |
column = "DENSIDADE" | |
caption = dns_p | |
colorscale = px.colors.sequential.Viridis | |
colormap = LinearColormap( | |
colors=colorscale, | |
vmin=gdf[column].min(), | |
vmax=gdf[column].max(), | |
caption=caption, | |
) | |
folium.GeoJson( | |
gdf, | |
style_function=lambda feature: { | |
"fillColor": colormap(feature["properties"][column]), | |
"color": "black", | |
"weight": 1, | |
"fillOpacity": 0.6, | |
}, | |
highlight_function=lambda feature: { | |
"fillColor": "#ffaf00", | |
"color": "green", | |
"weight": 3, | |
"fillOpacity": 0.9, | |
} if feature else {}, | |
tooltip=folium.GeoJsonTooltip( | |
fields=["Setor", column, "Área em km²"], | |
aliases=[ | |
"Setor Censitário:", | |
f"{caption}:", | |
"Área (km²):", | |
], | |
style=("background-color: white; color: #333333;" | |
"font-family: calibri; font-size: 12px;" | |
"padding: 10px;"), | |
), | |
).add_to(m) | |
colormap.add_to(m) | |
elif map_type == "Heatmap": | |
heat_data = [[ | |
row["geometry"].centroid.y, | |
row["geometry"].centroid.x, | |
row["População"], | |
] for idx, row in gdf.iterrows()] | |
HeatMap(heat_data).add_to(m) | |
folium.Marker( | |
[lat, long], | |
popup="UBS Flamengo", | |
tooltip="UBS Flamengo", | |
icon=folium.Icon(color="red", icon="info-sign"), | |
).add_to(m) | |
STYLE_STATEMENT = ( | |
"<style>.leaflet-control-layers" | |
"{ position: fixed; top: 10px; left: 50px; } </style>") | |
# folium.LayerControl().add_to(m) # Adding Layer Control is good practice. | |
# Display the map | |
folium_static(m) | |
# m.get_root().html.add_child(folium.Element(STYLE_STATEMENT)) | |
# folium_static(m) | |
with col2: | |
fig = px.bar( | |
gdf, | |
x="Setor", | |
y="População", | |
title="Distribuição da População por Setor Censitário", | |
color="População", | |
color_continuous_scale=px.colors.sequential.Viridis, | |
) | |
st.plotly_chart(fig) | |
age_columns = [ | |
"População_0A4", | |
"População_5A9", | |
"População_10A14", | |
"População_15A19", | |
"População_20A24", | |
"População_25A29", | |
"População_30A34", | |
"População_35A39", | |
"População_40A44", | |
"População_45A49", | |
"População_50A54", | |
"População_55A59", | |
"População_60A64", | |
"População_65A69", | |
"População_70A74", | |
"População_75A79", | |
"População_80A84", | |
"População_85A89", | |
"População_90A94", | |
"População_95A99", | |
"População_100OUMAIS", | |
] | |
fig = px.bar() | |
elif selected_tab == "Equipe Azul": | |
st.subheader("Crescimento populacional - UBS Flamengo - Equipe Azul") | |
with stylable_container( | |
key="exp1", | |
css_styles=""" | |
img { | |
width: 200px; | |
height: 200px; | |
overflow: hidden; | |
position: relative; | |
object-fit: cover; | |
border-radius: 20px; /* Adiciona bordas arredondadas */ | |
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), | |
rgba(0, 0, 0, 0)); | |
-webkit-mask-image: linear-gradient(to bottom, | |
rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); /* For Safari */ | |
} | |
""", | |
): | |
st.image("src/Images/blue.png", caption='Equipe Azul') | |
# st.image("src/Images/pop.jpg") | |
raw_data = [ | |
{ | |
"Mês": "set-21", | |
"Usuários": 3755, | |
"Domicílios": 1573, | |
"Famílias": 1380 | |
}, | |
{ | |
"Mês": "out-21", | |
"Usuários": 3776, | |
"Domicílios": 1533, | |
"Famílias": 1384 | |
}, | |
{ | |
"Mês": "nov-21", | |
"Usuários": 3839, | |
"Domicílios": 1553, | |
"Famílias": 1397 | |
}, | |
{ | |
"Mês": "dez-21", | |
"Usuários": 3926, | |
"Domicílios": 1581, | |
"Famílias": 1423 | |
}, | |
{ | |
"Mês": "jan-22", | |
"Usuários": 3951, | |
"Domicílios": 1596, | |
"Famílias": 1437 | |
}, | |
{ | |
"Mês": "fev-22", | |
"Usuários": 4035, | |
"Domicílios": 1638, | |
"Famílias": 1465 | |
}, | |
{ | |
"Mês": "mar-22", | |
"Usuários": 4131, | |
"Domicílios": 1672, | |
"Famílias": 1500 | |
}, | |
{ | |
"Mês": "abr-22", | |
"Usuários": 4306, | |
"Domicílios": 1723, | |
"Famílias": 1555 | |
}, | |
{ | |
"Mês": "mai-22", | |
"Usuários": 4553, | |
"Domicílios": 1795, | |
"Famílias": 1625 | |
}, | |
{ | |
"Mês": "jun-22", | |
"Usuários": 4639, | |
"Domicílios": 1817, | |
"Famílias": 1653 | |
}, | |
{ | |
"Mês": "jul-22", | |
"Usuários": 4719, | |
"Domicílios": 1848, | |
"Famílias": 1676 | |
}, | |
{ | |
"Mês": "ago-22", | |
"Usuários": 4776, | |
"Domicílios": 1869, | |
"Famílias": 1687 | |
}, | |
{ | |
"Mês": "set-22", | |
"Usuários": 4831, | |
"Domicílios": 1883, | |
"Famílias": 1699 | |
}, | |
{ | |
"Mês": "out-22", | |
"Usuários": 4871, | |
"Domicílios": 1900, | |
"Famílias": 1709 | |
}, | |
{ | |
"Mês": "nov-22", | |
"Usuários": 4874, | |
"Domicílios": 1906, | |
"Famílias": 1708 | |
}, | |
{ | |
"Mês": "dez-22", | |
"Usuários": 4920, | |
"Domicílios": 1914, | |
"Famílias": 1720 | |
}, | |
{ | |
"Mês": "jan-23", | |
"Usuários": 5135, | |
"Domicílios": 2006, | |
"Famílias": 1776 | |
}, | |
{ | |
"Mês": "fev-23", | |
"Usuários": 5396, | |
"Domicílios": 2084, | |
"Famílias": 1848 | |
}, | |
{ | |
"Mês": "mar-23", | |
"Usuários": 5544, | |
"Domicílios": 2127, | |
"Famílias": 1893 | |
}, | |
{ | |
"Mês": "abr-23", | |
"Usuários": 5546, | |
"Domicílios": 2140, | |
"Famílias": 1910 | |
}, | |
{ | |
"Mês": "mai-23", | |
"Usuários": 5579, | |
"Domicílios": 2164, | |
"Famílias": 1920 | |
}, | |
{ | |
"Mês": "jun-23", | |
"Usuários": 5642, | |
"Domicílios": 2181, | |
"Famílias": 1946 | |
}, | |
{ | |
"Mês": "jul-23", | |
"Usuários": 5680, | |
"Domicílios": 2200, | |
"Famílias": 1961 | |
}, | |
{ | |
"Mês": "ago-23", | |
"Usuários": 5727, | |
"Domicílios": 2208, | |
"Famílias": 1972 | |
}, | |
{ | |
"Mês": "set-23", | |
"Usuários": 5772, | |
"Domicílios": 2228, | |
"Famílias": 1983 | |
}, | |
{ | |
"Mês": "out-23", | |
"Usuários": 5839, | |
"Domicílios": 2245, | |
"Famílias": 2007 | |
}, | |
{ | |
"Mês": "nov-23", | |
"Usuários": 5889, | |
"Domicílios": 2297, | |
"Famílias": 2027 | |
}, | |
{ | |
"Mês": "dez-23", | |
"Usuários": 5932, | |
"Domicílios": 2281, | |
"Famílias": 2036 | |
}, | |
{ | |
"Mês": "jan-24", | |
"Usuários": 5980, | |
"Domicílios": 2307, | |
"Famílias": 2050 | |
}, | |
{ | |
"Mês": "fev-24", | |
"Usuários": 6003, | |
"Domicílios": 2333, | |
"Famílias": 2057 | |
}, | |
{ | |
"Mês": "mar-24", | |
"Usuários": 6018, | |
"Domicílios": 2327, | |
"Famílias": 2070 | |
}, | |
{ | |
"Mês": "abr-24", | |
"Usuários": 6072, | |
"Domicílios": 2370, | |
"Famílias": 2095 | |
}, | |
{ | |
"Mês": "mai-24", | |
"Usuários": 6080, | |
"Domicílios": 2357, | |
"Famílias": 2097 | |
}, | |
{ | |
"Mês": "jun-24", | |
"Usuários": 6112, | |
"Domicílios": 2372, | |
"Famílias": 2108 | |
}, | |
{ | |
"Mês": "jul-24", | |
"Usuários": 6130, | |
"Domicílios": 2413, | |
"Famílias": 2110 | |
}, | |
{ | |
"Mês": "ago-24", | |
"Usuários": 6169, | |
"Domicílios": 2397, | |
"Famílias": 2118 | |
}, | |
] | |
df = pd.DataFrame(raw_data) | |
def processar_dados(dados, intervalo): | |
""" | |
Process data based on the specified interval and return the aggregated data. | |
Parameters: | |
- dados: List of dictionaries containing data for each month. | |
- intervalo: String indicating the interval for data aggregation. | |
Returns: | |
- List of dictionaries with aggregated data based on the specified interval. | |
""" | |
if intervalo == "Mensal": | |
return dados | |
agrupamentos = {"Trimestral": 3, "Semestral": 6, "Anual": 12} | |
dados_agrupados = [] | |
for i in range(0, len(dados), agrupamentos[intervalo]): | |
grupo = dados[i:i + agrupamentos[intervalo]] | |
ultimo_Mês = grupo[-1]["Mês"] | |
dados_agrupados.append({ | |
"Mês": | |
ultimo_Mês, | |
"Usuários": | |
max(d["Usuários"] for d in grupo), | |
"Domicílios": | |
max(d["Domicílios"] for d in grupo), | |
"Famílias": | |
max(d["Famílias"] for d in grupo), | |
}) | |
return dados_agrupados | |
def formatar_data(Mês): | |
""" | |
A function that formats the data based on the input Mês parameter. | |
Parameters: | |
- Mês (str): A string containing the month and year separated by a hyphen. | |
Returns: | |
- str: A formatted string in the format "month/year". | |
""" | |
m, a = Mês.split("-") | |
return f"{m}/{a}" | |
# Adicionando estilo personalizado | |
st.markdown( | |
""" | |
<style> | |
.stSelectbox [data-baseweb="select"] { | |
max-width: 300px; | |
} | |
.st-emotion-cache-16idsys p { | |
font-size: 20px; | |
font-weight: bold; | |
color: #4FCBFC; | |
} | |
</style> | |
""", | |
unsafe_allow_html=True, | |
) | |
# Criando duas colunas para os menus de opções | |
col1, col2, col3 = st.columns([3, 2, 2]) | |
with col1: | |
st.dataframe(df, use_container_width=True, height=250, hide_index=True) | |
with col2: | |
intervalo = option_menu( | |
"Intervalo de Tempo", | |
["Mensal", "Trimestral", "Semestral", "Anual"], | |
icons=[ | |
"calendar-month", "calendar-quarter", "calendar-half", | |
"calendar-year" | |
], | |
menu_icon="cast", | |
default_index=0, | |
styles={ | |
"container": { | |
"padding": "0!important", | |
"background-color": "#f0f0f3", | |
"border-radius": "15px", | |
"box-shadow": | |
"5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff" | |
}, | |
"icon": { | |
"color": "#007bff", | |
"font-size": "18px" | |
}, | |
"nav-link": { | |
"font-size": "14px", | |
"text-align": "center", | |
"margin": "5px", | |
"padding": "10px", | |
"--hover-color": "#e6e6e9", | |
"color": "#333333", | |
"border-radius": "10px", | |
"transition": "all 0.3s ease", | |
}, | |
"nav-link-selected": { | |
"background-color": | |
"#ffffff", | |
"box-shadow": | |
"inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff" | |
}, | |
"separator": { | |
"border-color": "#e0e0e3" | |
}, | |
}, | |
) | |
with col3: | |
metrica = option_menu( | |
"Métrica", | |
["Todos", "Usuários", "Domicílios", "Famílias"], | |
icons=["list", "person", "house", "people"], | |
menu_icon="cast", | |
default_index=0, | |
styles={ | |
"container": { | |
"padding": "0!important", | |
"background-color": "#f0f0f3", | |
"border-radius": "15px", | |
"box-shadow": | |
"5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff" | |
}, | |
"icon": { | |
"color": "#007bff", | |
"font-size": "18px" | |
}, | |
"nav-link": { | |
"font-size": "14px", | |
"text-align": "center", | |
"margin": "5px", | |
"padding": "10px", | |
"--hover-color": "#e6e6e9", | |
"color": "#333333", | |
"border-radius": "10px", | |
"transition": "all 0.3s ease", | |
}, | |
"nav-link-selected": { | |
"background-color": | |
"#ffffff", | |
"box-shadow": | |
"inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff" | |
}, | |
"separator": { | |
"border-color": "#e0e0e3" | |
}, | |
}, | |
) | |
dados_processados = processar_dados(raw_data, intervalo) | |
# Criação do gráfico | |
fig = go.Figure() | |
metricas = ["Usuários", "Domicílios", "Famílias" | |
] if metrica == "Todos" else [metrica] | |
cores = { | |
"Usuários": "#007bff", | |
"Domicílios": "#28a745", | |
"Famílias": "#ffc107" | |
} | |
annotations = [] | |
for m in metricas: | |
x_data = [formatar_data(d["Mês"]) for d in dados_processados] | |
y_data = [d[m] for d in dados_processados] | |
fig.add_trace( | |
go.Scatter( | |
x=x_data, | |
y=y_data, | |
mode="lines+markers", | |
name=m, | |
line={ | |
"color": cores[m], | |
"width": 3 | |
}, | |
marker={ | |
"size": 12, | |
"symbol": "circle", | |
"line": { | |
"width": 2, | |
"color": "white" | |
} | |
}, | |
)) | |
fig.update_layout( | |
hoverlabel={ | |
"bgcolor": "white", | |
"font_size": 16, | |
"font_family": "Arial", | |
}, | |
hovermode="x unified", | |
) | |
fig.update_traces(hovertemplate="<b>%{y}</b><br>%{x}<extra></extra>") | |
st.plotly_chart(fig, use_container_width=True) | |
elif selected_tab == "Equipe Vermelha": | |
st.subheader("Crescimento populacional - UBS Flamengo - Equipe Vermelha") | |
with stylable_container( | |
key="exp1", | |
css_styles=""" | |
img { | |
width: 200px; | |
height: 200px; | |
overflow: hidden; | |
position: relative; | |
object-fit: cover; | |
border-radius: 20px; /* Adiciona bordas arredondadas */ | |
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), | |
rgba(0, 0, 0, 0)); | |
-webkit-mask-image: linear-gradient(to bottom, | |
rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); /* For Safari */ | |
} | |
""", | |
): | |
st.image("src/Images/red.png", caption='Equipe Vermelha') | |
# st.image("src/Images/pop.jpg") | |
raw_red = [{ | |
"Mês": "set-21", | |
"Usuários": 3542, | |
"Domicílios": 1243, | |
"Famílias": 1191 | |
}, { | |
"Mês": "out-21", | |
"Usuários": 3647, | |
"Domicílios": 1240, | |
"Famílias": 1204 | |
}, { | |
"Mês": "nov-21", | |
"Usuários": 3730, | |
"Domicílios": 1267, | |
"Famílias": 1227 | |
}, { | |
"Mês": "dez-21", | |
"Usuários": 3847, | |
"Domicílios": 1307, | |
"Famílias": 1267 | |
}, { | |
"Mês": "jan-22", | |
"Usuários": 3895, | |
"Domicílios": 1328, | |
"Famílias": 1284 | |
}, { | |
"Mês": "fev-22", | |
"Usuários": 3937, | |
"Domicílios": 1342, | |
"Famílias": 1297 | |
}, { | |
"Mês": "mar-22", | |
"Usuários": 4082, | |
"Domicílios": 1393, | |
"Famílias": 1348 | |
}, { | |
"Mês": "abr-22", | |
"Usuários": 4248, | |
"Domicílios": 1434, | |
"Famílias": 1375 | |
}, { | |
"Mês": "mai-22", | |
"Usuários": 4440, | |
"Domicílios": 1509, | |
"Famílias": 1442 | |
}, { | |
"Mês": "jun-22", | |
"Usuários": 4646, | |
"Domicílios": 1575, | |
"Famílias": 1499 | |
}, { | |
"Mês": "jul-22", | |
"Usuários": 4783, | |
"Domicílios": 1616, | |
"Famílias": 1539 | |
}, { | |
"Mês": "ago-22", | |
"Usuários": 4909, | |
"Domicílios": 1670, | |
"Famílias": 1567 | |
}, { | |
"Mês": "set-22", | |
"Usuários": 5008, | |
"Domicílios": 1720, | |
"Famílias": 1609 | |
}, { | |
"Mês": "out-22", | |
"Usuários": 5017, | |
"Domicílios": 1721, | |
"Famílias": 1610 | |
}, { | |
"Mês": "nov-22", | |
"Usuários": 5037, | |
"Domicílios": 1742, | |
"Famílias": 1613 | |
}, { | |
"Mês": "dez-22", | |
"Usuários": 5060, | |
"Domicílios": 1742, | |
"Famílias": 1615 | |
}, { | |
"Mês": "jan-23", | |
"Usuários": 5107, | |
"Domicílios": 1708, | |
"Famílias": 1563 | |
}, { | |
"Mês": "fev-23", | |
"Usuários": 5127, | |
"Domicílios": 1631, | |
"Famílias": 1496 | |
}, { | |
"Mês": "mar-23", | |
"Usuários": 5262, | |
"Domicílios": 1667, | |
"Famílias": 1533 | |
}, { | |
"Mês": "abr-23", | |
"Usuários": 5279, | |
"Domicílios": 1682, | |
"Famílias": 1545 | |
}, { | |
"Mês": "mai-23", | |
"Usuários": 5361, | |
"Domicílios": 1719, | |
"Famílias": 1575 | |
}, { | |
"Mês": "jun-23", | |
"Usuários": 5381, | |
"Domicílios": 1728, | |
"Famílias": 1591 | |
}, { | |
"Mês": "jul-23", | |
"Usuários": 5429, | |
"Domicílios": 1766, | |
"Famílias": 1609 | |
}, { | |
"Mês": "ago-23", | |
"Usuários": 5417, | |
"Domicílios": 1743, | |
"Famílias": 1618 | |
}, { | |
"Mês": "set-23", | |
"Usuários": 5447, | |
"Domicílios": 1748, | |
"Famílias": 1632 | |
}, { | |
"Mês": "out-23", | |
"Usuários": 5495, | |
"Domicílios": 1772, | |
"Famílias": 1646 | |
}, { | |
"Mês": "nov-23", | |
"Usuários": 5496, | |
"Domicílios": 1775, | |
"Famílias": 1650 | |
}, { | |
"Mês": "dez-23", | |
"Usuários": 5519, | |
"Domicílios": 1767, | |
"Famílias": 1657 | |
}, { | |
"Mês": "jan-24", | |
"Usuários": 5560, | |
"Domicílios": 1793, | |
"Famílias": 1673 | |
}, { | |
"Mês": "fev-24", | |
"Usuários": 5574, | |
"Domicílios": 1795, | |
"Famílias": 1679 | |
}, { | |
"Mês": "mar-24", | |
"Usuários": 5576, | |
"Domicílios": 1789, | |
"Famílias": 1676 | |
}, { | |
"Mês": "abr-24", | |
"Usuários": 5624, | |
"Domicílios": 1824, | |
"Famílias": 1696 | |
}, { | |
"Mês": "mai-24", | |
"Usuários": 5699, | |
"Domicílios": 1827, | |
"Famílias": 1713 | |
}, { | |
"Mês": "jun-24", | |
"Usuários": 5739, | |
"Domicílios": 1843, | |
"Famílias": 1733 | |
}, { | |
"Mês": "jul-24", | |
"Usuários": 5739, | |
"Domicílios": 1877, | |
"Famílias": 1742 | |
}, { | |
"Mês": "ago-24", | |
"Usuários": 5760, | |
"Domicílios": 1881, | |
"Famílias": 1757 | |
}] | |
df = pd.DataFrame(raw_red) | |
def processar_dados(dados, intervalo): | |
""" | |
Process data based on the specified interval and return the aggregated data. | |
Parameters: | |
- dados: List of dictionaries containing data for each month. | |
- intervalo: String indicating the interval for data aggregation. | |
Returns: | |
- List of dictionaries with aggregated data based on the specified interval. | |
""" | |
if intervalo == "Mensal": | |
return dados | |
agrupamentos = {"Trimestral": 3, "Semestral": 6, "Anual": 12} | |
dados_agrupados = [] | |
for i in range(0, len(dados), agrupamentos[intervalo]): | |
grupo = dados[i:i + agrupamentos[intervalo]] | |
ultimo_Mês = grupo[-1]["Mês"] | |
dados_agrupados.append({ | |
"Mês": | |
ultimo_Mês, | |
"Usuários": | |
max(d["Usuários"] for d in grupo), | |
"Domicílios": | |
max(d["Domicílios"] for d in grupo), | |
"Famílias": | |
max(d["Famílias"] for d in grupo), | |
}) | |
return dados_agrupados | |
def formatar_data(Mês): | |
""" | |
A function that formats the data based on the input Mês parameter. | |
Parameters: | |
- Mês (str): A string containing the month and year separated by a hyphen. | |
Returns: | |
- str: A formatted string in the format "month/year". | |
""" | |
m, a = Mês.split("-") | |
return f"{m}/{a}" | |
# Adicionando estilo personalizado | |
st.markdown( | |
""" | |
<style> | |
.stSelectbox [data-baseweb="select"] { | |
max-width: 300px; | |
} | |
.st-emotion-cache-16idsys p { | |
font-size: 20px; | |
font-weight: bold; | |
color: #4FCBFC; | |
} | |
</style> | |
""", | |
unsafe_allow_html=True, | |
) | |
# Criando duas colunas para os menus de opções | |
col1, col2, col3 = st.columns([3, 2, 2]) | |
with col1: | |
st.dataframe(df, use_container_width=True, height=250, hide_index=True) | |
with col2: | |
intervalo = option_menu( | |
"Intervalo de Tempo", | |
["Mensal", "Trimestral", "Semestral", "Anual"], | |
icons=[ | |
"calendar-month", "calendar-quarter", "calendar-half", | |
"calendar-year" | |
], | |
menu_icon="cast", | |
default_index=0, | |
styles={ | |
"container": { | |
"padding": "0!important", | |
"background-color": "#f0f0f3", | |
"border-radius": "15px", | |
"box-shadow": | |
"5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff" | |
}, | |
"icon": { | |
"color": "#007bff", | |
"font-size": "18px" | |
}, | |
"nav-link": { | |
"font-size": "14px", | |
"text-align": "center", | |
"margin": "5px", | |
"padding": "10px", | |
"--hover-color": "#e6e6e9", | |
"color": "#333333", | |
"border-radius": "10px", | |
"transition": "all 0.3s ease", | |
}, | |
"nav-link-selected": { | |
"background-color": | |
"#ffffff", | |
"box-shadow": | |
"inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff" | |
}, | |
"separator": { | |
"border-color": "#e0e0e3" | |
}, | |
}, | |
) | |
with col3: | |
metrica = option_menu( | |
"Métrica", | |
["Todos", "Usuários", "Domicílios", "Famílias"], | |
icons=["list", "person", "house", "people"], | |
menu_icon="cast", | |
default_index=0, | |
styles={ | |
"container": { | |
"padding": "0!important", | |
"background-color": "#f0f0f3", | |
"border-radius": "15px", | |
"box-shadow": | |
"5px 5px 10px #d1d1d4, -5px -5px 10px #ffffff" | |
}, | |
"icon": { | |
"color": "#007bff", | |
"font-size": "18px" | |
}, | |
"nav-link": { | |
"font-size": "14px", | |
"text-align": "center", | |
"margin": "5px", | |
"padding": "10px", | |
"--hover-color": "#e6e6e9", | |
"color": "#333333", | |
"border-radius": "10px", | |
"transition": "all 0.3s ease", | |
}, | |
"nav-link-selected": { | |
"background-color": | |
"#ffffff", | |
"box-shadow": | |
"inset 3px 3px 5px #d1d1d4, inset -3px -3px 5px #ffffff" | |
}, | |
"separator": { | |
"border-color": "#e0e0e3" | |
}, | |
}, | |
) | |
dados_processados = processar_dados(raw_red, intervalo) | |
# Criação do gráfico | |
fig = go.Figure() | |
metricas = ["Usuários", "Domicílios", "Famílias" | |
] if metrica == "Todos" else [metrica] | |
cores = { | |
"Usuários": "#007bff", | |
"Domicílios": "#28a745", | |
"Famílias": "#ffc107" | |
} | |
annotations = [] | |
for m in metricas: | |
x_data = [formatar_data(d["Mês"]) for d in dados_processados] | |
y_data = [d[m] for d in dados_processados] | |
fig.add_trace( | |
go.Scatter( | |
x=x_data, | |
y=y_data, | |
mode="lines+markers", | |
name=m, | |
line={ | |
"color": cores[m], | |
"width": 3 | |
}, | |
marker={ | |
"size": 12, | |
"symbol": "circle", | |
"line": { | |
"width": 2, | |
"color": "white" | |
} | |
}, | |
)) | |
fig.update_layout( | |
hoverlabel={ | |
"bgcolor": "white", | |
"font_size": 16, | |
"font_family": "Arial", | |
}, | |
hovermode="x unified", | |
) | |
fig.update_traces(hovertemplate="<b>%{y}</b><br>%{x}<extra></extra>") | |
st.plotly_chart(fig, use_container_width=True) | |
add_vertical_space(10) | |
st.write('----') |