Spaces:
				
			
			
	
			
			
		Sleeping
		
	
	
	
			
			
	
	
	
	
		
		
		Sleeping
		
	
		devjas1
		
	commited on
		
		
					Commit 
							
							Β·
						
						ff443f3
	
1
								Parent(s):
							
							56c06a1
								
(FEAT/UI): Streamline results display with enhanced metrics and consolidated confidence analysis
Browse files
    	
        app.py
    CHANGED
    
    | 
         @@ -718,8 +718,7 @@ def main(): 
     | 
|
| 718 | 
         
             
                        if uploaded_files:
         
     | 
| 719 | 
         
             
                            # --- START: Bug 1 Fix ---
         
     | 
| 720 | 
         
             
                            # Use a dictionary to keep only unique files based on name and size
         
     | 
| 721 | 
         
            -
                            unique_files = {(file.name, file.size)
         
     | 
| 722 | 
         
            -
                                             : file for file in uploaded_files}
         
     | 
| 723 | 
         
             
                            unique_file_list = list(unique_files.values())
         
     | 
| 724 | 
         | 
| 725 | 
         
             
                            num_uploaded = len(uploaded_files)
         
     | 
| 
         @@ -849,8 +848,8 @@ def main(): 
     | 
|
| 849 | 
         | 
| 850 | 
         
             
                        # --- START: BUG 2 FIX (Button) ---
         
     | 
| 851 | 
         
             
                        # This button will clear all results from col2 correctly.
         
     | 
| 852 | 
         
            -
                        st.button("Clear Results", on_click=clear_batch_results,
         
     | 
| 853 | 
         
            -
             
     | 
| 854 | 
         
             
                        # --- END: BUG 2 FIX (Button) ---
         
     | 
| 855 | 
         | 
| 856 | 
         
             
                        ResultsManager.display_results_table()
         
     | 
| 
         @@ -960,150 +959,75 @@ def main(): 
     | 
|
| 960 | 
         
             
                            )
         
     | 
| 961 | 
         | 
| 962 | 
         
             
                            if active_tab == "Details":
         
     | 
| 963 | 
         
            -
                                # MODIFIED: Wrap the expander in a div with the 'expander-results' class
         
     | 
| 964 | 
         
             
                                st.markdown('<div class="expander-results">',
         
     | 
| 965 | 
         
             
                                            unsafe_allow_html=True)
         
     | 
| 966 | 
         
            -
                                 
     | 
| 967 | 
         
            -
             
     | 
| 968 | 
         
            -
             
     | 
| 969 | 
         
            -
             
     | 
| 970 | 
         
            -
             
     | 
| 971 | 
         
            -
                                     
     | 
| 972 | 
         
            -
             
     | 
| 973 | 
         
            -
             
     | 
| 974 | 
         
            -
             
     | 
| 975 | 
         
            -
             
     | 
| 976 | 
         
            -
             
     | 
| 977 | 
         
            -
             
     | 
| 978 | 
         
            -
             
     | 
| 979 | 
         
            -
             
     | 
| 980 | 
         
            -
                                         
     | 
| 981 | 
         
            -
             
     | 
| 982 | 
         
            -
             
     | 
| 983 | 
         
            -
             
     | 
| 984 | 
         
            -
             
     | 
| 985 | 
         
            -
             
     | 
| 986 | 
         
            -
             
     | 
| 987 | 
         
            -
             
     | 
| 988 | 
         
            -
                                         
     | 
| 989 | 
         
            -
             
     | 
| 990 | 
         
            -
             
     | 
| 991 | 
         
            -
             
     | 
| 992 | 
         
            -
             
     | 
| 993 | 
         
            -
             
     | 
| 994 | 
         
            -
             
     | 
| 995 | 
         
            -
             
     | 
| 996 | 
         
            -
                                    #  
     | 
| 997 | 
         
            -
             
     | 
| 998 | 
         
            -
             
     | 
| 999 | 
         
            -
             
     | 
| 1000 | 
         
            -
             
     | 
| 1001 | 
         
            -
                                     
     | 
| 1002 | 
         
            -
             
     | 
| 1003 | 
         
            -
             
     | 
| 1004 | 
         
            -
             
     | 
| 1005 | 
         
            -
             
     | 
| 1006 | 
         
            -
             
     | 
| 1007 | 
         
            -
             
     | 
| 1008 | 
         
            -
             
     | 
| 1009 | 
         
            -
             
     | 
| 1010 | 
         
            -
             
     | 
| 1011 | 
         
            -
                                     
     | 
| 1012 | 
         
            -
                                         
     | 
| 1013 | 
         
            -
             
     | 
| 1014 | 
         
            -
             
     | 
| 1015 | 
         
            -
             
     | 
| 1016 | 
         
            -
                                             
     | 
| 1017 | 
         
            -
             
     | 
| 1018 | 
         
            -
             
     | 
| 1019 | 
         
            -
             
     | 
| 1020 | 
         
            -
                                         
     | 
| 1021 | 
         
            -
             
     | 
| 1022 | 
         
            -
             
     | 
| 1023 | 
         
            -
             
     | 
| 1024 | 
         
            -
             
     | 
| 1025 | 
         
            -
             
     | 
| 1026 | 
         
            -
                                    #  
     | 
| 1027 | 
         
            -
                                    #  
     | 
| 1028 | 
         
            -
                                     
     | 
| 1029 | 
         
            -
                                         
     | 
| 1030 | 
         
            -
             
     | 
| 1031 | 
         
            -
             
     | 
| 1032 | 
         
            -
             
     | 
| 1033 | 
         
            -
                                        def create_bullet_bar(probability, width=20, predicted=False):
         
     | 
| 1034 | 
         
            -
                                            filled_count = int(probability * width)
         
     | 
| 1035 | 
         
            -
                                            empty_count = width - filled_count
         
     | 
| 1036 | 
         
            -
             
     | 
| 1037 | 
         
            -
                                            # Use professional symbols
         
     | 
| 1038 | 
         
            -
                                            filled_symbol = "β "  # Solid block
         
     | 
| 1039 | 
         
            -
                                            empty_symbol = "β"   # Light shade
         
     | 
| 1040 | 
         
            -
             
     | 
| 1041 | 
         
            -
                                            # Create the bar
         
     | 
| 1042 | 
         
            -
                                            bar = filled_symbol * filled_count + empty_symbol * empty_count
         
     | 
| 1043 | 
         
            -
             
     | 
| 1044 | 
         
            -
                                            # Add percentage with scientific formatting
         
     | 
| 1045 | 
         
            -
                                            percentage = f"{probability:.1%}"
         
     | 
| 1046 | 
         
            -
             
     | 
| 1047 | 
         
            -
                                            # Add prediction indicator
         
     | 
| 1048 | 
         
            -
                                            pred_marker = "β© Predicted" if predicted else ""
         
     | 
| 1049 | 
         
            -
             
     | 
| 1050 | 
         
            -
                                            return f"{bar} {percentage}     {pred_marker}"
         
     | 
| 1051 | 
         
            -
             
     | 
| 1052 | 
         
            -
                                        # Get probabilities
         
     | 
| 1053 | 
         
            -
                                        stable_prob = probs[0]
         
     | 
| 1054 | 
         
            -
                                        weathered_prob = probs[1]
         
     | 
| 1055 | 
         
            -
                                        is_stable_predicted = int(prediction) == 0
         
     | 
| 1056 | 
         
            -
                                        is_weathered_predicted = int(prediction) == 1
         
     | 
| 1057 | 
         
            -
             
     | 
| 1058 | 
         
            -
                                        # Clean 2-column layout for assessment and probabilities
         
     | 
| 1059 | 
         
            -
                                        assess_col, prob_col = st.columns(
         
     | 
| 1060 | 
         
            -
                                            [1, 2.5], gap="small", border=True)
         
     | 
| 1061 | 
         
            -
             
     | 
| 1062 | 
         
            -
                                        # Left column: Assessment metrics
         
     | 
| 1063 | 
         
            -
                                        with assess_col:
         
     | 
| 1064 | 
         
            -
                                            st.markdown(
         
     | 
| 1065 | 
         
            -
                                                "Assessment", unsafe_allow_html=True)
         
     | 
| 1066 | 
         
            -
             
     | 
| 1067 | 
         
            -
                                            # Ground truth validation
         
     | 
| 1068 | 
         
            -
                                            if true_label_idx is not None:
         
     | 
| 1069 | 
         
            -
                                                is_correct = predicted_class == true_label_str
         
     | 
| 1070 | 
         
            -
                                                accuracy_icon = "β
" if is_correct else ""
         
     | 
| 1071 | 
         
            -
                                                status_text = "Correct" if is_correct else "Incorrect"
         
     | 
| 1072 | 
         
            -
                                                st.metric(
         
     | 
| 1073 | 
         
            -
                                                    label="**Ground Truth**",
         
     | 
| 1074 | 
         
            -
                                                    value=f"{accuracy_icon} {status_text}",
         
     | 
| 1075 | 
         
            -
                                                    delta=f"{'100%' if is_correct else '0%'}"
         
     | 
| 1076 | 
         
            -
                                                )
         
     | 
| 1077 | 
         
            -
                                            else:
         
     | 
| 1078 | 
         
            -
                                                st.metric(
         
     | 
| 1079 | 
         
            -
                                                    label="**Ground Truth**",
         
     | 
| 1080 | 
         
            -
                                                    value="N/A",
         
     | 
| 1081 | 
         
            -
                                                    delta="No reference"
         
     | 
| 1082 | 
         
            -
                                                )
         
     | 
| 1083 | 
         
            -
             
     | 
| 1084 | 
         
            -
                                            # Confidence level
         
     | 
| 1085 | 
         
            -
                                            confidence_icon = "π’" if max_confidence >= 0.8 else "π‘" if max_confidence >= 0.6 else "π΄"
         
     | 
| 1086 | 
         
            -
                                            st.metric(
         
     | 
| 1087 | 
         
            -
                                                label="**Confidence Level**",
         
     | 
| 1088 | 
         
            -
                                                value=f"{confidence_icon} {confidence_desc}",
         
     | 
| 1089 | 
         
            -
                                                delta=f"{max_confidence:.1%}"
         
     | 
| 1090 | 
         
            -
                                            )
         
     | 
| 1091 | 
         
            -
             
     | 
| 1092 | 
         
            -
                                        # Right column: Probability distribution
         
     | 
| 1093 | 
         
            -
                                        with prob_col:
         
     | 
| 1094 | 
         
            -
                                            st.markdown("Probability Distribution")
         
     | 
| 1095 | 
         
            -
             
     | 
| 1096 | 
         
            -
                                            st.markdown(f"""
         
     | 
| 1097 | 
         
            -
                                                        <div style="">
         
     | 
| 1098 | 
         
            -
                                                            Stable (Unweathered)<br>
         
     | 
| 1099 | 
         
            -
                                                            {create_bullet_bar(stable_prob, predicted=is_stable_predicted)}<br><br>
         
     | 
| 1100 | 
         
            -
                                                            Weathered (Degraded)<br>
         
     | 
| 1101 | 
         
            -
                                                            {create_bullet_bar(weathered_prob, predicted=is_weathered_predicted)}
         
     | 
| 1102 | 
         
            -
                                                        </div>
         
     | 
| 1103 | 
         
            -
             
     | 
| 1104 | 
         
            -
                                            """, unsafe_allow_html=True)
         
     | 
| 1105 | 
         
            -
                                st.markdown(
         
     | 
| 1106 | 
         
            -
                                    '</div>', unsafe_allow_html=True)  # Close the wrapper div
         
     | 
| 1107 | 
         | 
| 1108 | 
         
             
                            elif active_tab == "Technical":
         
     | 
| 1109 | 
         
             
                                with st.container():
         
     | 
| 
         | 
|
| 718 | 
         
             
                        if uploaded_files:
         
     | 
| 719 | 
         
             
                            # --- START: Bug 1 Fix ---
         
     | 
| 720 | 
         
             
                            # Use a dictionary to keep only unique files based on name and size
         
     | 
| 721 | 
         
            +
                            unique_files = {(file.name, file.size): file for file in uploaded_files}
         
     | 
| 
         | 
|
| 722 | 
         
             
                            unique_file_list = list(unique_files.values())
         
     | 
| 723 | 
         | 
| 724 | 
         
             
                            num_uploaded = len(uploaded_files)
         
     | 
| 
         | 
|
| 848 | 
         | 
| 849 | 
         
             
                        # --- START: BUG 2 FIX (Button) ---
         
     | 
| 850 | 
         
             
                        # This button will clear all results from col2 correctly.
         
     | 
| 851 | 
         
            +
                        # st.button("Clear Results", on_click=clear_batch_results,
         
     | 
| 852 | 
         
            +
                        #           help="Clear all uploaded files and results.")
         
     | 
| 853 | 
         
             
                        # --- END: BUG 2 FIX (Button) ---
         
     | 
| 854 | 
         | 
| 855 | 
         
             
                        ResultsManager.display_results_table()
         
     | 
| 
         | 
|
| 959 | 
         
             
                            )
         
     | 
| 960 | 
         | 
| 961 | 
         
             
                            if active_tab == "Details":
         
     | 
| 
         | 
|
| 962 | 
         
             
                                st.markdown('<div class="expander-results">',
         
     | 
| 963 | 
         
             
                                            unsafe_allow_html=True)
         
     | 
| 964 | 
         
            +
                                # Use a dynamic and informative title for the expander
         
     | 
| 965 | 
         
            +
                                with st.expander(f"Results for {filename}", expanded=True):
         
     | 
| 966 | 
         
            +
             
     | 
| 967 | 
         
            +
                                    # --- START: STREAMLINED METRICS ---
         
     | 
| 968 | 
         
            +
                                    # A single, powerful row for the most important results.
         
     | 
| 969 | 
         
            +
                                    key_metric_cols = st.columns(3)
         
     | 
| 970 | 
         
            +
             
     | 
| 971 | 
         
            +
                                    # Metric 1: The Prediction
         
     | 
| 972 | 
         
            +
                                    key_metric_cols[0].metric(
         
     | 
| 973 | 
         
            +
                                        "Prediction", predicted_class)
         
     | 
| 974 | 
         
            +
             
     | 
| 975 | 
         
            +
                                    # Metric 2: The Confidence (with level in tooltip)
         
     | 
| 976 | 
         
            +
                                    confidence_icon = "π’" if max_confidence >= 0.8 else "π‘" if max_confidence >= 0.6 else "π΄"
         
     | 
| 977 | 
         
            +
                                    key_metric_cols[1].metric(
         
     | 
| 978 | 
         
            +
                                        "Confidence",
         
     | 
| 979 | 
         
            +
                                        f"{confidence_icon} {max_confidence:.1%}",
         
     | 
| 980 | 
         
            +
                                        help=f"Confidence Level: {confidence_desc}"
         
     | 
| 981 | 
         
            +
                                    )
         
     | 
| 982 | 
         
            +
             
     | 
| 983 | 
         
            +
                                    # Metric 3: Ground Truth + Correctness (Combined)
         
     | 
| 984 | 
         
            +
                                    if true_label_idx is not None:
         
     | 
| 985 | 
         
            +
                                        is_correct = (predicted_class == true_label_str)
         
     | 
| 986 | 
         
            +
                                        delta_text = "β
 Correct" if is_correct else "β Incorrect"
         
     | 
| 987 | 
         
            +
                                        # Use delta_color="normal" to let the icon provide the visual cue
         
     | 
| 988 | 
         
            +
                                        key_metric_cols[2].metric(
         
     | 
| 989 | 
         
            +
                                            "Ground Truth", true_label_str, delta=delta_text, delta_color="normal")
         
     | 
| 990 | 
         
            +
                                    else:
         
     | 
| 991 | 
         
            +
                                        key_metric_cols[2].metric("Ground Truth", "N/A")
         
     | 
| 992 | 
         
            +
             
     | 
| 993 | 
         
            +
                                    st.divider()
         
     | 
| 994 | 
         
            +
                                    # --- END: STREAMLINED METRICS ---
         
     | 
| 995 | 
         
            +
             
     | 
| 996 | 
         
            +
                                    # --- START: CONSOLIDATED CONFIDENCE ANALYSIS ---
         
     | 
| 997 | 
         
            +
                                    st.markdown("##### Probability Breakdown")
         
     | 
| 998 | 
         
            +
             
     | 
| 999 | 
         
            +
                                    # This custom bullet bar logic remains as it is highly specific and valuable
         
     | 
| 1000 | 
         
            +
                                    def create_bullet_bar(probability, width=20, predicted=False):
         
     | 
| 1001 | 
         
            +
                                        filled_count = int(probability * width)
         
     | 
| 1002 | 
         
            +
                                        bar = "β " * filled_count + \
         
     | 
| 1003 | 
         
            +
                                            "β" * (width - filled_count)
         
     | 
| 1004 | 
         
            +
                                        percentage = f"{probability:.1%}"
         
     | 
| 1005 | 
         
            +
                                        pred_marker = "β© Predicted" if predicted else ""
         
     | 
| 1006 | 
         
            +
                                        return f"{bar} {percentage}     {pred_marker}"
         
     | 
| 1007 | 
         
            +
             
     | 
| 1008 | 
         
            +
                                    stable_prob, weathered_prob = probs[0], probs[1]
         
     | 
| 1009 | 
         
            +
                                    is_stable_predicted, is_weathered_predicted = (
         
     | 
| 1010 | 
         
            +
                                        int(prediction) == 0), (int(prediction) == 1)
         
     | 
| 1011 | 
         
            +
             
     | 
| 1012 | 
         
            +
                                    st.markdown(f"""
         
     | 
| 1013 | 
         
            +
                                        <div style="font-family: 'Fira Code', monospace;">
         
     | 
| 1014 | 
         
            +
                                            Stable (Unweathered)<br>
         
     | 
| 1015 | 
         
            +
                                            {create_bullet_bar(stable_prob, predicted=is_stable_predicted)}<br><br>
         
     | 
| 1016 | 
         
            +
                                            Weathered (Degraded)<br>
         
     | 
| 1017 | 
         
            +
                                            {create_bullet_bar(weathered_prob, predicted=is_weathered_predicted)}
         
     | 
| 1018 | 
         
            +
                                        </div>
         
     | 
| 1019 | 
         
            +
                                    """, unsafe_allow_html=True)
         
     | 
| 1020 | 
         
            +
                                    # --- END: CONSOLIDATED CONFIDENCE ANALYSIS ---
         
     | 
| 1021 | 
         
            +
             
     | 
| 1022 | 
         
            +
                                    st.divider()
         
     | 
| 1023 | 
         
            +
             
     | 
| 1024 | 
         
            +
                                    # --- START: CLEAN METADATA FOOTER ---
         
     | 
| 1025 | 
         
            +
                                    # Secondary info is now a clean, single-line caption
         
     | 
| 1026 | 
         
            +
                                    st.caption(
         
     | 
| 1027 | 
         
            +
                                        f"Analyzed with **{model_choice}** in **{inference_time:.2f}s**.")
         
     | 
| 1028 | 
         
            +
                                    # --- END: CLEAN METADATA FOOTER ---
         
     | 
| 1029 | 
         
            +
             
     | 
| 1030 | 
         
            +
                                st.markdown('</div>', unsafe_allow_html=True)
         
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 1031 | 
         | 
| 1032 | 
         
             
                            elif active_tab == "Technical":
         
     | 
| 1033 | 
         
             
                                with st.container():
         
     |