import pandas as pd import plotly.express as px import streamlit as st from process_kpi.process_lcg_capacity import load_and_process_lcg_data from utils.convert_to_excel import convert_dfs class LcgCapacity: final_results = None # Streamlit UI st.title(" 📊 LCG Analysis") doc_col, image_col = st.columns(2) with doc_col: st.write( """This app allows you to analyze the LCG of a network. It provides insights into the utilization of LCG resources, helping you identify potential capacity issues and plan for upgrades. The report should be run with a minimum of 3 days of data. - Daily Aggregated - LCG level - Exported in CSV format. """ ) with image_col: st.image("./assets/lcg_analysis.png", width=250) uploaded_file = st.file_uploader("Upload LCG report in CSV format", type="csv") param_col1, param_col2, param_col3 = st.columns(3) param_col4, param_col5, param_col6 = st.columns(3) # num_last_days # num_threshold_days # lcg_utilization_threshold # difference_between_lcgs if uploaded_file is not None: LcgCapacity.final_results = None with param_col1: num_last_days = st.number_input( "Number of days for analysis", min_value=3, max_value=30, value=7, ) with param_col2: num_threshold_days = st.number_input( "Number of days for threshold", min_value=1, max_value=30, value=2, ) with param_col3: lcg_utilization_threshold = st.number_input( "LCG Utilization Threshold (%)", min_value=0, max_value=100, value=80, ) with param_col4: difference_between_lcgs = st.number_input( "Difference between LCgs (%)", min_value=0, max_value=100, value=20, ) if st.button("Analyze Data", type="primary"): # Input validation try: if num_threshold_days > num_last_days: st.warning( "Number of threshold days cannot be greater than number of analysis days" ) st.stop() if num_last_days < 3: st.warning( "Analysis period should be at least 3 days for meaningful results" ) st.stop() if lcg_utilization_threshold <= 0 or lcg_utilization_threshold > 100: st.warning("LCG utilization threshold must be between 1 and 100") st.stop() with st.spinner("Processing data..."): results = load_and_process_lcg_data( uploaded_file, num_last_days, num_threshold_days, lcg_utilization_threshold, difference_between_lcgs, ) except Exception as e: st.error(f"An error occurred during input validation: {str(e)}") st.stop() if results is not None: lcg_analysis_df = results[0] kpi_df = results[1] LcgCapacity.final_results = convert_dfs( [lcg_analysis_df, kpi_df], ["lcg_analysis", "kpi"] ) st.download_button( on_click="ignore", type="primary", label="Download the Analysis Report", data=LcgCapacity.final_results, file_name="LCG_Capacity_Report.xlsx", mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ) st.write(lcg_analysis_df) # Add dataframe and Pie chart with "final_comments" distribution st.markdown("***") st.markdown(":blue[**Final comment distribution**]") final_comments_df = ( lcg_analysis_df.groupby("final_comments") .size() .reset_index(name="count") .sort_values(by="count", ascending=False) ) final_comments_df["percent"] = ( final_comments_df["count"] / final_comments_df["count"].sum() ) * 100 final_comments_col1, final_comments_col2 = st.columns((1, 3)) with final_comments_col1: st.write(final_comments_df) with final_comments_col2: fig = px.pie( final_comments_df, names="final_comments", values="count", hover_name="final_comments", hover_data=["count", "percent"], title="Final Comments Distribution", ) fig.update_layout(height=600) fig.update_traces( texttemplate="%{label}
%{value} (%{customdata[1]:.1f}%)", textfont_size=15, textposition="outside", ) st.plotly_chart(fig) # Add dataframe and Bar chart with "final_comments" distribution per Region st.markdown("***") st.markdown(":blue[**Final comment distribution per Region**]") final_comments_df = ( lcg_analysis_df.groupby(["Region", "final_comments"]) .size() .reset_index(name="count") .sort_values(by="count", ascending=False) ) final_comments_col1, final_comments_col2 = st.columns((1, 3)) with final_comments_col1: st.write(final_comments_df) with final_comments_col2: fig = px.bar( final_comments_df, x="Region", y="count", color="final_comments", title="Final Comments Distribution per Region", text="count", ) fig.update_traces(textposition="outside") fig.update_layout(height=600) st.plotly_chart(fig) # Add map plot with scatter_map with code ,Longitude,Latitude,final_comments st.markdown("***") st.markdown(":blue[**Final comments distribution**]") final_comments_map_df = lcg_analysis_df[ ["code", "Longitude", "Latitude", "final_comments"] ].dropna(subset=["code", "Longitude", "Latitude", "final_comments"]) # replace empty strings with "Cell OK" # final_comments_map_df["final_comments"] = final_comments_map_df[ # "final_comments" # ].replace("", "Cell OK") # add size column equalt to 20 final_comments_map_df["size"] = 20 fig = px.scatter_map( final_comments_map_df, lat="Latitude", lon="Longitude", color="final_comments", size="size", zoom=10, height=600, title="Final Comments Distribution", hover_data={ "code": True, "final_comments": True, }, hover_name="code", ) fig.update_layout(mapbox_style="open-street-map") st.plotly_chart(fig)