Spaces:
Running
Running
Update src/visualization.py
Browse files- src/visualization.py +42 -55
src/visualization.py
CHANGED
@@ -1206,114 +1206,101 @@ def display_graph_visualization(knowledge_graph, central_entity=None, max_distan
|
|
1206 |
|
1207 |
def visualize_path(path_info, ontology_manager):
|
1208 |
"""Visualize a semantic path between entities with enhanced graphics and details."""
|
|
|
|
|
|
|
|
|
|
|
1209 |
if not path_info or "path" not in path_info:
|
1210 |
st.warning("No path information available.")
|
1211 |
return
|
1212 |
-
|
1213 |
st.subheader("🔄 Semantic Path Visualization")
|
1214 |
-
|
1215 |
path = path_info["path"]
|
1216 |
-
|
1217 |
# Get entity information for each node in the path
|
1218 |
entities = {}
|
1219 |
all_nodes = set()
|
1220 |
-
|
1221 |
-
# Add source and target
|
1222 |
if "source" in path_info:
|
1223 |
source_id = path_info["source"]
|
1224 |
all_nodes.add(source_id)
|
1225 |
entities[source_id] = ontology_manager.get_entity_info(source_id)
|
1226 |
-
|
1227 |
if "target" in path_info:
|
1228 |
target_id = path_info["target"]
|
1229 |
all_nodes.add(target_id)
|
1230 |
entities[target_id] = ontology_manager.get_entity_info(target_id)
|
1231 |
-
|
1232 |
-
# Add all entities in the path
|
1233 |
for edge in path:
|
1234 |
source_id = edge["source"]
|
1235 |
target_id = edge["target"]
|
1236 |
all_nodes.add(source_id)
|
1237 |
all_nodes.add(target_id)
|
1238 |
-
|
1239 |
if source_id not in entities:
|
1240 |
entities[source_id] = ontology_manager.get_entity_info(source_id)
|
1241 |
-
|
1242 |
if target_id not in entities:
|
1243 |
entities[target_id] = ontology_manager.get_entity_info(target_id)
|
1244 |
-
|
1245 |
-
# Create tabs for different views
|
1246 |
tab1, tab2, tab3 = st.tabs(["Path Visualization", "Entity Details", "Path Summary"])
|
1247 |
-
|
1248 |
with tab1:
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1252 |
with tab2:
|
1253 |
-
# Display details of entities in the path
|
1254 |
st.markdown("### Entities in Path")
|
1255 |
-
|
1256 |
-
# Group entities by type
|
1257 |
entities_by_type = defaultdict(list)
|
1258 |
for entity_id in all_nodes:
|
1259 |
entity_info = entities.get(entity_id, {})
|
1260 |
entity_type = entity_info.get("class_type", entity_info.get("class", "Unknown"))
|
1261 |
entities_by_type[entity_type].append((entity_id, entity_info))
|
1262 |
-
|
1263 |
-
# Create an expander for each entity type
|
1264 |
for entity_type, entity_list in entities_by_type.items():
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
st.markdown(props_markdown)
|
1273 |
-
|
1274 |
-
st.markdown("---")
|
1275 |
-
|
1276 |
with tab3:
|
1277 |
-
# Display textual summary of the path
|
1278 |
st.markdown("### Path Description")
|
1279 |
-
|
1280 |
-
# If path_info has text, use it
|
1281 |
if "text" in path_info and path_info["text"]:
|
1282 |
st.markdown(f"**Path:** {path_info['text']}")
|
1283 |
else:
|
1284 |
-
# Otherwise, generate a description
|
1285 |
path_steps = []
|
1286 |
for edge in path:
|
1287 |
source_id = edge["source"]
|
1288 |
target_id = edge["target"]
|
1289 |
relation = edge["type"]
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
if source_id in entities and "properties" in entities[source_id]:
|
1296 |
-
props = entities[source_id]["properties"]
|
1297 |
-
if "name" in props:
|
1298 |
-
source_name = props["name"]
|
1299 |
-
|
1300 |
-
if target_id in entities and "properties" in entities[target_id]:
|
1301 |
-
props = entities[target_id]["properties"]
|
1302 |
-
if "name" in props:
|
1303 |
-
target_name = props["name"]
|
1304 |
-
|
1305 |
path_steps.append(f"{source_name} **{relation}** {target_name}")
|
1306 |
-
|
1307 |
st.markdown(" → ".join(path_steps))
|
1308 |
-
|
1309 |
-
# Display relevant business rules
|
1310 |
relevant_rules = find_relevant_rules_for_path(path, ontology_manager)
|
1311 |
if relevant_rules:
|
1312 |
st.markdown("### Relevant Business Rules")
|
1313 |
for rule in relevant_rules:
|
1314 |
st.markdown(f"- **{rule['id']}**: {rule['description']}")
|
1315 |
|
1316 |
-
|
1317 |
def display_path_visualization(path, entities):
|
1318 |
"""Create an enhanced visual representation of the path."""
|
1319 |
if not path:
|
|
|
1206 |
|
1207 |
def visualize_path(path_info, ontology_manager):
|
1208 |
"""Visualize a semantic path between entities with enhanced graphics and details."""
|
1209 |
+
import streamlit as st
|
1210 |
+
import networkx as nx
|
1211 |
+
import matplotlib.pyplot as plt
|
1212 |
+
from collections import defaultdict
|
1213 |
+
|
1214 |
if not path_info or "path" not in path_info:
|
1215 |
st.warning("No path information available.")
|
1216 |
return
|
1217 |
+
|
1218 |
st.subheader("🔄 Semantic Path Visualization")
|
1219 |
+
|
1220 |
path = path_info["path"]
|
1221 |
+
|
1222 |
# Get entity information for each node in the path
|
1223 |
entities = {}
|
1224 |
all_nodes = set()
|
1225 |
+
|
|
|
1226 |
if "source" in path_info:
|
1227 |
source_id = path_info["source"]
|
1228 |
all_nodes.add(source_id)
|
1229 |
entities[source_id] = ontology_manager.get_entity_info(source_id)
|
1230 |
+
|
1231 |
if "target" in path_info:
|
1232 |
target_id = path_info["target"]
|
1233 |
all_nodes.add(target_id)
|
1234 |
entities[target_id] = ontology_manager.get_entity_info(target_id)
|
1235 |
+
|
|
|
1236 |
for edge in path:
|
1237 |
source_id = edge["source"]
|
1238 |
target_id = edge["target"]
|
1239 |
all_nodes.add(source_id)
|
1240 |
all_nodes.add(target_id)
|
1241 |
+
|
1242 |
if source_id not in entities:
|
1243 |
entities[source_id] = ontology_manager.get_entity_info(source_id)
|
1244 |
+
|
1245 |
if target_id not in entities:
|
1246 |
entities[target_id] = ontology_manager.get_entity_info(target_id)
|
1247 |
+
|
|
|
1248 |
tab1, tab2, tab3 = st.tabs(["Path Visualization", "Entity Details", "Path Summary"])
|
1249 |
+
|
1250 |
with tab1:
|
1251 |
+
G = nx.DiGraph()
|
1252 |
+
for edge in path:
|
1253 |
+
G.add_edge(edge["source"], edge["target"], label=edge["type"])
|
1254 |
+
|
1255 |
+
pos = nx.spring_layout(G)
|
1256 |
+
edge_labels = nx.get_edge_attributes(G, 'label')
|
1257 |
+
|
1258 |
+
fig, ax = plt.subplots()
|
1259 |
+
nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=2000, font_size=10, ax=ax)
|
1260 |
+
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_color='red', ax=ax)
|
1261 |
+
st.pyplot(fig)
|
1262 |
+
|
1263 |
with tab2:
|
|
|
1264 |
st.markdown("### Entities in Path")
|
1265 |
+
|
|
|
1266 |
entities_by_type = defaultdict(list)
|
1267 |
for entity_id in all_nodes:
|
1268 |
entity_info = entities.get(entity_id, {})
|
1269 |
entity_type = entity_info.get("class_type", entity_info.get("class", "Unknown"))
|
1270 |
entities_by_type[entity_type].append((entity_id, entity_info))
|
1271 |
+
|
|
|
1272 |
for entity_type, entity_list in entities_by_type.items():
|
1273 |
+
st.subheader(f"{entity_type} ({len(entity_list)})")
|
1274 |
+
for entity_id, entity_info in entity_list:
|
1275 |
+
st.markdown(f"- **{entity_id}**")
|
1276 |
+
for k, v in entity_info.get("properties", {}).items():
|
1277 |
+
st.markdown(f" - {k}: {v}")
|
1278 |
+
st.markdown("---")
|
1279 |
+
|
|
|
|
|
|
|
|
|
1280 |
with tab3:
|
|
|
1281 |
st.markdown("### Path Description")
|
|
|
|
|
1282 |
if "text" in path_info and path_info["text"]:
|
1283 |
st.markdown(f"**Path:** {path_info['text']}")
|
1284 |
else:
|
|
|
1285 |
path_steps = []
|
1286 |
for edge in path:
|
1287 |
source_id = edge["source"]
|
1288 |
target_id = edge["target"]
|
1289 |
relation = edge["type"]
|
1290 |
+
|
1291 |
+
source_name = entities[source_id].get("properties", {}).get("name", source_id)
|
1292 |
+
target_name = entities[target_id].get("properties", {}).get("name", target_id)
|
1293 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1294 |
path_steps.append(f"{source_name} **{relation}** {target_name}")
|
1295 |
+
|
1296 |
st.markdown(" → ".join(path_steps))
|
1297 |
+
|
|
|
1298 |
relevant_rules = find_relevant_rules_for_path(path, ontology_manager)
|
1299 |
if relevant_rules:
|
1300 |
st.markdown("### Relevant Business Rules")
|
1301 |
for rule in relevant_rules:
|
1302 |
st.markdown(f"- **{rule['id']}**: {rule['description']}")
|
1303 |
|
|
|
1304 |
def display_path_visualization(path, entities):
|
1305 |
"""Create an enhanced visual representation of the path."""
|
1306 |
if not path:
|