]> rtime.felk.cvut.cz Git - hubacji1/iamcar2.git/blobdiff - scripts/plot.py
Fix plot when obst in json is null
[hubacji1/iamcar2.git] / scripts / plot.py
old mode 100644 (file)
new mode 100755 (executable)
index f43d642..07ad716
@@ -5,15 +5,25 @@ import numpy as np
 
 import scenario
 
-def boxplot(w={}, t=""):
+def boxplot(w={}, t="", yl=None, lx="Elapsed time [s]", ly=""):
     """Plot boxplot graph.
 
     Keyword arguments:
     w -- What to plot.
     t -- Graph title.
+    yl -- Y axis limit [min, max].
     """
     f, ax = plt.subplots()
-    ax.set_title(t)
+
+    if False: # is the y axis log scale?
+        ax.set_title("{} -- {} (log yscale)".format(scenario.SNAME, t))
+        ax.set_yscale("log")
+    else:
+        ax.set_title("{} -- {}".format(scenario.SNAME, t))
+
+    ax.set_xlabel(lx)
+    ax.set_ylabel(ly)
+
     ax.boxplot([v for k, v in w.items()], labels=[k for k, v in w.items()])
     ax.minorticks_on()
     ax.grid(
@@ -30,16 +40,208 @@ def boxplot(w={}, t=""):
         linewidth="0.5",
         color="gray",
     )
-    plt.xticks(rotation="vertical")
-    plt.savefig("out.eps", bbox_inches="tight")
+    if yl:
+        ax.set_ylim(yl)
+    plt.xticks(rotation=45)
+    plt.savefig("out.pdf", bbox_inches="tight")
     plt.close()
 
-def barplot(wl=[], t=""):
+def boxplots(w2=[]):
+    """Plot boxplot for multiple times.
+
+    Keyword arguments:
+    w -- What to plot. It is extracted from `w2`.
+    """
+    f, ax = plt.subplots()
+    eax = ax.twinx()
+
+    [w, no_opt, iterations] = w2
+
+    key = tuple(w.keys())[0]
+    title = ""
+    try:
+        title = (scenario
+            .TITLE
+            .split("/")[-2]
+            .split(".json")[0]
+            .split("sc")[1]
+            .replace("_", "-")
+        )
+        title = "scenario {}".format(title)
+        title = "Final path cost, {}, ({} avg. iters.)".format(
+            title,
+            np.average([i for i in iterations[key].values()]),
+        )
+    except:
+        pass
+    ax.set_title(title)
+    ax.set_xlabel("Number of iterations [-]")
+    ax.set_ylabel("Cost [m]")
+    eax.set_ylabel("Finished with no path [%]")
+
+    M = len(w[key][0])
+    err_hist = [0 for i in range(M)]
+    val_list = [[] for i in range(M)]
+    mi = 999999999999
+    ma = -1
+    N = len(w[key])
+    for i in range(len(w[key])):
+        for j in range(M):
+            if w[key][i][j] == 0:
+                err_hist[j] += 1
+            else:
+                v = w[key][i][j]
+                val_list[j].append(v)
+                if v < mi: mi = v
+                if v > ma: ma = v
+    for i in range(len(err_hist)):
+        err_hist[i] *= 100 / N
+
+    maxes = [max(val_list[i]) if len(val_list[i]) > 0 else 0 for i in range(M)]
+    MAX = max(maxes)
+    mins = [min(val_list[i]) if len(val_list[i]) > 0 else 0 for i in range(M)]
+    MIN = min(mins)
+    EMAX = max(err_hist)
+    EMIN = 0
+
+    ax.set_ylim([0, 100])
+    eax.set_ylim([0, 100])
+
+    average = [np.average(val_list[i]) for i in range(M)]
+    # 95 and 5 are not used
+    perct_95 = [np.percentile(val_list[i], [95])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
+    perct_5 = [np.percentile(val_list[i], [5])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
+    # percentiles by 10 %
+    perct_10 = [np.percentile(val_list[i], [10])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
+    perct_20 = [np.percentile(val_list[i], [20])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
+    perct_30 = [np.percentile(val_list[i], [30])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
+    perct_40 = [np.percentile(val_list[i], [40])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
+    perct_50 = [np.percentile(val_list[i], [50])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
+    perct_60 = [np.percentile(val_list[i], [60])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
+    perct_70 = [np.percentile(val_list[i], [70])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
+    perct_80 = [np.percentile(val_list[i], [80])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
+    perct_90 = [np.percentile(val_list[i], [90])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
+
+    # find index of the closest to average path
+    average_i = [
+        (i, w[key][i][-1])
+        for i in range(len(w[key]))
+    ]
+    average_i = sorted(average_i, key=lambda i: i[1])
+    # this is for figures to the paper -- min/max path cost
+    n0i = 0
+    for i in average_i:
+        if i[1] > 0:
+            n0i = i[0]
+            break
+    print("{} {}".format(n0i, average_i[-1][0]))
+
+    lhs = []
+    # err hist
+    lhs.append(
+    eax.fill_between(
+        range(1, M+1),
+        [i for i in err_hist],
+        [0 for i in range(1, M+1)],
+        color="tab:red",
+        alpha=0.2,
+        label="No path found",
+    )
+    )
+    # plot percentiles
+    lhs.append(
+    ax.fill_between(
+        range(1, M+1),
+        mins,
+        maxes,
+        color="tab:orange",
+        alpha=0.2,
+        label="Minimum and maximum",
+    )
+    )
+    lhs.append(
+    ax.fill_between(
+        range(1, M+1),
+        perct_10,
+        perct_90,
+        color="tab:orange",
+        alpha=0.25,
+        label="10 % and 90 % percentile",
+    )
+    )
+    lhs.append(
+    ax.fill_between(
+        range(1, M+1),
+        perct_20,
+        perct_80,
+        color="tab:orange",
+        alpha=0.3,
+        label="20 % and 80 % percentile",
+    )
+    )
+    lhs.append(
+    ax.fill_between(
+        range(1, M+1),
+        perct_30,
+        perct_70,
+        color="tab:orange",
+        alpha=0.35,
+        label="30 % and 70 % percentile",
+    )
+    )
+    lhs.append(
+    ax.fill_between(
+        range(1, M+1),
+        perct_40,
+        perct_60,
+        color="tab:orange",
+        alpha=0.4,
+        label="40 % and 60 % percentile",
+    )
+    )
+    # plot median and average
+    lhs.append(
+    ax.plot(
+        range(1, M+1),
+        perct_50,
+        color="tab:orange",
+        alpha=1,
+        label="50 % percentile (median)",
+    )
+    )
+    lhs.append(
+    ax.plot(
+        range(1, M+1),
+        average,
+        color="tab:red",
+        alpha=1,
+        label="Average cost",
+    )
+    )
+    # plot average before path optimization
+    #ax.plot(
+    #    range(1, M+1),
+    #    [np.average([i for i in no_opt[key].values()]) for i in range(1, M+1)],
+    #    label="Average cost before optimization",
+    #    color="tab:blue",
+    #    linestyle="--",
+    #)
+
+    ax.minorticks_on()
+
+    ax.tick_params(axis='x', labelrotation=45)
+    ax.legend(loc="upper left")
+    eax.legend(loc="upper right")
+    plt.savefig("out.pdf", bbox_inches="tight")
+    plt.close()
+
+def barplot(wl=[], t="", yl=None, lx="Entry Point Planner variant [-]", ly=""):
     """Plot barplot graph.
 
     Keyword arguments:
     wl -- What to plot list.
     t -- Graph title.
+    yl -- Y axis limit [min, max].
     """
     if len(wl) < 1:
         raise ValueError
@@ -47,6 +249,8 @@ def barplot(wl=[], t=""):
         wl.append([])
     f, ax = plt.subplots()
     ax.set_title(t)
+    ax.set_xlabel(lx)
+    ax.set_ylabel(ly)
     w = wl[0]
     ax.bar(
         range(len(w)),
@@ -76,11 +280,13 @@ def barplot(wl=[], t=""):
         linewidth="0.5",
         color="gray",
     )
-    plt.xticks(rotation="vertical")
-    plt.savefig("out.eps", bbox_inches="tight")
+    if yl:
+        ax.set_ylim(yl)
+    plt.xticks(rotation=45)
+    plt.savefig("out.pdf", bbox_inches="tight")
     plt.close()
 
-def histplot(w={}, t=""):
+def histplot(w={}, t="", lx="Algorithm computation time [s]", ly="Number of paths found [-]"):
     """Plot histogram graph.
 
     Keyword arguments:
@@ -90,16 +296,25 @@ def histplot(w={}, t=""):
     f, ax = plt.subplots()
     ax.set_title("{} (log yscale)".format(t))
     ax.set_yscale("log")
+    ax.set_xlim(-10, 500)
+    ax.set_xlabel(lx)
+    ax.set_ylabel(ly)
+
+    COLORS = ["tab:orange", "tab:red", "tab:blue", "tab:green"]
+    i = 0
 
     for ck, cv in w.items():
         ax.hist(
             [v for k, v in w.items() if k == ck],
             #alpha = 0.5,
             histtype = "step",
-            #bins = 100,
+            #bins = 30,
+            color=COLORS[i]
         )
         X_WHERE = np.percentile([v for k, v in w.items() if k == ck], [95])
-        plt.axvline(X_WHERE, lw=1, linestyle="--")
+        print("percentile is {}".format(X_WHERE))
+        plt.axvline(X_WHERE, lw=1, linestyle="--", color=COLORS[i])
+        i += 1
 
     ax.minorticks_on()
     ax.grid(
@@ -117,7 +332,8 @@ def histplot(w={}, t=""):
         color="gray",
     )
     plt.legend([k for k, v in w.items()])
-    plt.savefig("out.eps", bbox_inches="tight")
+    plt.xticks(rotation=45)
+    plt.savefig("out.pdf", bbox_inches="tight")
     plt.close()
 
 if __name__ == "__main__":
@@ -125,25 +341,47 @@ if __name__ == "__main__":
         w = sys.argv[1]
     else:
         w = "time"
+    if len(sys.argv) > 2:
+        scenario.DNAME = sys.argv[2]
 
+    plt.rcParams["figure.figsize"] = [12, 12]
     plt.rcParams["font.size"] = 24
+    plt.rcParams["font.family"] = "cmr10"
+    plt.rcParams["hatch.linewidth"] = 1.0
+    plt.rcParams["lines.linewidth"] = 1.0
+    plt.rc('axes', unicode_minus=False)
 
     if w == "time":
-        boxplot(scenario.time(), "Elapsed time")
+        boxplot(scenario.time(), "Elapsed time", yl=[0.0004, 200], ly="Time [s]")
     elif w == "htime":
-        histplot(scenario.time(), "Elapsed time histogram")
+        histplot(scenario.time(), "Histogram of time to find a path")
     elif w == "cost":
-        boxplot(scenario.cost(), "Final path cost")
+        boxplot(scenario.cost(), "Final path cost", yl=[0, 80], ly="Cost [m]")
+    elif w == "costs":
+        boxplots(scenario.costs())
     elif w == "hcost":
         histplot(scenario.cost(), "Final path cost histogram")
+    elif w == "orig_cost":
+        boxplot(scenario.orig_cost(), "Original path cost", yl=[0, 80], ly="Cost [m]")
+    elif w == "orig_hcost":
+        histplot(scenario.orig_cost(), "Original path cost histogram")
     elif w == "cusp":
-        boxplot(scenario.cusp(), "Changes in direction")
+        boxplot(scenario.cusp(), "Changes in direction", ly="Changes [-]")
     elif w == "hcusp":
         histplot(scenario.cusp(), "Changes in direction histogram")
     elif w == "error":
-        barplot(scenario.error_rate(), "Error rate")
+        barplot(
+            scenario.error_rate(),
+            "Path not found rate",
+            ly="Path not found [%]",
+        )
     elif w == "iter":
-        boxplot(scenario.iter(), "Number of iterations")
+        boxplot(
+            scenario.iter(),
+            "Number of iterations",
+            yl=[1, 1000],
+            ly="Iterations [-]",
+        )
     else:
         print("""The following arguments are allowed: