mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-09-12 04:01:35 +00:00
+32
-2
@@ -908,11 +908,19 @@ kg_viz.visualize_relationship_matrix(graph, output="html", file_path="relationsh
|
||||
#### Ontology Visualization
|
||||
```python
|
||||
from semantica.visualization import OntologyVisualizer
|
||||
from semantica.ontology import OntologyGenerator
|
||||
|
||||
# Initialize ontology visualizer
|
||||
onto_viz = OntologyVisualizer(color_scheme="default")
|
||||
|
||||
# Visualize class hierarchy
|
||||
# Option 1: Visualize from ontology generator result
|
||||
ontology_generator = OntologyGenerator()
|
||||
semantic_model = ontology_generator.generate_ontology(data)
|
||||
|
||||
# Visualize semantic model (handles both ontology and semantic network)
|
||||
onto_viz.visualize_semantic_model(semantic_model, output="html", file_path="semantic_model.html")
|
||||
|
||||
# Option 2: Visualize class hierarchy directly
|
||||
ontology = {
|
||||
"classes": classes,
|
||||
"properties": properties
|
||||
@@ -921,6 +929,15 @@ ontology = {
|
||||
# Hierarchy tree visualization
|
||||
onto_viz.visualize_hierarchy(ontology, output="html", file_path="ontology_hierarchy.html")
|
||||
|
||||
# Option 3: Visualize from semantic network (auto-extracts classes)
|
||||
from semantica.semantic_extract import SemanticNetworkExtractor
|
||||
extractor = SemanticNetworkExtractor()
|
||||
semantic_network = extractor.extract_network(text)
|
||||
|
||||
# Can visualize directly - will extract classes automatically
|
||||
onto_viz.visualize_hierarchy({"semantic_network": semantic_network},
|
||||
output="html", file_path="ontology_from_network.html")
|
||||
|
||||
# Property graph visualization
|
||||
onto_viz.visualize_properties(ontology, output="html", file_path="ontology_properties.html")
|
||||
|
||||
@@ -988,7 +1005,7 @@ from semantica.visualization import SemanticNetworkVisualizer
|
||||
# Initialize semantic network visualizer
|
||||
sem_net_viz = SemanticNetworkVisualizer()
|
||||
|
||||
# Visualize semantic network
|
||||
# Option 1: Visualize SemanticNetwork dataclass object
|
||||
from semantica.semantic_extract import SemanticNetworkExtractor
|
||||
extractor = SemanticNetworkExtractor()
|
||||
semantic_network = extractor.extract_network(text)
|
||||
@@ -996,6 +1013,19 @@ semantic_network = extractor.extract_network(text)
|
||||
# Network graph
|
||||
sem_net_viz.visualize_network(semantic_network, output="html", file_path="semantic_network.html")
|
||||
|
||||
# Option 2: Visualize from dictionary format
|
||||
semantic_network_dict = {
|
||||
"nodes": [{"id": "n1", "label": "Node 1", "type": "Entity"}],
|
||||
"edges": [{"source": "n1", "target": "n2", "label": "relatedTo"}]
|
||||
}
|
||||
sem_net_viz.visualize_network(semantic_network_dict, output="html", file_path="semantic_network.html")
|
||||
|
||||
# Option 3: Visualize from semantic model (ontology generator result)
|
||||
from semantica.ontology import OntologyGenerator
|
||||
generator = OntologyGenerator()
|
||||
semantic_model = generator.generate_ontology(data)
|
||||
sem_net_viz.visualize_network(semantic_model.semantic_network, output="html", file_path="semantic_model_network.html")
|
||||
|
||||
# Node type distribution
|
||||
sem_net_viz.visualize_node_types(semantic_network, output="html", file_path="node_types.html")
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@ class OntologyVisualizer:
|
||||
Visualize class hierarchy as tree.
|
||||
|
||||
Args:
|
||||
ontology: Ontology dictionary with classes
|
||||
ontology: Ontology dictionary with classes, or SemanticNetwork object,
|
||||
or ontology generator result
|
||||
output: Output type ("interactive", "html", "png", "svg", "dot")
|
||||
file_path: Output file path
|
||||
**options: Additional options
|
||||
@@ -78,10 +79,24 @@ class OntologyVisualizer:
|
||||
"""
|
||||
self.logger.info("Visualizing ontology class hierarchy")
|
||||
|
||||
classes = ontology.get("classes", [])
|
||||
# Handle different input formats
|
||||
if hasattr(ontology, "classes"):
|
||||
# OntologyGenerator result object
|
||||
classes = ontology.classes if hasattr(ontology, "classes") else []
|
||||
elif isinstance(ontology, dict):
|
||||
classes = ontology.get("classes", ontology.get("class_definitions", []))
|
||||
else:
|
||||
classes = []
|
||||
|
||||
# If no classes, try to extract from semantic network
|
||||
if not classes and isinstance(ontology, dict):
|
||||
# Check if it's a semantic model or semantic network
|
||||
semantic_network = ontology.get("semantic_network", ontology.get("network"))
|
||||
if semantic_network:
|
||||
classes = self._extract_classes_from_semantic_network(semantic_network)
|
||||
|
||||
if not classes:
|
||||
raise ProcessingError("No classes found in ontology")
|
||||
raise ProcessingError("No classes found in ontology. Please provide classes or a semantic network.")
|
||||
|
||||
# If output is dot and graphviz is available, use it
|
||||
if output == "dot" and graphviz is not None and file_path:
|
||||
@@ -103,7 +118,7 @@ class OntologyVisualizer:
|
||||
Visualize property graph showing properties and their domains/ranges.
|
||||
|
||||
Args:
|
||||
ontology: Ontology dictionary
|
||||
ontology: Ontology dictionary, SemanticNetwork, or ontology generator result
|
||||
output: Output type
|
||||
file_path: Output file path
|
||||
**options: Additional options
|
||||
@@ -113,8 +128,22 @@ class OntologyVisualizer:
|
||||
"""
|
||||
self.logger.info("Visualizing ontology properties")
|
||||
|
||||
properties = ontology.get("properties", [])
|
||||
classes = ontology.get("classes", [])
|
||||
# Handle different input formats
|
||||
if hasattr(ontology, "properties"):
|
||||
properties = ontology.properties if hasattr(ontology, "properties") else []
|
||||
classes = ontology.classes if hasattr(ontology, "classes") else []
|
||||
elif isinstance(ontology, dict):
|
||||
properties = ontology.get("properties", ontology.get("property_definitions", []))
|
||||
classes = ontology.get("classes", ontology.get("class_definitions", []))
|
||||
else:
|
||||
properties = []
|
||||
classes = []
|
||||
|
||||
# If no properties, try to extract from semantic network
|
||||
if not properties and isinstance(ontology, dict):
|
||||
semantic_network = ontology.get("semantic_network", ontology.get("network"))
|
||||
if semantic_network:
|
||||
properties = self._extract_properties_from_semantic_network(semantic_network)
|
||||
|
||||
if not properties:
|
||||
raise ProcessingError("No properties found in ontology")
|
||||
@@ -350,17 +379,129 @@ class OntologyVisualizer:
|
||||
|
||||
def _calculate_class_depth(self, cls: Dict[str, Any], all_classes: List[Dict[str, Any]]) -> int:
|
||||
"""Calculate depth of class in hierarchy."""
|
||||
parent = cls.get("parent") or cls.get("subClassOf")
|
||||
parent = cls.get("parent") or cls.get("subClassOf") or cls.get("superClassOf")
|
||||
if not parent:
|
||||
return 1
|
||||
|
||||
# Find parent class
|
||||
for p_cls in all_classes:
|
||||
if (p_cls.get("name") or p_cls.get("uri", "")) == parent:
|
||||
cls_name = p_cls.get("name") or p_cls.get("uri") or p_cls.get("label", "")
|
||||
if cls_name == parent:
|
||||
return 1 + self._calculate_class_depth(p_cls, all_classes)
|
||||
|
||||
return 1
|
||||
|
||||
def _extract_classes_from_semantic_network(self, semantic_network: Any) -> List[Dict[str, Any]]:
|
||||
"""Extract class definitions from semantic network."""
|
||||
classes = []
|
||||
|
||||
# Handle SemanticNetwork dataclass
|
||||
if hasattr(semantic_network, "nodes"):
|
||||
# Group nodes by type to form classes
|
||||
type_groups = {}
|
||||
for node in semantic_network.nodes:
|
||||
node_type = node.type if hasattr(node, "type") else "Unknown"
|
||||
if node_type not in type_groups:
|
||||
type_groups[node_type] = []
|
||||
type_groups[node_type].append(node)
|
||||
|
||||
# Create class definitions
|
||||
for node_type, nodes in type_groups.items():
|
||||
classes.append({
|
||||
"name": node_type,
|
||||
"label": node_type,
|
||||
"uri": f"#{node_type}",
|
||||
"instances": len(nodes),
|
||||
"properties": list(set(
|
||||
prop for node in nodes
|
||||
for prop in (node.properties.keys() if hasattr(node, "properties") else [])
|
||||
))
|
||||
})
|
||||
|
||||
# Handle dictionary format
|
||||
elif isinstance(semantic_network, dict):
|
||||
nodes = semantic_network.get("nodes", [])
|
||||
type_groups = {}
|
||||
for node in nodes:
|
||||
node_type = node.get("type") if isinstance(node, dict) else (
|
||||
node.type if hasattr(node, "type") else "Unknown"
|
||||
)
|
||||
if node_type not in type_groups:
|
||||
type_groups[node_type] = []
|
||||
type_groups[node_type].append(node)
|
||||
|
||||
for node_type, nodes in type_groups.items():
|
||||
classes.append({
|
||||
"name": node_type,
|
||||
"label": node_type,
|
||||
"uri": f"#{node_type}",
|
||||
"instances": len(nodes)
|
||||
})
|
||||
|
||||
return classes
|
||||
|
||||
def visualize_semantic_model(
|
||||
self,
|
||||
semantic_model: Any,
|
||||
output: str = "interactive",
|
||||
file_path: Optional[Union[str, Path]] = None,
|
||||
**options
|
||||
) -> Optional[Any]:
|
||||
"""
|
||||
Visualize semantic model from ontology generator.
|
||||
|
||||
This method extracts and visualizes both the ontology structure
|
||||
and the underlying semantic network that generated it.
|
||||
|
||||
Args:
|
||||
semantic_model: Semantic model from OntologyGenerator or semantic network
|
||||
output: Output type
|
||||
file_path: Output file path
|
||||
**options: Additional options
|
||||
|
||||
Returns:
|
||||
Visualization figure or None
|
||||
"""
|
||||
self.logger.info("Visualizing semantic model")
|
||||
|
||||
# Handle OntologyGenerator result
|
||||
if hasattr(semantic_model, "semantic_network"):
|
||||
# Visualize the semantic network
|
||||
from .semantic_network_visualizer import SemanticNetworkVisualizer
|
||||
sem_net_viz = SemanticNetworkVisualizer(**self.config)
|
||||
return sem_net_viz.visualize_network(
|
||||
semantic_model.semantic_network,
|
||||
output=output,
|
||||
file_path=file_path,
|
||||
**options
|
||||
)
|
||||
|
||||
# Handle dictionary format with semantic_network
|
||||
elif isinstance(semantic_model, dict):
|
||||
if "semantic_network" in semantic_model:
|
||||
from .semantic_network_visualizer import SemanticNetworkVisualizer
|
||||
sem_net_viz = SemanticNetworkVisualizer(**self.config)
|
||||
return sem_net_viz.visualize_network(
|
||||
semantic_model["semantic_network"],
|
||||
output=output,
|
||||
file_path=file_path,
|
||||
**options
|
||||
)
|
||||
# Otherwise treat as ontology
|
||||
else:
|
||||
return self.visualize_structure(semantic_model, output, file_path, **options)
|
||||
|
||||
# Handle direct semantic network
|
||||
else:
|
||||
from .semantic_network_visualizer import SemanticNetworkVisualizer
|
||||
sem_net_viz = SemanticNetworkVisualizer(**self.config)
|
||||
return sem_net_viz.visualize_network(
|
||||
semantic_model,
|
||||
output=output,
|
||||
file_path=file_path,
|
||||
**options
|
||||
)
|
||||
|
||||
def _visualize_hierarchy_plotly(
|
||||
self,
|
||||
hierarchy: Dict[str, List[str]],
|
||||
@@ -522,6 +663,46 @@ class OntologyVisualizer:
|
||||
kg_viz = KGVisualizer(**self.config)
|
||||
return kg_viz._visualize_network_plotly(nodes, edges, output, file_path, **options)
|
||||
|
||||
def _extract_properties_from_semantic_network(self, semantic_network: Any) -> List[Dict[str, Any]]:
|
||||
"""Extract property definitions from semantic network."""
|
||||
properties = []
|
||||
|
||||
# Handle SemanticNetwork dataclass
|
||||
if hasattr(semantic_network, "edges"):
|
||||
# Extract unique edge labels as properties
|
||||
property_types = set()
|
||||
for edge in semantic_network.edges:
|
||||
edge_label = edge.label if hasattr(edge, "label") else ""
|
||||
if edge_label and edge_label not in property_types:
|
||||
property_types.add(edge_label)
|
||||
properties.append({
|
||||
"name": edge_label,
|
||||
"label": edge_label,
|
||||
"uri": f"#{edge_label}",
|
||||
"domain": "Thing", # Default domain
|
||||
"range": "Thing" # Default range
|
||||
})
|
||||
|
||||
# Handle dictionary format
|
||||
elif isinstance(semantic_network, dict):
|
||||
edges = semantic_network.get("edges", semantic_network.get("relationships", []))
|
||||
property_types = set()
|
||||
for edge in edges:
|
||||
edge_label = edge.get("label") if isinstance(edge, dict) else (
|
||||
edge.label if hasattr(edge, "label") else ""
|
||||
)
|
||||
if edge_label and edge_label not in property_types:
|
||||
property_types.add(edge_label)
|
||||
properties.append({
|
||||
"name": edge_label,
|
||||
"label": edge_label,
|
||||
"uri": f"#{edge_label}",
|
||||
"domain": edge.get("domain", "Thing") if isinstance(edge, dict) else "Thing",
|
||||
"range": edge.get("range", "Thing") if isinstance(edge, dict) else "Thing"
|
||||
})
|
||||
|
||||
return properties
|
||||
|
||||
def _visualize_structure_plotly(
|
||||
self,
|
||||
nodes: List[Dict[str, Any]],
|
||||
|
||||
@@ -44,8 +44,14 @@ class SemanticNetworkVisualizer:
|
||||
"""
|
||||
Visualize semantic network.
|
||||
|
||||
Supports multiple input formats:
|
||||
- SemanticNetwork dataclass object
|
||||
- Dictionary with 'nodes' and 'edges' keys
|
||||
- Semantic model from ontology generator
|
||||
- Entities and relationships lists
|
||||
|
||||
Args:
|
||||
semantic_network: SemanticNetwork object
|
||||
semantic_network: SemanticNetwork object, dict, or semantic model
|
||||
output: Output type
|
||||
file_path: Output file path
|
||||
**options: Additional options
|
||||
@@ -57,40 +63,103 @@ class SemanticNetworkVisualizer:
|
||||
|
||||
# Extract nodes and edges from semantic network
|
||||
nodes = []
|
||||
if hasattr(semantic_network, "nodes"):
|
||||
edges = []
|
||||
|
||||
# Handle SemanticNetwork dataclass
|
||||
if hasattr(semantic_network, "nodes") and hasattr(semantic_network, "edges"):
|
||||
for node in semantic_network.nodes:
|
||||
nodes.append({
|
||||
"id": node.id,
|
||||
"label": node.label,
|
||||
"type": node.type,
|
||||
"metadata": node.metadata
|
||||
"id": getattr(node, "id", ""),
|
||||
"label": getattr(node, "label", ""),
|
||||
"type": getattr(node, "type", "entity"),
|
||||
"metadata": getattr(node, "metadata", {}) or {},
|
||||
"properties": getattr(node, "properties", {}) or {}
|
||||
})
|
||||
elif isinstance(semantic_network, dict):
|
||||
for node in semantic_network.get("nodes", []):
|
||||
nodes.append({
|
||||
"id": node.get("id", ""),
|
||||
"label": node.get("label", ""),
|
||||
"type": node.get("type", ""),
|
||||
"metadata": node.get("metadata", {})
|
||||
})
|
||||
|
||||
edges = []
|
||||
if hasattr(semantic_network, "edges"):
|
||||
|
||||
for edge in semantic_network.edges:
|
||||
edges.append({
|
||||
"source": edge.source,
|
||||
"target": edge.target,
|
||||
"label": edge.label,
|
||||
"metadata": edge.metadata
|
||||
"source": getattr(edge, "source", ""),
|
||||
"target": getattr(edge, "target", ""),
|
||||
"label": getattr(edge, "label", ""),
|
||||
"type": getattr(edge, "label", ""),
|
||||
"metadata": getattr(edge, "metadata", {}) or {},
|
||||
"properties": getattr(edge, "properties", {}) or {}
|
||||
})
|
||||
|
||||
# Handle dictionary format
|
||||
elif isinstance(semantic_network, dict):
|
||||
for edge in semantic_network.get("edges", []):
|
||||
edges.append({
|
||||
"source": edge.get("source", ""),
|
||||
"target": edge.get("target", ""),
|
||||
"label": edge.get("label", ""),
|
||||
"metadata": edge.get("metadata", {})
|
||||
})
|
||||
# Check if it's a semantic model from ontology generator
|
||||
if "semantic_network" in semantic_network:
|
||||
semantic_network = semantic_network["semantic_network"]
|
||||
|
||||
# Extract nodes
|
||||
network_nodes = semantic_network.get("nodes", [])
|
||||
for node in network_nodes:
|
||||
if isinstance(node, dict):
|
||||
nodes.append({
|
||||
"id": node.get("id", node.get("uri", "")),
|
||||
"label": node.get("label", node.get("name", "")),
|
||||
"type": node.get("type", node.get("class", "entity")),
|
||||
"metadata": node.get("metadata", {}),
|
||||
"properties": node.get("properties", {})
|
||||
})
|
||||
elif hasattr(node, "id"):
|
||||
nodes.append({
|
||||
"id": getattr(node, "id", ""),
|
||||
"label": getattr(node, "label", ""),
|
||||
"type": getattr(node, "type", "entity"),
|
||||
"metadata": getattr(node, "metadata", {}) or {},
|
||||
"properties": getattr(node, "properties", {}) or {}
|
||||
})
|
||||
|
||||
# Extract edges
|
||||
network_edges = semantic_network.get("edges", semantic_network.get("relationships", []))
|
||||
for edge in network_edges:
|
||||
if isinstance(edge, dict):
|
||||
edges.append({
|
||||
"source": edge.get("source", edge.get("subject", "")),
|
||||
"target": edge.get("target", edge.get("object", "")),
|
||||
"label": edge.get("label", edge.get("predicate", edge.get("type", ""))),
|
||||
"type": edge.get("type", edge.get("predicate", "")),
|
||||
"metadata": edge.get("metadata", {}),
|
||||
"properties": edge.get("properties", {})
|
||||
})
|
||||
elif hasattr(edge, "source"):
|
||||
edges.append({
|
||||
"source": getattr(edge, "source", ""),
|
||||
"target": getattr(edge, "target", ""),
|
||||
"label": getattr(edge, "label", ""),
|
||||
"type": getattr(edge, "label", ""),
|
||||
"metadata": getattr(edge, "metadata", {}) or {},
|
||||
"properties": getattr(edge, "properties", {}) or {}
|
||||
})
|
||||
|
||||
# Handle entities/relationships format (for semantic models)
|
||||
elif isinstance(semantic_network, (list, tuple)):
|
||||
# Assume it's a list of entities/relationships
|
||||
for item in semantic_network:
|
||||
if isinstance(item, dict):
|
||||
if "source" in item or "subject" in item:
|
||||
edges.append({
|
||||
"source": item.get("source", item.get("subject", "")),
|
||||
"target": item.get("target", item.get("object", "")),
|
||||
"label": item.get("label", item.get("predicate", item.get("type", ""))),
|
||||
"type": item.get("type", ""),
|
||||
"metadata": item.get("metadata", {})
|
||||
})
|
||||
else:
|
||||
nodes.append({
|
||||
"id": item.get("id", item.get("uri", "")),
|
||||
"label": item.get("label", item.get("name", "")),
|
||||
"type": item.get("type", "entity"),
|
||||
"metadata": item.get("metadata", {})
|
||||
})
|
||||
|
||||
if not nodes and not edges:
|
||||
raise ProcessingError(
|
||||
"Could not extract nodes and edges from semantic network. "
|
||||
"Please provide a SemanticNetwork object, dict with 'nodes'/'edges', or semantic model."
|
||||
)
|
||||
|
||||
# Use KG visualizer for network visualization
|
||||
from .kg_visualizer import KGVisualizer
|
||||
|
||||
Reference in New Issue
Block a user