Построение заштрихованной области неопределенности на линейном графике в matplotlib, когда данные имеют NaN

Мне нужен сюжет, который выглядит так:  сюжет с неопределенностью

Я пытаюсь сделать это с помощью matplotlib:

fig, ax = plt.subplots()

with sns.axes_style("darkgrid"):
    for i in range(5):
        ax.plot(means.ix[i][list(range(3,104))], label=means.ix[i]["label"])
        ax.fill_between(means.ix[i][list(range(3,104))]-stds.ix[i][list(range(3,104))], means.ix[i][list(range(3,104))]+stds.ix[i][list(range(3,104))])
    ax.legend()

Я хочу, чтобы заштрихованная область была того же цвета, что и линия в центре. Но прямо сейчас моя проблема в том, что у means есть некоторые NaN, а fill_between не принимает это. Я получаю ошибку

TypeError: ufunc 'isfinite' не поддерживается для входных типов, и входные данные не могут быть безопасно приведены к каким-либо поддерживаемым типам в соответствии с правилом приведения `` безопасно ''

Есть идеи, как я могу достичь того, чего хочу? В решении нет необходимости использовать matplotlib, если он может построить серию точек с их неопределенностями для нескольких серий.


person patapouf_ai    schedule 28.03.2017    source источник


Ответы (2)


В порядке. Итак, одна из проблем заключалась в том, что dtype моих данных было object, а не float, и это привело к сбою fill_between, когда он смотрел, были ли числа конечными. Наконец, мне удалось сделать это путем (а) преобразования в float, а затем (б) для решения проблемы соответствия цветов для неопределенности и линии, чтобы использовать цветовую палитру. Так что я:

import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
fig, ax = plt.subplots()
clrs = sns.color_palette("husl", 5)
with sns.axes_style("darkgrid"):
    epochs = list(range(101))
    for i in range(5):
        meanst = np.array(means.ix[i].values[3:-1], dtype=np.float64)
        sdt = np.array(stds.ix[i].values[3:-1], dtype=np.float64)
        ax.plot(epochs, meanst, label=means.ix[i]["label"], c=clrs[i])
        ax.fill_between(epochs, meanst-sdt, meanst+sdt ,alpha=0.3, facecolor=clrs[i])
    ax.legend()
    ax.set_yscale('log')

что дало мне следующий результат:  введите описание изображения здесь

person patapouf_ai    schedule 28.03.2017
comment
Отличный ответ, он делает свое дело без необходимости использовать временные ряды морских обитателей ... спасибо! - person David Alvarez; 20.08.2018
comment
Если у вас нет морского снаряжения, вы можете использовать pyplot.fill_between; соглашение о вызовах аналогично. - person Yibo Yang; 08.02.2019

Вы могли бы просто удалить NaNs из своего means фрейма данных и вместо этого построить полученный фрейм данных?

В приведенном ниже примере я попытался приблизиться к вашей структуре, у меня есть means DataFrame с некоторым NaN разбрызгиванием. Я полагаю, что stds DataFrame, вероятно, имеет NaN в тех же местах, но в этом случае это не имеет особого значения, я отбрасываю NaN из means, чтобы получить temp_means, и я использую индексы, оставшиеся в temp_means, для извлечения значений std из stds.

На графиках показаны результаты до (вверху) и после (внизу) сброса NaNs.

x = np.linspace(0, 30, 100)
y = np.sin(x/6*np.pi)
error = 0.2

means = pd.DataFrame(np.array([x,y]).T,columns=['time','mean'])
stds = pd.DataFrame(np.zeros(y.shape)+error)

#sprinkle some NaN in the mean
sprinkles = means.sample(10).index
means.loc[sprinkles] = np.NaN


fig, axs = plt.subplots(2,1)

axs[0].plot(means.ix[:,0], means.ix[:,1])
axs[0].fill_between(means.ix[:,0], means.ix[:,1]-stds.ix[:,0], means.ix[:,1]+stds.ix[:,0])

temp_means = means.dropna()

axs[1].plot(temp_means.ix[:,0], temp_means.ix[:,1])
axs[1].fill_between(temp_means.ix[:,0], temp_means.ix[:,1]-stds.loc[temp_means.index,0], temp_means.ix[:,1]+stds.loc[temp_means.index,0])


plt.show()

введите описание изображения здесь

person Diziet Asahi    schedule 28.03.2017
comment
Спасибо! Я попробую это. - person patapouf_ai; 28.03.2017
comment
Хорошо, моя проблема была в другом. Дело в том, что мои данные были объекта dtype, а не dtype float, поэтому, когда fill_between попытался использовать np.isfinite, он получил ошибку значения. Теперь у меня все заработало. Но проблема в том, что теперь все мои кривые имеют одинаковый цвет заливки. Как сделать, чтобы средняя линия и ее неопределенность были одного цвета? - person patapouf_ai; 28.03.2017