class ClusteringGui(QMainWindow): # ui layout: QVBoxLayout # Main Layout in which everything else is contained browse_btn: QPushButton # Load Dataset button k_selector: QSpinBox # Selector for k value repetitions_selector: QSpinBox # Select how many times K-Means is ran per dataset run_btn: QPushButton # Run button step_btn: QPushButton # Next button dimensions_label: QLabel # Filled with vector dimensions found from dataset recommended_k_label: QLabel # Filled with recommended K value as calculated using SSE / Elbow method plot_canvas: FigureCanvas # Canvas containing matplotlib plot path: str # Path of current loaded dataset kmeans: KMeans figure: plt.Figure elbow_chart: QWidget def __init__(self): self.kmeans = KMeans() super(ClusteringGui, self).__init__() uic.loadUi(main_interface_file, self) self.browse_btn = self.findChild(QPushButton, 'browse_button') self.browse_btn.clicked.connect(self.on_browse_click) self.k_selector = self.findChild(QSpinBox, 'k_val_selector') self.k_selector.valueChanged.connect(self.on_update_k) self.repetitions_selector = self.findChild(QSpinBox, 'k_repetitions_selector') self.repetitions_selector.valueChanged.connect(self.on_set_repetitions) self.run_btn = self.findChild(QPushButton, 'run_button') self.run_btn.clicked.connect(self.on_run_click) self.run_btn.setEnabled(False) self.step_btn = self.findChild(QPushButton, 'step_button') self.step_btn.clicked.connect(self.on_step_click) self.step_btn.setEnabled(False) self.elbow_btn = self.findChild(QPushButton, 'elbow_chart_button') self.elbow_btn.clicked.connect(self.on_show_elbow) self.elbow_btn.setEnabled(False) self.layout = self.findChild(QVBoxLayout, 'layout') self.dimensions_label = self.findChild(QLabel, 'dimensions_label') self.dimensions_label.setText("") self.show() @pyqtSlot() def on_browse_click(self): self.path, _ = QFileDialog.getOpenFileName(self, "Open Dataset", "", "CSV Files (*.csv)") try: self.kmeans.open_dataset(filepath=self.path) self.dimensions_label.setText("Dimensions: {}".format(self.kmeans.dimensions)) self.add_matplotlib_canvas() self.setWindowTitle('K-Means Clustering: {}'.format(self.path)) self.elbow_btn.setEnabled(True) self.run_btn.setEnabled(True) self.step_btn.setEnabled(True) except FileNotFoundError: print("Exception") error_dialog = QErrorMessage() error_dialog.showMessage("File Not Found, try again") error_dialog.exec() @pyqtSlot() def on_show_elbow(self): sse = [] # Calculate SSE for values of K ranging from 1 to 10. for i in range(1,10): print("Calculating SSE for K =", i) self.kmeans.update_k(i) # Cluster and update centroids 3 times for each K value self.kmeans.cluster_points() self.kmeans.cluster_points() self.kmeans.cluster_points() sse.append(self.kmeans.calculate_sse()) self.elbow_chart = ElbowChartGui() self.elbow_chart.plot(sse, self.path) # Handles K value being changed @pyqtSlot() def on_update_k(self): self.kmeans.update_k(self.k_selector.value()) # If there's data being displayed, update it now if self.kmeans.data_displayed: self.update_matplotlib() @pyqtSlot() def on_run_click(self): self.kmeans.run() self.update_matplotlib() @pyqtSlot() def on_set_repetitions(self): self.kmeans.repetitions = self.repetitions_selector.value() # Handles 'Next' button being pressed @pyqtSlot() def on_step_click(self): self.kmeans.step() self.update_matplotlib() # Adds the matplotlib canvas to the UI def add_matplotlib_canvas(self): try: self.figure.clear() except AttributeError: self.figure = plt.figure() self.plot_canvas = FigureCanvas(self.figure) self.layout.addWidget(self.plot_canvas) ax = self.figure.add_subplot(1, 1, 1) x = [point[0] for point in self.kmeans.vectors] y = [point[1] for point in self.kmeans.vectors] ax.scatter(x, y, alpha=0.8) self.plot_canvas.draw() # Updates the matplotlib UI def update_matplotlib(self): self.figure.clear() ax = self.figure.add_subplot(1, 1, 1) for cluster in self.kmeans.clusters: x = [point[0] for point in cluster] y = [point[1] for point in cluster] ax.scatter(x, y, alpha=0.5) for centroid in self.kmeans.centroids: x, y = centroid[0], centroid[1] ax.scatter(x, y, c='k', alpha=0.8) self.plot_canvas.draw()