3 @brief Output dynamic visualizer
5 @authors Andrei Novikov (pyclustering@yandex.ru)
7 @copyright BSD-3-Clause
11 import matplotlib.pyplot
as plt
18 @brief Describes plot where dynamic is displayed.
19 @details Used by 'dynamic_visualizer' class.
23 def __init__(self, x_title=None, y_title=None, x_lim=None, y_lim=None, x_labels=True, y_labels=True):
25 @brief Constructor of canvas.
27 @param[in] x_title (string): Title for X axis, if 'None', then nothing is displayed.
28 @param[in] y_title (string): Title for Y axis, if 'None', then nothing is displayed.
29 @param[in] x_lim (list): Defines borders of X axis like [from, to], for example [0, 3.14], if 'None' then
30 borders are calculated automatically.
31 @param[in] y_lim (list): Defines borders of Y axis like [from, to], if 'None' then borders are calculated
33 @param[in] x_labels (bool): If True then labels of X axis are displayed.
34 @param[in] y_labels (bool): If True then labels of Y axis are displayed.
59 @brief Output dynamic description that used to display.
60 @details Used by 'dynamic_visualizer' class.
64 def __init__(self, canvas, time, dynamics, separate, color):
66 @brief Constructor of output dynamic descriptor.
68 @param[in] canvas (uint): Index of canvas where dynamic should be displayed, in case of 'separate'
69 representation this argument is considered as a first canvas from that displaying should be done.
70 @param[in] time (list): Time points that are considered as a X axis.
71 @param[in] dynamics (list): Dynamic or dynamics that should be displayed.
72 @param[in] separate (bool|list): If 'True' then each dynamic is displayed on separate canvas, if it is defined
73 by list, for example, [ [1, 2], [3, 4] ], then the first and the second dynamics are displayed on
74 the canvas with index 'canvas' and the third and forth are displayed on the next 'canvas + 1'
76 @param[in] color (string): Color that is used to display output dynamic(s).
98 @brief Returns index of canvas where specified dynamic (by index 'index_dynamic') should be displayed.
100 @param[in] index_dynamic (uint): Index of dynamic that should be displayed.
102 @return (uint) Index of canvas.
105 return self.
separate[index_dynamic];
108 def __get_canonical_separate(self, input_separate):
110 @brief Return unified representation of separation value.
111 @details It represents list whose size is equal to amount of dynamics, where index of dynamic will show
112 where it should be displayed.
114 @param[in] input_separate (bool|list): Input separate representation that should transformed.
116 @return (list) Indexes where each dynamic should be displayed.
119 if (isinstance(input_separate, list)):
120 separate = [0] * len(self.
dynamics[0]);
121 for canvas_index
in range(len(input_separate)):
122 dynamic_indexes = input_separate[canvas_index];
123 for dynamic_index
in dynamic_indexes:
124 separate[dynamic_index] = canvas_index;
128 elif (input_separate
is False):
129 if (isinstance(self.
dynamics[0], list)
is True):
134 elif (input_separate
is True):
135 if (isinstance(self.
dynamics[0], list)
is True):
141 raise Exception(
"Incorrect type of argument 'separate' '%s'." % type(input_separate));
146 @brief Basic output dynamic visualizer.
147 @details The aim of the visualizer is to displayed output dynamic of any process, for example, output dynamic of
152 def __init__(self, canvas, x_title=None, y_title=None, x_lim=None, y_lim=None, x_labels=True, y_labels=True):
154 @brief Construct dynamic visualizer.
155 @details Default properties that are generalized in the constructor, for example, X axis title, can be
156 changed by corresponding method: 'set_canvas_properties'.
158 @param[in] canvas (uint): Amount of canvases that is used for visualization.
159 @param[in] x_title (string): Title for X axis of canvases, if 'None', then nothing is displayed.
160 @param[in] y_title (string): Title for Y axis of canvases, if 'None', then nothing is displayed.
161 @param[in] x_lim (list): Defines borders of X axis like [from, to], for example [0, 3.14], if 'None' then
162 borders are calculated automatically.
163 @param[in] y_lim (list): Defines borders of Y axis like [from, to], if 'None' then borders are calculated
165 @param[in] x_labels (bool): If True then labels of X axis are displayed.
166 @param[in] y_labels (bool): If True then labels of Y axis are displayed.
170 self.
__canvases = [
canvas_descr(x_title, y_title, x_lim, y_lim, x_labels, y_labels)
for _
in range(canvas) ];
174 def set_canvas_properties(self, canvas, x_title=None, y_title=None, x_lim=None, y_lim=None, x_labels=True, y_labels=True):
176 @brief Set properties for specified canvas.
178 @param[in] canvas (uint): Index of canvas whose properties should changed.
179 @param[in] x_title (string): Title for X axis, if 'None', then nothing is displayed.
180 @param[in] y_title (string): Title for Y axis, if 'None', then nothing is displayed.
181 @param[in] x_lim (list): Defines borders of X axis like [from, to], for example [0, 3.14], if 'None' then
182 borders are calculated automatically.
183 @param[in] y_lim (list): Defines borders of Y axis like [from, to], if 'None' then borders are calculated
185 @param[in] x_labels (bool): If True then labels of X axis are displayed.
186 @param[in] y_labels (bool): If True then labels of Y axis are displayed.
194 @brief Append single dynamic to specified canvas (by default to the first with index '0').
196 @param[in] t (list): Time points that corresponds to dynamic values and considered on a X axis.
197 @param[in] dynamic (list): Value points of dynamic that are considered on an Y axis.
198 @param[in] canvas (uint): Canvas where dynamic should be displayed.
199 @param[in] color (string): Color that is used for drawing dynamic on the canvas.
202 description =
dynamic_descr(canvas, t, dynamic,
False, color);
209 @brief Append several dynamics to canvas or canvases (defined by 'canvas' and 'separate' arguments).
211 @param[in] t (list): Time points that corresponds to dynamic values and considered on a X axis.
212 @param[in] dynamics (list): Dynamics where each of them is considered on Y axis.
213 @param[in] canvas (uint): Index of canvas where dynamic should be displayed, in case of 'separate'
214 representation this argument is considered as a first canvas from that displaying should be done.
215 @param[in] separate (bool|list): If 'True' then each dynamic is displayed on separate canvas, if it is defined
216 by list, for example, [ [1, 2], [3, 4] ], then the first and the second dynamics are displayed on
217 the canvas with index 'canvas' and the third and forth are displayed on the next 'canvas + 1'
219 @param[in] color (string): Color that is used to display output dynamic(s).
222 description =
dynamic_descr(canvas, t, dynamics, separate, color);
227 def show(self, axis=None, display=True):
229 @brief Draw and show output dynamics.
231 @param[in] axis (axis): If is not 'None' then user specified axis is used to display output dynamic.
232 @param[in] display (bool): Whether output dynamic should be displayed or not, if not, then user
233 should call 'plt.show()' by himself.
238 (_, axis) = plt.subplots(self.
__size, 1);
249 def __display_dynamic(self, axis, dyn_descr):
250 if (isinstance(dyn_descr.dynamics[0], list)
is True):
257 def __display_multiple_dynamic(self, axis, dyn_descr):
258 num_items = len(dyn_descr.dynamics[0]);
259 for index
in range(0, num_items, 1):
260 y = [item[index]
for item
in dyn_descr.dynamics];
262 axis_index = dyn_descr.get_axis_index(index);
265 ax.plot(dyn_descr.time, y,
'b-', linewidth = 0.5);
268 def __display_single_dynamic(self, axis, dyn_descr):
270 ax.plot(dyn_descr.time, dyn_descr.dynamics,
'b-', linewidth = 0.5);
273 def __format_canvases(self, axis):
274 for index
in range(self.
__size):
278 set_ax_param(ax, canvas.x_title, canvas.y_title, canvas.x_lim, canvas.y_lim, canvas.x_labels, canvas.y_labels,
True);
281 ax.get_xaxis().set_visible(
False);
284 def __update_canvas_xlim(self, t, separate):
285 for index
in separate:
289 def __update_single_canvas_xlim(self, canvas_index, t):
290 dynamic_xlim = [0, t[len(t) - 1]];
291 if ( (self.
__canvases[canvas_index].x_lim
is None)
or (self.
__canvases[canvas_index].x_lim < dynamic_xlim) ):
292 self.
__canvases[canvas_index].x_lim = dynamic_xlim;
295 def __get_axis(self, axis, index):
297 raise Exception(
"Impossible to get axis with index '%d' - total number of canvases '%d'."