0

I'm attempting to plot a PCP graph from the Pymoo package into a Pyside6 canvas. I've integrated an interactive mouse button that finds the closest line to the button press. However, I seem stuck at updating the plot with the new highlighted line as the program replicates the original without any highlights. Does anyone have any advise on how to overcome this issue?

import matplotlib.pyplot as plt
from PySide6 import QtCore, QtGui, QtWidgets
from matplotlib.backends.backend_qt5agg import (FigureCanvasQTAgg
, NavigationToolbar2QT as NavigationToolbar)
from pymoo.visualization.pcp import PCP
from pymoo.util.reference_direction import UniformReferenceDirectionFactory
from pymoo.problems.many.dtlz import DTLZ1
import numpy as np
import matplotlib.path as mpath
import sys
import math


def pymooplot(*lines):

    ref_dirs = UniformReferenceDirectionFactory(6, n_partitions=5)() * [2, 4, 8, 16, 32, 64]
    F = DTLZ1().pareto_front(ref_dirs)

    plot = PCP().add(F)
    if lines:
        y = lines[0]
        print(y)
        plot.add(F[y], linewidth=5, color="red")

    plot.do()
    return plot.fig


def method(plot):
    # Get all the lines from the figure
    # Extract the lines from the figure
    lines = plot.gca().get_lines()

    # Determine the maximum number of points in any line
    max_points = max([len(line.get_xdata()) for line in lines])

    # Initialize an array with the appropriate shape
    line_data = np.empty((len(lines), max_points, 2))
    line_data[:] = np.nan

    # Fill the array with the line data
    for i, line in enumerate(lines):
        xy = line.get_xydata()
        line_data[i, :len(xy), :] = xy

    return line_data


class MainWindow(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super().__init__()
        self.setInteractive(True)

        self.fig = pymooplot()
        self.canvas = FigureCanvasQTAgg(self.fig)
        self.toolbar = NavigationToolbar(self.canvas, self)

        # Create a layout for the figure and toolbar
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.canvas)
        layout.addWidget(self.toolbar)
        self.setLayout(layout)
        self.canvas.draw()

        # Connect the canvas to the mouse press event
        self.canvas.mpl_connect("button_press_event", self.on_press)

    def on_press(self, event):
        # Get the mouse click coordinates
        x = event.xdata
        y = event.ydata
        print("Mouse clicked at (%.2f, %.2f)" % (x, y))

        belowX = math.floor(x)
        aboveX = math.ceil(x)

        # Specify the point you want to check
        point = np.array([x, y])

        # Specify the range of error
        error_range = 0.05

        # Initialize a flag to indicate if the point intersects with any line
        intersects = False

        # Loop through the lines and check if the point intersects with any of them
        for count, line in enumerate(line_data):
            x1, y1 = line[belowX, :]
            x2, y2 = line[aboveX, :]
            # Calculate the point-to-line distance
            dist = np.abs((y2 - y1) * point[0] - (x2 - x1) * point[1] + x2 * y1 - y2 * x1) / np.sqrt(
                (y2 - y1) ** 2 + (x2 - x1) ** 2)
            # If the distance is within the range of error, the point intersects with the line
            if dist <= error_range:
                intersects = True
                print(count)
                self.fig = pymooplot(count)
                self.canvas.draw()
                break

        # Print the result
        print("Point intersects with a line:", intersects)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    line_data = method(pymooplot())

    sys.exit(app.exec())
Bram
  • 17
  • 2

0 Answers0