import pandas as pd import plotly.graph_objects as go from streamlit_option_menu import option_menu import streamlit as st from streamlit_extras.stylable_container import stylable_container st.title("Crescimento populacional - UBS Flamengo") with stylable_container( key="banner", css_styles=""" img { width: 1800px; height: 340px; 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("pop.jpg") st.title("Crescimento populacional - UBS Flamengo") raw_data = [ {"Mês": "mai-21", "Usuários": 3402, "Domicílios": 1440, "Famílias": 1269}, {"Mês": "jun-21", "Usuários": 3503, "Domicílios": 1462, "Famílias": 1304}, {"Mês": "jul-21", "Usuários": 3559, "Domicílios": 1478, "Famílias": 1323}, {"Mês": "ago-21", "Usuários": 3592, "Domicílios": 1490, "Famílias": 1338}, {"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": 5681, "Domicílios": 2200, "Famílias": 1961}, {"Mês": "ago-23", "Usuários": 5728, "Domicílios": 2208, "Famílias": 1972}, {"Mês": "set-23", "Usuários": 5774, "Domicílios": 2228, "Famílias": 1983}, {"Mês": "out-23", "Usuários": 5841, "Domicílios": 2245, "Famílias": 2007}, {"Mês": "nov-23", "Usuários": 5891, "Domicílios": 2297, "Famílias": 2027}, {"Mês": "dez-23", "Usuários": 5933, "Domicílios": 2281, "Famílias": 2036}, {"Mês": "jan-24", "Usuários": 5982, "Domicílios": 2307, "Famílias": 2050}, {"Mês": "fev-24", "Usuários": 6005, "Domicílios": 2333, "Famílias": 2057}, {"Mês": "mar-24", "Usuários": 6020, "Domicílios": 2327, "Famílias": 2070}, {"Mês": "abr-24", "Usuários": 6074, "Domicílios": 2370, "Famílias": 2095}, ] df = pd.DataFrame(raw_data) @st.cache_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 @st.cache_data 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( """ """, 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": "#262730"}, "icon": {"color": "#4FCBFC", "font-size": "18px"}, "nav-link": { "font-size": "14px", "text-align": "center", "margin": "0px", "padding": "10px", "--hover-color": "#363940", "color": "#FFFFFF", }, "nav-link-selected": {"background-color": "#0083B8"}, "separator": {"border-color": "#4B4B4B"}, }, ) 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": "#262730"}, "icon": {"color": "#4FCBFC", "font-size": "18px"}, "nav-link": { "font-size": "14px", "text-align": "center", "margin": "0px", "padding": "10px", "--hover-color": "#363940", "color": "#FFFFFF", }, "nav-link-selected": {"background-color": "#0083B8"}, "separator": {"border-color": "#4B4B4B"}, }, ) dados_processados = processar_dados(raw_data, intervalo) # Switch para mostrar valores nos pontos mostrar_valores = st.checkbox("Mostrar valores nos pontos", value=True) # Criação do gráfico fig = go.Figure() metricas = ["Usuários", "Domicílios", "Famílias"] if metrica == "Todos" else [metrica] cores = {"Usuários": "#1f77b4", "Domicílios": "#ff7f0e", "Famílias": "#2ca02c"} # Slider Component st.sidebar.header("Ajustes dos Balões") balloon_positions = {} for m in metricas: balloon_positions[m] = st.sidebar.slider( f"Posição do balão para {m}", min_value=-100, max_value=0, value=-40, step=5 ) 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=dict(color=cores[m], width=3), marker=dict(size=8, symbol="circle", line=dict(width=2, color="white")), ) ) if mostrar_valores: for i, (x, y) in enumerate(zip(x_data, y_data)): annotations.append( dict( x=x, y=y, xref="x", yref="y", text=f"{y:,.0f}", showarrow=True, arrowhead=7, ax=0, ay=balloon_positions[m], # Usa a posição ajustada para cada métrica bgcolor=cores[m], opacity=0.8, bordercolor="white", borderwidth=2, borderpad=4, font=dict(color="white", size=10), ) ) fig.update_layout( title={ "text": "Crescimento na Área de Saúde", "y": 0.95, "x": 0.5, "xanchor": "center", "yanchor": "top", "font": dict(size=24, color="#4FCBFC"), }, xaxis_title="Mês", yaxis_title="Quantidade", legend_title="Métricas", template="plotly_dark", plot_bgcolor="#262730", paper_bgcolor="#262730", font=dict(color="white"), xaxis=dict(showgrid=True, gridcolor="#4B4B4B", tickangle=45), yaxis=dict(showgrid=True, gridcolor="#4B4B4B"), legend=dict( bgcolor="rgba(0,0,0,0)", bordercolor="rgba(0,0,0,0)", font=dict(size=12, color="white"), ), margin=dict(l=50, r=50, t=80, b=50), annotations=annotations, ) st.plotly_chart(fig, use_container_width=True)