__init__.py
1 """!
2 
3 @brief pyclustering module for cluster analysis.
4 
5 @authors Andrei Novikov (pyclustering@yandex.ru)
6 @date 2014-2020
7 @copyright GNU Public License
8 
9 @cond GNU_PUBLIC_LICENSE
10  PyClustering is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  PyClustering is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program. If not, see <http://www.gnu.org/licenses/>.
22 @endcond
23 
24 """
25 
26 import itertools
27 import math
28 import warnings
29 
30 try:
31  import matplotlib.pyplot as plt
32  import matplotlib.gridspec as gridspec
33 except Exception:
34  warnings.warn("Impossible to import matplotlib (please, install 'matplotlib'), pyclustering's visualization "
35  "functionality is not available.")
36 
37 from pyclustering.utils.color import color as color_list
38 
39 
41  """!
42  @brief Description of cluster for representation on canvas.
43 
44  """
45 
46  def __init__(self, cluster, data, marker, markersize, color):
47  """!
48  @brief Constructor of cluster representation on the canvas.
49 
50  @param[in] cluster (list): Single cluster that consists of objects or indexes from data.
51  @param[in] data (list): Objects that should be displayed, can be None if clusters consist of objects instead of indexes.
52  @param[in] marker (string): Type of marker that is used for drawing objects.
53  @param[in] markersize (uint): Size of marker that is used for drawing objects.
54  @param[in] color (string): Color of the marker that is used for drawing objects.
55 
56  """
57 
58  self.cluster = cluster
59 
60 
61  self.data = data
62 
63 
64  self.marker = marker
65 
66 
67  self.markersize = markersize
68 
69 
70  self.color = color
71 
72 
73  self.attributes = []
74 
75 
77  """!
78  @brief Visualizer for cluster in multi-dimensional data.
79  @details This cluster visualizer is useful for clusters in data whose dimension is greater than 3. The
80  multidimensional visualizer helps to overcome 'cluster_visualizer' shortcoming - ability to display
81  clusters in 1D, 2D or 3D dimensional data space.
82 
83  Example of clustering results visualization where 'Iris' is used:
84  @code
85  from pyclustering.utils import read_sample
86  from pyclustering.samples.definitions import FAMOUS_SAMPLES
87  from pyclustering.cluster import cluster_visualizer_multidim
88 
89  # load 4D data sample 'Iris'
90  sample_4d = read_sample(FAMOUS_SAMPLES.SAMPLE_IRIS)
91 
92  # initialize 3 initial centers using K-Means++ algorithm
93  centers = kmeans_plusplus_initializer(sample_4d, 3).initialize()
94 
95  # performs cluster analysis using X-Means
96  xmeans_instance = xmeans(sample_4d, centers)
97  xmeans_instance.process()
98  clusters = xmeans_instance.get_clusters()
99 
100  # visualize obtained clusters in multi-dimensional space
101  visualizer = cluster_visualizer_multidim()
102  visualizer.append_clusters(clusters, sample_4d)
103  visualizer.show(max_row_size=3)
104  @endcode
105 
106  Visualized clustering results of 'Iris' data (multi-dimensional data):
107  @image html xmeans_clustering_famous_iris.png "Fig. 1. X-Means clustering results (data 'Iris')."
108 
109  Sometimes no need to display results in all dimensions. Parameter 'filter' can be used to display only
110  interesting coordinate pairs. Here is an example of visualization of pair coordinates (x0, x1) and (x0, x2) for
111  previous clustering results:
112  @code
113  visualizer = cluster_visualizer_multidim()
114  visualizer.append_clusters(clusters, sample_4d)
115  visualizer.show(pair_filter=[[0, 1], [0, 2]])
116  @endcode
117 
118  Visualized results of specified coordinate pairs:
119  @image html xmeans_clustering_famous_iris_filtered.png "Fig. 2. X-Means clustering results (x0, x1) and (x0, x2) (data 'Iris')."
120 
121  """
122 
123  def __init__(self):
124  """!
125  @brief Constructs cluster visualizer for multidimensional data.
126  @details The visualizer is suitable more data whose dimension is bigger than 3.
127 
128  """
129  self.__clusters = []
130  self.__figure = None
131  self.__grid_spec = None
132 
133 
134  def append_cluster(self, cluster, data = None, marker = '.', markersize = None, color = None):
135  """!
136  @brief Appends cluster for visualization.
137 
138  @param[in] cluster (list): cluster that may consist of indexes of objects from the data or object itself.
139  @param[in] data (list): If defines that each element of cluster is considered as a index of object from the data.
140  @param[in] marker (string): Marker that is used for displaying objects from cluster on the canvas.
141  @param[in] markersize (uint): Size of marker.
142  @param[in] color (string): Color of marker.
143 
144  @return Returns index of cluster descriptor on the canvas.
145 
146  """
147  if len(cluster) == 0:
148  raise ValueError("Empty cluster is provided.")
149 
150  markersize = markersize or 5
151  if color is None:
152  index_color = len(self.__clusters) % len(color_list.TITLES)
153  color = color_list.TITLES[index_color]
154 
155  cluster_descriptor = canvas_cluster_descr(cluster, data, marker, markersize, color)
156  self.__clusters.append(cluster_descriptor)
157 
158 
159  def append_clusters(self, clusters, data=None, marker='.', markersize=None):
160  """!
161  @brief Appends list of cluster for visualization.
162 
163  @param[in] clusters (list): List of clusters where each cluster may consist of indexes of objects from the data or object itself.
164  @param[in] data (list): If defines that each element of cluster is considered as a index of object from the data.
165  @param[in] marker (string): Marker that is used for displaying objects from clusters on the canvas.
166  @param[in] markersize (uint): Size of marker.
167 
168  """
169 
170  for cluster in clusters:
171  self.append_cluster(cluster, data, marker, markersize)
172 
173 
174  def save(self, filename, **kwargs):
175  """!
176 
177  @brief Saves figure to the specified file.
178 
179  @param[in] filename (string): File where the visualized clusters should be stored.
180  @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'visible_axis' 'visible_labels', 'visible_grid', 'row_size', 'show').
181 
182  <b>Keyword Args:</b><br>
183  - visible_axis (bool): Defines visibility of axes on each canvas, if True - axes are visible.
184  By default axis of each canvas are not displayed.
185  - visible_labels (bool): Defines visibility of labels on each canvas, if True - labels is displayed.
186  By default labels of each canvas are displayed.
187  - visible_grid (bool): Defines visibility of grid on each canvas, if True - grid is displayed.
188  By default grid of each canvas is displayed.
189  - max_row_size (uint): Maximum number of canvases on one row.
190 
191  """
192 
193  if len(filename) == 0:
194  raise ValueError("Impossible to save visualization to file: empty file path is specified.")
195 
196  self.show(None,
197  visible_axis=kwargs.get('visible_axis', False),
198  visible_labels=kwargs.get('visible_labels', True),
199  visible_grid=kwargs.get('visible_grid', True),
200  max_row_size=kwargs.get('max_row_size', 4))
201  plt.savefig(filename)
202 
203 
204  def show(self, pair_filter=None, **kwargs):
205  """!
206  @brief Shows clusters (visualize) in multi-dimensional space.
207 
208  @param[in] pair_filter (list): List of coordinate pairs that should be displayed. This argument is used as a filter.
209  @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'visible_axis' 'visible_labels', 'visible_grid', 'row_size', 'show').
210 
211  <b>Keyword Args:</b><br>
212  - visible_axis (bool): Defines visibility of axes on each canvas, if True - axes are visible.
213  By default axis of each canvas are not displayed.
214  - visible_labels (bool): Defines visibility of labels on each canvas, if True - labels is displayed.
215  By default labels of each canvas are displayed.
216  - visible_grid (bool): Defines visibility of grid on each canvas, if True - grid is displayed.
217  By default grid of each canvas is displayed.
218  - max_row_size (uint): Maximum number of canvases on one row. By default the maximum value is 4.
219  - show (bool): If True - then displays visualized clusters. By default is `True`.
220 
221  """
222 
223  if not len(self.__clusters) > 0:
224  raise ValueError("There is no non-empty clusters for visualization.")
225 
226  cluster_data = self.__clusters[0].data or self.__clusters[0].cluster
227  dimension = len(cluster_data[0])
228 
229  acceptable_pairs = pair_filter or []
230  pairs = []
231  amount_axis = 1
232  axis_storage = []
233 
234  if dimension > 1:
235  pairs = self.__create_pairs(dimension, acceptable_pairs)
236  amount_axis = len(pairs)
237 
238  self.__figure = plt.figure()
239  self.__grid_spec = self.__create_grid_spec(amount_axis, kwargs.get('max_row_size', 4))
240 
241  for index in range(amount_axis):
242  ax = self.__create_canvas(dimension, pairs, index, **kwargs)
243  axis_storage.append(ax)
244 
245  for cluster_descr in self.__clusters:
246  self.__draw_canvas_cluster(axis_storage, cluster_descr, pairs)
247 
248  if kwargs.get('show', True):
249  plt.show()
250 
251 
252  def __create_grid_spec(self, amount_axis, max_row_size):
253  """!
254  @brief Create grid specification for figure to place canvases.
255 
256  @param[in] amount_axis (uint): Amount of canvases that should be organized by the created grid specification.
257  @param[in] max_row_size (max_row_size): Maximum number of canvases on one row.
258 
259  @return (gridspec.GridSpec) Grid specification to place canvases on figure.
260 
261  """
262  row_size = amount_axis
263  if row_size > max_row_size:
264  row_size = max_row_size
265 
266  col_size = math.ceil(amount_axis / row_size)
267  return gridspec.GridSpec(col_size, row_size)
268 
269 
270  def __create_pairs(self, dimension, acceptable_pairs):
271  """!
272  @brief Create coordinate pairs that should be displayed.
273 
274  @param[in] dimension (uint): Data-space dimension.
275  @param[in] acceptable_pairs (list): List of coordinate pairs that should be displayed.
276 
277  @return (list) List of coordinate pairs that should be displayed.
278 
279  """
280  if len(acceptable_pairs) > 0:
281  return acceptable_pairs
282 
283  return list(itertools.combinations(range(dimension), 2))
284 
285 
286  def __create_canvas(self, dimension, pairs, position, **kwargs):
287  """!
288  @brief Create new canvas with user defined parameters to display cluster or chunk of cluster on it.
289 
290  @param[in] dimension (uint): Data-space dimension.
291  @param[in] pairs (list): Pair of coordinates that will be displayed on the canvas. If empty than label will not
292  be displayed on the canvas.
293  @param[in] position (uint): Index position of canvas on a grid.
294  @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'visible_axis' 'visible_labels', 'visible_grid').
295 
296  <b>Keyword Args:</b><br>
297  - visible_axis (bool): Defines visibility of axes on each canvas, if True - axes are visible.
298  By default axis are not displayed.
299  - visible_labels (bool): Defines visibility of labels on each canvas, if True - labels is displayed.
300  By default labels are displayed.
301  - visible_grid (bool): Defines visibility of grid on each canvas, if True - grid is displayed.
302  By default grid is displayed.
303 
304  @return (matplotlib.Axis) Canvas to display cluster of chuck of cluster.
305 
306  """
307  visible_grid = kwargs.get('visible_grid', True)
308  visible_labels = kwargs.get('visible_labels', True)
309  visible_axis = kwargs.get('visible_axis', False)
310 
311  ax = self.__figure.add_subplot(self.__grid_spec[position])
312 
313  if dimension > 1:
314  if visible_labels:
315  ax.set_xlabel("x%d" % pairs[position][0])
316  ax.set_ylabel("x%d" % pairs[position][1])
317  else:
318  ax.set_ylim(-0.5, 0.5)
319  ax.set_yticklabels([])
320 
321  if visible_grid:
322  ax.grid(True)
323 
324  if not visible_axis:
325  ax.set_yticklabels([])
326  ax.set_xticklabels([])
327 
328  return ax
329 
330 
331  def __draw_canvas_cluster(self, axis_storage, cluster_descr, pairs):
332  """!
333  @brief Draw clusters.
334 
335  @param[in] axis_storage (list): List of matplotlib axis where cluster dimensional chunks are displayed.
336  @param[in] cluster_descr (canvas_cluster_descr): Canvas cluster descriptor that should be displayed.
337  @param[in] pairs (list): List of coordinates that should be displayed.
338 
339  """
340 
341  for index_axis in range(len(axis_storage)):
342  for item in cluster_descr.cluster:
343  if len(pairs) > 0:
344  self.__draw_cluster_item_multi_dimension(axis_storage[index_axis], pairs[index_axis], item, cluster_descr)
345  else:
346  self.__draw_cluster_item_one_dimension(axis_storage[index_axis], item, cluster_descr)
347 
348 
349  def __draw_cluster_item_multi_dimension(self, ax, pair, item, cluster_descr):
350  """!
351  @brief Draw cluster chunk defined by pair coordinates in data space with dimension greater than 1.
352 
353  @param[in] ax (axis): Matplotlib axis that is used to display chunk of cluster point.
354  @param[in] pair (list): Coordinate of the point that should be displayed.
355  @param[in] item (list): Data point or index of data point.
356  @param[in] cluster_descr (canvas_cluster_descr): Cluster description whose point is visualized.
357 
358  """
359 
360  index_dimension1 = pair[0]
361  index_dimension2 = pair[1]
362 
363  if cluster_descr.data is None:
364  ax.plot(item[index_dimension1], item[index_dimension2],
365  color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)
366  else:
367  ax.plot(cluster_descr.data[item][index_dimension1], cluster_descr.data[item][index_dimension2],
368  color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)
369 
370 
371  def __draw_cluster_item_one_dimension(self, ax, item, cluster_descr):
372  """!
373  @brief Draw cluster point in one dimensional data space..
374 
375  @param[in] ax (axis): Matplotlib axis that is used to display chunk of cluster point.
376  @param[in] item (list): Data point or index of data point.
377  @param[in] cluster_descr (canvas_cluster_descr): Cluster description whose point is visualized.
378 
379  """
380 
381  if cluster_descr.data is None:
382  ax.plot(item[0], 0.0,
383  color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)
384  else:
385  ax.plot(cluster_descr.data[item][0], 0.0,
386  color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)
387 
388 
389 
391  """!
392  @brief Common visualizer of clusters on 1D, 2D or 3D surface.
393  @details Use 'cluster_visualizer_multidim' visualizer in case of data dimension is greater than 3.
394 
395  @see cluster_visualizer_multidim
396 
397  """
398 
399  def __init__(self, number_canvases=1, size_row=1, titles=None):
400  """!
401  @brief Constructor of cluster visualizer.
402 
403  @param[in] number_canvases (uint): Number of canvases that is used for visualization.
404  @param[in] size_row (uint): Amount of canvases that can be placed in one row.
405  @param[in] titles (list): List of canvas's titles.
406 
407  Example:
408  @code
409  # load 2D data sample
410  sample_2d = read_sample(SIMPLE_SAMPLES.SAMPLE_SIMPLE1);
411 
412  # load 3D data sample
413  sample_3d = read_sample(FCPS_SAMPLES.SAMPLE_HEPTA);
414 
415  # extract clusters from the first sample using DBSCAN algorithm
416  dbscan_instance = dbscan(sample_2d, 0.4, 2, False);
417  dbscan_instance.process();
418  clusters_sample_2d = dbscan_instance.get_clusters();
419 
420  # extract clusters from the second sample using DBSCAN algorithm
421  dbscan_instance = dbscan(sample_3d, 1, 3, True);
422  dbscan_instance.process();
423  clusters_sample_3d = dbscan_instance.get_clusters();
424 
425  # create plot with two canvases where each row contains 2 canvases.
426  size = 2;
427  row_size = 2;
428  visualizer = cluster_visualizer(size, row_size);
429 
430  # place clustering result of sample_2d to the first canvas
431  visualizer.append_clusters(clusters_sample_2d, sample_2d, 0, markersize = 5);
432 
433  # place clustering result of sample_3d to the second canvas
434  visualizer.append_clusters(clusters_sample_3d, sample_3d, 1, markersize = 30);
435 
436  # show plot
437  visualizer.show();
438  @endcode
439 
440  """
441 
442  self.__number_canvases = number_canvases
443  self.__size_row = size_row
444  self.__canvas_clusters = [ [] for _ in range(number_canvases) ]
445  self.__canvas_dimensions = [ None for _ in range(number_canvases) ]
446  self.__canvas_titles = [ None for _ in range(number_canvases) ]
447 
448  if titles is not None:
449  self.__canvas_titles = titles
450 
451  self.__default_2d_marker_size = 5
452  self.__default_3d_marker_size = 30
453 
454 
455  def append_cluster(self, cluster, data=None, canvas=0, marker='.', markersize=None, color=None):
456  """!
457  @brief Appends cluster to canvas for drawing.
458 
459  @param[in] cluster (list): cluster that may consist of indexes of objects from the data or object itself.
460  @param[in] data (list): If defines that each element of cluster is considered as a index of object from the data.
461  @param[in] canvas (uint): Number of canvas that should be used for displaying cluster.
462  @param[in] marker (string): Marker that is used for displaying objects from cluster on the canvas.
463  @param[in] markersize (uint): Size of marker.
464  @param[in] color (string): Color of marker.
465 
466  @return Returns index of cluster descriptor on the canvas.
467 
468  """
469 
470  if len(cluster) == 0:
471  return
472 
473  if canvas > self.__number_canvases or canvas < 0:
474  raise ValueError("Canvas index '%d' is out of range [0; %d]." % self.__number_canvases or canvas)
475 
476  if color is None:
477  index_color = len(self.__canvas_clusters[canvas]) % len(color_list.TITLES)
478  color = color_list.TITLES[index_color]
479 
480  added_canvas_descriptor = canvas_cluster_descr(cluster, data, marker, markersize, color)
481  self.__canvas_clusters[canvas].append(added_canvas_descriptor)
482 
483  if data is None:
484  dimension = len(cluster[0])
485  if self.__canvas_dimensions[canvas] is None:
486  self.__canvas_dimensions[canvas] = dimension
487  elif self.__canvas_dimensions[canvas] != dimension:
488  raise ValueError("Only clusters with the same dimension of objects can be displayed on canvas.")
489 
490  else:
491  dimension = len(data[0])
492  if self.__canvas_dimensions[canvas] is None:
493  self.__canvas_dimensions[canvas] = dimension
494  elif self.__canvas_dimensions[canvas] != dimension:
495  raise ValueError("Only clusters with the same dimension of objects can be displayed on canvas.")
496 
497  if (dimension < 1) or (dimension > 3):
498  raise ValueError("Only objects with size dimension 1 (1D plot), 2 (2D plot) or 3 (3D plot) "
499  "can be displayed. For multi-dimensional data use 'cluster_visualizer_multidim'.")
500 
501  if markersize is None:
502  if (dimension == 1) or (dimension == 2):
503  added_canvas_descriptor.markersize = self.__default_2d_marker_size
504  elif dimension == 3:
505  added_canvas_descriptor.markersize = self.__default_3d_marker_size
506 
507  return len(self.__canvas_clusters[canvas]) - 1
508 
509 
510  def append_cluster_attribute(self, index_canvas, index_cluster, data, marker = None, markersize = None):
511  """!
512  @brief Append cluster attribure for cluster on specific canvas.
513  @details Attribute it is data that is visualized for specific cluster using its color, marker and markersize if last two is not specified.
514 
515  @param[in] index_canvas (uint): Index canvas where cluster is located.
516  @param[in] index_cluster (uint): Index cluster whose attribute should be added.
517  @param[in] data (list): List of points (data) that represents attribute.
518  @param[in] marker (string): Marker that is used for displaying objects from cluster on the canvas.
519  @param[in] markersize (uint): Size of marker.
520 
521  """
522 
523  cluster_descr = self.__canvas_clusters[index_canvas][index_cluster]
524  attribute_marker = marker
525  if attribute_marker is None:
526  attribute_marker = cluster_descr.marker
527 
528  attribure_markersize = markersize
529  if attribure_markersize is None:
530  attribure_markersize = cluster_descr.markersize
531 
532  attribute_color = cluster_descr.color
533 
534  added_attribute_cluster_descriptor = canvas_cluster_descr(data, None, attribute_marker, attribure_markersize, attribute_color)
535  self.__canvas_clusters[index_canvas][index_cluster].attributes.append(added_attribute_cluster_descriptor)
536 
537 
538  def append_clusters(self, clusters, data=None, canvas=0, marker='.', markersize=None):
539  """!
540  @brief Appends list of cluster to canvas for drawing.
541 
542  @param[in] clusters (list): List of clusters where each cluster may consist of indexes of objects from the data or object itself.
543  @param[in] data (list): If defines that each element of cluster is considered as a index of object from the data.
544  @param[in] canvas (uint): Number of canvas that should be used for displaying clusters.
545  @param[in] marker (string): Marker that is used for displaying objects from clusters on the canvas.
546  @param[in] markersize (uint): Size of marker.
547 
548  """
549 
550  for cluster in clusters:
551  self.append_cluster(cluster, data, canvas, marker, markersize)
552 
553 
554  def set_canvas_title(self, text, canvas = 0):
555  """!
556  @brief Set title for specified canvas.
557 
558  @param[in] text (string): Title for canvas.
559  @param[in] canvas (uint): Index of canvas where title should be displayed.
560 
561  """
562 
563  if canvas > self.__number_canvases:
564  raise NameError('Canvas does ' + canvas + ' not exists.')
565 
566  self.__canvas_titles[canvas] = text
567 
568 
569  def get_cluster_color(self, index_cluster, index_canvas):
570  """!
571  @brief Returns cluster color on specified canvas.
572 
573  """
574  return self.__canvas_clusters[index_canvas][index_cluster].color
575 
576 
577  def save(self, filename, **kwargs):
578  """!
579 
580  @brief Saves figure to the specified file.
581 
582  @param[in] filename (string): File where the visualized clusters should be stored.
583  @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'invisible_axis', 'visible_grid').
584 
585  <b>Keyword Args:</b><br>
586  - invisible_axis (bool): Defines visibility of axes on each canvas, if `True` - axes are invisible.
587  By default axis are invisible.
588  - visible_grid (bool): Defines visibility of grid on each canvas, if `True` - grid is displayed.
589  By default grid of each canvas is displayed.
590 
591  There is an example how to save visualized clusters to the PNG file without showing them on a screen:
592  @code
593  from pyclustering.cluster import cluster_visualizer
594 
595  data = [[1.1], [1.7], [3.7], [5.3], [2.5], [-1.5], [-0.9], [6.3], [6.5], [8.1]]
596  clusters = [[0, 1, 2, 4, 5, 6], [3, 7, 8, 9]]
597 
598  visualizer = cluster_visualizer()
599  visualizer.append_clusters(clusters, data)
600  visualizer.save("1-dimensional-clustering.png")
601  @endcode
602 
603  """
604 
605  if len(filename) == 0:
606  raise ValueError("Impossible to save visualization to file: empty file path is specified.")
607 
608  invisible_axis = kwargs.get('invisible_axis', True)
609  visible_grid = kwargs.get('visible_grid', True)
610 
611  self.show(None, invisible_axis, visible_grid, False)
612  plt.savefig(filename)
613 
614 
615  def show(self, figure=None, invisible_axis=True, visible_grid=True, display=True, shift=None):
616  """!
617  @brief Shows clusters (visualize).
618 
619  @param[in] figure (fig): Defines requirement to use specified figure, if None - new figure is created for drawing clusters.
620  @param[in] invisible_axis (bool): Defines visibility of axes on each canvas, if True - axes are invisible.
621  @param[in] visible_grid (bool): Defines visibility of grid on each canvas, if True - grid is displayed.
622  @param[in] display (bool): Defines requirement to display clusters on a stage, if True - clusters are displayed,
623  if False - plt.show() should be called by user."
624  @param[in] shift (uint): Force canvas shift value - defines canvas index from which custers should be visualized.
625 
626  @return (fig) Figure where clusters are shown.
627 
628  """
629 
630  canvas_shift = shift
631  if canvas_shift is None:
632  if figure is not None:
633  canvas_shift = len(figure.get_axes())
634  else:
635  canvas_shift = 0
636 
637  if figure is not None:
638  cluster_figure = figure
639  else:
640  cluster_figure = plt.figure()
641 
642  maximum_cols = self.__size_row
643  maximum_rows = math.ceil( (self.__number_canvases + canvas_shift) / maximum_cols)
644 
645  grid_spec = gridspec.GridSpec(maximum_rows, maximum_cols)
646 
647  for index_canvas in range(len(self.__canvas_clusters)):
648  canvas_data = self.__canvas_clusters[index_canvas]
649  if len(canvas_data) == 0:
650  continue
651 
652  dimension = self.__canvas_dimensions[index_canvas]
653 
654  #ax = axes[real_index];
655  if (dimension == 1) or (dimension == 2):
656  ax = cluster_figure.add_subplot(grid_spec[index_canvas + canvas_shift])
657  else:
658  ax = cluster_figure.add_subplot(grid_spec[index_canvas + canvas_shift], projection='3d')
659 
660  if len(canvas_data) == 0:
661  plt.setp(ax, visible=False)
662 
663  for cluster_descr in canvas_data:
664  self.__draw_canvas_cluster(ax, dimension, cluster_descr)
665 
666  for attribute_descr in cluster_descr.attributes:
667  self.__draw_canvas_cluster(ax, dimension, attribute_descr)
668 
669  if invisible_axis is True:
670  ax.xaxis.set_ticklabels([])
671  ax.yaxis.set_ticklabels([])
672 
673  if (dimension == 3):
674  ax.zaxis.set_ticklabels([])
675 
676  if self.__canvas_titles[index_canvas] is not None:
677  ax.set_title(self.__canvas_titles[index_canvas])
678 
679  ax.grid(visible_grid)
680 
681  if display is True:
682  plt.show()
683 
684  return cluster_figure
685 
686 
687  def __draw_canvas_cluster(self, ax, dimension, cluster_descr):
688  """!
689  @brief Draw canvas cluster descriptor.
690 
691  @param[in] ax (Axis): Axis of the canvas where canvas cluster descriptor should be displayed.
692  @param[in] dimension (uint): Canvas dimension.
693  @param[in] cluster_descr (canvas_cluster_descr): Canvas cluster descriptor that should be displayed.
694 
695  @return (fig) Figure where clusters are shown.
696 
697  """
698 
699  cluster = cluster_descr.cluster
700  data = cluster_descr.data
701  marker = cluster_descr.marker
702  markersize = cluster_descr.markersize
703  color = cluster_descr.color
704 
705  for item in cluster:
706  if dimension == 1:
707  if data is None:
708  ax.plot(item[0], 0.0, color = color, marker = marker, markersize = markersize)
709  else:
710  ax.plot(data[item][0], 0.0, color = color, marker = marker, markersize = markersize)
711 
712  elif dimension == 2:
713  if data is None:
714  ax.plot(item[0], item[1], color = color, marker = marker, markersize = markersize)
715  else:
716  ax.plot(data[item][0], data[item][1], color = color, marker = marker, markersize = markersize)
717 
718  elif dimension == 3:
719  if data is None:
720  ax.scatter(item[0], item[1], item[2], c = color, marker = marker, s = markersize)
721  else:
722  ax.scatter(data[item][0], data[item][1], data[item][2], c = color, marker = marker, s = markersize)
def show(self, figure=None, invisible_axis=True, visible_grid=True, display=True, shift=None)
Shows clusters (visualize).
Definition: __init__.py:615
Common visualizer of clusters on 1D, 2D or 3D surface.
Definition: __init__.py:390
def append_cluster(self, cluster, data=None, canvas=0, marker='.', markersize=None, color=None)
Appends cluster to canvas for drawing.
Definition: __init__.py:455
def get_cluster_color(self, index_cluster, index_canvas)
Returns cluster color on specified canvas.
Definition: __init__.py:569
def append_cluster(self, cluster, data=None, marker='.', markersize=None, color=None)
Appends cluster for visualization.
Definition: __init__.py:134
def set_canvas_title(self, text, canvas=0)
Set title for specified canvas.
Definition: __init__.py:554
def __init__(self)
Constructs cluster visualizer for multidimensional data.
Definition: __init__.py:123
def __create_canvas(self, dimension, pairs, position, kwargs)
Create new canvas with user defined parameters to display cluster or chunk of cluster on it...
Definition: __init__.py:286
def append_cluster_attribute(self, index_canvas, index_cluster, data, marker=None, markersize=None)
Append cluster attribure for cluster on specific canvas.
Definition: __init__.py:510
markersize
Size of marker that is used for drawing objects.
Definition: __init__.py:67
data
Data where objects are stored.
Definition: __init__.py:61
def show(self, pair_filter=None, kwargs)
Shows clusters (visualize) in multi-dimensional space.
Definition: __init__.py:204
def __draw_canvas_cluster(self, ax, dimension, cluster_descr)
Draw canvas cluster descriptor.
Definition: __init__.py:687
Colors used by pyclustering library for visualization.
Definition: color.py:1
def save(self, filename, kwargs)
Saves figure to the specified file.
Definition: __init__.py:577
def __create_grid_spec(self, amount_axis, max_row_size)
Create grid specification for figure to place canvases.
Definition: __init__.py:252
def __init__(self, cluster, data, marker, markersize, color)
Constructor of cluster representation on the canvas.
Definition: __init__.py:46
marker
Marker that is used for drawing objects.
Definition: __init__.py:64
attributes
Attribures of the clusters - additional collections of data points that are regarded to the cluster...
Definition: __init__.py:73
def append_clusters(self, clusters, data=None, marker='.', markersize=None)
Appends list of cluster for visualization.
Definition: __init__.py:159
def __draw_cluster_item_multi_dimension(self, ax, pair, item, cluster_descr)
Draw cluster chunk defined by pair coordinates in data space with dimension greater than 1...
Definition: __init__.py:349
def __draw_cluster_item_one_dimension(self, ax, item, cluster_descr)
Draw cluster point in one dimensional data space.
Definition: __init__.py:371
Description of cluster for representation on canvas.
Definition: __init__.py:40
def save(self, filename, kwargs)
Saves figure to the specified file.
Definition: __init__.py:174
def __init__(self, number_canvases=1, size_row=1, titles=None)
Constructor of cluster visualizer.
Definition: __init__.py:399
Visualizer for cluster in multi-dimensional data.
Definition: __init__.py:76
cluster
Cluster that may consist of objects or indexes of objects from data.
Definition: __init__.py:58
def append_clusters(self, clusters, data=None, canvas=0, marker='.', markersize=None)
Appends list of cluster to canvas for drawing.
Definition: __init__.py:538
color
Color that is used for coloring marker.
Definition: __init__.py:70
def __create_pairs(self, dimension, acceptable_pairs)
Create coordinate pairs that should be displayed.
Definition: __init__.py:270
def __draw_canvas_cluster(self, axis_storage, cluster_descr, pairs)
Draw clusters.
Definition: __init__.py:331