You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While working on a project, I found this package called leidenalg. Based on my experience, it produces higher quality communities than Networkx's Louvain and tends to be faster. Here's an example of how it can be used to generate communities from a networkx graph object:
importnetworkxasnximportigraphasigimportleidenalgaslaimportcytoolz.curriedastlzdef_create_subgraph(
graph: nx.DiGraph,
nodes: Iterable[int],
name: str|int|None=None,
largest: bool=False,
) ->nx.DiGraph:
"""Create a subgraph from a networkx.DiGraph and list of nodes."""sub_graph=graph.__class__()
sub_graph.add_nodes_from((n, graph.nodes[n]) forninnodes)
ifsub_graph.is_multigraph():
sub_graph.add_edges_from(
(n, nbr, key, d)
forn, nbrsingraph.adj.items()
ifninnodesfornbr, keydictinnbrs.items()
ifnbrinnodesforkey, dinkeydict.items()
)
else:
sub_graph.add_edges_from(
(n, nbr, d)
forn, nbrsingraph.adj.items()
ifninnodesfornbr, dinnbrs.items()
ifnbrinnodes
)
sub_graph.graph.update(graph.graph) # pyright: ignore[reportGeneralTypeIssues]ifnameisnotNone:
nx.function.set_edge_attributes(sub_graph, name, "community")
iflargest:
ifgraph.is_directed():
conn=max(nx.weakly_connected_components(sub_graph), key=len)
else:
conn=max(nx.connected_components(sub_graph), key=len)
sub_graph=_create_subgraph(sub_graph, conn, name, largest=False)
returnnx.algorithms.tree.minimum_spanning_tree(sub_graph.to_undirected()).to_directed()
defcommunities(graph: nx.DiGraph, resolution: float=1e-5) ->list[nx.DiGraph]:
"""Get communities from a street network. Parameters ---------- graph : nx.DiGraph The street network. resolution : float, optional A higher resolution favors detecting smaller, more granular communities, while a lower resolution tends to merge smaller communities into larger ones. Defaults to ``1e-5``. Returns ------- list of networkx.DiGraph The communities as a list of ``networkx.DiGraph``. """graph_ig=ig.Graph.from_networkx(graph.to_undirected())
graph_ig.vs["community"] =la.find_partition(
graph_ig,
la.CPMVertexPartition,
seed=42,
resolution_parameter=resolution,
).membershipgnx=graph_ig.to_networkx()
comm=nx.get_node_attributes(gnx, "community")
nodes_nx=tlz.merge_with(list, ({p: i} fori, pincomm.items()))
return [
_create_subgraph(graph, c, i, largest=True)
fori, cinnodes_nx.items() # pyright: ignore[reportArgumentType]
]
The text was updated successfully, but these errors were encountered:
Thanks @szhorvat - igraph looks super helpful, as ultimately, I would envisage offering a range of options for a user to further customise the communities. I think it is fine to have just modularity objective and use of undirected graphs in this case - indeed that is how this community detection step currently works. The only point at which swmmanywhere requires a directed graph is for shortest path optimization of the pipe network topology, since slope is a directed variable. But community detection in this step is more focussed on eliminating or retaining potential pipe-carrying links based on the hydrological subbasins and the road network communities (more info in #227 ).
While working on a project, I found this package called
leidenalg
. Based on my experience, it produces higher quality communities than Networkx's Louvain and tends to be faster. Here's an example of how it can be used to generate communities from anetworkx
graph object:The text was updated successfully, but these errors were encountered: