Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

show error bar in multi line plot using matplotlib

I've created a multi line plot using marplot lib, and now I want to show the min-max value for each parameter on X-axis. My code is below:

import numpy as np
import pandas as pd
from pandas import DataFrame
import matplotlib.pyplot as plt
from matplotlib import pyplot as plt
import seaborn as sns

df = pd.DataFrame({'Time': ['D=0','D=2','D=5','D=X'],
    'Latency': [74.92, 75.32, 79.64, 100],
    'Delay': [18.2,80,82,84]
   })

  plt.plot( 'Time', 'Latency', data=df, marker='s', color='black', markersize=4,     linewidth=1, linestyle='--')
  plt.plot( 'Time', 'Delay', data=df, marker='o', color='black',  markersize=4, linewidth=1,linestyle='-')

   plt.legend()
   plt.xlabel("Time")
   plt.ylabel("Average Score (%)")
   plt.ylim(0, 100)
   plt.xlim('D=0','D=X')
   plt.savefig('Fig2.png', dpi=300, bbox_inches='tight')
   plt.show()

The interval min-max that I want to add is:

Latency: 
D=0 => {73.3, 76}
D=2 => {73.3, 80}
D=5 => {75, 83.3}
D=X => {100}
Delay:
D=0 => {0, 50}
D=2 => {50, 100}
D=5 => {68, 90}
D=X => {75, 90}

Thanks so much in advance

like image 667
Vincent Avatar asked Dec 05 '25 04:12

Vincent


2 Answers

First put the error values in lists:

latency_lower_err = [73.3, 73.3, 75, 100]
latency_upper_err = [76, 80, 83.3, 100]

Then subtract the data points from these values, because matplotlib needs the distance (in absolute units) from the error limit to the corresponding data point:

latency_lower_err = (latency_lower_err - df['Latency']).abs() 
latency_upper_err = (latency_upper_err - df['Latency']).abs()

Put the resulting values in a list, where the first element is the lower errors, and the second element is the upper errors:

yerr = [latency_lower_err, latency_upper_err]

Then change the call from plt.plot to plt.errorbar, adding the yerr argument:

plt.errorbar('Time', 'Latency', data=df, yerr=yerr, capsize=5, ... )

The remaining arguments are the same you previously used for plt.plot.

Result:

enter image description here

Adapt the same logic for Delay in order to get the errors for that variable, too.

like image 142
jfaccioni Avatar answered Dec 07 '25 20:12

jfaccioni


plt.errorbar() draws lineplots with error bars. It's parameters are quite similar to plt.plot(). The xlims need to be a bit wider to avoid the error bars being cut by the plot borders.

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

df = pd.DataFrame({'Time': ['D=0', 'D=2', 'D=5', 'D=X'],
                   'Latency': [74.92, 75.32, 79.64, 100],
                   'Delay': [18.2, 80, 82, 84]})
latency_min_max = np.array([(73.3, 76), (73.3, 80), (75, 83.3), (100, 100)]).T
latency_err = np.abs(latency_min_max - df['Latency'].to_numpy())
delay_min_max = np.array([(0, 50), (50, 100), (68, 90), (75, 90)]).T
delay_err = np.abs(delay_min_max - df['Delay'].to_numpy())

plt.errorbar('Time', 'Latency', yerr=latency_err, data=df, marker='s', capsize=2,
             color='black', markersize=4, linewidth=1, linestyle='--')
plt.errorbar('Time', 'Delay', yerr=delay_err, data=df,
             marker='o', capsize=4, color='black', markersize=4, linewidth=1, linestyle='-')
plt.legend()
plt.xlabel("Time")
plt.ylabel("Average Score (%)")
plt.ylim(0, 100)
plt.xlim(-0.2, 3.2)
plt.savefig('Fig2.png', dpi=300, bbox_inches='tight')
plt.show()

example plot

An alternative is to use plt.fill_between to create error bands:

plt.fill_between(df['Time'], latency_min_max[0, :], latency_min_max[1, :], color='red', alpha=0.2, label='Latency error')
plt.fill_between(df['Time'], delay_min_max[0, :], delay_min_max[1, :], color='blue', alpha=0.2, label='Delay error')

plot with errorbands

like image 32
JohanC Avatar answered Dec 07 '25 19:12

JohanC