""" Maturity Results Panel Panel for displaying multispectral maturity classification results with confidence bars. """ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QProgressBar, QSizePolicy from PyQt5.QtCore import Qt from PyQt5.QtGui import QFont class MaturityResultsPanel(QWidget): """ Panel for displaying maturity analysis results. """ def __init__(self, parent=None): super().__init__(parent) self.init_ui() def init_ui(self): """Initialize the panel UI.""" # Set size policy to expand equally self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) # Main panel container with card styling self.setStyleSheet(""" QWidget { background-color: white; border: 1px solid #ddd; } """) # Header header = QWidget() header.setFixedHeight(25) header.setStyleSheet("background-color: #8e44ad;") header_layout = QHBoxLayout(header) header_layout.setContentsMargins(10, 0, 0, 0) title = QLabel("Maturity Analysis Results") title.setStyleSheet("color: white; font-weight: bold; font-size: 16px;") header_layout.addWidget(title) # Current Classification classification_label = QLabel("Current Classification:") classification_label.setStyleSheet("font-weight: bold; font-size: 12px; margin: 8px 10px 5px 10px; color: #2c3e50;") classification_frame = QWidget() classification_frame.setStyleSheet("background-color: #95a5a6;") classification_frame.setMinimumHeight(45) classification_layout = QVBoxLayout(classification_frame) classification_layout.setAlignment(Qt.AlignCenter) classification_layout.setContentsMargins(5, 5, 5, 5) self.class_display = QLabel("—") self.class_display.setAlignment(Qt.AlignCenter) self.class_display.setStyleSheet("color: white; font-weight: bold; font-size: 18px;") classification_layout.addWidget(self.class_display) # Confidence Scores confidence_label = QLabel("Confidence Scores:") confidence_label.setStyleSheet("font-weight: bold; font-size: 11px; margin: 8px 10px 5px 10px; color: #2c3e50;") # Create progress bars for each category categories = [ ("Immature", 0, "#95a5a6"), ("Mature", 0, "#27ae60"), ("Overmature", 0, "#e74c3c") ] confidence_layout = QVBoxLayout() confidence_layout.setSpacing(4) self.confidence_bars = {} for name, value, color in categories: category_frame = QWidget() category_layout = QHBoxLayout(category_frame) category_layout.setContentsMargins(10, 0, 10, 0) category_layout.setSpacing(8) name_label = QLabel(f"{name}:") name_label.setFixedWidth(80) name_label.setStyleSheet("font-size: 10px; color: #2c3e50;") progress = QProgressBar() progress.setRange(0, 100) progress.setValue(int(value)) progress.setTextVisible(False) progress.setStyleSheet(f""" QProgressBar {{ background-color: #ecf0f1; border: 1px solid #bdc3c7; border-radius: 0px; height: 15px; }} QProgressBar::chunk {{ background-color: {color}; }} """) value_label = QLabel(f"{value}%") value_label.setFixedWidth(45) value_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) value_label.setStyleSheet("font-size: 12px; color: #2c3e50;") category_layout.addWidget(name_label) category_layout.addWidget(progress) category_layout.addWidget(value_label) confidence_layout.addWidget(category_frame) self.confidence_bars[name] = (progress, value_label) # Processing time self.info_label = QLabel("") self.info_label.setStyleSheet("color: #7f8c8d; font-size: 12px; margin: 8px 10px 5px 10px;") layout.addWidget(header) layout.addWidget(classification_label) layout.addWidget(classification_frame) layout.addWidget(confidence_label) layout.addLayout(confidence_layout) layout.addWidget(self.info_label) layout.addStretch() def update_results(self, classification: str, probabilities: dict, processing_time: float = 0, model_version: str = "MaturityNet v1.0"): """ Update the results display. Args: classification: Predicted class name probabilities: Dictionary of class probabilities (0-1) processing_time: Processing time in seconds model_version: Model version string """ # Map class names to display names class_mapping = { "Immature": "Immature", "Mature": "Mature", "Overmature": "Overmature" } display_class = class_mapping.get(classification, classification) # Update classification display self.class_display.setText(display_class.upper()) # Set color based on classification class_colors = { "Immature": "#95a5a6", "Mature": "#27ae60", "Overmature": "#e74c3c" } bg_color = class_colors.get(classification, "#95a5a6") self.class_display.parent().setStyleSheet(f"background-color: {bg_color};") self.class_display.setStyleSheet(""" color: white; font-weight: bold; font-size: 18px; """) # Update confidence bars for class_name, (progress_bar, value_label) in self.confidence_bars.items(): # Try to find matching probability (handle case variations) prob = 0 for key, value in probabilities.items(): if key.lower() == class_name.lower(): prob = value break percentage = prob * 100 # Update progress bar progress_bar.setValue(int(percentage)) # Update value label value_label.setText(f"{percentage:.1f}%") # Highlight primary class if class_name == display_class: value_label.setStyleSheet("font-size: 12px; font-weight: bold; color: #2c3e50;") else: value_label.setStyleSheet("font-size: 12px; color: #2c3e50;") # Update info label self.info_label.setText( f"Processing Time: {processing_time:.2f}s | Model: {model_version}" ) def clear_results(self): """Clear all results.""" self.class_display.setText("—") self.class_display.setStyleSheet(""" color: white; font-weight: bold; font-size: 18px; """) for progress_bar, value_label in self.confidence_bars.values(): progress_bar.setValue(0) value_label.setText("0%") value_label.setStyleSheet("font-size: 12px; color: #2c3e50;") self.info_label.setText("")