на основе этого кода доработай мой код с точки зрения алгоритма, визуализацию не меняй,каким образом тут высчитывается траектория? какие формулы используются?
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
df= pd.read_csv('df.csv')
df = df.drop(columns=['T[sec]'])
# Преобразование значений из строк в числа с заменой запятых
df = df.apply(lambda col: col.str.replace(',', '.').astype(float))
leads = pd.read_csv('leads.csv')
# Приведение столбцов df и поля Lead в leads к нижнему регистру
df.columns = df.columns.str.lower()  # Приводим названия столбцов df к нижнему регистру
leads['Lead'] = leads['Lead'].str.lower()  # Приводим значения в столбце Lead к нижнему регистру
# Создаем словарь координат
coords = leads.set_index('Lead').to_dict(orient='index')

# Сохраняем изначальные столбцы
original_columns = df.columns.tolist()
num_columns = len(df.columns)

# Функция для вычисления координаты
def calculate_weighted_coordinate(row, coord, relevant_columns):
    # Используем только существующие электроды
    electrodes = [e for e in relevant_columns if e in coords]
    weighted_sum = sum(row[e] * coords[e][coord] for e in electrodes)
    total_excitation = sum(row[e] for e in electrodes)
    return weighted_sum / total_excitation if total_excitation != 0 else 0
    #return weighted_sum / num_columns if total_excitation != 0 else 0
    # max_value = max(row[e] for e in electrodes)  # Находим максимальное значение в строке
    # return weighted_sum / max_value if max_value != 0 else 0  # Делим на максимальное значение

# Вычисляем x, y, z, исключая новые столбцы
df['x'] = df.apply(lambda row: calculate_weighted_coordinate(row, 'x', original_columns), axis=1)
df['y'] = df.apply(lambda row: calculate_weighted_coordinate(row, 'y', original_columns), axis=1)
df['z'] = df.apply(lambda row: calculate_weighted_coordinate(row, 'z', original_columns), axis=1)

# Создание 3D-графика
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

# Извлекаем координаты
x_coords = leads['x']
y_coords = leads['y']
z_coords = leads['z']

# Отрисовка точек
ax.scatter(x_coords, y_coords, z_coords, c='blue', marker='o', s=100, label='Leads')

# Добавление подписей к точкам
for i, lead in enumerate(leads['Lead']):
    ax.text(x_coords.iloc[i], y_coords.iloc[i], z_coords.iloc[i], lead, fontsize=12, color='red')

# Настройки осей
ax.set_xlabel('X Coordinate')
ax.set_ylabel('Y Coordinate')
ax.set_zlabel('Z Coordinate')
ax.set_title('3D Visualization of Leads')

# Показ графика
plt.legend()
plt.show()
import plotly.express as px

# Создание 3D-графика с помощью plotly
fig = px.scatter_3d(leads, x='x', y='y', z='z', text='Lead', title='3D Visualization of Leads')

# Настройка подписи
fig.update_traces(marker=dict(size=10, color='blue', opacity=0.6), textposition='top center')

# Показ графика
fig.show()
import plotly.graph_objects as go

# Задаем диапазон строк для отображения
n = 1  # Начальная строка (нумерация с 0)
m = 500  # Конечная строка (не включительно)

# Срез строки из df
df_subset = df.iloc[n:m]

# Создаем 3D-график
fig = go.Figure()

# Добавляем точки для leads
fig.add_trace(go.Scatter3d(
    x=leads['x'],
    y=leads['y'],
    z=leads['z'],
    mode='markers+text',
    marker=dict(size=10, color='blue', opacity=0.6),
    text=leads['Lead'],
    textposition='top center',
    name='Leads'
))

# Добавляем точки из среза df
fig.add_trace(go.Scatter3d(
    x=df_subset['x'],
    y=df_subset['y'],
    z=df_subset['z'],
    mode='markers+lines+text',
    marker=dict(size=8, color='red', opacity=0.7),
    text=[f'Point {i+1}' for i in df_subset.index],
    textposition='top center',
    name=f'Points from df (Rows {n} to {m})'
))

# Добавление стрелок между точками в срезе df
for i in range(1, len(df_subset)):
    fig.add_trace(go.Cone(
        x=[df_subset['x'].iloc[i-1]],
        y=[df_subset['y'].iloc[i-1]],
        z=[df_subset['z'].iloc[i-1]],
        u=[df_subset['x'].iloc[i] - df_subset['x'].iloc[i-1]],
        v=[df_subset['y'].iloc[i] - df_subset['y'].iloc[i-1]],
        w=[df_subset['z'].iloc[i] - df_subset['z'].iloc[i-1]],
        anchor="tail",
        showscale=False,
        colorscale='YlOrRd',
        sizemode="scaled",
        sizeref=0.1,
        opacity=0.7
    ))

# Настройки осей
fig.update_layout(
    scene=dict(
        xaxis_title='X Coordinate',
        yaxis_title='Y Coordinate',
        zaxis_title='Z Coordinate',
    ),
    title=f"3D Visualization of Leads and Points from df (Rows {n} to {m})"
)

# Показ графика
fig.show()

Мой код:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Загрузка данных
eeg_file_path = 'E:/maga/3 семестр/СРиОД/conan-EEG/Blinks/нормализованные_данные2.xlsx'
df = pd.read_excel(eeg_file_path)

# Предобработка данных
if 'Time' in df.columns:
    df.drop(columns=['Time'], inplace=True)

df = df.replace(',', '.', regex=True).astype(float)

# Вычисление координат возбуждения
df['x'] = np.sin(df.mean(axis=1))
df['y'] = np.cos(df.mean(axis=1))
df['z'] = df.var(axis=1)

# Пространственное расположение электродов
leads = pd.read_csv('E:/maga/3 семестр/СРиОД/conan-EEG/Blinks/leads.csv')

# Визуализация расположения электродов
plt.figure(figsize=(10, 8))
plt.scatter(leads['x'], leads['y'], c='blue', label='Электроды')
for i, txt in enumerate(leads['Lead']):  # 'Lead' - названия электродов
    plt.annotate(txt, (leads['x'][i], leads['y'][i]), fontsize=9, color='red')
plt.xlabel('X координата')
plt.ylabel('Y координата')
plt.title('Расположение электродов')
plt.legend()
plt.grid()
plt.show()

# Визуализация траектории возбуждения с цветом
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')

# Используем градиент цвета для времени
time_steps = np.linspace(0, 1, len(df))  # Массив для временного контекста
sc = ax.scatter(df['x'], df['y'], df['z'], c=time_steps, cmap='viridis', label='Траектория', s=15)

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.set_title('Траектория возбуждения')

# Добавляем colorbar, используя объект scatter (sc)
cbar = plt.colorbar(sc, ax=ax, pad=0.1)
cbar.set_label('Время')  # Подпись для цветовой шкалы

ax.legend()
plt.show()

# Совмещенная визуализация траектории и электродов
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')

# Электроды
ax.scatter(leads['x'], leads['y'], leads['z'], c='blue', label='Электроды', s=50)
for i, txt in enumerate(leads['Lead']):  # 'Lead' - названия электродов
    ax.text(leads['x'][i], leads['y'][i], leads['z'][i], txt, color='red', fontsize=9)

# Траектория возбуждения
time_steps = np.linspace(0, 1, len(df))  # Массив времени
ax.plot(df['x'], df['y'], df['z'], color='green', label='Траектория', linewidth=1.5)

# Оси и заголовок
ax.set_xlabel('X координата')
ax.set_ylabel('Y координата')
ax.set_zlabel('Z координата')
ax.set_title('Траектория возбуждения и расположение электродов')

ax.legend()
plt.show()

Внеси изменения в мой код, чтобы координаты расчитывались правильно, и правильно визуализировались