diff --git a/modules/Scenarios.py b/modules/Scenarios.py
index 1a36d12ed4a5d1badd91f98c88e86beb292cab08..173bf01e2b0db6a3808dd3fa6ab0d74a9280f2a3 100644
--- a/modules/Scenarios.py
+++ b/modules/Scenarios.py
@@ -60,6 +60,92 @@ class Scenarios:
         return upper_power_green[case-1]
 
 
+    def get_best_green_powers(self, total_req_rate, ratios, max_power_green=500, duration=60, load_type="High"):
+        """
+            Description: Return the green power values that include the max number of cases for the different scenarios.
+            In:
+                aaa
+            Out:
+        """
+        import operator
+        import pandas as pd
+        best_power = {}
+        for power in range(0, max_power_green+1):
+            best_power[power] = {'case 1': 0, 'case 2': 0, 'case 3': 0, 'case 4': 0}
+            for ratio in ratios:
+                rates = self.get_rates(total_req_rate, ratio[0], ratio[1], ratio[2])
+                if best_power[power]['case 4'] == 0:
+                    if self.sch.energy(self.sch.configurations[load_type]['QoE'].idxmin(), (rates['sust']), duration, load_type, "Median") >= power * duration:
+                        best_power[power]['case 4'] = 1
+                if best_power[power]['case 3'] == 0:
+                    if self.sch.energy(self.sch.configurations[load_type]['QoE'].idxmin(), (rates['sust'] + rates['bal']), duration, load_type, "Median") >= power * duration:
+                        best_power[power]['case 3'] = 1
+                if best_power[power]['case 2'] == 0:
+                    if (self.sch.energy(self.sch.configurations[load_type]['QoE'].idxmax(), (rates['perf']), duration, load_type, "Median") + self.sch.energy(self.sch.configurations[load_type]['QoE'].idxmin(), (rates['sust'] + rates['bal']), duration, load_type, "Median")) >= power * duration:
+                        best_power[power]['case 2'] = 1
+                if best_power[power]['case 1'] == 0:
+                    if (self.sch.energy(self.sch.configurations[load_type]['QoE'].idxmax(), (rates['sust'] + rates['bal'] + rates['perf']), duration, load_type, "Median")) <= power * duration:
+                        best_power[power]['case 1'] = 1
+            #best_power[power] = sum(best_power[power].values())
+            #best_power = dict(sorted(best_power.items(), key=operator.itemgetter(1), reverse=True))
+        #for power in range(0, max_power_green+1):
+        #    print(best_power[power]['case 2'])
+        print(pd.DataFrame(best_power))
+
+
+
+
+
+
+
+    def get_green_power(self, total_req_rate, ratios, max_power_green=500, duration=60, load_type='High', force=False):
+        """
+            Description: Generate randomly green power value for the case 2 of the scenarios.
+            In:
+                aaa
+            Out:
+        """
+        '''if ratio in [self.green_power[1].keys()] and force == False: # 1 for case1, but work also by using one of the other cases.
+            print("Already defined !")
+            return self.green_power'''
+            
+        import random
+        #random.seed
+        green_power = random.randint(int(0.25*max_power_green), int(0.75*max_power_green))
+        return green_power
+        """
+        # Choosing randomly a power_green for each case:
+        green_power = {}
+        for case in range(1, 5):
+            down_limit = -1
+            up_limit = 1000000000
+            for ratio in ratios:
+                tmp_down_limit = self.__get_green_lower_limit(case, total_req_rate, ratio[0], ratio[1], ratio[2], max_power_green, duration, load_type)
+                if tmp_down_limit == None:
+                    self.green_power[case][str(ratio)] = None
+                    continue
+                if down_limit < tmp_down_limit and tmp_down_limit <up_limit:
+                    down_limit = tmp_down_limit
+                tmp_up_limit = self.__get_green_upper_limit(case, total_req_rate, ratio[0], ratio[1], ratio[2], max_power_green, duration, load_type)
+                if tmp_up_limit < up_limit and tmp_up_limit > down_limit:
+                    up_limit = tmp_up_limit
+            
+            print("Down/up limit for the case", case, ":", down_limit, "/", up_limit)
+            green_power[case] = random.randint(down_limit, up_limit)
+        return green_power
+        """
+
+
+
+
+
+
+
+
+
+
+
+    
     def get_green_powers(self, total_req_rate, ratio_rate_perf, ratio_rate_bal, ratio_rate_sust, max_power_green=500, duration=60, load_type='High', force=False):
         """
             Description: Generate randomly green powers for the 4 cases of the scenarios.
@@ -87,7 +173,7 @@ class Scenarios:
                 up_limit = self.__get_green_lower_limit(case-2, total_req_rate, ratio_rate_perf, ratio_rate_bal, ratio_rate_sust, max_power_green, duration, load_type)
                 if up_limit == None:
                     up_limit = self.__get_green_lower_limit(case-3, total_req_rate, ratio_rate_perf, ratio_rate_bal, ratio_rate_sust, max_power_green, duration, load_type)'''
-            #print(ratio, "Down/up limit for the case", case, ":", down_limit, "/", up_limit)
+            print(ratio, "Down/up limit for the case", case, ":", down_limit, "/", up_limit)
             self.green_power[case][str(ratio)] = random.randint(down_limit, up_limit)
         return self.green_power
 
@@ -102,15 +188,18 @@ class Scenarios:
         ratios = []
         for perf_ratio in percentages:
             ratios.append([perf_ratio, 100-perf_ratio, 0])
-            ratios.append([perf_ratio, (100-perf_ratio)/2, (100-perf_ratio)/2])
+            bal_sust_value = int((100-perf_ratio)/2) if ((100-perf_ratio)/2).is_integer() else ((100-perf_ratio)/2)
+            ratios.append([perf_ratio, bal_sust_value, bal_sust_value])
             ratios.append([perf_ratio, 0, 100-perf_ratio])
         for bal_ratio in percentages:
             ratios.append([100-bal_ratio, bal_ratio, 0])
-            ratios.append([(100-bal_ratio)/2, bal_ratio, (100-bal_ratio)/2])
+            perf_sust_value = int((100-bal_ratio)/2) if ((100-bal_ratio)/2).is_integer() else ((100-bal_ratio)/2)
+            ratios.append([perf_sust_value, bal_ratio, perf_sust_value])
             ratios.append([0, bal_ratio, 100-bal_ratio])
         for sust_ratio in percentages:
             ratios.append([0, 100-sust_ratio, sust_ratio])
-            ratios.append([(100-sust_ratio)/2, (100-sust_ratio)/2, sust_ratio])
+            perf_bal_value = int((100-sust_ratio)/2) if ((100-sust_ratio)/2).is_integer() else ((100-sust_ratio)/2)
+            ratios.append([perf_bal_value, perf_bal_value, sust_ratio])
             ratios.append([100-sust_ratio, 0, sust_ratio])
         #print("\n\nRATIOS:", ratios)
         ratios = [list(i) for i in set(map(tuple, ratios))]
@@ -165,6 +254,36 @@ class Scenarios:
                     self.next_configuration[case][str(ratio)] = self.sch.get_next_configuration(load_type=load_type)
 
 
+    def next_configurations_v2(self, percentages, total_req_rate, max_power_green, duration, load_type, green_power=False):
+        """
+            Description:
+            In:
+                aaa
+            Out:
+        """   
+        self.next_configuration = {}
+        ratios = self.get_ratios(percentages)
+        if green_power == False:
+            self.green_power = self.get_green_power(total_req_rate, ratios, max_power_green, duration, load_type)
+        else:
+            self.green_power = green_power
+        for ratio in ratios:
+            rates = self.get_rates(total_req_rate, ratio[0], ratio[1], ratio[2])
+            self.sch.next_step(duration, self.green_power, rates['sust'], rates['bal'], rates['perf'])
+            '''
+            if self.green_power[case][str(ratio)] == None:
+                #self.green_power[case][str(ratio)] = 0
+                #self.sch.next_step(duration, 0, 0, 0, 0)
+                self.next_configuration[case][str(ratio)] = None #self.sch.get_next_configuration(load_type=load_type)
+                #self.next_configuration[case][str(ratio)]['QoE'] = 0
+            else:
+            '''
+            self.next_configuration[str(ratio)] = self.sch.get_next_configuration(load_type=load_type)
+
+
+
+
+
     def get_next_configurations(self):
         """
             Description:
@@ -333,6 +452,442 @@ class Scenarios:
 
 
 
+    def plot_v2(self, percentages, duration, total_req_rate, load_type, energy=None, date="", case_number=None):
+        """
+            Description:
+            In:
+                aaa
+            Out:
+        """
+        import matplotlib.pyplot as plt
+        from matplotlib.backends.backend_pdf import PdfPages
+        
+        #figs = {}
+        width = 0.2
+        ratios = self.get_ratios(percentages)
+        baselines = {}
+        
+        file_name = '.pdf' if energy == "" else date+'_scenarios'+'.pdf'
+        with PdfPages('Results/'+file_name) as pdf:
+            fig = plt.figure(figsize=(11.69, 8.27))
+            plt.rcParams.update({'font.size': 8})
+            ##### Green power vs power of the proposed configuration #####
+            #plt.figure(figsize=(8, 6))
+            plt.subplot(2, 2, 1)
+            plt.xticks([x for x in range(1,len(ratios)+1)], [str(x) for x in ratios], rotation=30, fontsize=8)
+            plt.axhline(y=self.green_power, color='g', label='Baseline', linestyle='--', linewidth=1)
+            '''plt.bar([x-width/2 for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['Tot. J (based on median)'][0]/duration for x in ratios], width=width, label='Gray power', color='lightgray')
+            plt.bar([x-width/2 for x in range(1,len(ratios)+1)], [self.green_power for x in ratios], width=width, label='Green power', color='g')
+            for x, y in zip(range(1,len(ratios)+1), ratios):
+                if self.green_power == None:
+                    continue
+                else:
+                    plt.text(x-width/2, self.green_power+1, f"{self.green_power:.1f}", ha='center', size=7)
+            '''
+            plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['Tot. J (based on median)'][0]/duration for x in ratios], width=width, label='Power(Perf)', color='r')
+            for x, y in zip(range(1,len(ratios)+1), ratios):
+                if self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration == 0:
+                    continue
+                plt.text(x+width/2, self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration+1, f"{self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration:.1f}", ha='center', size=7)
+            plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [(self.next_configuration[str(x)]['Energy'][1]+self.next_configuration[str(x)]['Energy'][0])/duration for x in ratios], width=width, label='Power(Bal)', color='orange')
+            plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['Energy'][0]/duration for x in ratios], width=width, label='Power(Sust)', color='lightgreen')
+            #ax.bar([x+0.1 for x in cases[str(ratio)].keys()], [next_configuration[str(ratio)][x]['Energy'][0]/duration for x in cases[str(ratio)].keys()], width=0.1, label='Power(Sust)', color='lightgreen')#, marker='^')
+            #plt.scatter([x+width/2 for x in range(1,len(case_ratios)+1)], [baselines[case][str(x)]['Tot. J (based on median)'][0]/duration for x in case_ratios])            
+            plt.xlabel('Load distribution [%Perf, %Bal, %Sust]')
+            plt.ylabel('Power (W)')
+            plt.title('Green power vs power of the proposed configuration')
+            plt.legend()
+            plt.tight_layout()
+            #plt.savefig('Stats/Green-vs-Config_Case'+str(case)+'.pdf', format='pdf', dpi=1200)
+            #plt.show()
+
+
+            ##### without vs with configuration proposition QoE #####
+            self.sch.next_step(duration, self.green_power, 0, 0, total_req_rate)
+            baseline = self.sch.get_next_configuration(load_type=load_type)
+            max_qoe = baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2]
+            
+            #plt.figure(figsize=(8, 6))
+            plt.subplot(2, 2, 4)
+            plt.xticks([0]+[x for x in range(1,len(ratios)+1)], ['Baseline']+[str(x) for x in ratios], rotation=30, fontsize=8)
+            #plt.axhline(y=baseline['Tot. J (based on median)'][0]/duration, color='b', label='Baseline', linestyle='--', linewidth=2)
+            plt.bar(0, baseline.loc[baseline['Mode']=='conf_perf', 'QoE']/max_qoe, width=width, label='Baseline')
+            plt.text(0, baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2]/max_qoe, str(baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2]/max_qoe), ha='center', size=7)
+            #plt.xticks([0], ['Baseline'])
+            plt.bar([x for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['QoE'][2]/max_qoe for x in ratios], width=width, label='QoE(Perf)', color='red')
+            for x, y in zip(range(1,len(ratios)+1), ratios):
+                if self.next_configuration[str(y)]['QoE'][2] == 0:
+                    continue
+                plt.text(x, self.next_configuration[str(y)]['QoE'][2]/max_qoe, f"{self.next_configuration[str(y)]['QoE'][2]/max_qoe:.1f}", ha='center', size=7)
+            plt.bar([x+width for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['QoE'][1]/max_qoe for x in ratios], width=width, label='QoE(Bal)', color='orange')
+            for x, y in zip(range(1,len(ratios)+1), ratios):
+                if self.next_configuration[str(y)]['QoE'][1] == 0:
+                    continue
+                plt.text(x+width, self.next_configuration[str(y)]['QoE'][1]/max_qoe, f"{self.next_configuration[str(y)]['QoE'][1]/max_qoe:.1f}", ha='center', size=7)
+            plt.bar([x+2*width for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['QoE'][0]/max_qoe for x in ratios], width=width, label='QoE(Sust)', color='lightgreen')
+            for x, y in zip(range(1,len(ratios)+1), ratios):
+                if self.next_configuration[str(y)]['QoE'][0] == 0:
+                    continue
+                plt.text(x+2*width, self.next_configuration[str(y)]['QoE'][0]/max_qoe, f"{self.next_configuration[str(y)]['QoE'][0]/max_qoe:.1f}", ha='center', size=7)
+            plt.xlabel('Load distribution [%Perf, %Bal, %Sust]')
+            plt.ylabel('Quality (QoE)')
+            plt.title('Without vs with configuration proposition QoE')
+            plt.legend()
+            plt.tight_layout()
+            #plt.savefig('Stats/QoE_Case'+str(case)+'.pdf', bbox_inches='tight', format='pdf', dpi=1200)
+            #plt.show()
+
+            
+
+            if energy != None:
+                ##### Estimated vs measured energy of the proposed configuration #####
+                #plt.figure(figsize=(8, 6))
+                plt.subplot(2, 2, 2)
+                plt.xticks([x for x in range(1,len(ratios)+1)], [str(x) for x in ratios], rotation=30, fontsize=8)
+                plt.bar([x+3*width/2 for x in range(1,len(ratios)+1)], [energy[str(x)]/duration for x in ratios], width=width, label='Meas. Power', color='black')
+                for x, y in zip(range(1,len(ratios)+1), ratios):
+                    if energy[str(y)]/duration == 0:
+                        continue
+                    plt.text(x+3*width/2, energy[str(y)]/duration+1, f"{energy[str(y)]/duration:.1f}", ha='center', size=7)
+                plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['Tot. J (based on median)'][0]/duration for x in ratios], width=width, label='Power(Perf)', color='r')
+                for x, y in zip(range(1,len(ratios)+1), ratios):
+                    if self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration == 0:
+                        continue
+                    plt.text(x+width/2, self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration+1, f"{self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration:.1f}", ha='center', size=7)
+                plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [(self.next_configuration[str(x)]['Energy'][1]+self.next_configuration[str(x)]['Energy'][0])/duration for x in ratios], width=width, label='Power(Bal)', color='orange')
+                plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['Energy'][0]/duration for x in ratios], width=width, label='Power(Sust)', color='lightgreen')
+
+                plt.xlabel('Load distribution [%Perf, %Bal, %Sust]')
+                plt.ylabel('Power (W)')
+                plt.title('Estimated vs measured energy of the proposition')
+                plt.legend()
+                plt.tight_layout()
+                #plt.savefig('Stats/Estimates-vs-Measured_Case'+str(case)+'.pdf', format='pdf', dpi=1200)
+                #plt.show()
+
+            
+                ##### without vs with configuration proposition energies #####
+                #from statistics import median
+                #baseline = median([energy[str(x)] for x in ratios])
+                baseline =energy[str([100, 0, 0])]
+                
+                #plt.figure(figsize=(8, 6))
+                plt.subplot(2, 2, 3)
+                plt.xticks([0]+[x for x in range(1,len(ratios)+1)], ['Baseline']+[str(x) for x in ratios], rotation=30, fontsize=8)
+                #plt.axhline(y=baseline['Tot. J (based on median)'][0]/duration, color='b', label='Baseline', linestyle='--', linewidth=2)
+                plt.bar(0, baseline/duration, width=width, label='Baseline')
+                plt.text(0, baseline/duration+1, f"{baseline/duration:.1f}", ha='center', size=7)
+                #plt.xticks([0], ['Baseline'])
+                plt.bar([x+3*width/2 for x in range(1,len(ratios)+1)], [energy[str(x)]/duration for x in ratios], width=width, label='Meas. Power', color='black')
+                for x, y in zip(range(1,len(ratios)+1), ratios):
+                    if energy[str(y)]/duration == 0:
+                        continue
+                    plt.text(x+3*width/2, energy[str(y)]/duration+1, f"{energy[str(y)]/duration:.1f}", ha='center', size=7)
+                plt.xlabel('Load distribution [%Perf, %Bal, %Sust]')
+                plt.ylabel('Power (W)')
+                plt.title('Without vs with configuration proposition energies')
+                plt.legend()
+                plt.tight_layout()
+                #plt.savefig('Stats/With-vs-Without_Case'+str(case)+'.pdf', format='pdf', dpi=1200)
+                #plt.show()
+
+
+
+                y_max = -1
+                for x in range(1, 4):
+                    plt.subplot(2, 2, x)
+                    axes = plt.gca()
+                    y_max = max(y_max, axes.get_ylim()[1])
+                for x in range(1, 4):
+                    plt.subplot(2, 2, x)
+                    axes = plt.gca()
+                    axes.set_ylim(0, y_max)
+                pdf.savefig(fig, orientation='landscape', bbox_inches='tight', dpi=1200)
+                plt.close()
+
+
+
+
+
+
+
+
+
+
+
+
+    def get_xticks(self, ratios, width):
+        """
+            Description:
+            In:
+                aaa
+            Out:
+        """
+        #print(ratios)
+        ticks = []
+        labels = []
+        shifts = []
+        # For the baseline:
+        ticks.append(0 - width / 2)
+        labels.append('')
+        shifts.append(0)
+        
+        ticks.append(0 + width / 2)
+        labels.append('Baseline')
+        shifts.append(-width / 2)
+        
+        for i in range(1, len(ratios)+1):
+            i1 = i - width/2
+            i_perf_width, i_bal_width, i_sust_width = 0, 0, 0
+            ticks.append(i1)
+            labels.append('')
+            shifts.append(0)
+            i2 = i + width/2
+            if ratios[i-1][0] != 0:
+                i_perf_width = width * ratios[i-1][0] / 100
+                i_perf = i1 + i_perf_width
+                ticks.append(i_perf)
+                labels.append(str(ratios[i-1][0]) + '% Perf')
+                shifts.append(-i_perf_width / 2)
+            if ratios[i-1][1] != 0:
+                i_bal_width = width * ratios[i-1][1] / 100
+                i_bal = i1 + i_perf_width + i_bal_width
+                ticks.append(i_bal)
+                labels.append(str(ratios[i-1][1]) + '% Bal')
+                shifts.append(-i_bal_width / 2)
+            if ratios[i-1][2] != 0:
+                i_sust_width = width * ratios[i-1][2] / 100
+                i_sust = i1 + i_perf_width + i_bal_width + i_sust_width
+                ticks.append(i_sust)
+                labels.append(str(ratios[i-1][2]) + '% Sust')
+                shifts.append(-i_sust_width / 2)
+            #ticks.append(i2)
+            #labels.append('*')
+        #print(len(ticks), ticks)
+        return ticks, labels, shifts
+
+    def plot_x_axis(self, fig, ax, ratios, width):
+        """
+            Description:
+            In:
+                aaa
+            Out:
+        """
+        import matplotlib.pyplot as plt
+        import matplotlib.transforms
+        ticks, labels, shifts = self.get_xticks(ratios, width)
+        ax.set_xlim(ticks[0]- width/2, ticks[-1]+width/2)
+        ax.set_xticks(ticks, labels)
+        plt.setp(ax.xaxis.get_majorticklabels(), rotation=90) # Reference: https://stackoverflow.com/questions/28615887/how-to-move-a-tick-label
+        dy = 0.0
+        for i, label in zip(range(len(shifts)), ax.xaxis.get_majorticklabels()):
+            #print(shifts[i])
+            dx = shifts[i]
+            offset = matplotlib.transforms.ScaledTranslation(dx, dy, fig.dpi_scale_trans)
+            label.set_transform(label.get_transform() + offset)
+
+    
+
+    def plot_v3(self, percentages, duration, total_req_rate, load_type, energy, date=""):
+        """
+            Description:
+            In:
+                aaa
+            Out:
+        """
+        import matplotlib.pyplot as plt
+        import matplotlib.transforms
+        from matplotlib.backends.backend_pdf import PdfPages
+        import numpy as np
+
+        width = 0.6
+        ratios = self.get_ratios(percentages)
+        baselines = {}
+
+        MOS = ['Poor', 'Medium', 'Good', 'Very good', 'Excellent']
+
+        fig, axs = plt.subplots(2, figsize=(11.69, 8.27))#, sharex=True)
+        plt.rcParams.update({'font.size': 8})
+        ##### without vs with configuration proposition QoE #####
+        self.sch.next_step(duration, self.green_power, 0, 0, total_req_rate)
+        baseline = self.sch.get_next_configuration(load_type=load_type)
+        max_qoe = baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2]
+        
+        axs[0].grid(axis='y')
+        #axs[0].grid(axis='x', alpha=0.15)
+        axs[0].set_axisbelow(True)
+        #plt.figure(figsize=(8, 6))
+        axs[0].tick_params(axis='x', direction='in', pad=-5, top=True, bottom=True)#, pad=-30
+        #plt.axhline(y=baseline['Tot. J (based on median)'][0]/duration, color='b', label='Baseline', linestyle='--', linewidth=2)
+        baseline_label = axs[0].scatter(0, MOS.index(baseline.loc[baseline['Mode']=='conf_perf', 'MOS'][2])+1, label='Baseline')
+        #axs[0].text(0, baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2]/max_qoe+.02, str(baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2]/max_qoe), ha='center', size=7)
+        #plt.xticks([0], ['Baseline'])
+        #axs[0].scatter([x for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['QoE'][2]/max_qoe for x in ratios], label='QoE(Perf)', color='blue', marker='*')
+        ticks, labels, shifts = self.get_xticks(ratios, width)
+        qoe_plots = {'perf':{'x':[], 'y':[]}, 'bal':{'x':[], 'y':[]}, 'sust':{'x':[], 'y':[]}}
+        i = 2
+        for x, y in zip(range(1,len(ratios)+1), ratios):
+            if self.next_configuration[str(y)]['QoE'][2] != 0:
+                while labels[i] == '':
+                    i += 1
+                qoe_plots['perf']['x'].append(ticks[i]+shifts[i])
+                qoe_plots['perf']['y'].append(MOS.index(self.next_configuration[str(y)]['MOS'][2])+1)
+                #perf_label = axs[0].scatter([ticks[i]+shifts[i]], [MOS.index(self.next_configuration[str(y)]['MOS'][2])+1], label='QoE(Perf)', color='brown', marker='*')
+                i += 1
+            if self.next_configuration[str(y)]['QoE'][1] != 0:
+                while labels[i] == '':
+                    i += 1
+                qoe_plots['bal']['x'].append(ticks[i]+shifts[i])
+                qoe_plots['bal']['y'].append(MOS.index(self.next_configuration[str(y)]['MOS'][1])+1)
+                #bal_label = axs[0].scatter([ticks[i]+shifts[i]], [MOS.index(self.next_configuration[str(y)]['MOS'][1])+1], label='QoE(Bal)', color='orange', marker='D')
+                i += 1
+            if self.next_configuration[str(y)]['QoE'][0] != 0:
+                while labels[i] == '':
+                    i += 1
+                qoe_plots['sust']['x'].append(ticks[i]+shifts[i])
+                qoe_plots['sust']['y'].append(MOS.index(self.next_configuration[str(y)]['MOS'][0])+1)
+                #sust_label = axs[0].scatter([ticks[i]+shifts[i]], [MOS.index(self.next_configuration[str(y)]['MOS'][0])+1], label='QoE(Sust)', color='green', marker='x')
+                i += 1
+        axs[0].scatter(qoe_plots['perf']['x'], qoe_plots['perf']['y'], label='QoE(Perf)', color='brown', marker='*')
+        axs[0].scatter(qoe_plots['bal']['x'], qoe_plots['bal']['y'], label='QoE(Bal)', color='orange', marker='D')
+        axs[0].scatter(qoe_plots['sust']['x'], qoe_plots['sust']['y'], label='QoE(Sust)', color='green', marker='x')
+        axs[0].set_yticks(np.arange(len(MOS)+1))
+        axs[0].set_yticklabels(['']+MOS)
+        axs[0].set_ylabel('Quality (QoE)')
+        #plt.title('Without vs with configuration proposition QoE')
+        self.plot_x_axis(fig, axs[0], ratios, width)
+        plt.setp(axs[0].xaxis.get_majorticklabels(), rotation=90, ha='left', va='bottom', rotation_mode="default")
+
+        axs[0].legend(loc='center left')#(baseline_label, perf_label, bal_label, sust_label), ('Baseline', 'QoE(Perf)', 'QoE(Bal)', 'QoE(Sust)'))
+        plt.tight_layout()
+            
+        ##### without vs with configuration proposition energies #####
+        #from statistics import median
+        #baseline = median([energy[str(x)] for x in ratios])
+        baseline =energy[str([100, 0, 0])]
+        axs[1].bar(0, baseline/duration, width=width, label='Baseline')
+        axs[1].text(0, baseline/duration+1, f"{baseline/duration:.1f}", ha='center', size=7)
+        #plt.xticks([0], ['Baseline'])
+        axs[1].bar([x for x in range(1,len(ratios)+1)], [energy[str(x)]/duration for x in ratios], width=width, label='Meas. Power', color='lightblue')
+        for x, y in zip(range(1,len(ratios)+1), ratios):
+            if energy[str(y)]/duration == 0:
+                continue
+            plt.text(x, energy[str(y)]/duration+1, f"{energy[str(y)]/duration:.1f}", ha='center', size=7)
+
+        '''axs[1].vlines(qoe_plots['perf']['x'], 0, qoe_plots['perf']['y'], label='QoE(Perf)')
+        axs[1].vlines(qoe_plots['bal']['x'], 0, qoe_plots['bal']['y'], label='QoE(Bal)')
+        axs[1].vlines(qoe_plots['sust']['x'], 0, qoe_plots['sust']['y'], label='QoE(Sust)', color='green')'''
+        
+        plt.xlabel('Load distribution [%Perf, %Bal, %Sust]')
+        axs[1].set_ylabel('Power (W)')
+        axs[1].axhline(y=self.green_power, color='g', label='Green Power', linestyle=':', dashes=(1, 5), linewidth=1)
+        axs[1].set_yticks(list(axs[1].get_yticks()) + [self.green_power])
+
+        
+        axs[1].tick_params(axis='x', direction='out', pad=width/2, top=True, bottom=True)
+
+        self.plot_x_axis(fig, axs[1], ratios, width)
+
+        
+        fig.suptitle('Power vs QoE depending on Load distribution')
+        plt.legend()
+        plt.tight_layout()
+        file_name = date + '_Power-vs-QoE' + '.pdf'
+        print("Saving file", file_name)
+        plt.savefig('Results/'+file_name)
+        plt.show()
+
+
+    def plot_v4(self, percentages, duration, total_req_rate, load_type, energy, date="", annotation=False):
+        """
+            Description:
+            In:
+                aaa
+            Out:
+        """
+        import matplotlib.pyplot as plt
+        import matplotlib.transforms
+        from matplotlib.backends.backend_pdf import PdfPages
+        import numpy as np
+
+        width = 0.6
+        ratios = self.get_ratios(percentages)
+        baselines = {}
+
+        MOS = ['Poor', 'Medium', 'Good', 'Very good', 'Excellent']
+
+        fig, axs = plt.subplots(figsize=(11.69, 6.2025))#8.27))#, sharex=True)
+        #plt.rcParams.update({'font.size': 8})
+        ##### without vs with configuration proposition QoE #####
+        self.sch.next_step(duration, self.green_power, 0, 0, total_req_rate)
+        baseline = self.sch.get_next_configuration(load_type=load_type)
+        max_qoe = baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2]
+
+        
+        ##### without vs with configuration proposition energies #####
+        #from statistics import median
+        #baseline = median([energy[str(x)] for x in ratios])
+        baseline = energy[str([100, 0, 0])]
+
+        if annotation == True:
+            axs.axhline(y=baseline/duration, color='black', linestyle='--', linewidth=.75, zorder=1)
+        
+        axs.axhline(y=self.green_power, color='g', label='Green Power', linestyle='--', zorder=1)#, dashes=(1, 5), linewidth=1)
+        #axs.text(4.5, baseline/duration+1, "Baseline", ha='center')
+        #axs.set_yticks(list(axs.get_yticks()) + [baseline/duration])
+        #axs.vlines(5, energy[str([0,100,0])]/duration, baseline/duration, color='red', linestyle='-')
+        #plt.stem(5, baseline/duration)
+        if annotation == True:
+            plt.annotate('', xy=(5, baseline/duration), xytext=(5, energy[str([0,100,0])]/duration), arrowprops=dict(arrowstyle='|-|', color='red'))
+            axs.text(5-.3, (energy[str([0,100,0])]+(baseline-energy[str([0,100,0])])/2)/duration, f"{100*(energy[str([0,100,0])]-baseline)/baseline:.1f}%", ha='center', color='red')
+            #axs.vlines(9, energy[str([50,25,25])]/duration, baseline/duration, color='red', linestyle='-')
+            plt.annotate('', xy=(9, baseline/duration), xytext=(9, energy[str([50,25,25])]/duration), arrowprops=dict(arrowstyle='|-|', color='red'))
+            axs.text(9-.3, (energy[str([50,25,25])]+(baseline-energy[str([50,25,25])])/2)/duration, f"{100*(energy[str([50,25,25])]-baseline)/baseline:.1f}%", ha='center', color='red')
+            
+        # For the baseline:
+        axs.bar(0, baseline/duration, width=width, label='Meas. Power')
+        axs.text(0, baseline/duration+1, f"{baseline/duration:.1f}", ha='center')#, size=7)
+        #plt.xticks([0], ['Baseline'])
+        
+        axs.bar([x for x in range(1,len(ratios)+1)], [energy[str(x)]/duration for x in ratios], width=width, label='Meas. Power', color='lightblue')
+        axs.set_yticks(list(axs.get_yticks()) + [self.green_power])
+        for x, y in zip(range(1,len(ratios)+1), ratios):
+            if energy[str(y)]/duration == 0:
+                continue
+            plt.text(x, energy[str(y)]/duration+1, f"{energy[str(y)]/duration:.1f}", ha='center')#, size=7)
+
+        '''axs[1].vlines(qoe_plots['perf']['x'], 0, qoe_plots['perf']['y'], label='QoE(Perf)')
+        axs[1].vlines(qoe_plots['bal']['x'], 0, qoe_plots['bal']['y'], label='QoE(Bal)')
+        axs[1].vlines(qoe_plots['sust']['x'], 0, qoe_plots['sust']['y'], label='QoE(Sust)', color='green')'''
+        
+        plt.xlabel('Load distribution [%Perf, %Bal, %Sust]')
+        axs.set_ylabel('Power (W)')
+
+        
+        axs.tick_params(axis='x', direction='out', pad=width/2, top=True, bottom=True, labelsize=11)
+        axs.tick_params(axis='y', labelsize=11)
+
+        self.plot_x_axis(fig, axs, ratios, width)
+
+        '''axs.axhline(y=baseline/duration, color='white', linestyle=':', dashes=(1, 5), linewidth=1)
+        axs.vlines(5, energy[str([0,100,0])]/duration, baseline/duration, color='white', linestyle='-')
+        #plt.stem(5, baseline/duration)
+        axs.text(5-.3, (energy[str([0,100,0])]+(baseline-energy[str([0,100,0])])/2)/duration, f"{100*(energy[str([0,100,0])]-baseline)/baseline:.1f}%", ha='center', color='white')
+        axs.vlines(9, energy[str([50,25,25])]/duration, baseline/duration, color='white', linestyle='-')
+        axs.text(9-.3, (energy[str([50,25,25])]+(baseline-energy[str([50,25,25])])/2)/duration-4.5, f"{100*(energy[str([50,25,25])]-baseline)/baseline:.1f}%", ha='center', color='white')'''
+
+
+        
+        #fig.suptitle('Power vs QoE depending on Load distribution')
+        plt.legend(loc='upper right', bbox_to_anchor=(0.87,0.88))
+        plt.tight_layout()
+        annot = ''
+        if annotation == True:
+            annot = '_annotation'
+        file_name = date + '_Power-vs-QoE' + annot + '.pdf'
+        print("Saving file", file_name)
+        plt.savefig('Results/'+file_name)
+        plt.show()
 
 
 
diff --git a/modules/Scheduler.py b/modules/Scheduler.py
index d96ace14440ce06ab08f1d3f8f8aec8030207f6c..e4fcdd5261c06f9620952a57e9a37ea607e17c4b 100644
--- a/modules/Scheduler.py
+++ b/modules/Scheduler.py
@@ -25,7 +25,23 @@ class Scheduler:
         self.configurations = {}
         for load in self.loads:
             self.configurations[load] = experience.loc[experience['Load type'] == load, ['Image size (px)', 'Filter', 'Req/s', 'Users', 'Mean J/Req', 'Min J/Req', 'Max J/Req', 'Median J/Req']].reset_index(drop=True)
+
             self.configurations[load]['QoE'] = [x + 1 for x in range(len(self.configurations[load]))]
+            
+            MOS = [] # Mean Opinion Score
+            for x in self.configurations[load]['Image size (px)']:
+                if x >= 1080:
+                    MOS.append("Excellent")
+                elif x >= 720:
+                    MOS.append("Very good")
+                elif x >= 480:
+                    MOS.append("Good")
+                elif x >= 360:
+                    MOS.append("Medium")
+                else: # elif x >= 144:
+                    MOS.append("Poor")
+            #print(qualities)
+            self.configurations[load]['MOS'] = MOS
             #print("\033[1m" + load + "\033[0m\n", self.configurations[load])
         #print(configurations)
         return self.configurations
@@ -75,6 +91,9 @@ class Scheduler:
         next_configuration['QoE'] = [self.configurations[load]['QoE'][conf_sust] if self.req_rate_sust!=0 else 0,
                                      self.configurations[load]['QoE'][conf_bal] if self.req_rate_bal!=0 else 0,
                                      self.configurations[load]['QoE'][conf_perf] if self.req_rate_perf!=0 else 0]
+        next_configuration['MOS'] = [self.configurations[load]['MOS'][conf_sust] if self.req_rate_sust!=0 else 0,
+                                     self.configurations[load]['MOS'][conf_bal] if self.req_rate_bal!=0 else 0,
+                                     self.configurations[load]['MOS'][conf_perf] if self.req_rate_perf!=0 else 0]
         
         next_configuration['Energy'] = [self.energy(conf_sust, self.req_rate_sust, self.duration, load), self.energy(conf_bal, self.req_rate_bal, self.duration, load), self.energy(conf_perf, self.req_rate_perf, self.duration, load)]