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.7.x)

In [5]:
#Specify the output folder and file containing the CO2MPAS summary output file.
folder = r'D:\Apps\CO2MPAS_runs\historic_CO2MPAS_versions\outs_TREA'
file = '20170802_201243-summary.xlsx'
infile = join(folder, file)
df=pd.read_excel(infile, 'anon', 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']['declared_value'].fillna(df['nedc_h']['prediction']['target']['value'])
NEDCtl = df['nedc_l']['prediction']['target']['declared_value'].fillna(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.dNEDCl.min()),2), 'UDC-L [gCO$_2$ km$^{-1}$]':round((valuesDF.dUDCl.max()-valuesDF.dUDCl.min()),2), 'EUDC-L [gCO$_2$ km$^{-1}$]':round((valuesDF.dEUDCl.max()-valuesDF.dEUDCl.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.75 -3.58 0.85 -2.07 -4.39 -0.43
StdError 0.55 1.16 0.6 1.06 1.54 1.14
Median -1.27 -3.75 1.14 -1.31 -4.52 0.19
StdDev 3.75 7.49 3.9 4.24 5.95 4.4
Variance 14.09 56.05 15.2 18 35.45 19.38
Kurtosis -0.97 -0.65 -0.46 5.11 -0.27 7.72
Skweness -0.14 0.05 -0.32 -1.95 -0.1 -2.36
Range 13.79 29.66 16.73 17.46 21.44 19.97
Minimum -8.44 -19.08 -7.85 -14.9 -15.81 -14.36
Maximum 5.35 10.57 8.88 2.55 5.63 5.61
Sum -35.11 -150.15 35.79 -33.16 -65.87 -6.46
Count 47 42 42 16 15 15
Confidence level (95%) 1.1 2.32 1.2 2.12 3.08 2.28

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.31 -1.58 0.94 -1.34 -2.85 0.08
StdDev 2.51 3.84 3.11 2.65 3.48 3.05
Minimum -4.99 -7.05 -4.2 -7.37 -7.82 -7.68
Maximum 4.22 7.69 9.89 2.38 3.12 6.24
Cases in ±4% 93.6 54.8 78.6 87.5 66.7 86.7
Cases in ±2.5% 61.7 33.3 52.4 68.8 26.7 73.3
P75-P25 4.11 5.71 3.53 3.25 5.08 2.39

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 [%]
AT_01 -4.99 -5.85 -4.18 NaN NaN NaN
AT_02 -3.28 -6.63 0.11 NaN NaN NaN
AT_03 0.64 0.78 0.47 -3.24 -6.18 -1.05
AT_04 2.29 5.74 -0.19 -1.96 -6.30 1.29
AT_05 2.68 3.48 1.95 0.49 -0.05 0.99
AT_06 -0.43 -6.49 4.87 NaN NaN NaN
AT_07 -3.88 NaN NaN -2.98 NaN NaN
AT_08 1.62 4.85 -0.19 -0.08 2.58 -1.45
AT_09 -1.77 -5.17 2.35 NaN NaN NaN
AT_10 -0.94 -4.09 2.30 NaN NaN NaN
AT_11 -3.44 -3.91 -3.00 0.76 1.59 0.04
AT_12 -2.19 -5.04 -0.18 NaN NaN NaN
AT_13 -2.20 -1.58 -2.58 NaN NaN NaN
AT_14 2.74 0.64 4.19 -1.48 -2.74 -0.60
AT_15 -3.22 -5.31 -0.81 NaN NaN NaN
AT_16 -1.45 -5.61 2.30 NaN NaN NaN
AT_17 2.01 0.96 2.85 NaN NaN NaN
AT_18 2.25 -0.61 4.57 NaN NaN NaN
AT_19 1.08 NaN NaN NaN NaN NaN
CVT_01 -4.56 -5.47 -3.73 -2.65 -6.00 0.14
MT_01 3.17 3.52 2.86 NaN NaN NaN
MT_02 0.58 -4.45 5.59 NaN NaN NaN
MT_03 -2.46 -7.05 1.92 NaN NaN NaN
MT_04 -1.99 0.06 -3.47 NaN NaN NaN
MT_05 -0.22 3.22 -2.30 NaN NaN NaN
MT_06 1.82 0.60 2.78 NaN NaN NaN
MT_07 2.96 7.69 -0.37 2.38 3.12 1.83
MT_08 -0.78 -1.67 -0.05 NaN NaN NaN
MT_09 3.78 2.64 4.82 NaN NaN NaN
MT_10 3.70 5.18 4.49 NaN NaN NaN
MT_11 -3.73 -3.33 -3.92 -5.67 -7.82 -3.49
MT_12 -2.35 -4.72 -0.24 NaN NaN NaN
MT_13 0.76 -0.72 1.80 -1.15 -3.43 0.41
MT_14 -1.39 -3.68 0.15 -0.98 -2.27 -0.09
MT_15 4.22 -3.06 9.89 2.37 -2.66 6.24
MT_16 -1.27 -1.00 -1.49 NaN NaN NaN
MT_17 -3.53 -4.09 -3.20 NaN NaN NaN
MT_18 0.31 -0.83 1.35 NaN NaN NaN
MT_19 0.64 -1.79 2.89 NaN NaN NaN
MT_20 -0.92 -0.87 0.83 NaN NaN NaN
MT_21 0.78 -2.74 3.95 0.57 -1.97 2.68
MT_22 -1.87 1.35 -4.20 -7.37 -6.95 -7.68
MT_23 -1.63 -5.54 2.16 NaN NaN NaN
MT_24 NaN NaN NaN -0.38 -3.73 1.93
MT_25 -2.60 NaN NaN NaN NaN NaN
MT_26 -1.79 -5.93 2.26 NaN NaN NaN
MT_27 3.40 NaN NaN NaN NaN NaN
MT_28 2.71 NaN NaN NaN NaN NaN