docs: def group_sources(self, radius='', plot=False):
          """
          Calculate the centers of the point clusters given the
          radius and minimum number of points
  
          Parameters
          ----------
          coords: array-like
              The list of (x,y) coordinates of all clicks
          radius: int
              The distance threshold in degrees for cluster membership
              [default of 0.36 arcseconds]
  
          Returns
          -------
          np.ndarray
              An array of the cluster centers
          """
          if len(self.catalogs)==0:
              print("No catalogs to start grouping! Add one with the ingest_data() method first.")
              
          else:
              
              # Gather the catalogs
              print('Grouping sources from the following catalogs:',list(self.catalogs.keys()))
              cats = pd.concat([getattr(self, cat_name) for cat_name in self.catalogs])
              
              # Clear the source grouping
              cats['oncID'] = np.nan
              cats['oncflag'] = ''
              self.xmatch_radius = radius if isinstance(radius,(float,int)) else self.xmatch_radius
              
              # Make a list of the coordinates of each catalog row
              coords = cats[['ra_corr','dec_corr']].values
              
              # Perform DBSCAN to find clusters
              db = DBSCAN(eps=self.xmatch_radius, min_samples=1, n_jobs=-1).fit(coords)
              
              # Group the sources
              core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
              core_samples_mask[db.core_sample_indices_] = True
              source_ids = db.labels_+1
              unique_source_ids = list(set(source_ids))
              self.n_sources = len(unique_source_ids)
              
              # Get the average coordinates of all clusters
              unique_coords = np.asarray([np.mean(coords[source_ids==id], axis=0) for id in list(set(source_ids))])
              
              # Generate a source catalog
              self.catalog = pd.DataFrame(columns=('id','ra','dec','flag','datasets'))
              self.catalog['id'] = unique_source_ids
              self.catalog[['ra','dec']] = unique_coords
              self.catalog['flag'] = [None]*len(unique_source_ids)
              # self.catalog['flag'] = ['d{}'.format(i) if i>1 else '' for i in Counter(source_ids).values()]
              self.catalog['datasets'] = Counter(source_ids).values()
              
              # Update history
              self.history += "\n{}: Catalog grouped with radius {} arcsec.".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.xmatch_radius)
              
              # Update the source_ids in each catalog
              cats['source_id'] = source_ids
              for cat_name in self.catalogs:
                  
                  # Get the source_ids for the catalog
                  cat_source_ids = cats.loc[cats['catID'].str.startswith(cat_name)]['source_id']
                  
                  # Get the catalog
                  cat = getattr(self, cat_name)
                  
                  # Update the source_ids and put it back
                  cat['source_id'] = cat_source_ids
                  setattr(self, cat_name, cat)
                  
                  del cat, cat_source_ids
                  
              del cats
              
              # Plot it
              if plot:
                  plt.figure()
                  plt.title('{} clusters for {} sources'.format(self.n_sources,len(coords)))
                  
                  colors = [plt.cm.Spectral(each) for each in np.linspace(0, 1, self.n_sources)]
                  for k, col in zip(unique_source_ids, colors):
                      
                      class_member_mask = (source_ids == k)
                      xy = coords[class_member_mask & core_samples_mask]
                      
                      marker = 'o'
                      if len(xy)==1:
                          col = [0,0,0,1]
                          marker = '+'
                          
                      plt.plot(xy[:, 0], xy[:, 1], color=tuple(col), marker=marker, markerfacecolor=tuple(col))