Подгонка нескольких кривых или отображение на тепловой карте - PullRequest
0 голосов
/ 26 февраля 2020

У меня есть два столбца, я пробовал это:

df[['EYE_WIDTH','LANE']].groupby(['EYE_WIDTH','LANE']).size().unstack()

Теперь я получил эту таблицу:

LANE          0      1      2      3      4      5      6      7      8   \
EYE_WIDTH                                                                  
31.2         NaN    NaN    NaN    NaN    NaN    NaN    1.0    NaN    NaN   
35.1         NaN    NaN    NaN    NaN    NaN    1.0    NaN    1.0    NaN   
39.0         NaN    1.0    NaN    2.0    NaN    NaN    2.0    1.0    NaN   
42.9         1.0    5.0    5.0   10.0    2.0    5.0    9.0   17.0    3.0   
46.8        19.0   14.0   17.0   23.0   27.0   31.0   42.0   39.0   27.0   
50.7        84.0   48.0   63.0   93.0   69.0   95.0  137.0  130.0   99.0   
54.6       204.0  173.0  176.0  206.0  158.0  158.0  207.0  182.0  199.0   
58.5       350.0  308.0  296.0  284.0  257.0  214.0  237.0  228.0  235.0   
62.4       282.0  278.0  242.0  257.0  275.0  236.0  259.0  206.0  237.0   
66.3       112.0  180.0  212.0  167.0  213.0  244.0  152.0  223.0  197.0   
70.2        26.0   64.0   65.0   41.0   80.0   91.0   39.0   59.0   76.0   
74.1         2.0   11.0    4.0    1.0    5.0    9.0    2.0    1.0    3.0   
78.0         NaN    NaN    NaN    NaN    NaN    NaN    1.0    NaN    1.0   

LANE          9      10     11     12     13     14     15  
EYE_WIDTH                                                   
31.2         NaN    NaN    NaN    NaN    NaN    NaN    NaN  
35.1         NaN    1.0    NaN    1.0    NaN    NaN    NaN  
39.0         3.0    3.0    3.0    2.0    3.0    6.0    NaN  
42.9        11.0    6.0    7.0    3.0   14.0    7.0    7.0  
46.8        43.0   39.0   41.0   15.0   16.0   29.0   35.0  
50.7       101.0  114.0  144.0   56.0   78.0   96.0  116.0  
54.6       206.0  210.0  193.0  187.0  158.0  186.0  283.0  
58.5       275.0  231.0  246.0  251.0  278.0  295.0  344.0  
62.4       219.0  233.0  217.0  203.0  278.0  257.0  212.0  
66.3       167.0  196.0  163.0  243.0  197.0  161.0   73.0  
70.2        50.0   46.0   58.0   99.0   53.0   40.0   10.0  
74.1         2.0    3.0    5.0   20.0    5.0    4.0    1.0  
78.0         NaN    NaN    NaN    NaN    NaN    NaN    NaN  

Теперь я хочу визуализировать эти отношения, одна вещь, которую я имею в разум подбирает их вдоль кривых, как показано ниже enter image description here, и хорошо, если я смогу также представить их в тепловой карте.

Первые несколько строк данных

   EYE_WIDTH  LANE
     66.3    11
     58.5    12
     70.2    13
     66.3     7
     58.5    14
     58.5     0
     62.4     1
     62.4     2
     54.6     3
     62.4     4
     58.5     5
     50.7     6
     62.4    15
     66.3     8
     70.2     9
     58.5    10
     66.3     1
     58.5     7
     66.3     8
     50.7     9
     62.4     0
     62.4    11
     62.4    12
     66.3    13
     66.3    15
     58.5    10
     50.7     2
     58.5     3
     54.6     4
     50.7     5
     50.7     6
     58.5    14
     62.4     1
     62.4     2
     62.4     3
     62.4     4
     54.6     5
     62.4     6
     58.5     7
     62.4     8
     66.3     9
     62.4    10
     62.4    11
     62.4    12
     62.4    13
     54.6     0
     66.3    15
     62.4    14
     58.5    15
     54.6    13

Таким образом, существует 13 различных значений EYE_WIDTH и 16 различных LANE, теперь, используя групповую разметку и размер стека, я узнал, сколько раз каждая полоса связана с отдельным EYE_WIDTH. Теперь мне нужно визуализировать эти отношения

Я пытался:

df[['EYE_WIDTH','LANE']].groupby(['EYE_WIDTH','LANE']).size().unstack().plot()

enter image description here

1 Ответ

1 голос
/ 26 февраля 2020

Ну, один из способов найти структуру в данных - это попробовать разные визуализации. Визуализация, которую вы получили с помощью команды 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()

resulting plot

...