Spaces:
Paused
Paused
File size: 6,043 Bytes
18a3a92 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | # metric_visualizations.py
import networkx as nx
import random
def get_cycle_highlights(G):
"""
Identifies all simple cycles and assigns a distinct neon color to each.
Returns a list of dictionaries containing node/edge sets and colors.
"""
try:
cycles = list(nx.simple_cycles(G))
except ImportError:
return []
highlights = []
# high-contrast "neon" colors for the glow effect
neon_colors = [
"#FF1493", # DeepPink
"#00FF00", # Lime
"#00FFFF", # Cyan
"#FFD700", # Gold
"#FF4500", # OrangeRed
"#9400D3", # DarkViolet
"#32CD32", # LimeGreen
"#1E90FF", # DodgerBlue
]
for i, path in enumerate(cycles):
color = neon_colors[i % len(neon_colors)]
# Build the edge list for this specific cycle
cycle_edges = []
for j in range(len(path)):
u = path[j]
v = path[(j + 1) % len(path)] # connect last node back to first
cycle_edges.append((u, v))
highlights.append({
"nodes": path,
"edges": cycle_edges,
"color": color,
"width": 8 # offset width slightly so overlapping cycles are visible
})
return highlights
import networkx as nx
def get_single_cycle_highlight(G, cycle_index):
"""
Highlights ONLY the cycle at the specified index, using a distinct color.
"""
try:
cycles = list(nx.simple_cycles(G))
if cycle_index < 0 or cycle_index >= len(cycles):
return []
path = cycles[cycle_index]
# Same as 'get_cycle_highlights'
neon_colors = [
"#FF1493", # DeepPink
"#00C000", # Darker Lime (Readable on white)
"#DE52D0", #
"#FFD700", # Gold
"#FF4500", # OrangeRed
"#9400D3", # DarkViolet
"#32CD32", # LimeGreen
"#060C12", # DodgerBlue
]
color = neon_colors[cycle_index % len(neon_colors)]
cycle_edges = []
for j in range(len(path)):
u = path[j]
v = path[(j + 1) % len(path)]
cycle_edges.append((u, v))
return [{
"nodes": path,
"edges": cycle_edges,
"color": color,
"width": 10
}]
except Exception as e:
print(f"Error highlighting cycle {cycle_index}: {e}")
return []
def get_interdependence_highlights(G):
"""
Identifies edges that cross agent boundaries (the drivers of interdependence).
"""
cross_edges = []
involved_nodes = set()
for u, v in G.edges():
agent_u = G.nodes[u].get('agent', 'Unassigned')
agent_v = G.nodes[v].get('agent', 'Unassigned')
if agent_u != agent_v:
cross_edges.append((u, v))
involved_nodes.add(u)
involved_nodes.add(v)
if not cross_edges:
return []
return [{
"nodes": list(involved_nodes),
"edges": cross_edges,
"color": "#FF0000", # highlight color of interdependency
"width": 8
}]
def get_modularity_highlights(G):
"""
Detects communities and assigns a unique color to each group.
Colors nodes and 'intra-community' edges (edges within the same group).
"""
try:
# 1. Detect Communities
# Return list of sets: [{n1, n2}, {n3, n4}...]
communities = nx.community.greedy_modularity_communities(G.to_undirected())
highlights = []
# 2. Define Palette
community_colors = [
"#FF6B6B", # Red
"#4ECDC4", # Teal
"#45B7D1", # Blue
"#FFA07A", # Light Salmon
"#98D8C8", # Pale Green
"#F7DC6F", # Yellow
"#BB8FCE", # Purple
"#B2BABB", # Gray
]
for i, community_set in enumerate(communities):
color = community_colors[i % len(community_colors)]
nodes_list = list(community_set)
# Find edges that stay completely within this community
intra_edges = []
for u in nodes_list:
for v in nodes_list:
if G.has_edge(u, v):
intra_edges.append((u, v))
# Create Highlight Group
highlights.append({
"nodes": nodes_list,
"edges": intra_edges,
"color": color,
"width": 10
})
return highlights
except Exception as e:
print(f"Modularity Vis Error: {e}")
return []
def get_single_modularity_highlight(G, group_index):
"""
Highlights ONLY the specific community group at the given index.
"""
try:
# 1. Detect Communities
communities = list(nx.community.greedy_modularity_communities(G.to_undirected()))
# Sort by size
communities.sort(key=len, reverse=True)
if group_index < 0 or group_index >= len(communities):
return []
target_group = list(communities[group_index])
# 2. Match Colors
community_colors = [
"#FF6B6B", "#4ECDC4", "#45B7D1", "#FFA07A",
"#98D8C8", "#F7DC6F", "#BB8FCE", "#B2BABB"
]
color = community_colors[group_index % len(community_colors)]
# 3. Find edges within this group
intra_edges = []
for u in target_group:
for v in target_group:
if G.has_edge(u, v):
intra_edges.append((u, v))
return [{
"nodes": target_group,
"edges": intra_edges,
"color": color,
"width": 10
}]
except Exception as e:
print(f"Modularity Single Error: {e}")
return [] |