]> rtime.felk.cvut.cz Git - hubacji1/iamcar2.git/blob - scripts/plot.py
Add script for plotting logged rewired data
[hubacji1/iamcar2.git] / scripts / plot.py
1 """Procedures for plotting graphs."""
2 import sys
3 import matplotlib.pyplot as plt
4 import numpy as np
5
6 import scenario
7
8 def boxplot(w={}, t="", yl=None, lx="Elapsed time [s]", ly=""):
9     """Plot boxplot graph.
10
11     Keyword arguments:
12     w -- What to plot.
13     t -- Graph title.
14     yl -- Y axis limit [min, max].
15     """
16     f, ax = plt.subplots()
17
18     if False: # is the y axis log scale?
19         ax.set_title("{} -- {} (log yscale)".format(scenario.SNAME, t))
20         ax.set_yscale("log")
21     else:
22         ax.set_title("{} -- {}".format(scenario.SNAME, t))
23
24     ax.set_xlabel(lx)
25     ax.set_ylabel(ly)
26
27     ax.boxplot([v for k, v in w.items()], labels=[k for k, v in w.items()])
28     ax.minorticks_on()
29     ax.grid(
30         which="major",
31         axis="y",
32         linestyle="-",
33         linewidth="0.5",
34         color="gray",
35     )
36     ax.grid(
37         which="minor",
38         axis="y",
39         linestyle=":",
40         linewidth="0.5",
41         color="gray",
42     )
43     if yl:
44         ax.set_ylim(yl)
45     plt.xticks(rotation=45)
46     plt.savefig("out.eps", bbox_inches="tight")
47     plt.close()
48
49 def boxplots(w2=[]):
50     """Plot boxplot for multiple times.
51
52     Keyword arguments:
53     w -- What to plot. It is extracted from `w2`.
54     """
55     f, ax = plt.subplots()
56     eax = ax.twinx()
57
58     [w, no_opt, iterations] = w2
59
60     key = tuple(w.keys())[0]
61     title = scenario.TITLE.split("/")[-2].split(".json")[0].split("sc")[1].replace("_", "-")
62     ax.set_title("Final path cost, out-of-slot planner, {}, ({} avg. iters.)".format(
63         title,
64         np.average([i for i in iterations[key].values()]),
65     ))
66     ax.set_xlabel("Elapsed time [s]")
67     ax.set_ylabel("Cost [m]")
68     eax.set_ylabel("Timed-out rate [%]")
69
70     M = len(w[key][0])
71     err_hist = [0 for i in range(M)]
72     val_list = [[] for i in range(M)]
73     mi = 999999999999
74     ma = -1
75     N = len(w[key])
76     for i in range(len(w[key])):
77         for j in range(M):
78             if w[key][i][j] == 0:
79                 err_hist[j] += 1
80             else:
81                 v = w[key][i][j]
82                 val_list[j].append(v)
83                 if v < mi: mi = v
84                 if v > ma: ma = v
85     for i in range(len(err_hist)):
86         err_hist[i] *= 100 / N
87
88     maxes = [max(val_list[i]) if len(val_list[i]) > 0 else 0 for i in range(M)]
89     MAX = max(maxes)
90     mins = [min(val_list[i]) if len(val_list[i]) > 0 else 0 for i in range(M)]
91     MIN = min(mins)
92     ax.set_ylim([MIN -5, MAX +5])
93
94     EMAX = max(err_hist)
95     EMIN = 0
96     #eax.set_ylim([-EMAX -5, 0])
97
98     average = [np.average(val_list[i]) for i in range(M)]
99     # 95 and 5 are not used
100     perct_95 = [np.percentile(val_list[i], [95])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
101     perct_5 = [np.percentile(val_list[i], [5])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
102     # percentiles by 10 %
103     perct_10 = [np.percentile(val_list[i], [10])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
104     perct_20 = [np.percentile(val_list[i], [20])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
105     perct_30 = [np.percentile(val_list[i], [30])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
106     perct_40 = [np.percentile(val_list[i], [40])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
107     perct_50 = [np.percentile(val_list[i], [50])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
108     perct_60 = [np.percentile(val_list[i], [60])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
109     perct_70 = [np.percentile(val_list[i], [70])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
110     perct_80 = [np.percentile(val_list[i], [80])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
111     perct_90 = [np.percentile(val_list[i], [90])[0] if len(val_list[i]) > 0 else 0 for i in range(M)]
112
113     # find index of the closest to average path
114     average_i = [
115         (i, w[key][i][-1])
116         for i in range(len(w[key]))
117     ]
118     average_i = sorted(average_i, key=lambda i: i[1])
119     # this is for figures to the paper -- min/max path cost
120     n0i = 0
121     for i in average_i:
122         if i[1] > 0:
123             n0i = i[0]
124             break
125     print("{} {}".format(n0i, average_i[-1][0]))
126
127     lhs = []
128     # err hist
129     lhs.append(
130     eax.fill_between(
131         range(1, M+1),
132         [i for i in err_hist],
133         [0 for i in range(1, M+1)],
134         color="tab:red",
135         alpha=0.2,
136         label="Not found paths",
137     )
138     )
139     # plot percentiles
140     lhs.append(
141     ax.fill_between(
142         range(1, M+1),
143         mins,
144         maxes,
145         color="tab:orange",
146         alpha=0.2,
147         label="Minimum and maximum, optimized",
148     )
149     )
150     lhs.append(
151     ax.fill_between(
152         range(1, M+1),
153         perct_10,
154         perct_90,
155         color="tab:orange",
156         alpha=0.25,
157         label="10 % and 90 % percentile, optimized",
158     )
159     )
160     lhs.append(
161     ax.fill_between(
162         range(1, M+1),
163         perct_20,
164         perct_80,
165         color="tab:orange",
166         alpha=0.3,
167         label="20 % and 80 % percentile, optimized",
168     )
169     )
170     lhs.append(
171     ax.fill_between(
172         range(1, M+1),
173         perct_30,
174         perct_70,
175         color="tab:orange",
176         alpha=0.35,
177         label="30 % and 70 % percentile, optimized",
178     )
179     )
180     lhs.append(
181     ax.fill_between(
182         range(1, M+1),
183         perct_40,
184         perct_60,
185         color="tab:orange",
186         alpha=0.4,
187         label="40 % and 60 % percentile, optimized",
188     )
189     )
190     # plot median and average
191     lhs.append(
192     ax.plot(
193         range(1, M+1),
194         perct_50,
195         color="tab:orange",
196         alpha=1,
197         label="50 % percentile (median), optimized",
198     )
199     )
200     lhs.append(
201     ax.plot(
202         range(1, M+1),
203         average,
204         color="tab:red",
205         alpha=1,
206         label="Average cost after optimization",
207     )
208     )
209     # plot average before path optimization
210     #ax.plot(
211     #    range(1, M+1),
212     #    [np.average([i for i in no_opt[key].values()]) for i in range(1, M+1)],
213     #    label="Average cost before optimization",
214     #    color="tab:blue",
215     #    linestyle="--",
216     #)
217
218     plt.xticks(range(1, M+1), ["{:.2f}".format(0.1 * (k+1)) for k in range(M)])
219     ax.minorticks_on()
220
221     ax.tick_params(axis='x', labelrotation=45)
222     ax.legend(loc="upper left")
223     eax.legend(loc="upper right")
224     plt.savefig("out.pdf", bbox_inches="tight")
225     plt.close()
226
227 def barplot(wl=[], t="", yl=None, lx="Entry Point Planner variant [-]", ly=""):
228     """Plot barplot graph.
229
230     Keyword arguments:
231     wl -- What to plot list.
232     t -- Graph title.
233     yl -- Y axis limit [min, max].
234     """
235     if len(wl) < 1:
236         raise ValueError
237     elif len(wl) == 1:
238         wl.append([])
239     f, ax = plt.subplots()
240     ax.set_title(t)
241     ax.set_xlabel(lx)
242     ax.set_ylabel(ly)
243     w = wl[0]
244     ax.bar(
245         range(len(w)),
246         [v for k, v in w.items()],
247         tick_label=[k for k, v in w.items()],
248         width=1 / (len(wl) + 1),
249     )
250     for i in range(1, len(wl) - 1):
251         w = wl[i]
252         ax.bar(
253             [j + i * 1/len(wl) for j in range(len(w))],
254             [v for k, v in w.items()],
255             width=1 / (len(wl) + 1),
256         )
257     ax.minorticks_on()
258     ax.grid(
259         which="major",
260         axis="y",
261         linestyle="-",
262         linewidth="0.5",
263         color="gray"
264     )
265     ax.grid(
266         which="minor",
267         axis="y",
268         linestyle=":",
269         linewidth="0.5",
270         color="gray",
271     )
272     if yl:
273         ax.set_ylim(yl)
274     plt.xticks(rotation=45)
275     plt.savefig("out.eps", bbox_inches="tight")
276     plt.close()
277
278 def histplot(w={}, t="", lx="Algorithm computation time [s]", ly="Number of paths found [-]"):
279     """Plot histogram graph.
280
281     Keyword arguments:
282     w -- What to plot.
283     t -- Graph title.
284     """
285     f, ax = plt.subplots()
286     ax.set_title("{} (log yscale)".format(t))
287     ax.set_yscale("log")
288     ax.set_xlim(-10, 500)
289     ax.set_xlabel(lx)
290     ax.set_ylabel(ly)
291
292     COLORS = ["tab:orange", "tab:red", "tab:blue", "tab:green"]
293     i = 0
294
295     for ck, cv in w.items():
296         ax.hist(
297             [v for k, v in w.items() if k == ck],
298             #alpha = 0.5,
299             histtype = "step",
300             #bins = 30,
301             color=COLORS[i]
302         )
303         X_WHERE = np.percentile([v for k, v in w.items() if k == ck], [95])
304         print("percentile is {}".format(X_WHERE))
305         plt.axvline(X_WHERE, lw=1, linestyle="--", color=COLORS[i])
306         i += 1
307
308     ax.minorticks_on()
309     ax.grid(
310         which="major",
311         axis="y",
312         linestyle="-",
313         linewidth="0.5",
314         color="gray",
315     )
316     ax.grid(
317         which="minor",
318         axis="y",
319         linestyle=":",
320         linewidth="0.5",
321         color="gray",
322     )
323     plt.legend([k for k, v in w.items()])
324     plt.xticks(rotation=45)
325     plt.savefig("out.eps", bbox_inches="tight")
326     plt.close()
327
328 if __name__ == "__main__":
329     if len(sys.argv) > 1:
330         w = sys.argv[1]
331     else:
332         w = "time"
333     if len(sys.argv) > 2:
334         scenario.DNAME = sys.argv[2]
335
336     plt.rcParams["figure.figsize"] = [12, 12]
337     plt.rcParams["font.size"] = 21
338     plt.rcParams["font.family"] = "cmr10"
339     plt.rcParams["hatch.linewidth"] = 1.0
340     plt.rcParams["lines.linewidth"] = 1.0
341
342     if w == "time":
343         boxplot(scenario.time(), "Elapsed time", yl=[0.0004, 200], ly="Time [s]")
344     elif w == "htime":
345         histplot(scenario.time(), "Histogram of time to find a path")
346     elif w == "cost":
347         boxplot(scenario.cost(), "Final path cost", yl=[0, 80], ly="Cost [m]")
348     elif w == "costs":
349         boxplots(scenario.costs())
350     elif w == "hcost":
351         histplot(scenario.cost(), "Final path cost histogram")
352     elif w == "orig_cost":
353         boxplot(scenario.orig_cost(), "Original path cost", yl=[0, 80], ly="Cost [m]")
354     elif w == "orig_hcost":
355         histplot(scenario.orig_cost(), "Original path cost histogram")
356     elif w == "cusp":
357         boxplot(scenario.cusp(), "Changes in direction", ly="Changes [-]")
358     elif w == "hcusp":
359         histplot(scenario.cusp(), "Changes in direction histogram")
360     elif w == "error":
361         barplot(
362             scenario.error_rate(),
363             "Path not found rate",
364             ly="Path not found [%]",
365         )
366     elif w == "iter":
367         boxplot(
368             scenario.iter(),
369             "Number of iterations",
370             yl=[1, 1000],
371             ly="Iterations [-]",
372         )
373     else:
374         print("""The following arguments are allowed:
375
376         time, htime, cost, hcost, cusp, hcusp, error, iter
377         """)