In [1]:
import IPython.core.display as di
# This line will hide code by default when the notebook is exported as HTML
di.display_html('<script>jQuery(function() {if (jQuery("body.notebook_app").length == 0) { jQuery(".input_area").toggle(); jQuery(".prompt").toggle();}});</script>', raw=True)
# This line will add a button to toggle visibility of code blocks, for use with the HTML export version
di.display_html('''<button onclick="jQuery('.input_area').toggle(); jQuery('.prompt').toggle();">Show/Hide code</button>''', raw=True)
In [2]:
#Allow the created content to be interactivelly ploted inline
%matplotlib inline
#Establish width and height for all plots in the report
#pylab.rcParams['figure.figsize'] = (18, 6) #width, height
In [3]:
#Import needed libraries
import os
from os.path import join, getsize
import pandas as pd
from cycler import cycler
import matplotlib.pyplot as plt
from IPython.display import display
import collections
import numpy as np
import matplotlib as mpl
inline_rc = dict(mpl.rcParams)
#the next cell enables plotting tables without borders
In [4]:
%%html
<style>
table,td,tr,th {border:none!important}
</style>

Summary report of the CO2MPAS WLTP to NEDC CO$_2$ emission simulation model - Real vehicles (v.1.5.x)

In [5]:
#Specify the output folder and file containing the CO2MPAS summary output file.
folder = r'D:\CO2MPAS\'
file = 'stamp_summary.xlsx'
infile = join(folder, file)
df=pd.read_excel(infile, 'summary', header=[0, 1, 2, 3], index_col=[0], skiprows=[4])
In [6]:
#Gather and name the basic variables used in the report according to their name in the CO2MPAS output file
NEDC = df['nedc_h']['prediction']['output']['declared_value']
NEDCl = df['nedc_l']['prediction']['output']['declared_value']
NEDCt = df['nedc_h']['prediction']['target']['value']
NEDCtl = df['nedc_l']['prediction']['target']['value']
UDC = df['nedc_h']['prediction']['output']['UDC']
UDCl = df['nedc_l']['prediction']['output']['UDC']
UDCt = df['nedc_h']['prediction']['target']['UDC']
UDCtl = df['nedc_l']['prediction']['target']['UDC']
EUDC = df['nedc_h']['prediction']['output']['EUDC']
EUDCl = df['nedc_l']['prediction']['output']['EUDC']
EUDCt = df['nedc_h']['prediction']['target']['EUDC']
EUDCtl = df['nedc_l']['prediction']['target']['EUDC']
#Obtain the case number and vehicle model from the input file
df['vehicle'] = df.index
model = df['vehicle'].str.split('_test').str[0]
#Create a dataframe with this data
valuesDF = pd.DataFrame({'NEDC': NEDC,'NEDCt':NEDCt,'NEDCtl':NEDCtl, 'dNEDC':NEDC-NEDCt,'dNEDCl':NEDCl-NEDCtl,'UDC': UDC,'UDCt':UDCt, 'UDCtl':UDCtl,'dUDC':UDC-UDCt,'dUDCl':UDCl-UDCtl,'EUDC': EUDC,'EUDCt':EUDCt,'EUDCtl':EUDCtl, 'dEUDC':EUDC-EUDCt,'dEUDCl':EUDCl-EUDCtl,'Model':model})   
#calculate percentages
valuesDF['NEDC-H error [%]'] = pd.Series((valuesDF.dNEDC/valuesDF.NEDCt*100), index=valuesDF.index)
valuesDF['UDC-H error [%]'] = pd.Series((valuesDF.dUDC/valuesDF.UDCt*100), index=valuesDF.index)
valuesDF['EUDC-H error [%]'] = pd.Series((valuesDF.dEUDC/valuesDF.EUDCt*100), index=valuesDF.index)
valuesDF['NEDC-L error [%]'] = pd.Series((valuesDF.dNEDCl/valuesDF.NEDCtl*100), index=valuesDF.index)
valuesDF['UDC-L error [%]'] = pd.Series((valuesDF.dUDCl/valuesDF.UDCtl*100), index=valuesDF.index)
valuesDF['EUDC-L error [%]'] = pd.Series((valuesDF.dEUDCl/valuesDF.EUDCtl*100), index=valuesDF.index)
valuesDF['NEDC-H error [%]'] = valuesDF['NEDC-H error [%]'].dropna()
valuesDF['UDC-H error [%]'] = valuesDF['UDC-H error [%]'].dropna()
valuesDF['EUDC-H error [%]'] = valuesDF['EUDC-H error [%]'].dropna()
valuesDF['NEDC-L error [%]'] = valuesDF['NEDC-L error [%]'].dropna()
valuesDF['UDC-L error [%]'] = valuesDF['UDC-L error [%]'].dropna()
valuesDF['EUDC-L error [%]'] = valuesDF['EUDC-L error [%]'].dropna()

Section 1. Performance of the model. All vehicles

Error statistics for CO$_2$ emission per driving cycle

Error statistics for NEDC, UDC, and EUDC CO$_2$ emission [gCO$_2$ km$^{-1}$]

In [7]:
#Create a dataframe with the NECD, UDC, EUDC error statistics
errorsDF = pd.DataFrame(index=['Averages','StdError','Median','StdDev','Variance','Kurtosis','Skweness','Range','Minimum','Maximum','Sum','Count','Confidence level (95%)'], columns=['NEDC-H [gCO$_2$ km$^{-1}$]','UDC-H [gCO$_2$ km$^{-1}$]', 'EUDC-H [gCO$_2$ km$^{-1}$]', 'NEDC-L [gCO$_2$ km$^{-1}$]','UDC-L [gCO$_2$ km$^{-1}$]', 'EUDC-L [gCO$_2$ km$^{-1}$]'])
errorsDF.loc['Averages'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDC.mean(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDC.mean(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDC.mean(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDCl.mean(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDCl.mean(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDCl.mean(),2)})
errorsDF.loc['StdError'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDC.sem(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDC.sem(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDC.sem(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDCl.sem(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDCl.sem(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDCl.sem(),2)})
errorsDF.loc['Median'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDC.median(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDC.median(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDC.median(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDCl.median(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDCl.median(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDCl.median(),2)})
errorsDF.loc['StdDev'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDC.std(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDC.std(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDC.std(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDCl.std(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDCl.std(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDCl.std(),2)})
errorsDF.loc['Variance'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDC.var(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDC.var(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDC.var(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDCl.var(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDCl.var(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDCl.var(),2)})
errorsDF.loc['Kurtosis'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDC.kurtosis(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDC.kurtosis(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDC.kurtosis(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDCl.kurtosis(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDCl.kurtosis(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDCl.kurtosis(),2)})
errorsDF.loc['Skweness'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDC.skew(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDC.skew(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDC.skew(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDCl.skew(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDCl.skew(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDCl.skew(),2)})
errorsDF.loc['Range'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round((valuesDF.dNEDC.max()-valuesDF.dNEDC.min()),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round((valuesDF.dUDC.max()-valuesDF.dUDC.min()),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round((valuesDF.dEUDC.max()-valuesDF.dEUDC.min()),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round((valuesDF.dNEDCl.max()-valuesDF.dNEDC.min()),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round((valuesDF.dUDCl.max()-valuesDF.dUDC.min()),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round((valuesDF.dEUDCl.max()-valuesDF.dEUDC.min()),2)})
errorsDF.loc['Minimum'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDC.min(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDC.min(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDC.min(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDCl.min(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDCl.min(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDCl.min(),2)})
errorsDF.loc['Maximum'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDC.max(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDC.max(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDC.max(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDCl.max(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDCl.max(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDCl.max(),2)})
errorsDF.loc['Sum'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDC.sum(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDC.sum(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDC.sum(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDCl.sum(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDCl.sum(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDCl.sum(),2)})
errorsDF.loc['Count'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDC.count(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDC.count(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDC.count(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dNEDCl.count(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dUDCl.count(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round(valuesDF.dEUDCl.count(),2)})
errorsDF.loc['Confidence level (95%)'] = pd.Series({'NEDC-H [gCO$_2$ km$^{-1}$]':2*round(valuesDF.dNEDC.sem(),2), 'UDC-H [gCO$_2$ km$^{-1}$]':2*round(valuesDF.dUDC.sem(),2), 'EUDC-H [gCO$_2$ km$^{-1}$]':2*round(valuesDF.dEUDC.sem(),2), 'NEDC-L [gCO$_2$ km$^{-1}$]':2*round(valuesDF.dNEDCl.sem(),2), 'UDC-L [gCO$_2$ km$^{-1}$]':2*round(valuesDF.dUDCl.sem(),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':2*round(valuesDF.dEUDCl.sem(),2)})
errorsDF
Out[7]:
NEDC-H [gCO$_2$ km$^{-1}$] UDC-H [gCO$_2$ km$^{-1}$] EUDC-H [gCO$_2$ km$^{-1}$] NEDC-L [gCO$_2$ km$^{-1}$] UDC-L [gCO$_2$ km$^{-1}$] EUDC-L [gCO$_2$ km$^{-1}$]
Averages -0.52 -3.89 1.72 -1.31 -3.75 0.37
StdError 0.54 1.47 0.61 1.07 1.74 1.1
Median -0.41 -3.69 1.67 -0.02 -3.92 0.68
StdDev 3.4 9.09 3.73 4.26 6.76 4.26
Variance 11.54 82.57 13.91 18.18 45.67 18.18
Kurtosis -1.28 -0.41 0.1 1.27 -1.15 4.26
Skweness 0.1 0.34 0.25 -1.05 -0.2 -1.48
Range 10.7 36.89 17.07 10.69 25.21 11.96
Minimum -5.44 -19.1 -5.5 -11.9 -13.69 -11.75
Maximum 5.26 17.79 11.57 5.25 6.1 6.46
Sum -20.19 -147.8 65.42 -20.91 -56.25 5.5
Count 39 38 38 16 15 15
Confidence level (95%) 1.08 2.94 1.22 2.14 3.48 2.2

Error statistics for NEDC, UDC, and EUDC CO2 emission [%]

In [8]:
#Create a dataframe with the NECD, UDC, EUDC error statistics
errorsDF = pd.DataFrame(index=['Averages','StdDev','Minimum','Maximum','Cases in ±4%','Cases in ±2.5%'], columns=['NEDC-H [%]','UDC-H [%]', 'EUDC-H [%]','NEDC-L [%]','UDC-L [%]', 'EUDC-L [%]'])
errorsDF.loc['Averages'] = pd.Series({'NEDC-H [%]':round(valuesDF['NEDC-H error [%]'].mean(),2), 'UDC-H [%]':round(valuesDF['UDC-H error [%]'].mean(),2), 'EUDC-H [%]':round(valuesDF['EUDC-H error [%]'].mean(),2),'NEDC-L [%]':round(valuesDF['NEDC-L error [%]'].mean(),2), 'UDC-L [%]':round(valuesDF['UDC-L error [%]'].mean(),2), 'EUDC-L [%]':round(valuesDF['EUDC-L error [%]'].mean(),2)})
errorsDF.loc['StdDev'] = pd.Series({'NEDC-H [%]':round(valuesDF['NEDC-H error [%]'].std(),2), 'UDC-H [%]':round(valuesDF['UDC-H error [%]'].std(),2), 'EUDC-H [%]':round(valuesDF['EUDC-H error [%]'].std(),2),'NEDC-L [%]':round(valuesDF['NEDC-L error [%]'].std(),2), 'UDC-L [%]':round(valuesDF['UDC-L error [%]'].std(),2), 'EUDC-L [%]':round(valuesDF['EUDC-L error [%]'].std(),2)})
errorsDF.loc['Minimum'] = pd.Series({'NEDC-H [%]':round(valuesDF['NEDC-H error [%]'].min(),2), 'UDC-H [%]':round(valuesDF['UDC-H error [%]'].min(),2), 'EUDC-H [%]':round(valuesDF['EUDC-H error [%]'].min(),2),'NEDC-L [%]':round(valuesDF['NEDC-L error [%]'].min(),2), 'UDC-L [%]':round(valuesDF['UDC-L error [%]'].min(),2), 'EUDC-L [%]':round(valuesDF['EUDC-L error [%]'].min(),2)})
errorsDF.loc['Maximum'] = pd.Series({'NEDC-H [%]':round(valuesDF['NEDC-H error [%]'].max(),2), 'UDC-H [%]':round(valuesDF['UDC-H error [%]'].max(),2), 'EUDC-H [%]':round(valuesDF['EUDC-H error [%]'].max(),2),'NEDC-L [%]':round(valuesDF['NEDC-L error [%]'].max(),2), 'UDC-L [%]':round(valuesDF['UDC-L error [%]'].max(),2), 'EUDC-L [%]':round(valuesDF['EUDC-L error [%]'].max(),2)})
errorsDF.loc['Cases in ±4%'] = pd.Series({'NEDC-H [%]':round(sum(abs(valuesDF['NEDC-H error [%]'].dropna())<4)/len(valuesDF['NEDC-H error [%]'].dropna())*100,1), 'UDC-H [%]':round(sum(abs(valuesDF['UDC-H error [%]'].dropna())<4)/len(valuesDF['UDC-H error [%]'].dropna())*100,1), 'EUDC-H [%]':round(sum(abs(valuesDF['EUDC-H error [%]'].dropna())<4)/len(valuesDF['EUDC-H error [%]'].dropna())*100,1),'NEDC-L [%]':round(sum(abs(valuesDF['NEDC-L error [%]'].dropna())<4)/len(valuesDF['NEDC-L error [%]'].dropna())*100,1), 'UDC-L [%]':round(sum(abs(valuesDF['UDC-L error [%]'].dropna())<4)/len(valuesDF['UDC-L error [%]'].dropna())*100,1), 'EUDC-L [%]':round(sum(abs(valuesDF['EUDC-L error [%]'].dropna())<4)/len(valuesDF['EUDC-L error [%]'].dropna())*100,1)})
errorsDF.loc['Cases in ±2.5%'] = pd.Series({'NEDC-H [%]':round(sum(abs(valuesDF['NEDC-H error [%]'].dropna())<2.5)/len(valuesDF['NEDC-H error [%]'].dropna())*100,1), 'UDC-H [%]':round(sum(abs(valuesDF['UDC-H error [%]'].dropna())<2.5)/len(valuesDF['UDC-H error [%]'].dropna())*100,1), 'EUDC-H [%]':round(sum(abs(valuesDF['EUDC-H error [%]'].dropna())<2.5)/len(valuesDF['EUDC-H error [%]'].dropna())*100,1),'NEDC-L [%]':round(sum(abs(valuesDF['NEDC-L error [%]'].dropna())<2.5)/len(valuesDF['NEDC-L error [%]'].dropna())*100,1), 'UDC-L [%]':round(sum(abs(valuesDF['UDC-L error [%]'].dropna())<2.5)/len(valuesDF['UDC-L error [%]'].dropna())*100,1), 'EUDC-L [%]':round(sum(abs(valuesDF['EUDC-L error [%]'].dropna())<2.5)/len(valuesDF['EUDC-L error [%]'].dropna())*100,1)})
errorsDF.loc['P75-P25'] = pd.Series({'NEDC-H [%]':round(valuesDF['NEDC-H error [%]'].quantile(0.75)-valuesDF['NEDC-H error [%]'].quantile(0.25),2), 'UDC-H [%]':round(valuesDF['UDC-H error [%]'].quantile(0.75)-valuesDF['UDC-H error [%]'].quantile(0.25),2), 'EUDC-H [%]':round(valuesDF['EUDC-H error [%]'].quantile(0.75)-valuesDF['EUDC-H error [%]'].quantile(0.25),2),'NEDC-L [%]':round(valuesDF['NEDC-L error [%]'].quantile(0.75)-valuesDF['NEDC-L error [%]'].quantile(0.25),2), 'UDC-L [%]':round(valuesDF['UDC-L error [%]'].quantile(0.75)-valuesDF['UDC-L error [%]'].quantile(0.25),2), 'EUDC-L [%]':round(valuesDF['EUDC-L error [%]'].quantile(0.75)-valuesDF['EUDC-L error [%]'].quantile(0.25),2)})
errorsDF
Out[8]:
NEDC-H [%] UDC-H [%] EUDC-H [%] NEDC-L [%] UDC-L [%] EUDC-L [%]
Averages -0.21 -1.93 1.68 -0.69 -2.17 0.72
StdDev 2.31 4.99 3.19 2.86 4.01 3.24
Minimum -4.16 -10.51 -3.28 -5.99 -8.71 -6.28
Maximum 3.82 8.8 12.88 4.11 3.71 7.2
Cases in ±4% 97.4 50 81.6 81.2 66.7 73.3
Cases in ±2.5% 66.7 36.8 60.5 68.8 33.3 66.7
P75-P25 3.87 5.87 3.39 3.49 5.55 2.47

Distribution of the NEDC, UDC and EUDC errors [%]

In [9]:
mydict = ([('NEDC', 0), ('UDC', 1), ('EUDC', 2)])
mydict = collections.OrderedDict(mydict)
for cycle in mydict:
    if cycle == 'NEDC':
        boxcolor = 'green'
    elif cycle == 'UDC':
        boxcolor = 'blue'
    else:
        boxcolor = 'red'
    # Create a figure instance
    fig = plt.figure(1, figsize=(14, 7))
    # Create an axes instance
    ax = fig.add_subplot(111)
    hist = valuesDF[cycle+'-H error [%]'].hist(bins=41, color=boxcolor, label = 'High')
    hist = valuesDF[cycle+'-L error [%]'].hist(bins=41, color=boxcolor, alpha=0.5, label='Low')
    hist.set_xlabel(cycle+" error [%]",fontsize=14)
    hist.set_ylabel("frequency",fontsize=14)
    hist.set_ylim(0,8)
    plt.title(cycle+' CO$_2$ emission error distribution', fontsize=20)
    plt.ylabel("frequency",fontsize=18)
    plt.tick_params(axis='x', which='major', labelsize=16)
    plt.tick_params(axis='y', which='major', labelsize=16)
    ax.get_xaxis().tick_bottom()
    ax.get_yaxis().tick_left()
    ax.set_xlim(-12, 12)
    plt.legend()
    plt.show()

Section 2. Performance of the model. Statistics per vehicle model

NEDC, UDC, and EUDC CO$_2$ emission error [%] per vehicle model

In [10]:
Carlist = list(valuesDF['Model'])
Cidlist = list(range(len(Carlist)))
valuesDF.cid = valuesDF['Model'].replace(Carlist, Cidlist, regex = True)
valuesDF['cod'] = valuesDF.cid
#Create a table with the error statistics for each car model
CarDF = pd.DataFrame(columns=['NEDC-H error [%]','UDC-H error [%]', 'EUDC-H error [%]',
                             'NEDC-L error [%]','UDC-L error [%]', 'EUDC-L error [%]'])
for x in Carlist:
    Car = valuesDF[valuesDF['Model'] == x]
    CarDF.loc[x] = pd.Series({'NEDC-H error [%]':round(Car['NEDC-H error [%]'].mean(),2), 'UDC-H error [%]':round(Car['UDC-H error [%]'].mean(),2), 'EUDC-H error [%]':round(Car['EUDC-H error [%]'].mean(),2),
                            'NEDC-L error [%]':round(Car['NEDC-L error [%]'].mean(),2), 'UDC-L error [%]':round(Car['UDC-L error [%]'].mean(),2), 'EUDC-L error [%]':round(Car['EUDC-L error [%]'].mean(),2)})
CarDF.columns.name='Error'
display(CarDF)
mydict = ([('NEDC-H', 0), ('UDC-H', 1), ('EUDC-H', 2),('NEDC-L', 3), ('UDC-L', 4), ('EUDC-L', 5)])
mydict = collections.OrderedDict(mydict)
for cycle in mydict:
    if cycle == 'NEDC-H':
        boxcolor = 'green'
    elif cycle == 'NEDC-L':
        boxcolor = 'green'
    elif cycle == 'UDC-H':
        boxcolor = 'blue'
    elif cycle == 'UDC-L':
        boxcolor = 'blue'
    else:
        boxcolor = 'red'
    #plot the emission error per model, and cycle
    fig = plt.figure(1, figsize=(14, 7))
    labels = ['{0}'.format(i) for i in valuesDF['Model']]
    plt.title(cycle+" error [%] per real vehicle",fontsize=20)
    plot = fig.add_subplot(111)
    plot.tick_params(axis='x', which='major', labelsize=14)
    plot.tick_params(axis='y', which='major', labelsize=14)
    plot.set_xlim(-1, 42)
    plot.set_ylim(-12,12)
    plot.get_xaxis().tick_bottom()
    plot.get_yaxis().tick_left()
    #plt.scatter(valuesDF['Case'],valuesDF[cycle+' error [%]'], color=boxcolor, marker = 'o')
    plt.scatter(valuesDF['cod'],valuesDF[cycle+' error [%]'], color=boxcolor, marker = 'o')
#     for label, x, y in zip(labels, valuesDF['Case'], valuesDF[cycle+' error [%]']):
    for label, x, y in zip(labels, valuesDF['cod'], valuesDF[cycle+' error [%]']):
        plt.annotate(label, xy = (x, y), size = 12)
    plot.set_xlabel("Vehicle #",fontsize=20)
    plot.set_ylabel(cycle+" error [%]",fontsize=20)
    line1 = plot.axhline(y=-2.5, color='grey', linestyle='-.', label='± 2.5%')
    line2 = plot.axhline(y=2.5, color='grey', linestyle='-.')
    line3 = plot.axhline(y=-4, color='black', linestyle='--', label='± 4.0%')
    line4 = plot.axhline(y=4, color='black', linestyle='--')
    plt.legend(handles=[line1, line3], loc = 3)
    plt.show()  
Error NEDC-H error [%] UDC-H error [%] EUDC-H error [%] NEDC-L error [%] UDC-L error [%] EUDC-L error [%]
AT01 -3.14 -3.83 -2.50 NaN NaN NaN
AT02 -2.64 -5.95 0.71 NaN NaN NaN
AT03 0.16 -0.20 0.34 0.04 0.30 -0.24
AT04 3.27 5.79 1.43 1.12 1.13 1.02
AT05 2.81 -1.07 6.38 1.28 -2.54 4.79
AT06 -0.66 -7.64 5.45 NaN NaN NaN
AT07 -2.28 NaN NaN -2.08 NaN NaN
AT08 0.16 0.87 0.43 -0.04 2.17 -1.03
AT09 -1.84 -5.18 2.20 NaN NaN NaN
AT10 0.49 -2.18 3.24 NaN NaN NaN
AT11 -0.52 -2.92 1.68 -0.39 -2.48 1.55
AT12 -0.39 -6.49 3.91 NaN NaN NaN
AT13 -1.32 -0.01 -2.12 NaN NaN NaN
AT14 1.85 -2.11 4.60 -3.10 -7.82 0.19
AT15 -2.37 -4.20 -0.27 NaN NaN NaN
AT16 -1.66 -6.70 2.93 NaN NaN NaN
CVT01 -3.27 -4.57 -2.14 -3.73 -7.05 -0.96
MT01 2.51 2.96 2.11 NaN NaN NaN
MT02 -1.95 -8.82 4.90 NaN NaN NaN
MT03 -3.87 -9.59 1.58 NaN NaN NaN
MT04 -1.84 0.15 -3.28 NaN NaN NaN
MT05 1.12 5.66 -1.80 NaN NaN NaN
MT06 0.62 -1.61 2.36 NaN NaN NaN
MT07 3.56 8.80 -0.14 2.26 3.67 1.25
MT08 -1.66 -2.99 -0.57 NaN NaN NaN
MT09 1.87 -0.82 4.36 NaN NaN NaN
MT10 3.08 4.94 3.53 NaN NaN NaN
MT11 NaN NaN NaN -5.99 -8.71 -3.27
MT12 -4.16 -8.72 -0.13 NaN NaN NaN
MT13 1.26 -0.19 2.28 -1.28 -2.66 -0.32
MT14 -0.17 -0.81 0.29 0.44 0.31 0.57
MT15 2.57 -10.51 12.88 2.16 -4.33 7.20
MT16 -0.25 1.14 -1.36 NaN NaN NaN
MT17 2.45 7.10 -1.18 NaN NaN NaN
MT18 -2.29 -6.27 1.29 NaN NaN NaN
MT19 0.61 -1.77 2.80 NaN NaN NaN
MT20 3.82 7.33 2.90 NaN NaN NaN
MT21 1.96 -3.39 6.82 4.11 3.71 4.26
MT22 -2.07 -0.87 -2.94 -5.88 -5.33 -6.28
MT23 -3.96 -8.75 0.68 NaN NaN NaN
MT24 NaN NaN NaN 0.07 -2.92 2.12