code: def louvain_communities(
      G, weight="weight", resolution=1, threshold=0.0000001, seed=None
  ):
      r"""Find the best partition of a graph using the Louvain Community Detection
      Algorithm.
  
      Louvain Community Detection Algorithm is a simple method to extract the community
      structure of a network. This is a heuristic method based on modularity optimization. [1]_
  
      The algorithm works in 2 steps. On the first step it assigns every node to be
      in its own community and then for each node it tries to find the maximum positive
      modularity gain by moving each node to all of its neighbor communities. If no positive
      gain is achieved the node remains in its original community.
  
      The modularity gain obtained by moving an isolated node $i$ into a community $C$ can
      easily be calculated by the following formula (combining [1]_ [2]_ and some algebra):
  
      .. math::
          \Delta Q = \frac{k_{i,in}}{2m} - \gamma\frac{ \Sigma_{tot} \cdot k_i}{2m^2}
  
      where $m$ is the size of the graph, $k_{i,in}$ is the sum of the weights of the links
      from $i$ to nodes in $C$, $k_i$ is the sum of the weights of the links incident to node $i$,
      $\Sigma_{tot}$ is the sum of the weights of the links incident to nodes in $C$ and $\gamma$
      is the resolution parameter.
  
      For the directed case the modularity gain can be computed using this formula according to [3]_
  
      .. math::
          \Delta Q = \frac{k_{i,in}}{m}
          - \gamma\frac{k_i^{out} \cdot\Sigma_{tot}^{in} + k_i^{in} \cdot \Sigma_{tot}^{out}}{m^2}
  
      where $k_i^{out}$, $k_i^{in}$ are the outer and inner weighted degrees of node $i$ and
      $\Sigma_{tot}^{in}$, $\Sigma_{tot}^{out}$ are the sum of in-going and out-going links incident
      to nodes in $C$.
  
      The first phase continues until no individual move can improve the modularity.
  
      The second phase consists in building a new network whose nodes are now the communities
      found in the first phase. To do so, the weights of the links between the new nodes are given by
      the sum of the weight of the links between nodes in the corresponding two communities. Once this
      phase is complete it is possible to reapply the first phase creating bigger communities with
      increased modularity.
  
      The above two phases are executed until no modularity gain is achieved (or is less than
      the `threshold`).
  
      Be careful with self-loops in the input graph. These are treated as
      previously reduced communities -- as if the process had been started
      in the middle of the algorithm. Large self-loop edge weights thus
      represent strong communities and in practice may be hard to add
      other nodes to.  If your input graph edge weights for self-loops
      do not represent already reduced communities you may want to remove
      the self-loops before inputting that graph.
  
      Parameters
      ----------
      G : NetworkX graph
      weight : string or None, optional (default="weight")
          The name of an edge attribute that holds the numerical value
          used as a weight. If None then each edge has weight 1.
      resolution : float, optional (default=1)
          If resolution is less than 1, the algorithm favors larger communities.
          Greater than 1 favors smaller communities
      threshold : float, optional (default=0.0000001)
          Modularity gain threshold for each level. If the gain of modularity
          between 2 levels of the algorithm is less than the given threshold
          then the algorithm stops and returns the resulting communities.
      seed : integer, random_state, or None (default)
          Indicator of random number generation state.
          See :ref:`Randomness<randomness>`.
  
      Returns
      -------
      list
          A list of sets (partition of `G`). Each set represents one community and contains
          all the nodes that constitute it.
  
      Examples
      --------
      >>> import networkx as nx
      >>> G = nx.petersen_graph()
      >>> nx.community.louvain_communities(G, seed=123)
      [{0, 4, 5, 7, 9}, {1, 2, 3, 6, 8}]
  
      Notes
      -----
      The order in which the nodes are considered can affect the final output. In the algorithm
      the ordering happens using a random shuffle.
  
      References
      ----------
      .. [1] Blondel, V.D. et al. Fast unfolding of communities in
         large networks. J. Stat. Mech 10008, 1-12(2008). https://doi.org/10.1088/1742-5468/2008/10/P10008
      .. [2] Traag, V.A., Waltman, L. & van Eck, N.J. From Louvain to Leiden: guaranteeing
         well-connected communities. Sci Rep 9, 5233 (2019). https://doi.org/10.1038/s41598-019-41695-z
      .. [3] Nicolas Dugué, Anthony Perez. Directed Louvain : maximizing modularity in directed networks.
          [Research Report] Université d’Orléans. 2015. hal-01231784. https://hal.archives-ouvertes.fr/hal-01231784
  
      See Also
      --------
      louvain_partitions
      """
  
      d = louvain_partitions(G, weight, resolution, threshold, seed)
      q = deque(d, maxlen=1)
      return q.pop()
  
file_path: networkx/networkx/algorithms/community/louvain.py
imports: from collections import defaultdict, deque
  import networkx
  from networkx.algorithms.community import modularity
  from networkx.utils import py_random_state
label_desc: Use image node_id 1 for calling a global function with example usage: louvain_communities(G, weight, resolution, threshold, seed) and returns: q