Как при нажатии на график сделать так,чтобы выбиралась ближайшая существующая точка

Есть график в матплотлибе,построенный по данным, считанным из эксель файла через пандас,график представляет собой точки по двум столбцам из эксель файла,необходимо сделать так,чтобы при нажатии на любое место на графике выделялась ближайшая лежащая к этому месту существующая точка


Ответы (1 шт):

Автор решения: Acinit

Я нашёл решение, только оно немного некрасивое, чтоли...

Нам нужно найти ближайшую точку массива от точки нажатия на график, можем создадть функцию используя numpy, скормим ей листы x и y и точки нажатия как x_val и y_val. Используя теорему Пифагора (формулу расстония между двумя точками в декартовой системе координат), а именно корень из суммы квадратов разности x-x_val и y-y_val мы получаем расстония от точки нажатия до точки на графике. Затем возьмём минимальное значение данного расстояния, вернём x[индекс данного расстояния] и y[индекс данного расстояния].

def find_nearest_point(x, y, x_val, y_val):
    distances = np.sqrt((np.array(x) - x_val) ** 2 + (np.array(y) - y_val) ** 2)
    index = np.argmin(distances)
    return x[index], y[index]

Чтобы реализовать клик, используем mpl_connect с эвентом 'button_press_event', в качестве аргумента зададим функцию on_click, в которой мы схватим данные ивента, из них достанем точку нажатия, првоерим, что она в предлелах графика, поулчим нашу минимальную дистанцию, заранее очистим график от других точек, а затем построим точку на основе функции минимальной дистанции по графику, а после отрисуем

def on_click(event):
    global selected_point

    if event.inaxes:  # Проверка, что событие произошло в пределах графика
        x, y = event.xdata, event.ydata  # Получите координаты клика
        x_nearest, y_nearest = find_nearest_point(x_data, y_data, x, y)

        # Удалите старую точку, если она есть
        if selected_point:
            selected_point.remove()

        selected_point, = plt.plot(x_nearest, y_nearest, 'ro')  # Установите новую точку на графике
        plt.draw()  # Перерисуйте график

В строке

fig.canvas.mpl_connect('button_press_event', on_click)

Можем протестировать, вот полный код

import matplotlib.pyplot as plt
import numpy as np

# Создайте пустой список для хранения выбранных точек
selected_point = None

# Примерные данные для графика
x_data = range(1,100)
y_data = range(1,100)

# Создайте функцию для поиска ближайшей точки на линии графика
def find_nearest_point(x, y, x_val, y_val):
    distances = np.sqrt((np.array(x) - x_val) ** 2 + (np.array(y) - y_val) ** 2)
    index = np.argmin(distances)
    return x[index], y[index]

# Функция, которая будет вызываться при клике мышью
def on_click(event):
    global selected_point

    if event.inaxes:  # Проверка, что событие произошло в пределах графика
        x, y = event.xdata, event.ydata  # Получите координаты клика
        x_nearest, y_nearest = find_nearest_point(x_data, y_data, x, y)

        # Удалите старую точку, если она есть
        if selected_point:
            selected_point.remove()

        selected_point, = plt.plot(x_nearest, y_nearest, 'ro')  # Установите новую точку на графике
        plt.draw()  # Перерисуйте график

# Создайте фигуру и оси для вашего графика
fig, ax = plt.subplots()

# Нарисуйте график
ax.plot(x_data, y_data, linestyle='-', color='black')

# Настройки для осей и заголовка
ax.set_xlabel('X-ось')
ax.set_ylabel('Y-ось')
ax.set_title('Выбор точек на графике')

# Настройте обработчик событий для кликов мышью
fig.canvas.mpl_connect('button_press_event', on_click)

# Отобразите график
plt.show()

Результат:

введите сюда описание изображения

→ Ссылка