db_query / apps /kpi_analysis /lcg_analysis.py
DavMelchi's picture
lcg image width update
888f6ab
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="<b>%{label}</b><br> %{value} <b>(%{customdata[1]:.1f}%)</b>",
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)