import igraph as ig
import kececilayout as kl
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import networkx as nx
import networkit as nk
import numpy as np
import platform
import rustworkx as rx
from typing import Any, Dict, List, Optional, Tuple, Union
import warnings
# graph-tool sadece Linux'ta import edilsin
if platform.system() == "Linux":
try:
import graph_tool.all as gt
GRAPH_TOOL_AVAILABLE = True
except ImportError:
gt = None
GRAPH_TOOL_AVAILABLE = False
else:
gt = None
GRAPH_TOOL_AVAILABLE = False
# Graphillion koşullu import
try:
import graphillion as gg
from graphillion import GraphSet
import itertools
GRAPHILLION_AVAILABLE = True
except ImportError:
GRAPHILLION_AVAILABLE = False
def generate_sample_graph(library_type: int, n_nodes: int = 10, directed: bool = False) -> Any:
"""Belirtilen kütüphaneye göre örnek graf oluşturur."""
if library_type == 1: # NetworkX
if directed:
G = nx.DiGraph()
for i in range(n_nodes - 1):
G.add_edge(i, i+1)
else:
G = nx.path_graph(n_nodes)
print(f"✓ NetworkX: {G.number_of_nodes()} düğüm, {G.number_of_edges()} kenar")
return G
elif library_type == 2: # RustworkX
if directed:
G = rx.PyDiGraph()
nodes = G.add_nodes_from(range(n_nodes))
for i in range(n_nodes - 1):
G.add_edge(i, i+1, None)
else:
G = rx.generators.path_graph(n_nodes)
print(f"✓ RustworkX: {G.num_nodes()} düğüm, {G.num_edges()} kenar")
return G
elif library_type == 3: # igraph
G = ig.Graph.Ring(n_nodes, directed=directed, circular=False)
print(f"✓ igraph: {G.vcount()} düğüm, {G.ecount()} kenar")
return G
elif library_type == 4: # Networkit
if directed:
G = nk.graph.Graph(n_nodes, weighted=False, directed=True)
else:
G = nk.graph.Graph(n_nodes, weighted=False, directed=False)
for i in range(n_nodes - 1):
G.addEdge(i, i+1)
print(f"✓ Networkit: {G.numberOfNodes()} düğüm, {G.numberOfEdges()} kenar")
return G
elif library_type == 5: # Graphillion
if not GRAPHILLION_AVAILABLE:
print("✗ Graphillion kullanılabilir değil, NetworkX'e dönülüyor.")
return nx.path_graph(min(n_nodes, 5))
try:
universe = [(i, i+1) for i in range(1, n_nodes)]
GraphSet.set_universe(universe)
gs = GraphSet()
print(f"✓ Graphillion: {n_nodes} düğüm, {len(universe)} kenar")
return gs
except Exception as e:
print(f"✗ Graphillion hatası: {e} - NetworkX'e dönülüyor.")
return nx.path_graph(min(n_nodes, 5))
elif library_type == 6: # graph-tool
if not GRAPH_TOOL_AVAILABLE:
print("✗ graph-tool kullanılabilir değil, NetworkX'e dönülüyor.")
return nx.path_graph(min(n_nodes, 5))
try:
G = gt.Graph(directed=directed)
G.add_vertex(n_nodes)
for i in range(n_nodes - 1):
G.add_edge(G.vertex(i), G.vertex(i+1))
print(f"✓ graph-tool: {G.num_vertices()} düğüm, {G.num_edges()} kenar")
return G
except Exception as e:
print(f"✗ graph-tool hatası: {e} - NetworkX'e dönülüyor.")
return nx.path_graph(min(n_nodes, 5))
def get_secondary_start(primary_direction: str) -> str:
"""Birincil yöne göre ikincil yönü belirler."""
if primary_direction in ['top_down', 'bottom_up']:
return 'right'
elif primary_direction in ['left-to-right', 'right-to-left']:
return 'up'
else:
return 'right'
def convert_to_networkx(graph: Any, library_type: int, directed: bool = False) -> nx.Graph:
"""Farklı kütüphane graflarını NetworkX'e dönüştürür."""
if graph is None:
if directed:
return nx.DiGraph([(1, 2), (2, 3)])
else:
return nx.path_graph(3)
try:
if library_type == 1: # NetworkX
return graph
elif library_type == 2: # RustworkX
if directed:
nx_graph = nx.DiGraph()
else:
nx_graph = nx.Graph()
nx_graph.add_nodes_from(graph.node_indices())
if hasattr(graph, 'edge_list'):
nx_graph.add_edges_from(graph.edge_list())
return nx_graph
elif library_type == 3: # igraph
if directed:
nx_graph = nx.DiGraph()
else:
nx_graph = nx.Graph()
nx_graph.add_nodes_from([v.index for v in graph.vs])
nx_graph.add_edges_from(graph.get_edgelist())
return nx_graph
elif library_type == 4: # Networkit
if directed:
nx_graph = nx.DiGraph()
else:
nx_graph = nx.Graph()
n_nodes = graph.numberOfNodes()
nx_graph.add_nodes_from(range(n_nodes))
for u, v in graph.iterEdges():
nx_graph.add_edge(u, v)
return nx_graph
elif library_type == 5: # Graphillion
if directed:
nx_graph = nx.DiGraph()
else:
nx_graph = nx.Graph()
try:
if hasattr(graph, 'universe'):
edges = list(graph.universe())
else:
edges = []
if edges:
all_nodes = set()
for edge in edges:
all_nodes.update(edge)
nx_graph.add_nodes_from(sorted(all_nodes))
nx_graph.add_edges_from(edges)
else:
if n_nodes > 1:
simple_edges = [(i, i+1) for i in range(1, min(n_nodes, 100))]
if simple_edges:
all_nodes = set()
for edge in simple_edges:
all_nodes.update(edge)
nx_graph.add_nodes_from(sorted(all_nodes))
nx_graph.add_edges_from(simple_edges)
if nx_graph.number_of_nodes() == 0:
nx_graph.add_edges_from([(1, 2), (2, 3)])
return nx_graph
except Exception as e:
print(f"✗ Graphillion dönüştürme hatası: {e} - basit graf kullanılıyor.")
return nx.path_graph(5)
elif library_type == 6: # graph-tool
if directed:
nx_graph = nx.DiGraph()
else:
nx_graph = nx.Graph()
try:
for v in graph.vertices():
nx_graph.add_node(int(v))
for e in graph.edges():
nx_graph.add_edge(int(e.source()), int(e.target()))
return nx_graph
except Exception as e:
print(f"✗ graph-tool dönüştürme hatası: {e} - basit graf kullanılıyor.")
return nx.path_graph(5)
except Exception as e:
print(f"✗ Dönüştürme hatası: {e} - basit graf kullanılıyor.")
if directed:
return nx.DiGraph([(1, 2), (2, 3)])
else:
return nx.path_graph(3)
def safe_kececi_layout(nx_graph: nx.Graph, layout_params: Dict) -> Dict:
"""Güvenli Keçeci Layout - Graphillion uyumlu."""
try:
if nx_graph.number_of_nodes() == 0:
nx_graph = nx.path_graph(3)
pos = kl.kececi_layout(nx_graph, **layout_params)
print(f"✓ Keçeci Layout başarılı: {len(pos)} düğüm")
return pos
except Exception as e:
print(f"✗ Keçeci Layout hatası: {e} - dairesel layout kullanılıyor.")
return nx.circular_layout(nx_graph)
def generate_3d_helix_layout(nx_graph: nx.Graph, z_spacing: float = 2.0, radius: float = 5.0, turns: float = 2.0) -> Dict:
"""3D sarmal layout oluşturur."""
nodes = sorted(list(nx_graph.nodes()))
pos_3d = {}
total_nodes = len(nodes)
if total_nodes == 0:
return pos_3d
total_angle = 2 * np.pi * turns
for i, node_id in enumerate(nodes):
z = i * z_spacing
angle = (i / (total_nodes - 1)) * total_angle if total_nodes > 1 else 0
x = np.cos(angle) * radius
y = np.sin(angle) * radius
pos_3d[node_id] = (x, y, z)
return pos_3d
def draw_edges_with_arrows(nx_graph: nx.Graph, pos: Dict, ax: plt.Axes, edge_style: str = 'standard', directed: bool = False) -> None:
"""Kenarları ok başlarıyla çizer."""
with warnings.catch_warnings():
warnings.simplefilter('ignore', category=UserWarning)
if edge_style == 'curved' and directed:
for edge in nx_graph.edges():
u, v = edge
if u in pos and v in pos:
arrowprops = dict(
arrowstyle='->',
color='darkblue',
lw=2,
alpha=0.7,
shrinkA=15,
shrinkB=15,
connectionstyle='arc3,rad=0.2'
)
ax.annotate("", xy=pos[v], xycoords='data',
xytext=pos[u], textcoords='data',
arrowprops=arrowprops)
elif edge_style == 'curved' and not directed:
for edge in nx_graph.edges():
u, v = edge
if u in pos and v in pos:
from matplotlib.patches import FancyArrowPatch
arrow = FancyArrowPatch(pos[u], pos[v],
connectionstyle='arc3,rad=0.2',
color='darkblue', alpha=0.7, lw=2,
arrowstyle='-')
ax.add_patch(arrow)
elif directed:
nx.draw_networkx_edges(
nx_graph, pos,
width=2,
alpha=0.7,
edge_color='darkred',
arrows=True,
arrowsize=20,
arrowstyle='->',
ax=ax
)
else:
nx.draw_networkx_edges(
nx_graph, pos,
width=2,
alpha=0.7,
edge_color='darkblue',
arrows=False,
ax=ax
)
def plot_with_kececi_layout(graph: Any, library_type: int, layout_params: Dict, ax: plt.Axes, style: str = 'standard', directed: bool = False) -> Tuple:
"""Keçeci Layout ile çizim yapar."""
nx_graph = convert_to_networkx(graph, library_type, directed)
if nx_graph.number_of_nodes() < 2:
if directed:
nx_graph = nx.DiGraph([(1, 2), (2, 3), (3, 4)])
else:
nx_graph = nx.path_graph(4)
edge_style = 'standard'
if style == 'curved':
edge_style = 'curved'
elif style == '3d':
edge_style = 'standard'
if style == '3d':
pos_3d = generate_3d_helix_layout(nx_graph)
node_colors = list(range(len(nx_graph.nodes())))
for i, node_id in enumerate(sorted(nx_graph.nodes())):
if node_id in pos_3d:
x, y, z = pos_3d[node_id]
ax.scatter([x], [y], [z],
s=300,
c=[node_colors[i]],
cmap='viridis',
alpha=0.8,
depthshade=True)
ax.text(x, y, z, f' {node_id}', fontsize=8, fontweight='bold')
for u, v in nx_graph.edges():
if u in pos_3d and v in pos_3d:
x_vals = [pos_3d[u][0], pos_3d[v][0]]
y_vals = [pos_3d[u][1], pos_3d[v][1]]
z_vals = [pos_3d[u][2], pos_3d[v][2]]
ax.plot(x_vals, y_vals, z_vals,
color='blue', alpha=0.6, linewidth=2)
scatter = ax.scatter([], [], [], c=[], cmap='viridis')
return scatter, nx_graph, pos_3d
elif style == 'helix':
nodes = sorted(list(nx_graph.nodes()))
pos = {}
for i, node_id in enumerate(nodes):
angle = i * (2 * np.pi / len(nodes))
radius = 1.0 + (i * 0.3)
x = radius * np.cos(angle)
y = radius * np.sin(angle)
pos[node_id] = (x, y)
else:
primary_direction = layout_params.get('primary_direction', 'top_down')
layout_params['secondary_start'] = get_secondary_start(primary_direction)
pos = safe_kececi_layout(nx_graph, layout_params)
node_colors = list(range(len(nx_graph.nodes())))
nodes_viz = nx.draw_networkx_nodes(
nx_graph, pos,
node_color=node_colors,
node_size=500,
cmap='viridis',
ax=ax
)
draw_edges_with_arrows(nx_graph, pos, ax, edge_style, directed)
nx.draw_networkx_labels(nx_graph, pos, font_size=10, font_weight='bold', ax=ax)
return nodes_viz, nx_graph, pos
def plot_3d_graph(graph: Any, library_type: int, layout_params: Dict, ax: plt.Axes) -> Tuple:
"""3D çizim yapar."""
nx_graph = convert_to_networkx(graph, library_type)
if nx_graph.number_of_nodes() < 2:
nx_graph = nx.path_graph(4)
pos_3d = generate_3d_helix_layout(nx_graph)
node_colors = list(range(len(nx_graph.nodes())))
for node_id, (x, y, z) in pos_3d.items():
ax.scatter([x], [y], [z],
s=300,
c=[node_colors[node_id]],
cmap='viridis',
alpha=0.8,
depthshade=True)
ax.text(x, y, z, f' {node_id}', fontsize=8, fontweight='bold')
for u, v in nx_graph.edges():
if u in pos_3d and v in pos_3d:
x_vals = [pos_3d[u][0], pos_3d[v][0]]
y_vals = [pos_3d[u][1], pos_3d[v][1]]
z_vals = [pos_3d[u][2], pos_3d[v][2]]
ax.plot(x_vals, y_vals, z_vals,
color='blue', alpha=0.6, linewidth=2)
scatter = ax.scatter([], [], [], c=[], cmap='viridis')
return scatter, nx_graph, pos_3d
def show_library_status() -> None:
"""Kütüphane durumlarını gösterir."""
print("\n" + "="*50)
print("KÜTÜPHANE DURUMU")
print("="*50)
libraries = [
("NetworkX", True),
("RustworkX", True),
("igraph", True),
("Networkit", True),
("Graphillion", GRAPHILLION_AVAILABLE),
("Graph Tool", GRAPH_TOOL_AVAILABLE)
]
for lib_name, available in libraries:
status = "✓ KURULU" if available else "✗ KURULU DEĞİL"
print(f"{lib_name:<15} {status}")
def show_style_options() -> None:
"""Çizim stillerini gösterir."""
print("\n" + "="*40)
print("ÇİZİM STİLLERİ")
print("="*40)
print("1. Standart - Düz kenarlar")
print("2. Varsayılan - Düz kenarlar")
print("3. Eğri - Eğri kenarlar")
print("4. Sarmal - Sarmal düzen")
print("5. 3D - Üç boyutlu sarmal")
print("6. Ağırlıklı - Ağırlıklı kenarlar")
print("7. Renkli - Renkli düğümler")
print("="*40)
def show_direction_options() -> None:
"""Yön seçeneklerini gösterir."""
print("\n" + "="*40)
print("YÖN SEÇENEKLERİ")
print("="*40)
print("1. Yönsüz - Çift yönlü kenarlar")
print("2. Yönlü - Ok başlı kenarlar")
print("="*40)
def interactive_graph_menu() -> None:
"""Interaktif graf kütüphanesi seçim menüsü."""
while True:
print("\n" + "="*60)
print("KEÇECİ LAYOUT - GELİŞMİŞ MENÜ")
print("="*60)
print("1. Tek Kütüphane Testi")
print("2. Tüm Kütüphaneleri Karşılaştır")
print("3. Stil Karşılaştırması")
print("4. Kütüphane Durumunu Göster")
print("0. Çıkış")
print("="*60)
try:
main_choice = int(input("Ana menü seçimi (0-4): "))
if main_choice == 0:
print("Program sonlandırılıyor...")
break
elif main_choice == 1:
single_library_test()
elif main_choice == 2:
compare_all_libraries()
elif main_choice == 3:
compare_styles()
elif main_choice == 4:
show_library_status()
else:
print("Geçersiz seçim! Lütfen 0-4 arasında bir sayı girin.")
except ValueError:
print("Lütfen geçerli bir sayı girin!")
def single_library_test() -> None:
"""Tek kütüphane testi."""
print("\n" + "="*50)
print("TEK KÜTÜPHANE TESTİ")
print("="*50)
print("1. NetworkX")
print("2. RustworkX")
print("3. igraph")
print("4. Networkit")
if GRAPHILLION_AVAILABLE:
print("5. Graphillion")
max_choice = 6 if GRAPH_TOOL_AVAILABLE else 5
else:
print("5. Graphillion (Kurulu Değil)")
max_choice = 5 if GRAPH_TOOL_AVAILABLE else 4
if GRAPH_TOOL_AVAILABLE:
print("6. Graph Tool")
else:
print("6. Graph Tool (Kurulu Değil)")
print("0. Ana Menüye Dön")
try:
choice = int(input(f"Kütüphane seçimi (0-{max_choice}): "))
if choice == 0:
return
elif choice in [1, 2, 3, 4]:
pass
elif choice == 5 and GRAPHILLION_AVAILABLE:
pass
elif choice == 6 and GRAPH_TOOL_AVAILABLE:
pass
else:
print(f"Geçersiz seçim! Lütfen 0-{max_choice} arasında bir sayı girin.")
return
default_nodes = 8
show_direction_options()
dir_choice = int(input("Yön seçimi (1-2, varsayılan: 1): ") or 1)
directed = (dir_choice == 2)
show_style_options()
style_choice = int(input("Stil seçimi (1-7, varsayılan: 1): ") or 1)
styles = ['standard', 'default', 'curved', 'helix', '3d', 'weighted', 'colored']
selected_style = styles[style_choice - 1] if 1 <= style_choice <= 7 else 'standard'
library_names = {
1: 'NetworkX',
2: 'RustworkX',
3: 'igraph',
4: 'Networkit',
5: 'Graphillion',
6: 'Graph Tool'
}
direction_text = "Yönlü" if directed else "Yönsüz"
print(f"\n--- {library_names[choice]} Testi ({direction_text}, {selected_style.upper()} stili) ---")
n_nodes = int(input(f"Düğüm sayısı (varsayılan: {default_nodes}): ") or default_nodes)
primary_spacing = float(input("Birincil aralık (varsayılan: 1.0): ") or 1.0)
secondary_spacing = float(input("İkincil aralık (varsayılan: 0.6): ") or 0.6)
if selected_style != '3d':
print("Layout yönü: 1.top_down 2.bottom_up 3.left-right 4.right-left")
dir_choice = int(input("Seçim (1-4, varsayılan: 1): ") or 1)
directions = ['top_down', 'bottom_up', 'left-to-right', 'right-to-left']
primary_direction = directions[dir_choice - 1] if 1 <= dir_choice <= 4 else 'top_down'
else:
primary_direction = 'top_down'
layout_params = {
'primary_spacing': primary_spacing,
'secondary_spacing': secondary_spacing,
'primary_direction': primary_direction,
'expanding': True
}
graph = generate_sample_graph(choice, n_nodes, directed)
if selected_style == '3d':
fig = plt.figure(figsize=(12, 10))
ax = fig.add_subplot(111, projection='3d')
else:
fig, ax = plt.subplots(figsize=(12, 10))
nodes, nx_graph, pos = plot_with_kececi_layout(
graph, choice, layout_params, ax, selected_style, directed
)
if nodes is not None and selected_style != '3d':
plt.colorbar(nodes, ax=ax, label='Düğüm Sırası')
elif selected_style == '3d':
plt.colorbar(nodes, ax=ax, label='Düğüm Sırası')
title = f'Keçeci Layout - {library_names[choice]}\n'
title += f'{direction_text} | {selected_style.upper()} stili\n'
title += f'{nx_graph.number_of_nodes()} düğüm, {nx_graph.number_of_edges()} kenar'
if selected_style != '3d':
title += f'\nLayout: {primary_direction}'
ax.set_title(title, fontsize=12)
if selected_style != '3d':
ax.axis('off')
else:
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.tight_layout()
plt.show()
except ValueError:
print("Lütfen geçerli bir sayı girin!")
except Exception as e:
print(f"Hata: {e}")
def compare_directed_undirected() -> None:
"""Yönlü ve yönsüz grafikleri karşılaştırır."""
print("\nYönlü ve yönsüz grafikler karşılaştırılıyor...")
library_type = 1 # NetworkX kullan
n_nodes = 6
fig, axes = plt.subplots(1, 2, figsize=(16, 8))
layout_params = {
'primary_spacing': 1.0,
'secondary_spacing': 0.6,
'primary_direction': 'top_down',
'expanding': True
}
undirected_graph = generate_sample_graph(library_type, n_nodes, directed=False)
nodes_undir, nx_graph_undir, pos_undir = plot_with_kececi_layout(
undirected_graph, library_type, layout_params, axes[0], 'standard', False
)
axes[0].set_title('Yönsüz Graf\nÇift yönlü kenarlar',
fontsize=14, fontweight='bold')
axes[0].axis('off')
directed_graph = generate_sample_graph(library_type, n_nodes, directed=True)
nodes_dir, nx_graph_dir, pos_dir = plot_with_kececi_layout(
directed_graph, library_type, layout_params, axes[1], 'standard', True
)
axes[1].set_title('Yönlü Graf\nOk başlı kenarlar',
fontsize=14, fontweight='bold')
axes[1].axis('off')
plt.suptitle('YÖNLÜ VE YÖNSÜZ GRAFİKLER KARŞILAŞTIRMASI',
fontsize=16, fontweight='bold', y=0.95)
plt.tight_layout()
plt.subplots_adjust(top=0.85)
plt.show()
def compare_styles() -> None:
"""Farklı stilleri karşılaştırır."""
print("\nStiller karşılaştırılıyor...")
library_type = 1 # NetworkX kullan
n_nodes = 6
graph = generate_sample_graph(library_type, n_nodes)
styles = ['standard', 'default', 'curved', 'helix', '3d', 'weighted', 'colored']
style_names = ['Standart', 'Varsayılan', 'Eğri', 'Sarmal', '3D', 'Ağırlıklı', 'Renkli']
fig = plt.figure(figsize=(20, 16))
layout_params = {
'primary_spacing': 1.0,
'secondary_spacing': 0.6,
'primary_direction': 'top_down',
'expanding': True
}
for idx, (style, style_name) in enumerate(zip(styles, style_names)):
if style == '3d':
ax = fig.add_subplot(3, 3, idx+1, projection='3d')
else:
ax = fig.add_subplot(3, 3, idx+1)
try:
nodes, nx_graph, pos = plot_with_kececi_layout(graph, library_type, layout_params, ax, style)
ax.set_title(f'{style_name} Stili\n{nx_graph.number_of_nodes()} düğüm',
fontsize=14, fontweight='bold')
if style != '3d':
ax.axis('off')
else:
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
except Exception as e:
print(f"{style_name} stili için hata: {e}")
ax.clear()
ax.text(0.5, 0.5, f'{style_name}\nHATA', ha='center', va='center', fontsize=12, color='red', weight='bold')
ax.set_title(f'{style_name} - Hata', fontsize=12)
if style != '3d':
ax.axis('off')
plt.suptitle('KEÇECİ LAYOUT - STİL KARŞILAŞTIRMASI', fontsize=18, fontweight='bold', y=0.95)
plt.tight_layout()
plt.subplots_adjust(top=0.90)
plt.show()
def compare_all_libraries() -> None:
"""Tüm kütüphaneleri karşılaştırır."""
print("\nTüm kütüphaneler karşılaştırılıyor...")
libraries = []
if GRAPHILLION_AVAILABLE:
libraries = [(1, 'NetworkX'), (2, 'RustworkX'), (3, 'igraph'), (4, 'Networkit'), (5, 'Graphillion')]
else:
libraries = [(1, 'NetworkX'), (2, 'RustworkX'), (3, 'igraph'), (4, 'Networkit')]
if GRAPH_TOOL_AVAILABLE:
libraries.append((6, 'Graph Tool'))
n_nodes = 6
layout_params = {'primary_spacing': 1.0, 'secondary_spacing': 0.6, 'primary_direction': 'top_down', 'expanding': True}
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
axes = axes.flatten()
successful_plots = 0
for idx, (lib_type, lib_name) in enumerate(libraries):
if idx >= len(axes):
break
try:
ax = axes[idx]
print(f"{lib_name}...", end=" ")
graph = generate_sample_graph(lib_type, n_nodes)
nodes, nx_graph, pos = plot_with_kececi_layout(graph, lib_type, layout_params, ax)
ax.set_title(f'{lib_name}\n{nx_graph.number_of_nodes()} düğüm', fontsize=12, fontweight='bold')
ax.axis('off')
successful_plots += 1
print("✓")
except Exception as e:
print(f"✗ ({e})")
axes[idx].clear()
axes[idx].text(0.5, 0.5, f'{lib_name}\nHATA', ha='center', va='center',
fontsize=10, color='red', weight='bold')
axes[idx].set_title(f'{lib_name} - Hata', fontsize=10)
axes[idx].axis('off')
for idx in range(len(libraries), len(axes)):
axes[idx].axis('off')
plt.suptitle(f'KEÇECİ LAYOUT - TÜM KÜTÜPHANELER\n{successful_plots}/{len(libraries)} başarılı', fontsize=16, fontweight='bold', y=0.95)
plt.tight_layout()
plt.subplots_adjust(top=0.90)
plt.show()
# Main program
if __name__ == "__main__":
print("🚀 KEÇECİ LAYOUT - GELİŞMİŞ GÖRSELLEŞTİRME")
print("="*60)
print("Özellikler: Yönlü/Yönsüz grafikler, Eğri, Sarmal, 3D")
print("Graphillion tam destek - sınırsız düğüm")
show_library_status()
interactive_graph_menu()
Loading...
🚀 KEÇECİ LAYOUT - GELİŞMİŞ GÖRSELLEŞTİRME
============================================================
Özellikler: Yönlü/Yönsüz grafikler, Eğri, Sarmal, 3D
Graphillion tam destek - sınırsız düğüm
==================================================
KÜTÜPHANE DURUMU
==================================================
NetworkX ✓ KURULU
RustworkX ✓ KURULU
igraph ✓ KURULU
Networkit ✓ KURULU
Graphillion ✓ KURULU
Graph Tool ✓ KURULU
============================================================
KEÇECİ LAYOUT - GELİŞMİŞ MENÜ
============================================================
1. Tek Kütüphane Testi
2. Tüm Kütüphaneleri Karşılaştır
3. Stil Karşılaştırması
4. Kütüphane Durumunu Göster
0. Çıkış
============================================================
Ana menü seçimi (0-4): 2
Tüm kütüphaneler karşılaştırılıyor...
NetworkX... ✓ NetworkX: 6 düğüm, 5 kenar
✓ Keçeci Layout başarılı: 6 düğüm
✓
RustworkX... ✓ RustworkX: 6 düğüm, 5 kenar
✓ Keçeci Layout başarılı: 6 düğüm
✓
igraph... ✓ igraph: 6 düğüm, 5 kenar
✓ Keçeci Layout başarılı: 6 düğüm
✓
Networkit... ✓ Networkit: 6 düğüm, 5 kenar
✓ Keçeci Layout başarılı: 6 düğüm
✓
Graphillion... ✓ Graphillion: 6 düğüm, 5 kenar
✓ Keçeci Layout başarılı: 6 düğüm
✓
Graph Tool... ✓ graph-tool: 6 düğüm, 5 kenar
✓ Keçeci Layout başarılı: 6 düğüm
✓

============================================================
KEÇECİ LAYOUT - GELİŞMİŞ MENÜ
============================================================
1. Tek Kütüphane Testi
2. Tüm Kütüphaneleri Karşılaştır
3. Stil Karşılaştırması
4. Kütüphane Durumunu Göster
0. Çıkış
============================================================
Ana menü seçimi (0-4): 3
Stiller karşılaştırılıyor...
✓ NetworkX: 6 düğüm, 5 kenar
✓ Keçeci Layout başarılı: 6 düğüm
✓ Keçeci Layout başarılı: 6 düğüm
✓ Keçeci Layout başarılı: 6 düğüm
✓ Keçeci Layout başarılı: 6 düğüm
✓ Keçeci Layout başarılı: 6 düğüm

============================================================
KEÇECİ LAYOUT - GELİŞMİŞ MENÜ
============================================================
1. Tek Kütüphane Testi
2. Tüm Kütüphaneleri Karşılaştır
3. Stil Karşılaştırması
4. Kütüphane Durumunu Göster
0. Çıkış
============================================================
Ana menü seçimi (0-4): 1
==================================================
TEK KÜTÜPHANE TESTİ
==================================================
1. NetworkX
2. RustworkX
3. igraph
4. Networkit
5. Graphillion
6. Graph Tool
0. Ana Menüye Dön
Kütüphane seçimi (0-6): 2
========================================
YÖN SEÇENEKLERİ
========================================
1. Yönsüz - Çift yönlü kenarlar
2. Yönlü - Ok başlı kenarlar
========================================
Yön seçimi (1-2, varsayılan: 1):
========================================
ÇİZİM STİLLERİ
========================================
1. Standart - Düz kenarlar
2. Varsayılan - Düz kenarlar
3. Eğri - Eğri kenarlar
4. Sarmal - Sarmal düzen
5. 3D - Üç boyutlu sarmal
6. Ağırlıklı - Ağırlıklı kenarlar
7. Renkli - Renkli düğümler
========================================
Stil seçimi (1-7, varsayılan: 1):
--- RustworkX Testi (Yönsüz, STANDARD stili) ---
Düğüm sayısı (varsayılan: 8):
Birincil aralık (varsayılan: 1.0):
İkincil aralık (varsayılan: 0.6):
Layout yönü: 1.top_down 2.bottom_up 3.left-right 4.right-left
Seçim (1-4, varsayılan: 1):
✓ RustworkX: 8 düğüm, 7 kenar
✓ Keçeci Layout başarılı: 8 düğüm

============================================================
KEÇECİ LAYOUT - GELİŞMİŞ MENÜ
============================================================
1. Tek Kütüphane Testi
2. Tüm Kütüphaneleri Karşılaştır
3. Stil Karşılaştırması
4. Kütüphane Durumunu Göster
0. Çıkış
============================================================
Ana menü seçimi (0-4): 0
Program sonlandırılıyor...