Ну, один из способов найти структуру в данных - это попробовать разные визуализации. Визуализация, которую вы получили с помощью команды pandas plot, уже предполагает, что между каждой из «дорожек» нет большой разницы.
Вот некоторый код для рисования графика с гладкой линией и тепловой карты данного данные. Как и на прямом графике, данные, по-видимому, не указывают на сильное влияние параметра полосы движения. Прямая линия более «честна», так как показывает чистые данные.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from numpy import NaN
from scipy.interpolate import interp1d
eye_width = [31.2, 35.1, 39.0, 42.9, 46.8, 50.7, 54.6, 58.5, 62.4, 66.3, 70.2, 74.1, 78.0]
rows = np.array([
[NaN, NaN, NaN, NaN, NaN, NaN, 1.0, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN],
[NaN, NaN, NaN, NaN, NaN, 1.0, NaN, 1.0, NaN, NaN, 1.0, NaN, 1.0, NaN, NaN, NaN],
[NaN, 1.0, NaN, 2.0, NaN, NaN, 2.0, 1.0, NaN, 3.0, 3.0, 3.0, 2.0, 3.0, 6.0, NaN],
[1.0, 5.0, 5.0, 10.0, 2.0, 5.0, 9.0, 17.0, 3.0, 11.0, 6.0, 7.0, 3.0, 14.0, 7.0, 7.0],
[19.0, 14.0, 17.0, 23.0, 27.0, 31.0, 42.0, 39.0, 27.0, 43.0, 39.0, 41.0, 15.0, 16.0, 29.0, 35.0],
[84.0, 48.0, 63.0, 93.0, 69.0, 95.0, 137.0, 130.0, 99.0, 101.0, 114.0, 144.0, 56.0, 78.0, 96.0, 116.0],
[204.0, 173.0, 176.0, 206.0, 158.0, 158.0, 207.0, 182.0, 199.0, 206.0, 210.0, 193.0, 187.0, 158.0, 186.0, 283.0],
[350.0, 308.0, 296.0, 284.0, 257.0, 214.0, 237.0, 228.0, 235.0, 275.0, 231.0, 246.0, 251.0, 278.0, 295.0, 344.0],
[282.0, 278.0, 242.0, 257.0, 275.0, 236.0, 259.0, 206.0, 237.0, 219.0, 233.0, 217.0, 203.0, 278.0, 257.0, 212.0],
[112.0, 180.0, 212.0, 167.0, 213.0, 244.0, 152.0, 223.0, 197.0, 167.0, 196.0, 163.0, 243.0, 197.0, 161.0, 73.0],
[26.0, 64.0, 65.0, 41.0, 80.0, 91.0, 39.0, 59.0, 76.0, 50.0, 46.0, 58.0, 99.0, 53.0, 40.0, 10.0],
[2.0, 11.0, 4.0, 1.0, 5.0, 9.0, 2.0, 1.0, 3.0, 2.0, 3.0, 5.0, 20.0, 5.0, 4.0, 1.0],
[NaN, NaN, NaN, NaN, NaN, NaN, 1.0, NaN, 1.0, NaN, NaN, NaN, NaN, NaN, NaN, NaN]])
df = pd.DataFrame(data=rows)
df['eye_width'] = eye_width
df.set_index(['eye_width'], inplace=True)
df.fillna(value=0, inplace=True)
fig, (ax, ax2) = plt.subplots(ncols=2, figsize=(12, 4))
x = np.linspace(min(eye_width), max(eye_width), 1000)
for i in range(0, 16, 3):
# ax.plot(df.index, df[i], label=f'Lane {i}')
interpolation = interp1d(df.index, df[i], kind='cubic')
ax.plot(x, interpolation(x), label=f'Lane {i}')
ax.legend(loc='best')
img = ax2.imshow(rows, origin='lower')
ax2.set_xticks(range(16))
ax2.set_yticks(range(len(eye_width)))
ax2.set_yticklabels(eye_width)
plt.colorbar(img, ax=ax2)
plt.tight_layout()
plt.show()