blob: 3808e8760657f708031c067bdd32eb7a714af9c3 [file] [log] [blame]
terelius54ce6802016-07-13 06:44:41 -07001/*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "rtc_tools/event_log_visualizer/plot_python.h"
terelius54ce6802016-07-13 06:44:41 -070012
13#include <stdio.h>
tereliusdc35dcd2016-08-01 12:03:27 -070014
Stefan Holmer13181032016-07-29 14:48:54 +020015#include <memory>
terelius54ce6802016-07-13 06:44:41 -070016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "rtc_base/checks.h"
philipel23c7f252017-07-14 06:30:03 -070018
terelius54ce6802016-07-13 06:44:41 -070019namespace webrtc {
terelius54ce6802016-07-13 06:44:41 -070020
21PythonPlot::PythonPlot() {}
22
23PythonPlot::~PythonPlot() {}
24
tereliusdc35dcd2016-08-01 12:03:27 -070025void PythonPlot::Draw() {
terelius54ce6802016-07-13 06:44:41 -070026 // Write python commands to stdout. Intended program usage is
27 // ./event_log_visualizer event_log160330.dump | python
28
tereliusdc35dcd2016-08-01 12:03:27 -070029 if (!series_list_.empty()) {
30 printf("color_count = %zu\n", series_list_.size());
terelius54ce6802016-07-13 06:44:41 -070031 printf(
32 "hls_colors = [(i*1.0/color_count, 0.25+i*0.5/color_count, 0.8) for i "
33 "in range(color_count)]\n");
Bjorn Tereliusb577d5e2017-11-10 16:21:34 +010034 printf("colors = [colorsys.hls_to_rgb(*hls) for hls in hls_colors]\n");
terelius54ce6802016-07-13 06:44:41 -070035
tereliusdc35dcd2016-08-01 12:03:27 -070036 for (size_t i = 0; i < series_list_.size(); i++) {
philipel35ba9bd2017-04-19 05:58:51 -070037 printf("\n# === Series: %s ===\n", series_list_[i].label.c_str());
terelius54ce6802016-07-13 06:44:41 -070038 // List x coordinates
39 printf("x%zu = [", i);
tereliusdc35dcd2016-08-01 12:03:27 -070040 if (series_list_[i].points.size() > 0)
Stefan Holmer1d4a2272018-05-24 13:48:09 +020041 printf("%.3f", series_list_[i].points[0].x);
tereliusdc35dcd2016-08-01 12:03:27 -070042 for (size_t j = 1; j < series_list_[i].points.size(); j++)
Stefan Holmer1d4a2272018-05-24 13:48:09 +020043 printf(", %.3f", series_list_[i].points[j].x);
terelius54ce6802016-07-13 06:44:41 -070044 printf("]\n");
45
46 // List y coordinates
47 printf("y%zu = [", i);
tereliusdc35dcd2016-08-01 12:03:27 -070048 if (series_list_[i].points.size() > 0)
49 printf("%G", series_list_[i].points[0].y);
50 for (size_t j = 1; j < series_list_[i].points.size(); j++)
51 printf(", %G", series_list_[i].points[j].y);
terelius54ce6802016-07-13 06:44:41 -070052 printf("]\n");
53
Bjorn Tereliusb577d5e2017-11-10 16:21:34 +010054 if (series_list_[i].line_style == LineStyle::kBar) {
terelius54ce6802016-07-13 06:44:41 -070055 // There is a plt.bar function that draws bar plots,
56 // but it is *way* too slow to be useful.
57 printf(
58 "plt.vlines(x%zu, map(lambda t: min(t,0), y%zu), map(lambda t: "
Bjorn Tereliusb577d5e2017-11-10 16:21:34 +010059 "max(t,0), y%zu), color=colors[%zu], "
terelius54ce6802016-07-13 06:44:41 -070060 "label=\'%s\')\n",
tereliusdc35dcd2016-08-01 12:03:27 -070061 i, i, i, i, series_list_[i].label.c_str());
Bjorn Tereliusb577d5e2017-11-10 16:21:34 +010062 if (series_list_[i].point_style == PointStyle::kHighlight) {
63 printf(
64 "plt.plot(x%zu, y%zu, color=colors[%zu], "
65 "marker='.', ls=' ')\n",
66 i, i, i);
67 }
68 } else if (series_list_[i].line_style == LineStyle::kLine) {
69 if (series_list_[i].point_style == PointStyle::kHighlight) {
70 printf(
71 "plt.plot(x%zu, y%zu, color=colors[%zu], label=\'%s\', "
72 "marker='.')\n",
73 i, i, i, series_list_[i].label.c_str());
74 } else {
75 printf("plt.plot(x%zu, y%zu, color=colors[%zu], label=\'%s\')\n", i,
76 i, i, series_list_[i].label.c_str());
77 }
78 } else if (series_list_[i].line_style == LineStyle::kStep) {
terelius77f05802017-02-01 06:34:53 -080079 // Draw lines from (x[0],y[0]) to (x[1],y[0]) to (x[1],y[1]) and so on
80 // to illustrate the "steps". This can be expressed by duplicating all
81 // elements except the first in x and the last in y.
Bjorn Tereliusb577d5e2017-11-10 16:21:34 +010082 printf("xd%zu = [dup for v in x%zu for dup in [v, v]]\n", i, i);
83 printf("yd%zu = [dup for v in y%zu for dup in [v, v]]\n", i, i);
terelius77f05802017-02-01 06:34:53 -080084 printf(
Bjorn Tereliusb577d5e2017-11-10 16:21:34 +010085 "plt.plot(xd%zu[1:], yd%zu[:-1], color=colors[%zu], "
terelius77f05802017-02-01 06:34:53 -080086 "label=\'%s\')\n",
87 i, i, i, series_list_[i].label.c_str());
Bjorn Tereliusb577d5e2017-11-10 16:21:34 +010088 if (series_list_[i].point_style == PointStyle::kHighlight) {
89 printf(
90 "plt.plot(x%zu, y%zu, color=colors[%zu], "
91 "marker='.', ls=' ')\n",
92 i, i, i);
93 }
94 } else if (series_list_[i].line_style == LineStyle::kNone) {
philipele127e7a2017-03-29 16:28:53 +020095 printf(
Bjorn Tereliusb577d5e2017-11-10 16:21:34 +010096 "plt.plot(x%zu, y%zu, color=colors[%zu], label=\'%s\', "
philipel10fc0e62017-04-11 01:50:23 -070097 "marker='o', ls=' ')\n",
philipele127e7a2017-03-29 16:28:53 +020098 i, i, i, series_list_[i].label.c_str());
terelius54ce6802016-07-13 06:44:41 -070099 } else {
100 printf("raise Exception(\"Unknown graph type\")\n");
101 }
102 }
philipel23c7f252017-07-14 06:30:03 -0700103
104 // IntervalSeries
Ilya Nikolaevskiya4259f62017-12-05 13:19:45 +0100105 printf("interval_colors = ['#ff8e82','#5092fc','#c4ffc4','#aaaaaa']\n");
106 RTC_CHECK_LE(interval_list_.size(), 4);
Bjorn Tereliusb577d5e2017-11-10 16:21:34 +0100107 // To get the intervals to show up in the legend we have to create patches
philipel23c7f252017-07-14 06:30:03 -0700108 // for them.
109 printf("legend_patches = []\n");
110 for (size_t i = 0; i < interval_list_.size(); i++) {
111 // List intervals
112 printf("\n# === IntervalSeries: %s ===\n",
113 interval_list_[i].label.c_str());
114 printf("ival%zu = [", i);
115 if (interval_list_[i].intervals.size() > 0) {
116 printf("(%G, %G)", interval_list_[i].intervals[0].begin,
117 interval_list_[i].intervals[0].end);
118 }
119 for (size_t j = 1; j < interval_list_[i].intervals.size(); j++) {
120 printf(", (%G, %G)", interval_list_[i].intervals[j].begin,
121 interval_list_[i].intervals[j].end);
122 }
123 printf("]\n");
124
125 printf("for i in range(0, %zu):\n", interval_list_[i].intervals.size());
126 if (interval_list_[i].orientation == IntervalSeries::kVertical) {
127 printf(
128 " plt.axhspan(ival%zu[i][0], ival%zu[i][1], "
129 "facecolor=interval_colors[%zu], "
130 "alpha=0.3)\n",
131 i, i, i);
132 } else {
133 printf(
134 " plt.axvspan(ival%zu[i][0], ival%zu[i][1], "
135 "facecolor=interval_colors[%zu], "
136 "alpha=0.3)\n",
137 i, i, i);
138 }
139 printf(
140 "legend_patches.append(mpatches.Patch(ec=\'black\', "
141 "fc=interval_colors[%zu], label='%s'))\n",
142 i, interval_list_[i].label.c_str());
143 }
terelius54ce6802016-07-13 06:44:41 -0700144 }
145
tereliusdc35dcd2016-08-01 12:03:27 -0700146 printf("plt.xlim(%f, %f)\n", xaxis_min_, xaxis_max_);
147 printf("plt.ylim(%f, %f)\n", yaxis_min_, yaxis_max_);
148 printf("plt.xlabel(\'%s\')\n", xaxis_label_.c_str());
149 printf("plt.ylabel(\'%s\')\n", yaxis_label_.c_str());
150 printf("plt.title(\'%s\')\n", title_.c_str());
philipel23c7f252017-07-14 06:30:03 -0700151 if (!series_list_.empty() || !interval_list_.empty()) {
152 printf("handles, labels = plt.gca().get_legend_handles_labels()\n");
153 printf("for lp in legend_patches:\n");
154 printf(" handles.append(lp)\n");
155 printf(" labels.append(lp.get_label())\n");
156 printf("plt.legend(handles, labels, loc=\'best\', fontsize=\'small\')\n");
terelius54ce6802016-07-13 06:44:41 -0700157 }
158}
159
160PythonPlotCollection::PythonPlotCollection() {}
161
162PythonPlotCollection::~PythonPlotCollection() {}
163
tereliusdc35dcd2016-08-01 12:03:27 -0700164void PythonPlotCollection::Draw() {
terelius54ce6802016-07-13 06:44:41 -0700165 printf("import matplotlib.pyplot as plt\n");
philipel23c7f252017-07-14 06:30:03 -0700166 printf("import matplotlib.patches as mpatches\n");
167 printf("import matplotlib.patheffects as pe\n");
terelius54ce6802016-07-13 06:44:41 -0700168 printf("import colorsys\n");
tereliusdc35dcd2016-08-01 12:03:27 -0700169 for (size_t i = 0; i < plots_.size(); i++) {
terelius54ce6802016-07-13 06:44:41 -0700170 printf("plt.figure(%zu)\n", i);
tereliusdc35dcd2016-08-01 12:03:27 -0700171 plots_[i]->Draw();
terelius54ce6802016-07-13 06:44:41 -0700172 }
173 printf("plt.show()\n");
174}
175
tereliusdc35dcd2016-08-01 12:03:27 -0700176Plot* PythonPlotCollection::AppendNewPlot() {
terelius54ce6802016-07-13 06:44:41 -0700177 Plot* plot = new PythonPlot();
tereliusdc35dcd2016-08-01 12:03:27 -0700178 plots_.push_back(std::unique_ptr<Plot>(plot));
terelius54ce6802016-07-13 06:44:41 -0700179 return plot;
180}
181
terelius54ce6802016-07-13 06:44:41 -0700182} // namespace webrtc