knowledge-graph-engine / src /visualizer.py
Yogesh18018's picture
Upload folder using huggingface_hub
09141b1 verified
Raw
History Blame Contribute Delete
5.38 kB
"""
Graph Visualization Utilities
==============================
Functions for rendering knowledge graphs as interactive HTML (PyVis)
and statistical charts (Plotly).
"""
from typing import Dict, Any
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
from src.graph_builder import KnowledgeGraph, ENTITY_COLORS
# ------------------------------------------------------------------
# PyVis interactive graph
# ------------------------------------------------------------------
def create_pyvis_graph(kg: KnowledgeGraph, height: str = "650px") -> str:
"""
Render *kg* as an interactive PyVis graph and return raw HTML.
The HTML string can be embedded directly with
``streamlit.components.v1.html()``.
"""
net = kg.to_pyvis(height=height)
# Generate HTML string (PyVis >= 0.3 supports generate_html)
try:
html = net.generate_html()
except AttributeError:
# Fallback for older pyvis
import tempfile, os
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".html", mode="w", encoding="utf-8")
net.save_graph(tmp.name)
tmp.close()
with open(tmp.name, "r", encoding="utf-8") as f:
html = f.read()
os.unlink(tmp.name)
return html
# ------------------------------------------------------------------
# Plotly statistical charts
# ------------------------------------------------------------------
_CHART_LAYOUT = dict(
paper_bgcolor="#0a0a0a",
plot_bgcolor="#111111",
font_color="white",
font_size=13,
margin=dict(l=40, r=40, t=50, b=40),
)
def graph_stats_chart(stats: Dict[str, Any]) -> go.Figure:
"""
Create a combined Plotly figure with:
- Entity type distribution (bar)
- Relationship type distribution (bar)
"""
entity_counts = stats.get("entity_type_counts", {})
relation_counts = stats.get("relation_type_counts", {})
fig = make_subplots(
rows=1,
cols=2,
subplot_titles=("Entity Types", "Relationship Types"),
horizontal_spacing=0.15,
)
# --- Entity type bar chart ---
if entity_counts:
types = list(entity_counts.keys())
counts = list(entity_counts.values())
colors = [ENTITY_COLORS.get(t, "#888888") for t in types]
fig.add_trace(
go.Bar(
x=types,
y=counts,
marker_color=colors,
text=counts,
textposition="outside",
name="Entity Types",
showlegend=False,
),
row=1,
col=1,
)
# --- Relationship type bar chart ---
if relation_counts:
rels = list(relation_counts.keys())
rcounts = list(relation_counts.values())
fig.add_trace(
go.Bar(
x=rels,
y=rcounts,
marker_color="#00d4ff",
text=rcounts,
textposition="outside",
name="Relationships",
showlegend=False,
),
row=1,
col=2,
)
fig.update_layout(
height=370,
**_CHART_LAYOUT,
)
fig.update_xaxes(tickangle=-40)
return fig
def centrality_chart(top_nodes: list) -> go.Figure:
"""
Horizontal bar chart of the top-N most central nodes.
"""
if not top_nodes:
fig = go.Figure()
fig.update_layout(
title="No nodes to display",
**_CHART_LAYOUT,
height=300,
)
return fig
names = [n[0] for n in reversed(top_nodes)]
values = [round(n[1], 4) for n in reversed(top_nodes)]
fig = go.Figure(
go.Bar(
x=values,
y=names,
orientation="h",
marker=dict(
color=values,
colorscale=[[0, "#0a0a0a"], [0.5, "#00d4ff"], [1, "#00ff88"]],
),
text=[f"{v:.3f}" for v in values],
textposition="outside",
)
)
fig.update_layout(
title="Top Nodes by Degree Centrality",
xaxis_title="Centrality Score",
height=max(300, len(top_nodes) * 35 + 100),
**_CHART_LAYOUT,
)
return fig
def community_chart(communities: list) -> go.Figure:
"""Pie chart showing community sizes."""
if not communities:
fig = go.Figure()
fig.update_layout(title="No communities detected", **_CHART_LAYOUT, height=300)
return fig
labels = [f"Community {i+1}" for i in range(len(communities))]
sizes = [len(c) for c in communities]
fig = go.Figure(
go.Pie(
labels=labels,
values=sizes,
hole=0.45,
marker=dict(
colors=["#00ff88", "#00d4ff", "#a855f7", "#f59e0b", "#ec4899",
"#6366f1", "#14b8a6", "#f43f5e", "#84cc16", "#06b6d4"],
),
textinfo="label+percent",
textfont_size=12,
)
)
fig.update_layout(
title="Community Distribution",
height=370,
**_CHART_LAYOUT,
)
return fig