Как при нажатии на график сделать так,чтобы выбиралась ближайшая существующая точка
Есть график в матплотлибе,построенный по данным, считанным из эксель файла через пандас,график представляет собой точки по двум столбцам из эксель файла,необходимо сделать так,чтобы при нажатии на любое место на графике выделялась ближайшая лежащая к этому месту существующая точка
Ответы (1 шт):
Я нашёл решение, только оно немного некрасивое, чтоли...
Нам нужно найти ближайшую точку массива от точки нажатия на график, можем создадть функцию используя 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()
Результат:
