AI Terakoya Home›Machine Learning›Network Analysis›Chapter 4
🌐 EN | 🇯🇵 JP | Last sync: 2025-11-16
1. NetworkX Visualization
1.1 Integration with Matplotlib
NetworkX is fully integrated with matplotlib, making it suitable for static graph visualization.
import networkx as nx
import matplotlib.pyplot as plt
# Create graph
G = nx.karate_club_graph()
# Basic visualization
plt.figure(figsize=(12, 8))
nx.draw(G, with_labels=True, node_color='lightblue',
node_size=500, font_size=10, font_weight='bold')
plt.title('Karate Club Network')
plt.axis('off')
plt.tight_layout()
plt.savefig('karate_network.png', dpi=300, bbox_inches='tight')
plt.show()
1.2 Layout Algorithms
Selecting the appropriate layout is essential for understanding network structure.
import numpy as np
# Comparison of various layouts
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
layouts = {
'Spring': nx.spring_layout(G, k=0.3, iterations=50),
'Circular': nx.circular_layout(G),
'Kamada-Kawai': nx.kamada_kawai_layout(G),
'Spectral': nx.spectral_layout(G)
}
for ax, (name, pos) in zip(axes.flat, layouts.items()):
nx.draw(G, pos, ax=ax, node_color='lightblue',
node_size=300, with_labels=True, font_size=8)
ax.set_title(f'{name} Layout', fontsize=14, fontweight='bold')
ax.axis('off')
plt.tight_layout()
plt.savefig('layout_comparison.png', dpi=300, bbox_inches='tight')
plt.show()
# Layout algorithm selection criteria
# - Spring: General-purpose, force-directed balance (O(n²))
# - Circular: Visualizes symmetry (O(n))
# - Kamada-Kawai: More accurate distance representation (O(n³))
# - Spectral: Emphasizes community structure (O(n²))
1.3 Node and Edge Customization
Visually representing network attributes deepens data insights.
# Customization based on degree centrality
degree_centrality = nx.degree_centrality(G)
betweenness_centrality = nx.betweenness_centrality(G)
# Node size: degree centrality
node_sizes = [v * 3000 for v in degree_centrality.values()]
# Node color: betweenness centrality
node_colors = list(betweenness_centrality.values())
# Edge width: weight (in this example, product of degrees)
edge_weights = [G.degree(u) * G.degree(v) * 0.1
for u, v in G.edges()]
plt.figure(figsize=(14, 10))
pos = nx.spring_layout(G, k=0.3, seed=42)
# Draw
nx.draw_networkx_nodes(G, pos, node_size=node_sizes,
node_color=node_colors, cmap='YlOrRd',
alpha=0.9, edgecolors='black', linewidths=1.5)
nx.draw_networkx_edges(G, pos, width=edge_weights,
alpha=0.5, edge_color='gray')
nx.draw_networkx_labels(G, pos, font_size=9, font_weight='bold')
plt.title('Network Visualization Using Centrality Metrics',
fontsize=16, fontweight='bold')
plt.colorbar(plt.cm.ScalarMappable(cmap='YlOrRd'),
label='Betweenness Centrality', ax=plt.gca())
plt.axis('off')
plt.tight_layout()
plt.savefig('customized_network.png', dpi=300, bbox_inches='tight')
plt.show()
# Visualization best practices
# 1. Node size: Represents importance (centrality)
# 2. Node color: Represents category or continuous value
# 3. Edge width: Represents relationship strength
# 4. Layout: Choose according to data characteristics
2. Advanced Visualization Libraries
2.1 Interactive Visualization with PyVis
PyVis generates interactive network visualizations in HTML format.
from pyvis.network import Network
import networkx as nx
# Create PyVis network
net = Network(height='750px', width='100%', bgcolor='#222222',
font_color='white', notebook=True)
# Import from NetworkX graph
G = nx.karate_club_graph()
# Community detection
from networkx.algorithms import community
communities = community.greedy_modularity_communities(G)
community_map = {}
for i, comm in enumerate(communities):
for node in comm:
community_map[node] = i
# Set node colors and sizes
for node in G.nodes():
# Change color by community
color = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A'][community_map[node]]
# Change size by degree
size = G.degree(node) * 3
net.add_node(node, label=str(node), color=color, size=size,
title=f'Node {node}
Degree: {G.degree(node)}')
# Add edges
for edge in G.edges():
net.add_edge(edge[0], edge[1])
# Physics simulation settings
net.set_options("""
var options = {
"physics": {
"forceAtlas2Based": {
"gravitationalConstant": -50,
"centralGravity": 0.01,
"springLength": 100,
"springConstant": 0.08
},
"maxVelocity": 50,
"solver": "forceAtlas2Based",
"timestep": 0.35,
"stabilization": {"iterations": 150}
}
}
""")
# HTML output
net.save_graph('interactive_network.html')
print("Interactive graph saved to interactive_network.html")
2.2 Interactive Graphs with Plotly
Plotly provides highly customizable interactive graphs.
import plotly.graph_objects as go
# Calculate layout
pos = nx.spring_layout(G, k=0.5, seed=42)
# Create edge trace
edge_x = []
edge_y = []
for edge in G.edges():
x0, y0 = pos[edge[0]]
x1, y1 = pos[edge[1]]
edge_x.extend([x0, x1, None])
edge_y.extend([y0, y1, None])
edge_trace = go.Scatter(
x=edge_x, y=edge_y,
line=dict(width=0.5, color='#888'),
hoverinfo='none',
mode='lines')
# Create node trace
node_x = []
node_y = []
node_text = []
node_sizes = []
for node in G.nodes():
x, y = pos[node]
node_x.append(x)
node_y.append(y)
node_text.append(f'Node {node}
Degree: {G.degree(node)}')
node_sizes.append(G.degree(node) * 5)
node_trace = go.Scatter(
x=node_x, y=node_y,
mode='markers',
hoverinfo='text',
text=node_text,
marker=dict(
showscale=True,
colorscale='YlOrRd',
size=node_sizes,
color=[G.degree(node) for node in G.nodes()],
colorbar=dict(
thickness=15,
title='Node Degree',
xanchor='left',
titleside='right'
),
line=dict(width=2, color='white')))
# Create figure
fig = go.Figure(data=[edge_trace, node_trace],
layout=go.Layout(
title='Plotly Interactive Network',
showlegend=False,
hovermode='closest',
margin=dict(b=0, l=0, r=0, t=40),
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
plot_bgcolor='rgba(240,240,240,0.9)'))
fig.write_html('plotly_network.html')
fig.show()
2.3 Large-Scale Network Visualization
Large graphs with over 10,000 nodes require special approaches.
# Efficient visualization of large graphs
def visualize_large_network(G, max_nodes=5000, sample_method='degree'):
"""
Sample and visualize large networks
Parameters:
- G: NetworkX graph
- max_nodes: Maximum number of nodes to display
- sample_method: 'degree', 'random', 'pagerank'
"""
if len(G.nodes()) > max_nodes:
print(f"Sampling nodes from {len(G.nodes())} to {max_nodes}")
if sample_method == 'degree':
# Prioritize high-degree nodes
top_nodes = sorted(G.degree(), key=lambda x: x[1],
reverse=True)[:max_nodes]
nodes_to_keep = [n for n, d in top_nodes]
elif sample_method == 'pagerank':
# Select high PageRank nodes
pr = nx.pagerank(G)
top_nodes = sorted(pr.items(), key=lambda x: x[1],
reverse=True)[:max_nodes]
nodes_to_keep = [n for n, p in top_nodes]
else: # random
import random
nodes_to_keep = random.sample(list(G.nodes()), max_nodes)
G_sample = G.subgraph(nodes_to_keep).copy()
else:
G_sample = G
# Visualize
plt.figure(figsize=(16, 12))
pos = nx.spring_layout(G_sample, k=1/np.sqrt(len(G_sample.nodes())),
iterations=20)
degree_centrality = nx.degree_centrality(G_sample)
node_sizes = [v * 1000 for v in degree_centrality.values()]
nx.draw_networkx(G_sample, pos,
node_size=node_sizes,
node_color=list(degree_centrality.values()),
cmap='viridis',
with_labels=False,
alpha=0.7,
edge_color='gray',
width=0.5)
plt.title(f'Sampled Network ({len(G_sample.nodes())} nodes)',
fontsize=16, fontweight='bold')
plt.axis('off')
plt.tight_layout()
plt.savefig('large_network_sampled.png', dpi=300, bbox_inches='tight')
plt.show()
# Usage example
G_large = nx.barabasi_albert_graph(10000, 3, seed=42)
visualize_large_network(G_large, max_nodes=500, sample_method='pagerank')
3. Fast Analysis with igraph
3.1 igraph vs NetworkX
igraph is implemented in C and excels at high-speed processing of large graphs.
| Feature | NetworkX | igraph |
|---|---|---|
| Implementation Language | Python | C (with Python bindings) |
| Speed | Moderate | Fast (10-100x faster) |
| Memory Efficiency | Standard | Efficient |
| Learning Curve | Gentle | Somewhat steep |
| Ecosystem | Rich (matplotlib, etc.) | Custom visualization |
| Applicability | Small to medium scale (~10K nodes) | Large scale (100K+ nodes) |
3.2 High-Speed Algorithm Implementation
import igraph as ig
import time
# Convert NetworkX graph to igraph
def nx_to_igraph(G_nx):
"""Convert NetworkX graph to igraph"""
G_ig = ig.Graph()
G_ig.add_vertices(list(G_nx.nodes()))
G_ig.add_edges(list(G_nx.edges()))
return G_ig
# Performance comparison
G_nx = nx.barabasi_albert_graph(5000, 3, seed=42)
G_ig = nx_to_igraph(G_nx)
# NetworkX: PageRank
start = time.time()
pr_nx = nx.pagerank(G_nx)
time_nx = time.time() - start
# igraph: PageRank
start = time.time()
pr_ig = G_ig.pagerank()
time_ig = time.time() - start
print(f"NetworkX PageRank: {time_nx:.4f} seconds")
print(f"igraph PageRank: {time_ig:.4f} seconds")
print(f"Speedup: {time_nx/time_ig:.2f}x")
# Community detection with igraph
start = time.time()
communities = G_ig.community_multilevel()
time_community = time.time() - start
print(f"\nigraph community detection: {time_community:.4f} seconds")
print(f"Communities detected: {len(communities)}")
print(f"Modularity: {communities.modularity:.4f}")
3.3 Large Graph Processing
# Efficient processing of large graphs using igraph
def analyze_large_graph_igraph(n_nodes=100000, m_edges=3):
"""Efficient analysis of large graphs"""
print(f"Generating graph: {n_nodes} nodes...")
G = ig.Graph.Barabasi(n_nodes, m_edges)
print("Calculating centrality metrics...")
start = time.time()
# Calculate various centralities
degree = G.degree()
betweenness = G.betweenness()
closeness = G.closeness()
pagerank = G.pagerank()
calc_time = time.time() - start
print(f"Calculation time: {calc_time:.2f} seconds")
# Community detection
print("Detecting communities...")
start = time.time()
communities = G.community_multilevel()
comm_time = time.time() - start
print(f"Detection time: {comm_time:.2f} seconds")
print(f"Number of communities: {len(communities)}")
# Visualization (sampling)
print("Sampling for visualization...")
# Select top 500 nodes
top_nodes = sorted(range(len(pagerank)),
key=lambda i: pagerank[i], reverse=True)[:500]
G_sample = G.subgraph(top_nodes)
# igraph visualization
visual_style = {
"vertex_size": [pagerank[i] * 1000 for i in top_nodes],
"vertex_color": [communities.membership[i] for i in top_nodes],
"vertex_label": None,
"edge_width": 0.5,
"edge_color": "#cccccc",
"layout": G_sample.layout_fruchterman_reingold()
}
ig.plot(G_sample,
"large_graph_igraph.png",
bbox=(1200, 1200),
**visual_style)
print("Visualization complete: large_graph_igraph.png")
return {
'nodes': n_nodes,
'edges': G.ecount(),
'calc_time': calc_time,
'comm_time': comm_time,
'communities': len(communities),
'modularity': communities.modularity
}
# Execute
results = analyze_large_graph_igraph(n_nodes=100000, m_edges=3)
print(f"\nResults summary: {results}")
4. Introduction to Gephi
4.1 Gephi Features
Gephi is a powerful desktop application for interactive visualization and network exploration.
Main Advantages of Gephi:
- Real-time visual feedback
- Advanced layout algorithms (ForceAtlas2, etc.)
- Statistical analysis and filtering capabilities
- High-quality output (publication-ready graphics)
- Plugin ecosystem
4.2 Data Export/Import
# Export from NetworkX to Gephi format
import networkx as nx
# Create sample graph and add attributes
G = nx.karate_club_graph()
# Add node attributes
degree_centrality = nx.degree_centrality(G)
betweenness_centrality = nx.betweenness_centrality(G)
communities = nx.community.greedy_modularity_communities(G)
# Add community ID to nodes
community_map = {}
for i, comm in enumerate(communities):
for node in comm:
community_map[node] = i
for node in G.nodes():
G.nodes[node]['degree_centrality'] = degree_centrality[node]
G.nodes[node]['betweenness_centrality'] = betweenness_centrality[node]
G.nodes[node]['community'] = community_map[node]
G.nodes[node]['label'] = f'Node_{node}'
# Add edge attributes
for u, v in G.edges():
G[u][v]['weight'] = G.degree(u) + G.degree(v)
# Export as GEXF format (Gephi recommended format)
nx.write_gexf(G, 'network_for_gephi.gexf')
print("GEXF file created: network_for_gephi.gexf")
# Can also export as GraphML format
nx.write_graphml(G, 'network_for_gephi.graphml')
print("GraphML file created: network_for_gephi.graphml")
# CSV edge list format (simple method)
import pandas as pd
edges_data = []
for u, v, data in G.edges(data=True):
edges_data.append({
'Source': u,
'Target': v,
'Weight': data.get('weight', 1)
})
edges_df = pd.DataFrame(edges_data)
edges_df.to_csv('edges.csv', index=False)
# Node list CSV
nodes_data = []
for node, data in G.nodes(data=True):
nodes_data.append({
'Id': node,
'Label': data.get('label', str(node)),
'Community': data.get('community', 0),
'Degree_Centrality': data.get('degree_centrality', 0),
'Betweenness_Centrality': data.get('betweenness_centrality', 0)
})
nodes_df = pd.DataFrame(nodes_data)
nodes_df.to_csv('nodes.csv', index=False)
print("CSV files created: edges.csv, nodes.csv")
4.3 Visualization Best Practices
Recommended Gephi Workflow Steps
- Data Import : File → Open → Select GEXF/GraphML file
- Calculate Statistics : Run the following in Statistics panel
- Average Degree
- Network Diameter
- Modularity (community detection)
- PageRank
- Apply Layout : Select ForceAtlas2 in Layout panel
- Scaling: 2.0-10.0 (depending on graph size)
- Gravity: 1.0
- Prevent Overlap: Check
- Visual Adjustments : Configure in Appearance panel
- Node size: Ranking → Degree/PageRank
- Node color: Partition → Modularity Class
- Labels: Size = proportional to node size
- Export : Preview → Export → PNG/PDF (300+ DPI recommended)
5. Practice: Large-Scale Network Visualization
5.1 Sampling Techniques
# Implementation of various sampling techniques
class NetworkSampler:
"""Network sampling class for large networks"""
@staticmethod
def random_node_sampling(G, sample_size):
"""Random node sampling"""
import random
nodes = random.sample(list(G.nodes()),
min(sample_size, len(G.nodes())))
return G.subgraph(nodes).copy()
@staticmethod
def random_edge_sampling(G, sample_ratio=0.1):
"""Random edge sampling"""
import random
n_edges = int(len(G.edges()) * sample_ratio)
edges = random.sample(list(G.edges()), n_edges)
H = nx.Graph()
H.add_edges_from(edges)
return H
@staticmethod
def induced_subgraph_sampling(G, sample_size):
"""Induced subgraph sampling (prioritizing important nodes)"""
# Select important nodes using PageRank
pr = nx.pagerank(G)
top_nodes = sorted(pr.items(), key=lambda x: x[1],
reverse=True)[:sample_size]
nodes = [n for n, _ in top_nodes]
return G.subgraph(nodes).copy()
@staticmethod
def snowball_sampling(G, seed_nodes, k=2):
"""Snowball sampling (k-hop neighborhood)"""
sampled_nodes = set(seed_nodes)
for _ in range(k):
new_nodes = set()
for node in sampled_nodes:
new_nodes.update(G.neighbors(node))
sampled_nodes.update(new_nodes)
return G.subgraph(sampled_nodes).copy()
@staticmethod
def forest_fire_sampling(G, sample_size, p=0.4):
"""Forest Fire sampling"""
import random
sampled_nodes = set()
queue = [random.choice(list(G.nodes()))]
while len(sampled_nodes) < sample_size and queue:
current = queue.pop(0)
if current not in sampled_nodes:
sampled_nodes.add(current)
neighbors = list(G.neighbors(current))
# Add neighboring nodes with probability p
n_select = int(len(neighbors) * p)
queue.extend(random.sample(neighbors,
min(n_select, len(neighbors))))
return G.subgraph(sampled_nodes).copy()
# Comparison of sampling techniques
G_large = nx.barabasi_albert_graph(10000, 3, seed=42)
sample_size = 500
samplers = {
'Random Node': NetworkSampler.random_node_sampling(G_large, sample_size),
'Induced (PageRank)': NetworkSampler.induced_subgraph_sampling(G_large, sample_size),
'Snowball (k=2)': NetworkSampler.snowball_sampling(
G_large, [0, 1, 2], k=2),
'Forest Fire': NetworkSampler.forest_fire_sampling(
G_large, sample_size, p=0.4)
}
# Compare characteristics of each sampling technique
fig, axes = plt.subplots(2, 2, figsize=(16, 14))
for ax, (name, G_sample) in zip(axes.flat, samplers.items()):
pos = nx.spring_layout(G_sample, k=0.5, iterations=20)
degree_centrality = nx.degree_centrality(G_sample)
node_sizes = [v * 500 for v in degree_centrality.values()]
nx.draw_networkx(G_sample, pos, ax=ax,
node_size=node_sizes,
node_color=list(degree_centrality.values()),
cmap='viridis',
with_labels=False,
alpha=0.7,
edge_color='gray',
width=0.5)
# Statistical information
density = nx.density(G_sample)
avg_degree = sum(dict(G_sample.degree()).values()) / len(G_sample.nodes())
ax.set_title(f'{name}\nNodes: {len(G_sample.nodes())}, '
f'Density: {density:.4f}, Avg Degree: {avg_degree:.2f}',
fontsize=12, fontweight='bold')
ax.axis('off')
plt.tight_layout()
plt.savefig('sampling_comparison.png', dpi=300, bbox_inches='tight')
plt.show()
5.2 Hierarchical Visualization
# Hierarchical network visualization
def hierarchical_visualization(G, threshold_degree=10):
"""
Hierarchical visualization: Display important nodes and their surroundings progressively
"""
# Level 1: High-degree nodes (hubs)
high_degree_nodes = [n for n, d in G.degree() if d >= threshold_degree]
# Level 2: Direct neighbors of hubs
level2_nodes = set()
for hub in high_degree_nodes:
level2_nodes.update(G.neighbors(hub))
level2_nodes = list(level2_nodes - set(high_degree_nodes))
# Level 3: Other nodes (sampled)
remaining = set(G.nodes()) - set(high_degree_nodes) - set(level2_nodes)
import random
level3_nodes = random.sample(list(remaining),
min(100, len(remaining)))
# Hierarchical layout
fig = plt.figure(figsize=(18, 6))
# Level 1 visualization
ax1 = plt.subplot(131)
G1 = G.subgraph(high_degree_nodes).copy()
pos1 = nx.spring_layout(G1, k=1, seed=42)
nx.draw_networkx(G1, pos1, ax=ax1,
node_color='red', node_size=500,
with_labels=True, font_size=8)
ax1.set_title(f'Level 1: Hub Nodes ({len(high_degree_nodes)})',
fontsize=14, fontweight='bold')
ax1.axis('off')
# Level 2 visualization
ax2 = plt.subplot(132)
G2 = G.subgraph(high_degree_nodes + level2_nodes).copy()
pos2 = nx.spring_layout(G2, k=0.5, seed=42)
node_colors = ['red' if n in high_degree_nodes else 'lightblue'
for n in G2.nodes()]
node_sizes = [500 if n in high_degree_nodes else 200
for n in G2.nodes()]
nx.draw_networkx(G2, pos2, ax=ax2,
node_color=node_colors, node_size=node_sizes,
with_labels=False)
ax2.set_title(f'Level 2: +Direct Neighbors ({len(G2.nodes())})',
fontsize=14, fontweight='bold')
ax2.axis('off')
# Level 3 visualization
ax3 = plt.subplot(133)
all_nodes = high_degree_nodes + level2_nodes + level3_nodes
G3 = G.subgraph(all_nodes).copy()
pos3 = nx.spring_layout(G3, k=0.3, seed=42)
node_colors = ['red' if n in high_degree_nodes
else 'lightblue' if n in level2_nodes
else 'lightgreen' for n in G3.nodes()]
node_sizes = [500 if n in high_degree_nodes
else 200 if n in level2_nodes
else 100 for n in G3.nodes()]
nx.draw_networkx(G3, pos3, ax=ax3,
node_color=node_colors, node_size=node_sizes,
with_labels=False, alpha=0.8)
ax3.set_title(f'Level 3: +Others ({len(G3.nodes())})',
fontsize=14, fontweight='bold')
ax3.axis('off')
plt.tight_layout()
plt.savefig('hierarchical_viz.png', dpi=300, bbox_inches='tight')
plt.show()
# Usage example
G = nx.barabasi_albert_graph(1000, 3, seed=42)
hierarchical_visualization(G, threshold_degree=20)
5.3 Creating Interactive Dashboards
# Interactive dashboard using Plotly Dash
from dash import Dash, dcc, html, Input, Output
import plotly.graph_objects as go
import networkx as nx
# Create graph
G = nx.karate_club_graph()
# Dashboard application
app = Dash(__name__)
# Layout
app.layout = html.Div([
html.H1("Network Visualization Dashboard",
style={'textAlign': 'center'}),
html.Div([
html.Label("Layout Algorithm:"),
dcc.Dropdown(
id='layout-dropdown',
options=[
{'label': 'Spring Layout', 'value': 'spring'},
{'label': 'Circular Layout', 'value': 'circular'},
{'label': 'Kamada-Kawai', 'value': 'kamada_kawai'},
{'label': 'Spectral Layout', 'value': 'spectral'}
],
value='spring'
)
], style={'width': '300px', 'margin': '20px'}),
html.Div([
html.Label("Node Color Metric:"),
dcc.Dropdown(
id='metric-dropdown',
options=[
{'label': 'Degree Centrality', 'value': 'degree'},
{'label': 'Betweenness Centrality', 'value': 'betweenness'},
{'label': 'Eigenvector Centrality', 'value': 'eigenvector'},
{'label': 'PageRank', 'value': 'pagerank'}
],
value='degree'
)
], style={'width': '300px', 'margin': '20px'}),
dcc.Graph(id='network-graph', style={'height': '800px'})
])
# Callback
@app.callback(
Output('network-graph', 'figure'),
[Input('layout-dropdown', 'value'),
Input('metric-dropdown', 'value')]
)
def update_graph(layout_type, metric_type):
# Calculate layout
if layout_type == 'spring':
pos = nx.spring_layout(G, k=0.5, seed=42)
elif layout_type == 'circular':
pos = nx.circular_layout(G)
elif layout_type == 'kamada_kawai':
pos = nx.kamada_kawai_layout(G)
else: # spectral
pos = nx.spectral_layout(G)
# Calculate metrics
if metric_type == 'degree':
metric = nx.degree_centrality(G)
elif metric_type == 'betweenness':
metric = nx.betweenness_centrality(G)
elif metric_type == 'eigenvector':
metric = nx.eigenvector_centrality(G)
else: # pagerank
metric = nx.pagerank(G)
# Edge trace
edge_x, edge_y = [], []
for edge in G.edges():
x0, y0 = pos[edge[0]]
x1, y1 = pos[edge[1]]
edge_x.extend([x0, x1, None])
edge_y.extend([y0, y1, None])
edge_trace = go.Scatter(
x=edge_x, y=edge_y,
line=dict(width=0.5, color='#888'),
hoverinfo='none',
mode='lines'
)
# Node trace
node_x = [pos[node][0] for node in G.nodes()]
node_y = [pos[node][1] for node in G.nodes()]
node_text = [f'Node {node}
{metric_type}: {metric[node]:.4f}'
for node in G.nodes()]
node_trace = go.Scatter(
x=node_x, y=node_y,
mode='markers+text',
hoverinfo='text',
text=[str(n) for n in G.nodes()],
textposition="top center",
hovertext=node_text,
marker=dict(
showscale=True,
colorscale='YlOrRd',
size=[metric[node] * 50 for node in G.nodes()],
color=[metric[node] for node in G.nodes()],
colorbar=dict(
thickness=15,
title=metric_type,
xanchor='left',
titleside='right'
),
line=dict(width=2, color='white')
)
)
# Create figure
fig = go.Figure(
data=[edge_trace, node_trace],
layout=go.Layout(
title=f'{layout_type.title()} Layout - {metric_type.title()}',
showlegend=False,
hovermode='closest',
margin=dict(b=0, l=0, r=0, t=40),
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
plot_bgcolor='white'
)
)
return fig
# Run application
# if __name__ == '__main__':
# app.run_server(debug=True, port=8050)
print("Dashboard code ready")
print("To execute, uncomment the last 2 lines")
Visualization Tool Selection Guidelines:
- NetworkX + Matplotlib : Static visualization, for papers/reports, small scale (~1K nodes)
- PyVis : Quick interactive exploration, for presentations
- Plotly : Highly customizable interactive visualization, dashboards
- igraph : Fast processing and analysis of large graphs (10K+ nodes)
- Gephi : Publication-quality visualization, detailed visual exploration, large graphs (100K+ nodes)
Disclaimer
- This content is provided solely for educational, research, and informational purposes and does not constitute professional advice (legal, accounting, technical warranty, etc.).
- This content and accompanying code examples are provided “AS IS” without any warranty, express or implied, including but not limited to merchantability, fitness for a particular purpose, non-infringement, accuracy, completeness, operation, or safety.
- The author and Tohoku University assume no responsibility for the content, availability, or safety of external links, third-party data, tools, libraries, etc.
- To the maximum extent permitted by applicable law, the author and Tohoku University shall not be liable for any direct, indirect, incidental, special, consequential, or punitive damages arising from the use, execution, or interpretation of this content.
- The content may be changed, updated, or discontinued without notice.
- The copyright and license of this content are subject to the stated conditions (e.g., CC BY 4.0). Such licenses typically include no-warranty clauses.