class_docstr: The gui to start and manipulate the analysis model
class_docstr_tok: ["The","gui","to","start","and","manipulate","the","analysis","model"]
docstr: All the ui layout in one place. Note: Part of the ui
  is switchable depending on the selected demo type, see the ui_matrix
docstr_tok: ["All","the","ui","layout","in","one","place",".","Note",":","Part","of","the","ui","is","switchable","depending","on","the","selected","demo","type",",","see","the","ui_matrix"]
code: def init_ui(self):
      """All the ui layout in one place. Note: Part of the ui
      is switchable depending on the selected demo type, see the ui_matrix
      """
      self.setWindowTitle(self.title)
      self.setGeometry(self.left, self.top, self.width, self.height)
  
      self.model = self.create_analysis_model(self)
      self.analysis_model = None
      self.top_scale = None
      self.thumb_size = (40, 40)
  
      # The analysis tree
      self.tree = QTreeView()
      self.tree.setSelectionBehavior(QAbstractItemView.SelectRows)
      self.tree.header().setSectionResizeMode(
          QHeaderView.ResizeToContents
      )
      self.tree.setIconSize(QSize(*self.thumb_size))
      self.tree.setModel(self.model)
  
      self.tree.setAnimated(False)
      self.tree.setIndentation(20)
      self.tree.setSortingEnabled(True)
  
      self.tree.resize(640, 480)
  
      # Control layout
      controlLayout = QVBoxLayout()
  
      self.preconfigured_group = QGroupBox("Preconfigured")
      preconfigured_layout = QFormLayout(self)
      self.preconfigured_combo = QComboBox(self)
      self.preconfigured_combo.addItem("None", userData=None)
      for config in CONFIGS:
          self.preconfigured_combo.addItem(
              config.descriptor, userData=config
          )
      self.preconfigured_combo.currentIndexChanged[int].connect(
          self.on_preconfigured
      )
      preconfigured_layout.addRow(
          QLabel("Load preset demo:"), self.preconfigured_combo
      )
      self.preconfigured_group.setLayout(preconfigured_layout)
      controlLayout.addWidget(self.preconfigured_group)
  
      # Data type settings
      self.demo_type_group = QGroupBox("Data type")
      data_type_layout = QFormLayout(self)
      self.data_type_combo = QComboBox(self)
      self.data_type_combo.addItem(
          "Image is a data point", DemoType.LABELLED_DEMO
      )
      self.data_type_combo.addItem(
          "Point and metadata", DemoType.POINT_DEMO
      )
      self.data_type_combo.addItem(
          "Hyperspectral image", DemoType.HYPERSPECTRAL_DEMO
      )
      data_type_layout.addRow(
          QLabel("Visualization style:"), self.data_type_combo
      )
      self.data_type_combo.currentIndexChanged[int].connect(
          self.on_demo_style
      )
  
      data_button = QPushButton("Data")
      data_button.clicked.connect(self.on_load)
      self.data_label = QLabel("<choose data .npy>")
      data_type_layout.addRow(data_button, self.data_label)
  
      self.xy_label = QLabel("Image size")
      self.label_x = QLabel("X:")
      self.label_y = QLabel("Y:")
      self.image_x = QLineEdit()
      self.image_x.setValidator(QIntValidator(1, 10000))
      self.image_y = QLineEdit()
      self.image_y.setValidator(QIntValidator(1, 10000))
  
      self.xy_container = QWidget()
      self.xy_layout = QHBoxLayout()
      self.xy_layout.setContentsMargins(0, 0, 0, 0)
      self.xy_layout.addWidget(self.label_x)
      self.xy_layout.addWidget(self.image_x)
      self.xy_layout.addWidget(self.label_y)
      self.xy_layout.addWidget(self.image_y)
      self.xy_container.setLayout(self.xy_layout)
      data_type_layout.addRow(self.xy_label, self.xy_container)
  
      self.label_button = QPushButton("Labels")
      self.label_button.clicked.connect(self.on_load_labels)
      self.label_label = QLabel("<optionally choose labels .npy>")
      data_type_layout.addRow(self.label_button, self.label_label)
  
      self.meta_button = QPushButton("Label/Color metadata")
      self.meta_button.clicked.connect(self.on_load_labelscolors)
      self.meta_label = QLabel("<optionally choose label/color .csv>")
      data_type_layout.addRow(self.meta_button, self.meta_label)
      self.demo_type_group.setLayout(data_type_layout)
      controlLayout.addWidget(self.demo_type_group)
  
      # Hsne settings
      self.hsne_group = QGroupBox("hSNE settings")
      self.hsne_form_layout = QFormLayout(self)
  
      hsne_button = QPushButton("Preload")
      hsne_button.clicked.connect(self.on_load_hsne)
      self.hsne_label = QLabel("<optionally choose existing .hsne>")
      self.hsne_form_layout.addRow(hsne_button, self.hsne_label)
  
      self.scale_spin = QSpinBox(self)
      self.scale_spin.setRange(1, 10)
      self.scale_spin.setValue(4)
      self.hsne_form_layout.addRow(QLabel("Scales:"), self.scale_spin)
  
      self.hsne_group.setLayout(self.hsne_form_layout)
      controlLayout.addWidget(self.hsne_group)
  
      # Embedding settings
      self.embedding_group = QGroupBox("Embedding settings")
      embed_form_layout = QFormLayout(self)
      self.iter_spin = QSpinBox(self)
      self.iter_spin.setRange(350, 1000)
      self.iter_spin.setSingleStep(5)
      self.iter_spin.setValue(500)
      embed_form_layout.addRow(QLabel("Iterations:"), self.iter_spin)
      self.embedding_group.setLayout(embed_form_layout)
  
      controlLayout.addWidget(self.embedding_group)
  
      clear_start_layout = QHBoxLayout()
      self.start_button = QPushButton("Start")
      self.start_button.clicked.connect(self.on_start)
      self.start_button.setDisabled(True)
      self.clear_button = QPushButton("Clear")
      self.clear_button.clicked.connect(self.on_clear)
  
      clear_start_layout.addWidget(self.start_button)
      clear_start_layout.addWidget(self.clear_button)
  
      controlLayout.addLayout(clear_start_layout)
  
      self.delete_button = QPushButton("Delete selected")
      self.delete_button.clicked.connect(self.on_delete)
  
      # Selection
      self.tree.clicked.connect(self.on_selected)
  
      # Layout
      main_layout = QGridLayout()
      # row, col, rowSpan, colSpan
      main_layout.addWidget(self.tree, 0, 0, 10, 5)
      main_layout.addLayout(controlLayout, 0, 5, 10, 3)
  
      main_layout.addWidget(self.delete_button, 11, 2, 1, 2)
      self.setLayout(main_layout)
      self.counter = 0
      self.event_timer = QTimer(self)
      self.event_timer.start(500)
      self.event_timer.timeout.connect(self.update_tree)
  
      # Dynamic UI matrix
      # According to DemoType True widgets are shown False widgets hidden
      self.ui_matrix = {
          DemoType.LABELLED_DEMO: {
              True: [
                  self.label_button,
                  self.label_label,
                  self.xy_container,
                  self.xy_label,
              ],
              False: [self.meta_button, self.meta_label],
          },
          DemoType.POINT_DEMO: {
              True: [self.meta_button, self.meta_label],
              False: [
                  self.label_button,
                  self.label_label,
                  self.xy_container,
                  self.xy_label,
              ],
          },
          DemoType.HYPERSPECTRAL_DEMO: {
              True: [self.xy_container, self.xy_label],
              False: [
                  self.label_button,
                  self.label_label,
                  self.meta_button,
                  self.meta_label,
              ],
          },
      }
  
      self.show()
      self.on_demo_style(0)
  
imports: import sys
  import os
  import queue
  from pathlib import Path
  import math
  from enum import Enum
  import nptsne
  import numpy
  import PIL
  from PIL import ImageQt, Image
  from PyQt5.QtWidgets import QApplication, QTreeView, QWidget, QGridLayout, QDialog, QGroupBox, QFormLayout, QPushButton, QLabel, QSpinBox, QFileDialog, QAbstractItemView, QComboBox, QHBoxLayout, QVBoxLayout, QLineEdit, QHeaderView
  from PyQt5.QtCore import Qt, QTimer, QSize, pyqtSlot
  from PyQt5.QtGui import QIcon, QStandardItemModel, QStandardItem, QPixmap, QIntValidator
  from DemoConfig import CONFIGS
label_desc: Use image node_id 2 for calling the ModelGui obj's underlying member method code with example usage: obj.init_ui() without return types