docs: def analyze(self, method_name, mapper=map, invert=False, **kwargs):
          """
          Apply a method from NetworkX to each of the graphs in the
          :class:`.GraphCollection`\.
  
          Examples
          --------
          .. code-block:: python
  
             >>> G.analyze('betweenness_centrality')
             {'test': {0: 1.0, 1: 0.0, 2: 0.0},
              'test2': {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0}}
             >>> G.analyze('betweenness_centrality', results_by='node')
             {0: {'test': 1.0, 'test2': 0.0},
              1: {'test': 0.0, 'test2': 0.0},
              2: {'test': 0.0, 'test2': 0.0},
              3: {'test2': 0.0}}
  
          Parameters
          ----------
          method : str or iterable
              Must be the name of a method accessible directly from the
              `networkx` namespace. If an iterable, should be the complete
              dot-path to the method, e.g. ``nx.connected.is_connected`` would be
              written as ``['connected', 'is_connected']``.
          mapper : func
              A mapping function. Be default uses Python's builtin ``map``
              function. MUST return results in order.
          results_by : str
              (default: 'graph'). By default, the top-level key in the results
              are graph names. If results_by='node', node labels are used as
              top-level keys.
          kwargs : kwargs
              Any additional kwargs are passed to the NetworkX method.
  
          Returns
          -------
          dict
  
          """
  
          # Find the analysis method, if possible.
          if hasattr(method_name, '__iter__'):
              mpath = method_name
              if type(mpath) in [str, unicode]:
                  mpath = [mpath]
  
              root = nx
              while len(mpath) > 0:
                  head = getattr(root, mpath.pop(0))
              if hasattr(head, '__call__'):
                  method = head
              else:
                  raise NameError("No matching method in NetworkX")
  
          elif hasattr(nx, method_name):
              method = getattr(nx, method_name)
          else:
              raise AttributeError('No such method in NetworkX')
  
          # Farm out the analysis using ``mapper``. This allows us to use
          #  multiprocessing in the future, or to add pre- or post-processing
          #  routines.
          keys, graphs = zip(*self.items())
          results = mapper(method, graphs, **kwargs)
  
          # Group the results by graph.
          by_graph = dict(zip(keys, results))
  
          # Invert results.
          inverse = defaultdict(dict)
          for gname, result in by_graph.iteritems():
              if hasattr(result, '__iter__'):
                  for n, val in result.iteritems():
                      inverse[n].update({gname: val})
  
          if type(list(by_graph.values())[0]) is dict:
              # Look for a result set that we can inspect.
              i = 0
              while True:
                  if len(by_graph.values()[i]) > 0:
                      inspect = by_graph.values()[i]
                      break
                  i += 1
  
              if type(list(inspect.keys())[0]) is tuple:
                  # Results correspond to edges.
                  by_edge = dict(inverse)
  
                  # Set edge attributes in each graph.
                  for graph, attrs in by_graph.iteritems():
                      nx.set_edge_attributes(self[graph], method_name, attrs)
  
                  # Set edge attributes in the master graph.
                  for (s, t), v in by_edge.iteritems():
                      for i, attrs in self.master_graph.edge[s][t].iteritems():
                          val = v[attrs['graph']]
                          self.master_graph.edge[s][t][i][method_name] = val
  
                  if invert:
                      return by_edge
              else:
                  # Results correspond to nodes.
                  by_node = dict(inverse)
  
                  # Set node attributes for each graph.
                  for graph, attrs in by_graph.iteritems():
                      nx.set_node_attributes(self[graph], method_name, attrs)
  
                  # Store node attributes in the master graph.
                  nx.set_node_attributes(self.master_graph, method_name, by_node)
  
                  if invert:
                      return by_node
          return by_graph