docs: def plot_embedding(coordinates, partition=None, add_sphere=False, point_size=8,
          colours=None, labels=None, legend=True, outfile=False, **kwargs):
      """ plot_embedding(coordinates, partition=None, add_sphere=False, point_size=8,
      colours=None, labels=None, legend=True, outfile=False, **kwargs):
      
      Plot a 2D / 3D scatterplot of coordinates, optionally
      coloured by group membership.
  
      Args:
          coordinates: numpy array or treeCl.CoordinateMatrix -
              The coordinates of the points to plot. The number
              of columns determines the number of dimensions in
              the plot.
          add_sphere: bool -
              Add a wireframe sphere to a 3D plot. Spectral clustering
              places points on the surface of a unit sphere.
          colours: list of rgb hexes, or 'auto', or None -
              Colours to use to colour the points, as a list of
              RGB hex values. If None, defaults
              (colorbrewer set3). If 'auto', generates a set
              of colours equally spaced from the colour wheel.
          labels: Tuple(xlab, ylab, title, zlab) -
              Plot labels. Must be given in the above order.
              Missing options will be replaced by None. E.g.
              to set the title: (None, None, "Some points")
          outfile: str -
              Save figure to this filename
      """
      if isinstance(coordinates, CoordinateMatrix):
          coordinates = coordinates.values
      dimensions = min(3, coordinates.shape[1])
      partition = (partition or
                   Partition(tuple([0] * len(coordinates))))
      ngrp = partition.num_groups()
  
      if colours is None:
          colours = SET2
      elif colours == 'auto':
          colours = ggColorSlice(ngrp)
  
      colour_cycle = itertools.cycle(colours)
      colours = np.array([hex2color(c) for c in itertools.islice(colour_cycle, ngrp)])
  
      if labels is None:
          xlab, ylab, zlab, title = None, None, None, None
      else:
          if isinstance(labels, (tuple, list)):
              labels = list(labels[:4])
              labels.extend([None]*(4-len(labels)))
              xlab, ylab, title, zlab = labels
  
      fig = plt.figure()
  
      if dimensions == 3:
          ax = fig.add_subplot(111, projection='3d')
          if add_sphere:
              ax = _add_sphere(ax)
      else:
          ax = fig.add_subplot(111)
      
      members = partition.get_membership()
      for grp in range(ngrp):
          index = np.array(members[grp])
          points = coordinates[index,:dimensions].T
          ax.scatter(*points, s=point_size, c=colours[grp], edgecolor=None, label='Group {}'.format(grp+1), **kwargs)
  
      if xlab:
          ax.set_xlabel(xlab)
      if ylab:
          ax.set_ylabel(ylab)
      if zlab:
          ax.set_zlabel(zlab)
      if title:
          ax.set_title(title)
      if legend:
          plt.legend()
      if outfile:
          fig.savefig('{0}.pdf'.format(outfile))
  
      return fig