Как построить границы неопределенности множества кривых, где каждая кривая имеет несовместимые временные шаги - PullRequest
0 голосов
/ 12 сентября 2018

Предположим, у нас есть набор последовательностей дискретных точек.Каждый из них имеет различное горизонтальное значение (скажем, временные шаги), тогда как лучше всего построить границы неопределенности по кривым, описываемым дискретными точками выборки.

Более конкретно, давайте определим следующие две кривые (с их дискретными точками)

x1 = [1, 4, 5, 7, 9, 13, 20]
y1 = [0.1, 0.25, 0.22, 0.53, 0.37, 0.5, 0.55]
x2 = [2, 4, 6, 7, 9, 11, 15]
y2 = [0.03, 0.12, 0.4, 0.2, 0.18, 0.32, 0.39]
plt.plot(x1, y1)
plt.plot(x2, y2, 'red')

И мы хотим построить гладкое среднее с границами неопределенности с одним стандартным отклонением.enter image description here

На приведенном выше графике зеленые и красные кривые являются реальными данными, а заштрихованный синий указывает установленные полосы неопределенности.

1 Ответ

0 голосов
/ 12 сентября 2018

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

import pandas as pd
import seaborn as sns

s1 = pd.Series(y1, index=x1).rename('s1')
s2 = pd.Series(y2, index=x2).rename('s2')

df = pd.concat([s1, s2], axis=1)

# Now let's unstack the dataframe so seaborn can recognize it
data = df.unstack().dropna().to_frame()
data.columns = ['values']

Тогда сюжет можно сделать так:

ax = sns.lineplot(x='level_1', y = 'values', hue='level_0',
              data=data.reset_index())

# Fill the missing points using interpolation
df_filled = df.copy().interpolate()

ma = df_filled.mean(axis=1).interpolate()

ax.plot(ma.index, ma, color='r', linestyle='--', label='mean')

mstd = ma.std()

ax.fill_between(ma.index, ma + mstd, ma - mstd,
                color='b', alpha=0.2)
plt.legend()

enter image description here

СТАРЫЕ РЕШЕНИЯ : Вчера я столкнулся с подобной проблемой, и вот как я решил ее применительно к вашей проблеме:

import pandas as pd
import seaborn as sns

# Convert the timeseries to pd.Serires

s1 = pd.Series(y1, index=x1).rename('s1')
s2 = pd.Series(y2, index=x2).rename('s2')

# Put all together in a dataframe

df = pd.concat([s1, s2], axis=1)

>> df
      s1    s2
1   0.10   NaN
2    NaN  0.03
4   0.25  0.12
5   0.22   NaN
6    NaN  0.40
7   0.53  0.20
9   0.37  0.18
11   NaN  0.32
13  0.50   NaN
15   NaN  0.39
20  0.55   NaN

Затем используйте seaborn.pointplot , чтобы настроить фрейм данных, чтобы он мог быть полезен для установки переменных 'x', 'y' для seaborn.pointplot:

data = df.unstack().dropna().to_frame()
data.columns = ['values']

>> data.reset_index()

   level_0  level_1  values
0       s1        1    0.10
1       s1        4    0.25
2       s1        5    0.22
3       s1        7    0.53
4       s1        9    0.37
5       s1       13    0.50
6       s1       20    0.55
7       s2        2    0.03
8       s2        4    0.12
9       s2        6    0.40
10      s2        7    0.20
11      s2        9    0.18
12      s2       11    0.32
13      s2       15    0.39

Наконец, результат при построении графика будет таким:

ax = sns.pointplot(x='level_1', y = 'values', ci='sd',
                   data=data.reset_index())

ax.set_xlabel('')

enter image description here

Средняя точка должна быть средним значением для этой временной точки, а полоса ошибок по умолчанию настроена на «sd» (вы можете также установить доверительный интервал в «ci» или удалить его. Подробнее информация в документации ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...