"""Procedures for plotting graphs."""
import sys
import matplotlib.pyplot as plt
+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(which="major", linestyle="-", linewidth="0.5", color="gray")
- ax.grid(which="minor", linestyle=":", linewidth="0.5", color="gray")
- plt.show()
+ ax.grid(
+ which="major",
+ axis="y",
+ linestyle="-",
+ linewidth="0.5",
+ color="gray",
+ )
+ ax.grid(
+ which="minor",
+ axis="y",
+ linestyle=":",
+ linewidth="0.5",
+ color="gray",
+ )
+ if yl:
+ ax.set_ylim(yl)
+ plt.xticks(rotation=45)
+ plt.savefig("out.eps", bbox_inches="tight")
+ plt.close()
+
+def boxplots(w2=[]):
+ """Plot boxplot for multiple times.
+
+ Keyword arguments:
+ w -- What to plot. It is extracted from `w2`.
+ """
+ f, ax = plt.subplots()
+
+ [w, no_opt] = w2
+
+ key = tuple(w.keys())[0]
+ ax.set_title("Final path cost, Out-of-Slot Planner, scenario 5-1".format(key))
+ ax.set_xlabel("Elapsed time [s]")
+ ax.set_ylabel("Cost [m]")
+
+ err_hist = [0 for i in range(19)]
+ val_list = [[] for i in range(19)]
+ m = len(w[key][0])
+ mi = 999999999999
+ ma = -1
+ 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
+ print("min: {}, max: {}".format(mi, ma))
+
+ maxes = [max(val_list[i]) for i in range(19)]
+ mins = [min(val_list[i]) for i in range(19)]
+ average = [np.average(val_list[i]) for i in range(19)]
+ # 95 and 5 are not used
+ perct_95 = [np.percentile(val_list[i], [95])[0] for i in range(19)]
+ perct_5 = [np.percentile(val_list[i], [5])[0] for i in range(19)]
+ # percentiles by 10 %
+ perct_10 = [np.percentile(val_list[i], [10])[0] for i in range(19)]
+ perct_20 = [np.percentile(val_list[i], [20])[0] for i in range(19)]
+ perct_30 = [np.percentile(val_list[i], [30])[0] for i in range(19)]
+ perct_40 = [np.percentile(val_list[i], [40])[0] for i in range(19)]
+ perct_50 = [np.percentile(val_list[i], [50])[0] for i in range(19)]
+ perct_60 = [np.percentile(val_list[i], [60])[0] for i in range(19)]
+ perct_70 = [np.percentile(val_list[i], [70])[0] for i in range(19)]
+ perct_80 = [np.percentile(val_list[i], [80])[0] for i in range(19)]
+ perct_90 = [np.percentile(val_list[i], [90])[0] for i in range(19)]
+
+ # 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
+ print("min: {}".format(average_i[0]))
+ print("max: {}".format(average_i[-1]))
+ print("diff: {}".format(abs(average_i[0][1] - average_i[-1][1])))
+
+ # plot percentiles
+ ax.fill_between(
+ range(1, 20),
+ mins,
+ maxes,
+ color="tab:orange",
+ alpha=0.2,
+ label="Minimum and maximum, optimized",
+ )
+ ax.fill_between(
+ range(1, 20),
+ perct_10,
+ perct_90,
+ color="tab:orange",
+ alpha=0.25,
+ label="10 % and 90 % percentile, optimized",
+ )
+ ax.fill_between(
+ range(1, 20),
+ perct_20,
+ perct_80,
+ color="tab:orange",
+ alpha=0.3,
+ label="20 % and 80 % percentile, optimized",
+ )
+ ax.fill_between(
+ range(1, 20),
+ perct_30,
+ perct_70,
+ color="tab:orange",
+ alpha=0.35,
+ label="30 % and 70 % percentile, optimized",
+ )
+ ax.fill_between(
+ range(1, 20),
+ perct_40,
+ perct_60,
+ color="tab:orange",
+ alpha=0.4,
+ label="40 % and 60 % percentile, optimized",
+ )
+ # plot median and average
+ ax.plot(
+ range(1, 20),
+ perct_50,
+ color="tab:orange",
+ alpha=1,
+ label="50 % percentile (median), optimized",
+ )
+ ax.plot(
+ range(1, 20),
+ average,
+ color="tab:red",
+ alpha=1,
+ label="Average cost after optimization",
+ )
+ # plot average before path optimization
+ ax.plot(
+ range(1, 20),
+ [np.average([i for i in no_opt[key].values()]) for i in range(1, 20)],
+ label="Average cost before optimization",
+ color="tab:blue",
+ linestyle="--",
+ )
+
+ plt.xticks(range(1, 20), ["{:.2f}".format(0.1 * (k+1)) for k in range(m)])
+ ax.minorticks_on()
-def barplot(w={}, t=""):
+ plt.rcParams["font.size"] = 21
+ plt.rcParams['hatch.linewidth'] = 1.0
+ plt.rcParams['lines.linewidth'] = 1.0
+ plt.legend()
+ plt.xticks(rotation=45)
+ 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:
- w -- What to plot.
+ wl -- What to plot list.
t -- Graph title.
+ yl -- Y axis limit [min, max].
"""
+ if len(wl) < 1:
+ raise ValueError
+ elif len(wl) == 1:
+ 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)),
[v for k, v in w.items()],
tick_label=[k for k, v in w.items()],
+ width=1 / (len(wl) + 1),
)
+ for i in range(1, len(wl) - 1):
+ w = wl[i]
+ ax.bar(
+ [j + i * 1/len(wl) for j in range(len(w))],
+ [v for k, v in w.items()],
+ width=1 / (len(wl) + 1),
+ )
ax.minorticks_on()
- ax.grid(which="major", linestyle="-", linewidth="0.5", color="gray")
- ax.grid(which="minor", linestyle=":", linewidth="0.5", color="gray")
- plt.show()
+ ax.grid(
+ which="major",
+ axis="y",
+ linestyle="-",
+ linewidth="0.5",
+ color="gray"
+ )
+ ax.grid(
+ which="minor",
+ axis="y",
+ linestyle=":",
+ linewidth="0.5",
+ color="gray",
+ )
+ if yl:
+ ax.set_ylim(yl)
+ plt.xticks(rotation=45)
+ plt.savefig("out.eps", 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:
f, ax = plt.subplots()
ax.set_title("{} (log yscale)".format(t))
ax.set_yscale("log")
- ax.hist([v for k, v in w.items()])
+ 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 = 30,
+ color=COLORS[i]
+ )
+ X_WHERE = np.percentile([v for k, v in w.items() if k == ck], [95])
+ print("percentile is {}".format(X_WHERE))
+ plt.axvline(X_WHERE, lw=1, linestyle="--", color=COLORS[i])
+ i += 1
+
ax.minorticks_on()
- ax.grid(which="major", linestyle="-", linewidth="0.5", color="gray")
- ax.grid(which="minor", linestyle=":", linewidth="0.5", color="gray")
+ ax.grid(
+ which="major",
+ axis="y",
+ linestyle="-",
+ linewidth="0.5",
+ color="gray",
+ )
+ ax.grid(
+ which="minor",
+ axis="y",
+ linestyle=":",
+ linewidth="0.5",
+ color="gray",
+ )
plt.legend([k for k, v in w.items()])
- plt.show()
+ plt.xticks(rotation=45)
+ plt.savefig("out.eps", bbox_inches="tight")
+ plt.close()
if __name__ == "__main__":
if len(sys.argv) > 1:
w = sys.argv[1]
else:
w = "time"
+ if len(sys.argv) > 2:
+ scenario.DNAME = sys.argv[2]
+
+ plt.rcParams["font.size"] = 22
+ plt.rcParams["font.family"] = "sans-serif"
+ plt.rcParams["figure.figsize"] = [12, 12]
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",
+ yl=[1, 1000],
+ ly="Iterations [-]",
+ )
+ else:
+ print("""The following arguments are allowed:
+
+ time, htime, cost, hcost, cusp, hcusp, error, iter
+ """)