¿Cómo agregar barra de error a la gráfica de línea de Matplotlib?

Oct 10 2020

Tengo el siguiente conjunto de datos que utilizo para trazar un diagrama de líneas. La gráfica se obtiene como la meande los valores obtenidos a partir de los datos. Quiero agregar barras de error a este gráfico que mostrará la desviación estándar. He buscado diferentes respuestas pero en la mayoría de ellas se habían definido xy yexplícitamente, pero aquí calculo la trama directamente desde el marco de datos. ¿Cómo agregar una barra de error a este gráfico?

Marco de datos df

UserId     |   date                 |-7|-6|-5|-4|-3|-2|-1|0 |1 |2 |3 |4 |5 |6 |7
     1      2009-10-17 17:38:32.590 |0 |0 |0 |0 |0 |0 |1 |0 |1 |0 |0 |0 |0 |0 |0  
     2      2009-10-19 00:37:23.067 |0 |0 |0 |0 |0 |1 |1 |0 |1 |0 |0 |0 |0 |0 |0    
     3      2009-10-20 08:37:14.143 |0 |0 |0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 
     4      2009-10-21 18:07:51.247 |0 |0 |0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 
     5      2009-10-22 21:25:24.483 |0 |0 |0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0

Código

badges = ["A", "B", "C"]

for badge in badges:
  res.iloc[:,2:].mean().plot(kind='line', label = badge)

Salida

EDITAR (Trazar solo un gráfico con desviación estándar)

res.iloc[:,2:].mean().plot(kind='line', label = 'A')
plt.errorbar(x = res.columns.values[:-1], y = res.iloc[:,2:].mean(),yerr = res.iloc[:,2:].std())

La ejecución de este código produce el siguiente error:

TypeError: 'value' must be an instance of str or bytes, not a int

Respuestas

gherka Oct 10 2020 at 17:50

Si desea crear sus líneas y barras de error en el bucle, puede usar el plt.errorbar()como de costumbre dentro del bucle, pero usar seabornes mucho más fácil si puede obtener sus datos en el formato apropiado.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

df = pd.concat([
    pd.DataFrame(np.random.randint(0,2, (5, 14))).assign(badge="A"),
    pd.DataFrame(np.random.randint(0,2, (5, 14))).assign(badge="B"),
])

plt.figure(figsize=(10, 5))

badges = ["A", "B"]
colors = ["teal", "firebrick"]

for i, badge in enumerate(badges):
    
    sub_df = df[df["badge"]==badge]
    
    sub_df.iloc[:,:-1].mean().plot(kind='line', label=badge, color=colors[i])

    plt.errorbar(
        sub_df.columns.values[:-1] + (i*0.1), # offset the second error bar a bit
        sub_df.iloc[:,:-1].mean(),
        yerr=sub_df.iloc[:,:-1].std(),
        fmt='|', ecolor='grey', elinewidth=1
    );