class_docstr: !
  @brief Common cluster visualizer for 1-, 2- and 3-dimensional data.
  @details `cluster_visualizer_multidim` visualizer can be used to display clusters in N-dimensional data.
  
  The general difference between `cluster_visualizer` and `cluster_visualizer_multidim` is a way of representation
  of 3-dimensional data. In case of `cluster_visualizer` 3-dimensional data is displayed in 3-dimensional plot with
  `x0`, `x1` and `x2` axis. In case of `cluster_visualizer_multidim` it displayed on three 2-dimensional plots:
  `(x0, x1)`, `(x0, x2)` and `(x1, x2)`.
  
  There is an example where sample `Atom` is used for clustering and displayed by `cluster_visualizer`:
  @code
      from pyclustering.utils import read_sample
      from pyclustering.samples.definitions import FCPS_SAMPLES
      from pyclustering.cluster import cluster_visualizer
      from pyclustering.cluster.dbscan import dbscan
  
      sample = read_sample(FCPS_SAMPLES.SAMPLE_ATOM)
      clusters = dbscan(sample, 15, 3).process().get_clusters()
  
      visualizer = cluster_visualizer()
      visualizer.append_clusters(clusters, sample)
      visualizer.show()
  @endcode
  
  Visualized clustering results of `Atom` data:
  @image html dbscan_atom_visualizer.png "Fig. 1. DBSCAN clustering results (3-dimensional data 'Atom')."
  
  @see cluster_visualizer_multidim
docstr: !
  
  @brief Saves figure to the specified file.
  
  @param[in] filename (string): File where the visualized clusters should be stored.
  @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'invisible_axis', 'visible_grid').
  
  <b>Keyword Args:</b><br>
      - invisible_axis (bool): Defines visibility of axes on each canvas, if `True` - axes are invisible.
                                By default axis are invisible.
      - visible_grid (bool): Defines visibility of grid on each canvas, if `True` - grid is displayed.
                              By default grid of each canvas is displayed.
  
  There is an example how to save visualized clusters to the PNG file without showing them on a screen:
  @code
      from pyclustering.cluster import cluster_visualizer
  
      data = [[1.1], [1.7], [3.7], [5.3], [2.5], [-1.5], [-0.9], [6.3], [6.5], [8.1]]
      clusters = [[0, 1, 2, 4, 5, 6], [3, 7, 8, 9]]
  
      visualizer = cluster_visualizer()
      visualizer.append_clusters(clusters, data)
      visualizer.save("1-dimensional-clustering.png")
  @endcode
docstr_tok: ["!","@","brief","Saves","figure","to","the","specified","file",".","@","param","[","in","]","filename","(","string",")",":","File","where","the","visualized","clusters","should","be","stored",".","@","param","[","in","]","*","*","kwargs",":","Arbitrary","keyword","arguments","(","available","arguments",":","'invisible_axis","'",",","'visible_grid","'",")",".","<","b",">","Keyword","Args",":","<","\/b",">","<","br",">","-","invisible_axis","(","bool",")",":","Defines","visibility","of","axes","on","each","canvas",",","if","`","True","`","-","axes","are","invisible",".","By","default","axis","are","invisible",".","-","visible_grid","(","bool",")",":","Defines","visibility","of","grid","on","each","canvas",",","if","`","True","`","-","grid","is","displayed",".","By","default","grid","of","each","canvas","is","displayed",".","There","is","an","example","how","to","save","visualized","clusters","to","the","PNG","file","without","showing","them","on","a","screen",":","@","code","from","pyclustering.cluster","import","cluster_visualizer","data","=","[","[","1.1","]",",","[","1.7","]",",","[","3.7","]",",","[","5.3","]",",","[","2.5","]",",","[","-1.5","]",",","[","-0.9","]",",","[","6.3","]",",","[","6.5","]",",","[","8.1","]","]","clusters","=","[","[","0",",","1",",","2",",","4",",","5",",","6","]",",","[","3",",","7",",","8",",","9","]","]","visualizer","=","cluster_visualizer","(",")","visualizer.append_clusters","(","clusters",",","data",")","visualizer.save","(","``","1-dimensional-clustering.png","''",")","@","endcode"]
code: def save(self, filename, **kwargs):
      """!
  
      @brief Saves figure to the specified file.
  
      @param[in] filename (string): File where the visualized clusters should be stored.
      @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'invisible_axis', 'visible_grid').
  
      <b>Keyword Args:</b><br>
          - invisible_axis (bool): Defines visibility of axes on each canvas, if `True` - axes are invisible.
                                    By default axis are invisible.
          - visible_grid (bool): Defines visibility of grid on each canvas, if `True` - grid is displayed.
                                  By default grid of each canvas is displayed.
  
      There is an example how to save visualized clusters to the PNG file without showing them on a screen:
      @code
          from pyclustering.cluster import cluster_visualizer
  
          data = [[1.1], [1.7], [3.7], [5.3], [2.5], [-1.5], [-0.9], [6.3], [6.5], [8.1]]
          clusters = [[0, 1, 2, 4, 5, 6], [3, 7, 8, 9]]
  
          visualizer = cluster_visualizer()
          visualizer.append_clusters(clusters, data)
          visualizer.save("1-dimensional-clustering.png")
      @endcode
  
      """
  
      if len(filename) == 0:
          raise ValueError(
              "Impossible to save visualization to file: empty file path is specified."
          )
  
      invisible_axis = kwargs.get("invisible_axis", True)
      visible_grid = kwargs.get("visible_grid", True)
  
      self.show(None, invisible_axis, visible_grid, False)
      plt.savefig(filename)
  
imports: import itertools
  import math
  import matplotlib.pyplot
  import matplotlib.gridspec
  from mpl_toolkits.mplot3d import Axes3D
  from pyclustering.utils.color import color
label_desc: Use image node_id 7 for calling the cluster_visualizer obj's underlying member method code with example usage: obj.save(filename) without return types