i am making a dashboard for visualizing my machine learning result, now the code below show 2 graph, which is beam index graph(first graph on the left) and data rate graph(second graph on the right), now the instruction is i want to show the second graph after the first graph animation done playing and will reset/disappear after the we select different machine learning method with the radio button at the sidebar. Thanks
import streamlit as st
import plotly.express as px
import pandas as pd
import os
import numpy as np
import plotly.graph_objects as go
import warnings
import threading
import time
warnings.filterwarnings('ignore')
def load_xlsx(selected_lokasi):
file_path = f"C:/Users/David/Downloads/amin/Dataset_Backup/lokasi_kereta_{selected_lokasi}.xlsx"
df = pd.read_excel(file_path)
# Get the current working directory
cwd = os.getcwd()
# Specify the relative path to your file from the cwd
file_path = os.path.join(cwd, "C:/Users/David/Downloads/amin")
st.set_page_config(page_title="Dashboard", page_icon=":bar_chart:", layout="wide")
# Title
with st.container():
st.title("5G Beam Prediction with Machine Learning on High Speed Train with Machine Learning Dashboard")
# Define the choices for the train tracks
tracks = list(range(1, 9))
# Create the selectbox for selecting a train track
track = st.sidebar.selectbox("Pilih Lintasan", options=tracks, index=0)
selected_track = f"C:/Users/David/Downloads/amin/Testing/Track"
ml_method = st.sidebar.radio(
"Select the Beam Index Prediction Method",
('KNN', 'Neural Networks', 'Lookup Table', 'Naive Bayes', 'Support Vector Machine', 'Random Forest')
)
# Define the choices for the multiselect box
choices = ['KNN', 'Neural Networks', 'Lookup Table', 'Naive Bayes', 'Support Vector Machine', 'Random Forest']
# Create the multiselect box in the sidebar
method = st.sidebar.multiselect('Select machine learning method to compare', choices)
# Display the selected track and methods
st.subheader(f"TRACK {track} Train Coordinates")
# Determine the folder path for the selected track
selected_track_folder = f"C:/Users/David/Downloads/amin/Testing/Track{track}"
selected_track = f"C:/Users/David/Downloads/amin/Testing/Track{track}/down_lokasi_kereta_{track}.xlsx"
df_track = pd.read_excel(selected_track)
# Column
with st.container():
st.write("---")
left_column, right_column = st.columns(2) #Generate 2 column
with left_column:
st.header("Beam Index")
selected_index = track
# Read train coordinates and time data from Excel file
file_path_train = f"C:/Users/David/Downloads/amin/Testing/Track{track}/down_lokasi_kereta_{track}.xlsx"
df_train = pd.read_excel(file_path_train)
# Read Index
file_azimuth = f"C:/Users/David/Downloads/amin/Testing/Track{track}/sum_{track}.xlsx"
df_azimuth = pd.read_excel(file_azimuth)
# Define base station coordinates
base_station_x = 0
base_station_y = 0
# Define beam length
beam_length = 1000 # Example length
# Create Plotly figure
fig = px.scatter(df_train, x=f'lokasi_{track}_y', y=f'lokasi_{track}_x', title='Train with Beam Pattern')
# Add base station
fig.add_trace(go.Scatter(x=[base_station_x], y=[base_station_y], mode='markers', marker=dict(color='red', size=10), name='Base Station'))
# Add initial beam pattern based on azimuth angle
initial_azimuth = df_azimuth.loc[0, f'azimuth_{ml_method}']
angle1 = np.radians(initial_azimuth + 15) # Convert to radians and add/subtract 30 degrees for beam pattern
angle2 = np.radians(initial_azimuth - 15)
tip1_x = base_station_x + beam_length * np.cos(angle1)
tip1_y = base_station_y + beam_length * np.sin(angle1)
tip2_x = base_station_x + beam_length * np.cos(angle2)
tip2_y = base_station_y + beam_length * np.sin(angle2)
beam_shape_x = [base_station_x, tip1_x, tip2_x, base_station_x]
beam_shape_y = [base_station_y, tip1_y, tip2_y, base_station_y]
fig.add_trace(go.Scatter(x=beam_shape_x, y=beam_shape_y, mode='lines', fill='toself', fillcolor='rgba(0, 0, 255, 0.2)', line=dict(color='blue'), name='Beam Pattern'))
# Update layout
fig.update_layout(
xaxis_title='X',
yaxis_title='Y',
xaxis=dict(range=[-400, 400]), # Set fixed range for x-axis
yaxis=dict(range=[-400, 400]), # Set fixed range for y-axis
showlegend=True,
width=800,
height=500,
updatemenus=[{
"buttons": [{"args": [None, {"frame": {"duration": 300, "redraw": True}, "fromcurrent": True}],
"label": "Play",
"method": "animate"}],
"direction": "left",
"pad": {"r": -100, "t": 20},
"showactive": False,
"type": "buttons",
"x": 1,
"xanchor": "right",
"y": 0,
"yanchor": "top"
}]
)
# Define frames for animation
frames = []
for i, row in df_train.iterrows():
closest_train_x = row[f'lokasi_{track}_y']
closest_train_y = row[f'lokasi_{track}_x']
azimuth_angle = df_azimuth.loc[i, f'azimuth_{ml_method}']
angle1 = np.radians(azimuth_angle + 15)
angle2 = np.radians(azimuth_angle - 15)
tip1_x = base_station_x + beam_length * np.cos(angle1)
tip1_y = base_station_y + beam_length * np.sin(angle1)
tip2_x = base_station_x + beam_length * np.cos(angle2)
tip2_y = base_station_y + beam_length * np.sin(angle2)
beam_shape_x = [base_station_x, tip1_x, tip2_x, base_station_x]
beam_shape_y = [base_station_y, tip1_y, tip2_y, base_station_y]
frames.append(go.Frame(data=[
go.Scatter(x=[base_station_x], y=[base_station_y], mode='markers', marker=dict(color='red', size=10), name='Base Station'),
go.Scatter(x=[closest_train_x], y=[closest_train_y], mode='markers', marker=dict(color='blue'), name='Train'),
go.Scatter(x=beam_shape_x, y=beam_shape_y, mode='lines', fill='toself', fillcolor='rgba(0, 0, 255, 0.2)', line=dict(color='blue'), name='Beam Pattern')],
name=str(i)
))
# Add frames to the figure
fig.frames = frames
# Display the plot using Streamlit
st.plotly_chart(fig)
st.write(f'Initial azimuth angle: {initial_azimuth} degrees')
# Dynamic text that updates every frame
dynamic_text = st.empty()
with right_column:
st.header("Data Rate")
st.subheader("")
# Read data from Excel file
file_datarate = f"C:/Users/David/Downloads/amin/Testing/Track{track}/sum_{track}.xlsx"
data = pd.read_excel(file_datarate)
# Calculate maximum value for normalization
max_value = data[f'convert_{ml_method}'].max()
# Initial plot
fig_rate = px.bar(data, x='point', y=f'convert_{ml_method}', barmode='group',color_discrete_sequence =['green']*len(data),)
chart = st.plotly_chart(fig_rate, use_container_width=True)
# Dynamic text that updates every frame
dynamic_text = st.empty()
# Function to read data from Excel file and update the text dynamically
def update_text(track):
while True:
# Read Excel file
df = pd.read_excel(file_datarate)
# Get the value from the specified column based on track
value = df[f'convert_{ml_method}'].iloc[0] # Assuming only one row is needed
# Update the text value
dynamic_text.text(f"Dynamic Value for Track {track}: {value}")
# Wait for a certain amount of time before updating again
time.sleep(1)
# Function to run the update_text function as a thread
def run():
update_text(track)
# Create a thread for updating the text
thread = None
# Define play button callback
def on_play():
global thread
if thread is None or not thread.is_alive():
# Create a thread for updating the text
thread = threading.Thread(target=run)
# Start the thread
thread.start()
# Dynamic text that updates every frame
dynamic_text = st.empty()
st.write("---")
# Create a 3x2 grid layout
st.subheader("Accuracy and Prediction Time")
# Function to display comparison
def display_comparison(method_name, accuracy, pred_time,outtage, column):
with column:
# Display the method name in a larger font size using HTML <h1> tag
st.markdown(f"<h1>{method_name}</h1>", unsafe_allow_html=True)
# Display accuracy with larger font size
st.markdown(f"**Accuracy:** <h2>{accuracy}%</h2>", unsafe_allow_html=True)
st.markdown(f"**Prediction Time:**<h2>{pred_time}s</h2>", unsafe_allow_html=True)
st.markdown(f"**Outtage Percentage:**<h2>{outtage}%</h2>", unsafe_allow_html=True)
# Read the Excel file once
file_acc = f"C:/Users/David/Downloads/amin/Testing/Track{track}/Acc_Track{track}.xlsx"
df_method = pd.read_excel(file_acc)
# List of methods to visualize
methods = ['KNN', 'Neural Networks', 'Lookup Table', 'Naive Bayes', 'Support Vector Machine', 'Random Forest']
if method:
cols = st.columns(3)
for i, method_name in enumerate(method):
if i < 6: # Ensure we don't exceed 6 methods
# Check if the method exists in the DataFrame
if method_name in df_method["method"].values:
# Get the accuracy and prediction time for the current method
accuracy = df_method.loc[df_method["method"] == method_name, "Accuracy"].values[0]
pred_time = df_method.loc[df_method["method"] == method_name, "Prediction Time"].values[0]
outtage = df_method.loc[df_method["method"] == method_name, "Outtage Percentage"].values[0]
# Display the method information in the appropriate column
display_comparison(method_name, accuracy, pred_time, outtage, cols[i % 3])
# Reset columns after every 3 items
if (i + 1) % 3 == 0:
cols = st.columns(3)
else:
st.write(f"Method {method_name} not found in the data.")
else:
st.write("No methods selected")