Basic Usage
This guide covers the fundamental operations in Graphizy, from creating your first graph to performing basic analysis. By the end, you’ll understand all the core features and be ready for advanced applications.
The Graphing Class
The Graphing class is your main interface to Graphizy. It creates graphs, performs analysis, and handles visualization.
Basic Initialization:
from graphizy import Graphing, GraphizyConfig
# Simple initialization
grapher = Graphing(dimension=(800, 600))
# With custom configuration
config = GraphizyConfig(dimension=(800, 600))
grapher = Graphing(config=config)
Configuration Options:
from graphizy import GraphizyConfig
# Create detailed configuration
config = GraphizyConfig(
dimension=(800, 600),
drawing={
"point_color": (255, 100, 100), # Red points
"line_color": (100, 100, 255), # Blue lines
"point_radius": 6,
"line_thickness": 2
}
)
grapher = Graphing(config=config)
Creating Graphs
Graphizy uses a unified make_graph() interface for all graph types:
Unified Interface:
from graphizy import generate_and_format_positions
# Generate sample data
data = generate_and_format_positions(800, 600, 100)
# Create different graph types
proximity_graph = grapher.make_graph("proximity", data, proximity_thresh=50.0)
delaunay_graph = grapher.make_graph("delaunay", data)
knn_graph = grapher.make_graph("knn", data, k=4)
mst_graph = grapher.make_graph("mst", data)
gabriel_graph = grapher.make_graph("gabriel", data)
Graph Type Details:
- Proximity Graph
Connects points within a specified distance:
# Connect points within 60 units graph = grapher.make_graph("proximity", data, proximity_thresh=60.0) # Different distance metrics graph = grapher.make_graph("proximity", data, proximity_thresh=60.0, metric="euclidean") # default graph = grapher.make_graph("proximity", data, proximity_thresh=60.0, metric="manhattan")
- Delaunay Triangulation
Creates optimal triangular mesh:
# No additional parameters needed delaunay_graph = grapher.make_graph("delaunay", data)
- K-Nearest Neighbors
Connects each point to its k closest neighbors:
# Each point connects to 4 nearest neighbors knn_graph = grapher.make_graph("knn", data, k=4) # Different k values change connectivity sparse_graph = grapher.make_graph("knn", data, k=2) # Sparse dense_graph = grapher.make_graph("knn", data, k=8) # Dense
- Minimum Spanning Tree
Creates minimal connected graph:
# Minimal edges to connect all points mst_graph = grapher.make_graph("mst", data)
- Gabriel Graph
Geometric proximity graph (subset of Delaunay):
# Geometric connectivity rules gabriel_graph = grapher.make_graph("gabriel", data)
Data Formats
Graphizy expects data in a simple 3-column format:
Standard Format:
import numpy as np
# Manual data creation
data = np.array([
[0, 100, 150], # Point ID=0 at (100, 150)
[1, 200, 200], # Point ID=1 at (200, 200)
[2, 150, 100], # Point ID=2 at (150, 100)
[3, 250, 180], # Point ID=3 at (250, 180)
])
Data Generation Helpers:
from graphizy import generate_and_format_positions, generate_positions
# Generate random points (recommended)
data = generate_and_format_positions(
size_x=800, # Canvas width
size_y=600, # Canvas height
num_particles=50 # Number of points
)
# Just positions (you add IDs)
positions = generate_positions(800, 600, 50)
data = np.column_stack((np.arange(50), positions))
Data Validation:
from graphizy import validate_graphizy_input
# Check your data format
is_valid = validate_graphizy_input(data, verbose=True)
if not is_valid:
print("Data format issues detected!")
Graph Analysis
The new GraphAnalysisResult provides comprehensive analysis:
Basic Analysis:
# Get analysis result
result = grapher.get_graph_info(graph)
# Basic properties (computed lazily)
print(f"Vertices: {result.vertex_count}")
print(f"Edges: {result.edge_count}")
print(f"Density: {result.density:.3f}")
print(f"Connected: {result.is_connected}")
print(f"Components: {result.num_components}")
# Advanced properties (when available)
if result.transitivity is not None:
print(f"Clustering: {result.transitivity:.3f}")
if result.diameter is not None:
print(f"Diameter: {result.diameter}")
Summary Report:
# Get formatted summary
print(result.summary())
# Output:
# Graph Analysis Summary:
# - Vertices: 100
# - Edges: 245
# - Density: 0.0495
# - Connected: True
# - Clustering (Transitivity): 0.3421
Top Nodes Analysis:
# Find most central nodes
top_degree = result.get_top_n_by('degree', n=5)
top_betweenness = result.get_top_n_by('betweenness', n=5)
print("Top 5 most connected nodes:")
for node_id, degree in top_degree:
print(f" Node {node_id}: {degree} connections")
print("Top 5 bridge nodes:")
for node_id, betweenness in top_betweenness:
print(f" Node {node_id}: {betweenness:.3f}")
Statistical Analysis:
# Get statistics for any metric
degree_stats = result.get_metric_stats('degree')
betweenness_stats = result.get_metric_stats('betweenness')
print("Degree Distribution:")
print(f" Mean: {degree_stats['mean']:.2f}")
print(f" Std: {degree_stats['std']:.2f}")
print(f" Range: {degree_stats['min']:.0f} - {degree_stats['max']:.0f}")
Advanced Analysis Tools
Graphizy now includes research-grade analysis tools:
Percolation Analysis:
# Analyze critical thresholds
ranges = [20, 30, 40, 50, 60, 70, 80]
percolation_result = result.percolation_analyzer.analyze_percolation_threshold(
data, ranges
)
print(f"Critical threshold: {percolation_result.critical_range}")
print(f"Max cluster size: {max(percolation_result.largest_cluster_sizes)}")
# Detect phase transition
transition = result.percolation_analyzer.detect_phase_transition(percolation_result)
if transition['has_transition']:
print(f"Phase transition at: {transition['transition_range']}")
print(f"Transition sharpness: {transition['transition_sharpness']:.3f}")
Social Network Analysis:
# Identify social roles
social_roles = result.social_analyzer.identify_social_roles(graph)
# Find different role types
bridges = [node_id for node_id, role in social_roles.items() if role.is_bridge()]
hubs = [node_id for node_id, role in social_roles.items() if role.is_hub()]
peripheral = [node_id for node_id, role in social_roles.items() if role.is_peripheral()]
print(f"Bridge nodes (connectors): {bridges}")
print(f"Hub nodes (popular): {hubs}")
print(f"Peripheral nodes: {peripheral}")
# Analyze specific roles
for node_id, role in list(social_roles.items())[:5]:
print(f"Node {node_id}: {role.roles}")
print(f" Betweenness: {role.stats['betweenness']:.3f}")
print(f" Degree: {role.stats['degree']}")
Accessibility Analysis:
# For spatial applications (urban planning, etc.)
population_data = data # Your population points
service_data = service_locations # Your service points
accessibility = result.accessibility_analyzer.analyze_service_accessibility(
population_data,
service_data,
service_type="hospital",
service_distance=500.0 # 500m walking distance
)
print(f"Coverage: {accessibility.get_coverage_percentage():.1f}%")
print(f"Equity score: {accessibility.get_equity_score():.3f}")
print(f"Underserved areas: {len(accessibility.underserved_areas)}")
# Identify service gaps
gaps = result.accessibility_analyzer.identify_service_gaps(accessibility)
print(f"Service gaps: {len(gaps)}")
Visualization
Create beautiful visualizations of your networks:
Basic Visualization:
# Draw the graph
image = grapher.draw_graph(graph)
# Display on screen
grapher.show_graph(image, "My Network")
# Save to file
grapher.save_graph(image, "network.png")
Custom Styling:
# Update drawing configuration
grapher.update_config(drawing={
"point_color": (255, 100, 100), # Red points (BGR format)
"line_color": (100, 255, 100), # Green lines
"point_radius": 8, # Larger points
"line_thickness": 2 # Thicker lines
})
# Draw with new style
styled_image = grapher.draw_graph(graph)
grapher.save_graph(styled_image, "styled_network.png")
Multiple Visualizations:
# Compare different graph types visually
graph_types = {
'Proximity': grapher.make_graph("proximity", data, proximity_thresh=50.0),
'Delaunay': grapher.make_graph("delaunay", data),
'MST': grapher.make_graph("mst", data)
}
for name, graph in graph_types.items():
image = grapher.draw_graph(graph)
grapher.save_graph(image, f"{name.lower()}_graph.png")
print(f"Saved {name} visualization")
Memory System (Temporal Analysis)
Track how networks evolve over time:
Basic Memory Setup:
# Initialize memory system
grapher.init_memory_manager(
max_memory_size=50, # Remember last 50 connections
track_edge_ages=True # Track connection ages
)
Temporal Evolution:
# Simulate network evolution
original_data = data.copy()
for timestep in range(30):
# Simulate movement (your own function)
data = simulate_movement(data, timestep)
# Create current network
current_graph = grapher.make_graph("proximity", data, proximity_thresh=60.0)
# Update memory with current connections
grapher.update_memory_with_graph(current_graph)
# Analyze memory periodically
if timestep % 10 == 0:
memory_stats = grapher.get_memory_stats()
print(f"Timestep {timestep}: {memory_stats['total_connections']} total connections")
Memory Visualization:
# Create memory-enhanced graph
memory_graph = grapher.make_memory_graph(data)
# Visualize with age-based coloring
memory_image = grapher.draw_memory_graph(
memory_graph,
use_age_colors=True, # Color by connection age
alpha_range=(0.3, 1.0) # Fade old connections
)
grapher.save_graph(memory_image, "memory_network.png")
Memory Analysis:
# Get detailed memory statistics
memory_stats = grapher.get_memory_stats()
print("Memory Statistics:")
print(f" Total connections tracked: {memory_stats['total_connections']}")
print(f" Active connections: {memory_stats['active_connections']}")
# Get edge age information
if hasattr(grapher.memory_manager, 'get_edge_ages'):
edge_ages = grapher.memory_manager.get_edge_ages()
# Find most persistent connections
persistent = []
for edge, age_info in edge_ages.items():
duration = age_info['last_seen'] - age_info['first_seen']
persistent.append((edge, duration))
# Sort by persistence
persistent.sort(key=lambda x: x[1], reverse=True)
print("Most persistent connections:")
for (node1, node2), duration in persistent[:5]:
print(f" {node1} <-> {node2}: {duration} timesteps")
Performance Tips
For Large Datasets:
# Use efficient graph types for large data
large_data = generate_and_format_positions(1000, 1000, 500)
# MST is efficient for large datasets
mst_graph = grapher.make_graph("mst", large_data)
# Use reasonable proximity thresholds
prox_graph = grapher.make_graph("proximity", large_data, proximity_thresh=30.0)
# Smaller k for KNN
knn_graph = grapher.make_graph("knn", large_data, k=4)
Memory Optimization:
# For large temporal datasets
grapher.init_memory_manager(
max_memory_size=20, # Smaller memory
track_edge_ages=False # Disable for performance
)
Batch Processing:
# Process multiple datasets efficiently
datasets = [generate_and_format_positions(400, 300, n) for n in [20, 50, 100]]
results = []
for i, data in enumerate(datasets):
graph = grapher.make_graph("proximity", data, proximity_thresh=50.0)
result = grapher.get_graph_info(graph)
results.append({
'dataset': i,
'vertices': result.vertex_count,
'edges': result.edge_count,
'density': result.density
})
Common Workflows
Research Analysis Pipeline:
def analyze_network(data, graph_type="proximity", **kwargs):
"""Complete analysis pipeline"""
# 1. Create graph
graph = grapher.make_graph(graph_type, data, **kwargs)
# 2. Basic analysis
result = grapher.get_graph_info(graph)
# 3. Advanced analysis
percolation = None
social_roles = None
if graph_type == "proximity":
# Percolation analysis for proximity graphs
ranges = [kwargs.get('proximity_thresh', 50) * factor
for factor in [0.5, 0.75, 1.0, 1.25, 1.5]]
percolation = result.percolation_analyzer.analyze_percolation_threshold(data, ranges)
# Social analysis for all graph types
social_roles = result.social_analyzer.identify_social_roles(graph)
# 4. Visualization
image = grapher.draw_graph(graph)
return {
'graph': graph,
'analysis': result,
'percolation': percolation,
'social_roles': social_roles,
'image': image
}
# Use the pipeline
analysis = analyze_network(data, "proximity", proximity_thresh=60.0)
print(f"Network has {analysis['analysis'].vertex_count} nodes")
print(f"Found {len(analysis['social_roles'])} nodes with roles")
Comparative Analysis:
def compare_graph_types(data):
"""Compare different graph types on same data"""
graph_configs = [
("proximity", {"proximity_thresh": 50.0}),
("delaunay", {}),
("mst", {}),
("knn", {"k": 4})
]
results = {}
for graph_type, params in graph_configs:
try:
graph = grapher.make_graph(graph_type, data, **params)
analysis = grapher.get_graph_info(graph)
results[graph_type] = {
'vertices': analysis.vertex_count,
'edges': analysis.edge_count,
'density': analysis.density,
'connected': analysis.is_connected,
'clustering': analysis.transitivity
}
# Save visualization
image = grapher.draw_graph(graph)
grapher.save_graph(image, f"comparison_{graph_type}.png")
except Exception as e:
print(f"Failed to create {graph_type}: {e}")
results[graph_type] = None
return results
# Compare graph types
comparison = compare_graph_types(data)
# Print comparison table
print(f"{'Type':<12} {'Edges':<8} {'Density':<10} {'Connected':<10} {'Clustering':<10}")
print("-" * 60)
for graph_type, stats in comparison.items():
if stats:
clustering = stats['clustering']
clustering_str = f"{clustering:.3f}" if clustering is not None else "N/A"
print(f"{graph_type:<12} {stats['edges']:<8} {stats['density']:<10.3f} "
f"{str(stats['connected']):<10} {clustering_str:<10}")
Error Handling
Handle common issues gracefully:
from graphizy import GraphCreationError, InvalidDataShapeError
try:
# Validate data first
is_valid = validate_graphizy_input(data, verbose=True)
if not is_valid:
print("Data validation failed")
return
# Create graph
graph = grapher.make_graph("proximity", data, proximity_thresh=50.0)
# Analyze graph
result = grapher.get_graph_info(graph)
except InvalidDataShapeError as e:
print(f"Data format error: {e}")
except GraphCreationError as e:
print(f"Graph creation failed: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
Handling Empty Graphs:
# Check for empty graphs
if graph.vcount() == 0:
print("Warning: Graph has no vertices")
return
if graph.ecount() == 0:
print("Warning: Graph has no edges (isolated points)")
# Safe analysis
result = grapher.get_graph_info(graph)
if result.vertex_count > 0:
print(f"Graph analysis successful: {result.vertex_count} vertices")
else:
print("Cannot analyze empty graph")
Integration with Other Libraries
NetworkX Integration:
# Export to NetworkX for advanced analysis
try:
import networkx as nx
# Convert Graphizy graph to NetworkX
nx_graph = grapher.to_networkx(graph)
# Use NetworkX algorithms
communities = nx.community.greedy_modularity_communities(nx_graph)
centrality = nx.betweenness_centrality(nx_graph)
print(f"Found {len(communities)} communities")
print(f"Average betweenness: {sum(centrality.values()) / len(centrality):.3f}")
except ImportError:
print("NetworkX not available")
Pandas Integration:
# Export analysis results to DataFrame
try:
import pandas as pd
# Convert graph analysis to DataFrame
analysis_data = []
for node_id in range(result.vertex_count):
node_data = {
'node_id': node_id,
'degree': graph.degree(node_id),
'betweenness': graph.betweenness(vertices=[node_id])[0]
}
analysis_data.append(node_data)
df = pd.DataFrame(analysis_data)
print(df.describe())
# Save to CSV
df.to_csv('network_analysis.csv', index=False)
except ImportError:
print("Pandas not available")
Next Steps
Now that you understand the basics, explore these advanced topics:
Advanced Analysis: Learn the research-grade analysis tools
Memory Systems: Master temporal network analysis
Weight Computation: Add sophisticated edge weights
Plugin System: Create custom graph types
Research Applications: Use domain-specific tutorials
Performance Optimization: Handle large datasets efficiently
Recommended Learning Path:
Master basic graph creation and analysis
Experiment with different graph types
Learn the advanced analysis tools
Explore memory systems for temporal data
Try the research tutorials for your domain
Develop custom analysis pipelines
You now have a solid foundation in Graphizy’s core functionality and are ready to tackle advanced spatial network analysis!