Plot.py 17.5 KB
Newer Older
Marc Serramia's avatar
Marc Serramia committed
1
import os
Marc Serramia's avatar
Marc Serramia committed
2
import sys
Marc Serramia's avatar
Marc Serramia committed
3 4 5
import PARAMETERS
import numpy as np
import matplotlib.pyplot as plt
6 7
from matplotlib.colors import LinearSegmentedColormap
import math
Marc Serramia's avatar
Marc Serramia committed
8 9 10 11 12 13 14 15 16 17

class Plot:

    def __init__(self, plotfile):
        self.plot_filename = plotfile

    @staticmethod
    def sortData(x, y):
        for passnum in range(len(x) - 1, 0, -1):
            for i in range(passnum):
18 19 20 21 22 23 24 25 26 27
                if isinstance(x[i], int) or isinstance(x[i], float):
                    if x[i] > x[i + 1]:
                        temp = x[i]
                        x[i] = x[i + 1]
                        x[i + 1] = temp
                        temp = y[i]
                        y[i] = y[i + 1]
                        y[i + 1] = temp
                else:
                    print("WARNING: SORTING BY NON NUMERICALX")
Marc Serramia's avatar
Marc Serramia committed
28

Marc Serramia's avatar
Marc Serramia committed
29
    def loadScatterPointsRatio(self):
Marc Serramia's avatar
Marc Serramia committed
30 31 32 33 34 35 36 37 38
        size = os.path.getsize(self.plot_filename)
        plotfile = open(self.plot_filename, "r")
        x = []
        y = []
        while size:
            line = plotfile.readline()
            data = line.strip('\n').split(',')
            height = data[0]
            width = data[1]
39
            num_inc = int(data[2])
Marc Serramia's avatar
Marc Serramia committed
40 41 42 43 44
            num_dgen = data[3]
            num_igen = data[4]
            time = data[5]
            if PARAMETERS.PLOT_TYPE == "RATIO":
                if PARAMETERS.RATIO_TYPE == "D":
45
                    num_genrels = int(num_dgen)
Marc Serramia's avatar
Marc Serramia committed
46
                elif PARAMETERS.RATIO_TYPE == "I":
47
                    num_genrels = int(num_igen)
Marc Serramia's avatar
Marc Serramia committed
48
                else:
49
                    num_genrels = None
Marc Serramia's avatar
Marc Serramia committed
50
                    print("INVALID RATIO TYPE")
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
                if PARAMETERS.RATIO_ORDER == "GI":
                    if num_inc != 0:
                        x.append(float(num_genrels) / float(num_inc))
                        y.append(float(time))
                elif PARAMETERS.RATIO_ORDER == "IG":
                    if num_genrels:
                        x.append(float(num_inc) / float(num_genrels))
                        y.append(float(time))
                elif PARAMETERS.RATIO_ORDER == "G":
                    x.append(num_genrels)
                    y.append(float(time))
                elif PARAMETERS.RATIO_ORDER == "I":
                    x.append(num_inc)
                    y.append(float(time))
            size -= len(line)
        plotfile.close()
        return x, y

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
    def loadScatterPointsRatioHeatmap(self):
        size = os.path.getsize(self.plot_filename)
        plotfile = open(self.plot_filename, "r")
        x = []
        y = []
        z = []
        maxrels = math.factorial(PARAMETERS.PLOT_NORMS) // math.factorial(2) // math.factorial(PARAMETERS.PLOT_NORMS - 2)
        while size:
            line = plotfile.readline()
            data = line.strip('\n').split(',')
            rel_prob = data[0]
            inc_prob = data[1]
            num_inc = int(data[2])
            num_dgen = data[3]
            num_igen = data[4]
            time = data[5]
            if num_inc != 0:
                x.append(round(float(inc_prob),2))
                y.append(round(float(rel_prob),2))
                z.append(float(time))
            size -= len(line)
        plotfile.close()
        return x,y,z

Marc Serramia's avatar
Marc Serramia committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
    def loadScatterPointsValuesHeatmap(self):
        size = os.path.getsize(self.plot_filename)
        plotfile = open(self.plot_filename, "r")
        x = []
        y = []
        z = []
        while size:
            line = plotfile.readline()
            data = line.strip('\n').split(',')
            ind_prob = data[3]
            normvalue_prob = data[4]
            if PARAMETERS.TO_PLOT == "SOLVE":
                time = data[9]
            else:
                time = data[8]
            if ind_prob != 0:
                x.append(round(float(ind_prob),2))
                y.append(round(float(normvalue_prob),2))
                z.append(float(time))
            size -= len(line)
        plotfile.close()
        return x,y,z

116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    def loadScatterPointsValues(self):
        size = os.path.getsize(self.plot_filename)
        plotfile = open(self.plot_filename, "r")
        x = []
        y = []
        while size:
            line = plotfile.readline()
            data = line.strip('\n').split(',')
            num_values = data[0]
            height = data[1]
            width = data[2]
            inc_prob = data[3]
            num_inc = data[4]
            num_dgen = data[5]
            num_igen = data[6]
131 132
            buildtime = data[7]
            solvetime = data[8]
133
            x.append(int(num_values))
134 135 136 137
            if PARAMETERS.TO_PLOT == "BUILD":
                y.append(float(buildtime))
            else:
                y.append(float(solvetime))
Marc Serramia's avatar
Marc Serramia committed
138 139 140 141 142
            size -= len(line)
        plotfile.close()
        return x, y

    def plotratio(self):
143
        plot_fig_path = self.plot_filename[:-4]+"Plot"+PARAMETERS.RATIO_TYPE+"Ratio.pdf"
Marc Serramia's avatar
Marc Serramia committed
144 145 146
        fig = plt.figure()
        ax = fig.add_subplot(111)
        fig.suptitle('Effect of the problem structure on the execution time', size=16)
147 148 149 150 151 152 153 154
        if PARAMETERS.RATIO_ORDER == "GI":
            ax.set_xlabel('Ratio (Generalisation relations / Incompatibility relations)', size=12)
        elif PARAMETERS.RATIO_ORDER == "IG":
            ax.set_xlabel('Ratio (Incompativility relations / Generalisatioon relations)', size=12)
        elif PARAMETERS.RATIO_ORDER == "G":
            ax.set_xlabel('Generalisation relations', size=12)
        elif PARAMETERS.RATIO_ORDER == "I":
            ax.set_xlabel('Incompatibility relations', size=12)
Marc Serramia's avatar
Marc Serramia committed
155
        ax.set_ylabel('Time (sec)', size=12)
Marc Serramia's avatar
Marc Serramia committed
156 157 158
        x, y = self.loadScatterPointsRatio()
        self.sortData(x,y)
        if PARAMETERS.CUT:
159
            toRemove = {}
Marc Serramia's avatar
Marc Serramia committed
160
            upper_cut = np.percentile(y, 100-PARAMETERS.QUARTILE_CUT)
161
            print(np.median(y))
Marc Serramia's avatar
Marc Serramia committed
162 163
            for i in range(len(x)):
                if x[i] < PARAMETERS.SHOW_X_RANGE[0] or x[i] > PARAMETERS.SHOW_X_RANGE[1]:
164
                    toRemove[i] = True
Marc Serramia's avatar
Marc Serramia committed
165
                if y[i] < PARAMETERS.SHOW_Y_RANGE[0] or y[i] > PARAMETERS.SHOW_Y_RANGE[1]:
166
                    toRemove[i] = True
Marc Serramia's avatar
Marc Serramia committed
167
                if y[i] > upper_cut:
168 169 170 171
                    toRemove[i] = True
            els = list(toRemove)
            els.sort(reverse=True)
            for i in els:
Marc Serramia's avatar
Marc Serramia committed
172 173 174 175 176 177 178 179 180
                x.pop(i)
                y.pop(i)
        plt.scatter(x, y, color=PARAMETERS.POINT_COLOR, s=PARAMETERS.POINT_SIZE)
        if PARAMETERS.SAVE:
            plt.savefig(plot_fig_path)
        if PARAMETERS.SHOW:
            plt.show()
        plt.close(fig)

181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
    def plotratioHeatmap(self):
        plot_fig_path = self.plot_filename[:-4]+"PlotRatioHeatmap.pdf"
        fig = plt.figure()
        ax = fig.add_subplot(111)
        fig.suptitle('Effect of the problem structure on the execution time', size=16)
        ax.set_xlabel('Incompatibility percentage', size=12)
        ax.set_ylabel('Relation density', size=12)
        x, y, z = self.loadScatterPointsRatioHeatmap()
        maxtime = max(z)
        for i in range(len(z)):
            if z[i] > 10.0:
                z[i] = 10.0
        cdict = {'red': [[0.0, 0.0, 0.0],
                         [0.05, 1.0, 1.0],
                         [0.1, 1.0, 1.0],
                         [1, 0.0, 0.0]],
                 'green': [[0.0, 1.0, 1.0],
                           [0.05, 1.0, 1.0],
                           [0.1, 0.0, 0.0],
                           [1, 0.0, 0.0]],
                 'blue': [[0.0, 0.0, 0.0],
                          [1, 0.0, 0.0]]}
        newcmp = LinearSegmentedColormap('testCmap', segmentdata=cdict, N=256)
        plt.scatter(x, y, c=z, cmap = newcmp)
        plt.colorbar(ticks = [min(z),0.5,1, 10], extend = "max", format = "%.1f", label = "Seconds")
        plt.show()
        if PARAMETERS.SAVE:
            plt.savefig(plot_fig_path)
        if PARAMETERS.SHOW:
            plt.show()
        plt.close(fig)

Marc Serramia's avatar
Marc Serramia committed
213 214 215 216 217 218 219 220 221 222 223
    def loadScatterPointsNormRange(self):
        size = os.path.getsize(self.plot_filename)
        plotfile = open(self.plot_filename, "r")
        x = []
        y = []
        while size:
            line = plotfile.readline()
            data = line.strip('\n').split(',')
            num_norms = data[0]
            height = data[1]
            width = data[2]
224 225 226 227 228
            inc_prob = data[3]
            num_inc = data[4]
            num_dgen = data[5]
            num_igen = data[6]
            time = data[7]
229
            x.append(int(num_norms))
Marc Serramia's avatar
Marc Serramia committed
230 231 232 233 234
            y.append(float(time))
            size -= len(line)
        plotfile.close()
        return x, y

235
    def plotvaluerange(self):
236
        plot_fig_path = self.plot_filename[:-4]+"PlotValues"+PARAMETERS.TO_PLOT+".pdf"
237 238
        fig = plt.figure()
        ax = fig.add_subplot(111)
239 240 241 242
        if PARAMETERS.TO_PLOT == "BUILD":
            fig.suptitle('Effect of the number of values on the LP building time', size=16)
        else:
            fig.suptitle('Effect of the number of values on execution time', size=16)
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
        ax.set_xlabel('Number of values', size=12)
        ax.set_ylabel('Time (sec)', size=12)
        x, y = self.loadScatterPointsValues()
        self.sortData(x,y)
        if not PARAMETERS.DRAW_LINE:
            plt.scatter(x, y, color=PARAMETERS.POINT_COLOR, s=PARAMETERS.POINT_SIZE)
        else:
            aux = {}
            for i in range(len(x)):
                if x[i] not in aux:
                    aux[x[i]] = []
                aux[x[i]].append(y[i])
            xline = []
            yline = []
            sdline = []
            for v in x:
                if v not in xline:
                    xline.append(v)
                    yline.append(np.mean(aux[v]))
                    sdline.append(np.std(aux[v]))
            plt.plot(xline, yline, color="blue", linewidth=4)
            if PARAMETERS.SD:
                lowlimits = []
                highlimits = []
                for i in range(len(sdline)):
                    lowlimits.append(yline[i] - sdline[i])
                    highlimits.append(yline[i] + sdline[i])
                plt.fill_between(xline, lowlimits, highlimits, color="blue", alpha=.2)

        if PARAMETERS.SAVE:
            plt.savefig(plot_fig_path)
        if PARAMETERS.SHOW:
            plt.show()
        plt.close(fig)

Marc Serramia's avatar
Marc Serramia committed
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
    def plotvaluerangeheatmap(self):
        plot_fig_path = self.plot_filename[:-4]+"PlotValueHeatmap.pdf"
        fig = plt.figure()
        ax = fig.add_subplot(111)
        if PARAMETERS.TO_PLOT == "SOLVE":
            fig.suptitle('Effect of value indifference and value promotion probability on solving times', size=16)
        else:
            fig.suptitle('Effect of value indifference and value promotion probability on building times', size=16)
        ax.set_xlabel('Value promotion probability', size=12)
        ax.set_ylabel('Value indifference probability', size=12)
        x, y, z = self.loadScatterPointsValuesHeatmap()
        maxtime = max(z)
        for i in range(len(z)):
            if z[i] > 10.0:
                z[i] = 10.0
        cdict = {'red': [[0.0, 0.0, 0.0],
                         [0.25, 1.0, 1.0],
                         [0.75, 1.0, 1.0],
                         [1, 0.0, 0.0]],
                 'green': [[0.0, 1.0, 1.0],
                           [0.25, 1.0, 1.0],
                           [0.75, 0.0, 0.0],
                           [1, 0.0, 0.0]],
                 'blue': [[0.0, 0.0, 0.0],
                          [1, 0.0, 0.0]]}
        newcmp = LinearSegmentedColormap('testCmap', segmentdata=cdict, N=256)
        plt.scatter(x, y, c=z, cmap = newcmp)
        plt.colorbar(label = "Seconds")
        plt.show()
        if PARAMETERS.SAVE:
            plt.savefig(plot_fig_path)
        if PARAMETERS.SHOW:
            plt.show()
        plt.close(fig)

Marc Serramia's avatar
Marc Serramia committed
313
    def plotnormrange(self):
314
        plot_fig_path = os.getcwd()+"/PLOTDATA/PlotNormRange.pdf"
Marc Serramia's avatar
Marc Serramia committed
315 316 317 318 319 320
        fig = plt.figure()
        ax = fig.add_subplot(111)
        fig.suptitle('Scalability of the optimisation', size=16)
        ax.set_xlabel('Number of norms', size=12)
        ax.set_ylabel('Time (sec)', size=12)
        x, y = self.loadScatterPointsNormRange()
Marc Serramia's avatar
Marc Serramia committed
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
        self.sortData(x,y)
        if PARAMETERS.CUT:
            toRemove = []
            upper_cut = np.percentile(y, 100-PARAMETERS.QUARTILE_CUT)
            for i in range(len(x)):
                if x[i] < PARAMETERS.SHOW_X_RANGE[0] or x[i] > PARAMETERS.SHOW_X_RANGE[1]:
                    toRemove.append(i)
                if y[i] < PARAMETERS.SHOW_Y_RANGE[0] or y[i] > PARAMETERS.SHOW_Y_RANGE[1]:
                    toRemove.append(i)
                if y[i] > upper_cut:
                    toRemove.append(i)
            toRemove.sort(reverse=True)
            for i in toRemove:
                x.pop(i)
                y.pop(i)
        plt.scatter(x, y, color=PARAMETERS.POINT_COLOR, s=PARAMETERS.POINT_SIZE)
        if PARAMETERS.SAVE:
            plt.savefig(plot_fig_path)
        if PARAMETERS.SHOW:
            plt.show()
        plt.close(fig)

343 344 345 346 347 348 349 350 351
    def loadScatterPointsNormRangeProb(self):
        size = os.path.getsize(self.plot_filename)
        plotfile = open(self.plot_filename, "r")
        times = {}
        sd = {}
        while size:
            line = plotfile.readline()
            data = line.strip('\n').split(',')
            num_norms = data[0]
352 353
            density = data[1]
            inc_perc = data[2]
354 355 356 357 358 359 360 361
            inc_prob = data[3]
            num_inc = data[4]
            num_dgen = data[5]
            num_igen = data[6]
            time = data[7]
            if not num_norms in times:
                times[num_norms] = {}
                sd[num_norms] = {}
362 363 364 365
            if not density in times[num_norms]:
                times[num_norms][density] = []
                sd[num_norms][density] = None
            times[num_norms][density].append(float(time))
366 367 368 369 370
            size -= len(line)
        plotfile.close()
        return times, sd

    def plotnormrangeprobs(self):
371
        plot_fig_path = os.getcwd()+"/PLOTDATA/PlotNormRange.pdf"
372 373 374 375 376 377 378
        fig = plt.figure()
        ax = fig.add_subplot(111)
        fig.suptitle('Scalability of the optimisation', size=16)
        ax.set_xlabel('Number of norms', size=12)
        ax.set_ylabel('Time (sec)', size=12)
        times, sd = self.loadScatterPointsNormRangeProb()
        norms = list(times.keys())
379 380 381 382 383 384
        if PARAMETERS.PLOT_INCOMPATIBILITY_PROB:
            probs = []
            for p in PARAMETERS.PLOT_INCOMPATIBILITY_PROB:
                probs.append(str(p))
        else:
            probs = list(times[norms[0]].keys())
385 386 387
        for n in norms:
            for p in probs:
                sd[n][p] = np.std(times[n][p])
388 389 390
                times[n][p] = np.mean(times[n][p])
        timesp = {}
        sdp = {}
391
        for p in probs:
392 393
            timesp[p] = []
            sdp[p] = []
394
            for n in list(times.keys()):
395 396
                timesp[p].append(times[n][p])
                sdp[p].append(sd[n][p])
397
        num = 0
398 399 400
        for i in range(len(probs)):
            p = probs[i]
            l = PARAMETERS.LABELS[i]
401 402
            x = norms
            y = timesp[p]
403
            plt.plot(x, y, marker='o', markerfacecolor=PARAMETERS.COLORS[len(PARAMETERS.COLORS)-len(probs)+num], markersize=12, color=PARAMETERS.COLORS[len(PARAMETERS.COLORS)-len(probs)+num], linewidth=4, label= l)
404 405 406 407 408 409 410 411
            if PARAMETERS.SD:
                deviations = sdp[p]
                lowlimits = []
                highlimits = []
                for i in range(len(deviations)):
                    lowlimits.append(y[i] - deviations[i])
                    highlimits.append(y[i] + deviations[i])
                plt.fill_between(x, lowlimits, highlimits, color = PARAMETERS.COLORS[len(PARAMETERS.COLORS)-len(probs)+num], alpha = .2)
412 413 414 415 416 417 418 419
            num += 1
        plt.legend()
        if PARAMETERS.SAVE:
            plt.savefig(plot_fig_path)
        if PARAMETERS.SHOW:
            plt.show()
        plt.close(fig)

Marc Serramia's avatar
Marc Serramia committed
420
def main():
Marc Serramia's avatar
Marc Serramia committed
421 422 423 424
    if PARAMETERS.PLOT_TYPE == "RATIO":
        plot_data_file = os.getcwd()+"/PLOTDATA/"+str(PARAMETERS.PLOT_NORMS)+"N.txt"
        if os.path.exists(plot_data_file):
            pl = Plot(plot_data_file)
Marc Serramia's avatar
Marc Serramia committed
425
            pl.plotratio()
Marc Serramia's avatar
Marc Serramia committed
426 427
        else:
            print("INEXISTENT PLOT FILE")
428 429 430 431 432 433 434
    elif PARAMETERS.PLOT_TYPE == "RATIO_HEATMAP":
        plot_data_file = os.getcwd()+"/PLOTDATA/"+str(PARAMETERS.PLOT_NORMS)+"N.txt"
        if os.path.exists(plot_data_file):
            pl = Plot(plot_data_file)
            pl.plotratioHeatmap()
        else:
            print("INEXISTENT PLOT FILE")
Marc Serramia's avatar
Marc Serramia committed
435 436 437 438 439 440 441
    elif PARAMETERS.PLOT_TYPE == "SCALABILITY":
        plot_data_file = os.getcwd() + "/PLOTDATA/NORMRANGE.txt"
        if os.path.exists(plot_data_file):
            pl = Plot(plot_data_file)
            pl.plotnormrange()
        else:
            print("INEXISTENT PLOT FILE")
442 443 444 445 446 447 448
    elif PARAMETERS.PLOT_TYPE == "SCALABILITY_PROB":
        plot_data_file = os.getcwd() + "/PLOTDATA/NORMRANGE.txt"
        if os.path.exists(plot_data_file):
            pl = Plot(plot_data_file)
            pl.plotnormrangeprobs()
        else:
            print("INEXISTENT PLOT FILE")
449 450 451 452 453 454 455
    elif PARAMETERS.PLOT_TYPE == "VALUES":
        plot_data_file = os.getcwd()+"/PLOTDATA/"+str(PARAMETERS.PLOT_NORMS)+"N.txt"
        if os.path.exists(plot_data_file):
            pl = Plot(plot_data_file)
            pl.plotvaluerange()
        else:
            print("INEXISTENT PLOT FILE")
Marc Serramia's avatar
Marc Serramia committed
456 457 458 459 460 461 462
    elif PARAMETERS.PLOT_TYPE == "VALUES_HEATMAP":
        plot_data_file = os.getcwd()+"/PLOTDATA/"+str(PARAMETERS.PLOT_NORMS)+"N.txt"
        if os.path.exists(plot_data_file):
            pl = Plot(plot_data_file)
            pl.plotvaluerangeheatmap()
        else:
            print("INEXISTENT PLOT FILE")
Marc Serramia's avatar
Marc Serramia committed
463
    else:
Marc Serramia's avatar
Marc Serramia committed
464
        print("INVALID PLOT TYPE")
Marc Serramia's avatar
Marc Serramia committed
465 466

if __name__ == "__main__":
Marc Serramia's avatar
Marc Serramia committed
467 468 469 470
    if sys.version > str(3):
        main()
    else:
        print("Run with Python3")