kececilayout 0.4.3__py3-none-any.whl → 0.4.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kececilayout/__init__.py CHANGED
@@ -10,7 +10,7 @@ import inspect
10
10
  import warnings
11
11
 
12
12
  # Paket sürüm numarası
13
- __version__ = "0.4.3"
13
+ __version__ = "0.4.5"
14
14
 
15
15
  # =============================================================================
16
16
  # OTOMATİK İÇE AKTARMA VE __all__ OLUŞTURMA
@@ -141,3 +141,5 @@ def old_function_placeholder():
141
141
 
142
142
 
143
143
 
144
+
145
+
kececilayout/_version.py CHANGED
@@ -1,14 +1,9 @@
1
1
  # _version.py
2
2
 
3
- __version__ = "0.4.3"
3
+ __version__ = "0.4.5"
4
4
  __license__ = "MIT"
5
5
  __description__ = "A deterministic node placement algorithm used in graph visualization. In this layout, nodes are arranged sequentially along a defined primary axis. Each subsequent node is then alternately offset along a secondary, perpendicular axis, typically moving to one side of the primary axis and then the other. Often, the magnitude of this secondary offset increases as nodes progress along the primary axis, creating a characteristic zig-zag or serpentine pattern."
6
6
  __author__ = "Mehmet Keçeci"
7
7
  __url__ = "https://github.com/WhiteSymmetry/kececilayout"
8
8
  __docs__ = "https://github.com/WhiteSymmetry/kececilayout" # Opsiyonel: Dokümantasyon linki
9
9
  __dependencies__ = ["python>=3.10"] # Diğer bağımlılıkları da ekleyebilirsiniz
10
-
11
-
12
-
13
-
14
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kececilayout
3
- Version: 0.4.3
3
+ Version: 0.4.5
4
4
  Summary: Çeşitli graf kütüphaneleri için sıralı-zigzag yerleşimleri sağlayan bir Python paketi.
5
5
  Home-page: https://github.com/WhiteSymmetry/kececilayout
6
6
  Author: Mehmet Keçeci
@@ -48,7 +48,7 @@ Requires-Dist: pytest; extra == "test"
48
48
  Requires-Dist: pytest-cov; extra == "test"
49
49
  Requires-Dist: pytest-mock; extra == "test"
50
50
  Requires-Dist: ruff; extra == "test"
51
- Requires-Dist: igraph; extra == "test"
51
+ Requires-Dist: python-igraph; extra == "test"
52
52
  Requires-Dist: python-louvain; extra == "test"
53
53
  Requires-Dist: rustworkx; extra == "test"
54
54
  Requires-Dist: networkit; extra == "test"
@@ -140,11 +140,11 @@ import matplotlib.pyplot as plt
140
140
  import kececilayout as kl
141
141
 
142
142
  G = nx.path_graph(10)
143
- pos = kl.kececi_layout_v4(
143
+ pos = kl.kececi_layout(
144
144
  G,
145
145
  primary_spacing=1.0,
146
146
  secondary_spacing=0.5,
147
- primary_direction='top-down',
147
+ primary_direction='top_down',
148
148
  secondary_start='right'
149
149
  )
150
150
 
@@ -162,14 +162,51 @@ plt.show()
162
162
  ```python
163
163
  import igraph as ig
164
164
  import matplotlib.pyplot as plt
165
- from kececilayout import kececi_layout_v4_igraph
165
+ import kececilayout as kl
166
166
 
167
167
  G = ig.Graph.Ring(10, circular=False)
168
- pos_list = kececi_layout_v4_igraph(G, primary_direction='left-to-right', secondary_start='up')
168
+
169
+ # Get the positions using kececi_layout with proper conversion
170
+ try:
171
+ # Method 1: Direct conversion
172
+ pos = kl.kececi_layout(G, primary_direction='left-to-right', secondary_start='up')
173
+
174
+ # If pos is not iterable, it might be returning an error code
175
+ if not hasattr(pos, '__iter__'):
176
+ raise TypeError("kececi_layout returned non-iterable object")
177
+
178
+ except (TypeError, AttributeError) as e:
179
+ print(f"Direct approach failed: {e}")
180
+ print("Using NetworkX conversion method...")
181
+
182
+ # Method 2: Convert to NetworkX first
183
+ import networkx as nx
184
+ nx_graph = nx.Graph()
185
+ nx_graph.add_nodes_from(range(G.vcount()))
186
+ nx_graph.add_edges_from(G.get_edgelist())
187
+
188
+ pos = kl.kececi_layout(nx_graph, primary_direction='left-to-right', secondary_start='up')
189
+
190
+ # Ensure we have proper coordinates
191
+ if isinstance(pos, dict):
192
+ # Convert dictionary to list
193
+ pos_list = [pos[i] for i in range(G.vcount())]
194
+ else:
195
+ # Assume it's already a list of coordinates
196
+ pos_list = pos
197
+
169
198
  layout = ig.Layout(pos_list)
170
199
 
171
200
  fig, ax = plt.subplots(figsize=(8, 6))
172
- ig.plot(G, target=ax, layout=layout, vertex_label=[f"N{i}" for i in range(10)])
201
+ ig.plot(G,
202
+ target=ax,
203
+ layout=layout,
204
+ vertex_label=[f"N{i}" for i in range(G.vcount())],
205
+ vertex_size=30,
206
+ edge_width=2,
207
+ margin=50)
208
+
209
+ ax.set_title("Keçeci Layout with igraph")
173
210
  ax.set_aspect('equal')
174
211
  plt.show()
175
212
  ```
@@ -179,13 +216,94 @@ plt.show()
179
216
  #### Example with RustworkX
180
217
 
181
218
  ```python
219
+ import matplotlib.pyplot as plt
220
+ from matplotlib.collections import LineCollection # Efficient edge drawing
221
+ import math
182
222
  import rustworkx as rx
183
223
  import kececilayout as kl
184
- import matplotlib.pyplot as plt
224
+ import random
225
+
226
+
227
+ try:
228
+ import kececilayout as kl
229
+ except ImportError:
230
+ print("Error: 'kececi_layout.py' not found or could not be imported.")
231
+ print("Please ensure the file containing kececi_layout_v4 is accessible.")
232
+ exit()
233
+
234
+ # --- General Layout Parameters ---
235
+ LAYOUT_PARAMS = {
236
+ 'primary_spacing': 1.0,
237
+ 'secondary_spacing': 0.6, # Make the zigzag noticeable
238
+ 'primary_direction': 'top_down',
239
+ 'secondary_start': 'right'
240
+ }
241
+ N_NODES = 10 # Number of nodes in the example graph
242
+
243
+ # === Rustworkx Example ===
244
+ try:
245
+ import rustworkx as rx
246
+ print("\n--- Rustworkx Example ---")
247
+
248
+ # Generate graph (Path graph)
249
+ G_rx = rx.generators.path_graph(N_NODES)
250
+ print(f"Rustworkx graph generated: {G_rx.num_nodes()} nodes, {G_rx.num_edges()} edges")
251
+
252
+ # Calculate layout
253
+ print("Calculating Keçeci Layout...")
254
+ # Call the layout function from the imported module
255
+ pos_rx = kl.kececi_layout_v4(G_rx, **LAYOUT_PARAMS)
256
+ # print("Rustworkx positions:", pos_rx) # Debug print if needed
257
+
258
+ # Plot using Matplotlib directly (Rustworkx doesn't have a built-in draw)
259
+ print("Plotting graph using Matplotlib...")
260
+ plt.figure(figsize=(6, 8))
261
+ ax = plt.gca() # Get current axes
262
+
263
+ node_indices_rx = G_rx.node_indices() # Get node indices [0, 1, ...]
264
+
265
+ # Check if all nodes have positions
266
+ if not all(idx in pos_rx for idx in node_indices_rx):
267
+ print("ERROR: Rustworkx positions dictionary does not cover all nodes!")
268
+ # Decide how to handle: exit, plot partial, etc.
269
+ else:
270
+ # Draw nodes
271
+ x_coords_rx = [pos_rx[i][0] for i in node_indices_rx]
272
+ y_coords_rx = [pos_rx[i][1] for i in node_indices_rx]
273
+ ax.scatter(x_coords_rx, y_coords_rx, s=700, c='#88CCEE', zorder=2, label='Nodes') # Skyblue color
274
+
275
+ # Draw labels
276
+ for i in node_indices_rx:
277
+ ax.text(pos_rx[i][0], pos_rx[i][1], str(i), ha='center', va='center', fontsize=10, zorder=3)
185
278
 
186
- G = rx.generators.path_graph(10)
187
- pos = kl.kececi_layout_v4(G, primary_direction='bottom-up')
188
- # Use matplotlib for drawing (see full example in repo)
279
+ # Draw edges using LineCollection for efficiency
280
+ edge_lines = []
281
+ for u, v in G_rx.edge_list(): # Get list of edges (node index pairs)
282
+ if u in pos_rx and v in pos_rx:
283
+ # Segment format: [(x1, y1), (x2, y2)]
284
+ edge_lines.append([pos_rx[u], pos_rx[v]])
285
+ else:
286
+ print(f"Warning: Position not found for edge ({u},{v}) in Rustworkx graph.")
287
+
288
+ if edge_lines:
289
+ lc = LineCollection(edge_lines, colors='gray', linewidths=1.0, zorder=1, label='Edges')
290
+ ax.add_collection(lc) # Add edges to the plot axes
291
+
292
+ plt.title(f"Rustworkx ({N_NODES} Nodes) with Keçeci Layout (Matplotlib)") # Plot title
293
+ plt.xlabel("X Coordinate") # X-axis label
294
+ plt.ylabel("Y Coordinate") # Y-axis label
295
+ plt.axis('equal') # Ensure equal aspect ratio
296
+ plt.grid(False) # Ensure grid is off
297
+ plt.show() # Display the plot
298
+
299
+ except ImportError:
300
+ print("Rustworkx is not installed. Skipping this example.")
301
+ except Exception as e:
302
+ print(f"An error occurred in the Rustworkx example: {e}")
303
+ import traceback
304
+ traceback.print_exc()
305
+
306
+ print("\n--- Rustworkx Example Finished ---")
189
307
  ```
190
308
 
191
309
  ![Rustworkx Example](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/rx-1.png?raw=true)
@@ -193,15 +311,100 @@ pos = kl.kececi_layout_v4(G, primary_direction='bottom-up')
193
311
  #### Example with Networkit
194
312
 
195
313
  ```python
314
+ import matplotlib.pyplot as plt
315
+ from matplotlib.collections import LineCollection # Efficient edge drawing
316
+ import math
196
317
  import networkit as nk
197
318
  import kececilayout as kl
198
- import matplotlib.pyplot as plt
319
+ import random
320
+
321
+ try:
322
+ import kececilayout as kl
323
+ except ImportError:
324
+ print("Error: 'kececi_layout.py' not found or could not be imported.")
325
+ print("Please ensure the file containing kececi_layout_v4 is accessible.")
326
+ exit()
327
+
328
+ # --- General Layout Parameters ---
329
+ LAYOUT_PARAMS = {
330
+ 'primary_spacing': 1.0,
331
+ 'secondary_spacing': 0.6, # Make the zigzag noticeable
332
+ 'primary_direction': 'top_down',
333
+ 'secondary_start': 'right'
334
+ }
335
+ N_NODES = 10 # Number of nodes in the example graph
336
+
337
+ # === Networkit Example ===
338
+ try:
339
+ import networkit as nk
340
+ print("\n--- Networkit Example ---")
341
+
342
+ # Generate graph (Path graph, manually)
343
+ G_nk = nk.graph.Graph(N_NODES, weighted=False, directed=False) # Generate empty graph container
344
+ print("Empty Networkit graph generated.")
345
+ # Add nodes first (Networkit often requires this)
346
+ for i in range(N_NODES):
347
+ if not G_nk.hasNode(i): # Check if node already exists (good practice)
348
+ G_nk.addNode()
349
+ print(f"{G_nk.numberOfNodes()} nodes added.")
350
+ # Add edges
351
+ for i in range(N_NODES - 1):
352
+ G_nk.addEdge(i, i+1) # Add edges 0-1, 1-2, ...
353
+ print(f"Networkit graph constructed: {G_nk.numberOfNodes()} nodes, {G_nk.numberOfEdges()} edges")
354
+
355
+ # Calculate layout
356
+ print("Calculating Keçeci Layout...")
357
+ # Call the layout function from the imported module
358
+ pos_nk = kl.kececi_layout_v4(G_nk, **LAYOUT_PARAMS)
359
+ # print("Networkit positions:", pos_nk) # Debug print if needed
360
+
361
+ # Plot using Matplotlib directly (Networkit doesn't have a simple built-in draw)
362
+ print("Plotting graph using Matplotlib...")
363
+ plt.figure(figsize=(6, 8))
364
+ ax = plt.gca() # Get current axes
365
+
366
+ node_indices_nk = sorted(list(G_nk.iterNodes())) # Get node indices [0, 1, ...]
199
367
 
200
- G = nk.graph.Graph(10)
201
- for i in range(9):
202
- G.addEdge(i, i+1)
203
- pos = kl.kececi_layout_v4(G)
204
- # Draw with matplotlib
368
+ # Check if all nodes have positions
369
+ if not all(idx in pos_nk for idx in node_indices_nk):
370
+ print("ERROR: Networkit positions dictionary does not cover all nodes!")
371
+ else:
372
+ # Draw nodes
373
+ x_coords_nk = [pos_nk[i][0] for i in node_indices_nk]
374
+ y_coords_nk = [pos_nk[i][1] for i in node_indices_nk]
375
+ ax.scatter(x_coords_nk, y_coords_nk, s=700, c='coral', zorder=2, label='Nodes')
376
+
377
+ # Draw labels
378
+ for i in node_indices_nk:
379
+ ax.text(pos_nk[i][0], pos_nk[i][1], str(i), ha='center', va='center', fontsize=10, zorder=3)
380
+
381
+ # Draw edges using LineCollection
382
+ edge_lines_nk = []
383
+ for u, v in G_nk.iterEdges(): # Iterate through edges
384
+ if u in pos_nk and v in pos_nk:
385
+ edge_lines_nk.append([pos_nk[u], pos_nk[v]])
386
+ else:
387
+ print(f"Warning: Position not found for edge ({u},{v}) in Networkit graph.")
388
+
389
+ if edge_lines_nk:
390
+ lc_nk = LineCollection(edge_lines_nk, colors='gray', linewidths=1.0, zorder=1, label='Edges')
391
+ ax.add_collection(lc_nk)
392
+
393
+ plt.title(f"Networkit ({N_NODES} Nodes) with Keçeci Layout (Matplotlib)") # Plot title
394
+ plt.xlabel("X Coordinate") # X-axis label
395
+ plt.ylabel("Y Coordinate") # Y-axis label
396
+ plt.axis('equal') # Ensure equal aspect ratio
397
+ plt.grid(False) # Ensure grid is off
398
+ plt.show() # Display the plot
399
+
400
+ except ImportError:
401
+ print("Networkit is not installed. Skipping this example.")
402
+ except Exception as e:
403
+ print(f"An error occurred in the Networkit example: {e}")
404
+ import traceback
405
+ traceback.print_exc()
406
+
407
+ print("\n--- Networkit Example Finished ---")
205
408
  ```
206
409
 
207
410
  ![Networkit Example](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/nk-1.png?raw=true)
@@ -209,15 +412,105 @@ pos = kl.kececi_layout_v4(G)
209
412
  #### Example with Graphillion
210
413
 
211
414
  ```python
415
+ import matplotlib.pyplot as plt
416
+ from matplotlib.collections import LineCollection # Efficient edge drawing
417
+ import math
418
+ import itertools # Graphillion might implicitly need itertools if find_max_node_id uses it internally
212
419
  import graphillion as gg
213
420
  import kececilayout as kl
214
- import matplotlib.pyplot as plt
421
+ import random
422
+
423
+
424
+ try:
425
+ import kececilayout as kl
426
+ except ImportError:
427
+ print("Error: 'kececi_layout.py' not found or could not be imported.")
428
+ print("Please ensure the file containing kececi_layout_v4 is accessible.")
429
+ exit()
430
+
431
+ # --- General Layout Parameters ---
432
+ LAYOUT_PARAMS = {
433
+ 'primary_spacing': 1.0,
434
+ 'secondary_spacing': 0.6, # Make the zigzag noticeable
435
+ 'primary_direction': 'top_down',
436
+ 'secondary_start': 'right'
437
+ }
438
+ N_NODES = 10 # Number of nodes in the example graph (will be 1 to N_NODES)
439
+
440
+ # === Graphillion Example ===
441
+ try:
442
+ import graphillion as gg
443
+ print("\n--- Graphillion Example ---")
444
+
445
+ # Define the universe of possible edges (Path graph, 1-based indexing common)
446
+ universe = []
447
+ # Edges (1,2), (2,3), ..., (N_NODES-1, N_NODES)
448
+ for i in range(1, N_NODES):
449
+ universe.append((i, i + 1))
450
+ gg.GraphSet.set_universe(universe)
451
+ max_node_gg = N_NODES # We know the max node ID for this simple case
452
+ print(f"Graphillion universe defined: {len(universe)} edges, max node ID {max_node_gg}")
453
+
454
+ # Generate a GraphSet object (can be empty, layout function uses the universe)
455
+ # The layout function provided seems to derive nodes from the universe edges.
456
+ gs = gg.GraphSet()
457
+
458
+ # Calculate layout
459
+ print("Calculating Keçeci Layout...")
460
+ # Call the layout function; it should handle the Graphillion GraphSet object
461
+ # and likely use 1-based indexing based on the universe.
462
+ pos_gg = kl.kececi_layout_v4(gs, **LAYOUT_PARAMS)
463
+ # print("Graphillion positions:", pos_gg) # Debug print if needed
464
+
465
+ # Plot using Matplotlib directly (Graphillion has no plotting)
466
+ print("Plotting graph using Matplotlib...")
467
+ plt.figure(figsize=(6, 8))
468
+ ax = plt.gca() # Get current axes
469
+
470
+ # Node indices are expected to be 1, 2, ... N_NODES from the universe
471
+ node_indices_gg = sorted(pos_gg.keys())
472
+
473
+ # Check if all expected nodes (1 to N_NODES) have positions
474
+ expected_nodes = set(range(1, N_NODES + 1))
475
+ if not expected_nodes.issubset(set(node_indices_gg)):
476
+ print(f"ERROR: Graphillion positions missing expected nodes. Found: {node_indices_gg}, Expected: {list(expected_nodes)}")
477
+ else:
478
+ # Draw nodes
479
+ x_coords_gg = [pos_gg[i][0] for i in node_indices_gg]
480
+ y_coords_gg = [pos_gg[i][1] for i in node_indices_gg]
481
+ ax.scatter(x_coords_gg, y_coords_gg, s=700, c='gold', zorder=2, label='Nodes')
482
+
483
+ # Draw labels (using the 1-based indices)
484
+ for i in node_indices_gg:
485
+ ax.text(pos_gg[i][0], pos_gg[i][1], str(i), ha='center', va='center', fontsize=10, zorder=3)
486
+
487
+ # Draw edges using LineCollection (from the defined universe)
488
+ edge_lines_gg = []
489
+ for u, v in universe: # Use the universe edges
490
+ if u in pos_gg and v in pos_gg:
491
+ edge_lines_gg.append([pos_gg[u], pos_gg[v]])
492
+ else:
493
+ print(f"Warning: Position not found for universe edge ({u},{v}) in Graphillion.")
494
+
495
+ if edge_lines_gg:
496
+ lc_gg = LineCollection(edge_lines_gg, colors='gray', linewidths=1.0, zorder=1, label='Edges')
497
+ ax.add_collection(lc_gg)
498
+
499
+ plt.title(f"Graphillion ({N_NODES} Nodes) with Keçeci Layout (Matplotlib)") # Plot title
500
+ plt.xlabel("X Coordinate") # X-axis label
501
+ plt.ylabel("Y Coordinate") # Y-axis label
502
+ plt.axis('equal') # Ensure equal aspect ratio
503
+ plt.grid(False) # Ensure grid is off
504
+ plt.show() # Display the plot
505
+
506
+ except ImportError:
507
+ print("Graphillion is not installed. Skipping this example.")
508
+ except Exception as e:
509
+ print(f"An error occurred in the Graphillion example: {e}")
510
+ import traceback
511
+ traceback.print_exc()
215
512
 
216
- universe = [(i, i+1) for i in range(1, 10)]
217
- gg.GraphSet.set_universe(universe)
218
- gs = gg.GraphSet()
219
- pos = kl.kececi_layout_v4(gs)
220
- # Draw with matplotlib
513
+ print("\n--- Graphillion Example Finished ---")
221
514
  ```
222
515
 
223
516
  ![Graphillion Example](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/gg-1.png?raw=true)
@@ -271,131 +564,457 @@ If this library was useful in your research, please cite:
271
564
  }
272
565
  ```
273
566
 
274
- ---
567
+ ---
568
+
569
+ ## 🇹🇷 Türkçe
570
+
571
+ ### Keçeci Yerleşimi (Kececi Layout)
572
+
573
+ **KececiLayout**, doğrusal veya ardışık yapıları görselleştirmek için tasarlanmış, karakteristik bir "zıgzag" veya "yılanvari" desen oluşturan deterministik bir graf yerleşim algoritmasıdır.
574
+
575
+ *Graf görselleştirme için Keçeci yerleşim algoritmasının Python uygulaması.*
576
+
577
+ ---
578
+
579
+ ### Açıklama
580
+
581
+ Bu algoritma, düğümleri birincil eksen boyunca sıralı olarak yerleştirir ve ikincil eksen boyunca dönüşümlü olarak kaydırır. Yol grafları, zincirler veya ilerlemeyi göstermek için özellikle kullanışlıdır.
582
+
583
+ **Temel Özellikler:**
584
+ * **Doğrusal Odak:** Yollar, zincirler veya sıralı süreçler için idealdir.
585
+ * **Deterministik:** Aynı giriş için her zaman aynı çıktıyı üretir.
586
+ * **Çakışmayı Azaltma:** Düğümleri eksenler boyunca yayarak çakışmaları önler.
587
+ * **Parametrik:** `primary_spacing`, `secondary_spacing`, `primary_direction`, `secondary_start` gibi parametrelerle özelleştirilebilir.
588
+
589
+ => **v0.2.7**: Eğri, şeffaf, 3B ve `expanding=True` stilleri desteklenir.
590
+
591
+ ---
592
+
593
+ ### Kurulum
594
+
595
+ ```bash
596
+ conda install bilgi::kececilayout -y
597
+ pip install kececilayout
598
+ ```
599
+
600
+ 🔗 [PyPI](https://pypi.org/project/kececilayout/) | [Conda](https://anaconda.org/bilgi/kececilayout) | [GitHub](https://github.com/WhiteSymmetry/kececilayout)
601
+
602
+ ---
603
+
604
+ ### Kullanım
605
+
606
+ #### NetworkX ile Örnek
607
+
608
+ ```python
609
+ import networkx as nx
610
+ import matplotlib.pyplot as plt
611
+ import kececilayout as kl
612
+
613
+ G = nx.path_graph(10)
614
+ pos = kl.kececi_layout(
615
+ G,
616
+ primary_spacing=1.0,
617
+ secondary_spacing=0.5,
618
+ primary_direction='top_down',
619
+ secondary_start='right'
620
+ )
621
+
622
+ plt.figure(figsize=(6, 8))
623
+ nx.draw(G, pos=pos, with_labels=True, node_color='skyblue', node_size=500)
624
+ plt.title("Kececi Layout with NetworkX")
625
+ plt.axis('equal')
626
+ plt.show()
627
+ ```
628
+
629
+ ![NetworkX Örneği](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/nx-1.png?raw=true)
630
+
631
+ #### iGraph ile Örnek
632
+
633
+ ```python
634
+ import matplotlib.pyplot as plt
635
+ import math
636
+ import igraph as ig
637
+ import kececilayout as kl
638
+
639
+
640
+ try:
641
+ import kececilayout as kl
642
+ except ImportError:
643
+ print("Error: 'kececi_layout.py' not found or could not be imported.")
644
+ print("Please ensure the file containing kececi_layout_v4 is accessible.")
645
+ exit()
646
+
647
+ # --- General Layout Parameters ---
648
+ LAYOUT_PARAMS = {
649
+ 'primary_spacing': 1.0,
650
+ 'secondary_spacing': 0.6, # Make the zigzag noticeable
651
+ 'primary_direction': 'top_down',
652
+ 'secondary_start': 'right'
653
+ }
654
+ N_NODES = 10 # Number of nodes in the example graph
655
+
656
+ # === igraph Example ===
657
+ try:
658
+ import igraph as ig
659
+ print("\n--- igraph Example ---")
660
+
661
+ # Generate graph (Path graph using Ring(circular=False))
662
+ G_ig = ig.Graph.Ring(N_NODES, directed=False, circular=False)
663
+ print(f"igraph graph generated: {G_ig.vcount()} vertices, {G_ig.ecount()} edges")
664
+
665
+ # Calculate layout
666
+ print("Calculating Keçeci Layout...")
667
+ # Call the layout function from the imported module
668
+ pos_ig = kl.kececi_layout_v4(G_ig, **LAYOUT_PARAMS)
669
+ # print("igraph positions (dict):", pos_ig) # Debug print if needed
670
+
671
+ # Convert positions dict to list ordered by vertex index for ig.plot
672
+ layout_list_ig = []
673
+ plot_possible = True
674
+ if pos_ig: # Check if dictionary is not empty
675
+ try:
676
+ # Generate list: [pos_ig[0], pos_ig[1], ..., pos_ig[N-1]]
677
+ layout_list_ig = [pos_ig[i] for i in range(G_ig.vcount())]
678
+ # print("igraph layout (list):", layout_list_ig) # Debug print if needed
679
+ except KeyError as e:
680
+ print(f"ERROR: Key {e} not found while creating position list for igraph.")
681
+ print("The layout function might not have returned positions for all vertices.")
682
+ plot_possible = False # Cannot plot if list is incomplete
683
+ else:
684
+ print("ERROR: Keçeci Layout returned empty positions for igraph.")
685
+ plot_possible = False
686
+
687
+ # Plot using igraph's plotting capabilities
688
+ print("Plotting graph using igraph.plot...")
689
+ fig, ax = plt.subplots(figsize=(6, 8)) # Generate matplotlib figure and axes
690
+
691
+ if plot_possible:
692
+ ig.plot(G_ig,
693
+ target=ax, # Draw on the matplotlib axes
694
+ layout=layout_list_ig, # Use the ORDERED LIST of coordinates
695
+ vertex_label=[str(i) for i in range(G_ig.vcount())], # Labels 0, 1,...
696
+ vertex_color='lightgreen',
697
+ vertex_size=30, # Note: igraph vertex_size scale differs
698
+ edge_color='gray')
699
+ else:
700
+ ax.text(0.5, 0.5, "Plotting failed:\nMissing or incomplete layout positions.",
701
+ ha='center', va='center', color='red', fontsize=12) # Error message on plot
702
+
703
+ ax.set_title(f"igraph ({N_NODES} Nodes) with Keçeci Layout") # Plot title
704
+ ax.set_aspect('equal', adjustable='box') # Ensure equal aspect ratio
705
+ # ax.grid(False) # Ensure grid is off
706
+ plt.show() # Display the plot
707
+
708
+ except ImportError:
709
+ print("python-igraph is not installed. Skipping this example.")
710
+ except Exception as e:
711
+ print(f"An error occurred in the igraph example: {e}")
712
+ import traceback
713
+ traceback.print_exc()
714
+
715
+ print("\n--- igraph Example Finished ---")
716
+ ```
717
+
718
+ ![iGraph Örneği](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/ig-1.png?raw=true)
719
+
720
+ #### RustworkX ile Örnek
721
+
722
+ ```python
723
+ import matplotlib.pyplot as plt
724
+ from matplotlib.collections import LineCollection # Efficient edge drawing
725
+ import math
726
+ import rustworkx as rx
727
+ import kececilayout as kl
728
+ import random
729
+
730
+
731
+ try:
732
+ import kececilayout as kl
733
+ except ImportError:
734
+ print("Error: 'kececi_layout.py' not found or could not be imported.")
735
+ print("Please ensure the file containing kececi_layout_v4 is accessible.")
736
+ exit()
737
+
738
+ # --- General Layout Parameters ---
739
+ LAYOUT_PARAMS = {
740
+ 'primary_spacing': 1.0,
741
+ 'secondary_spacing': 0.6, # Make the zigzag noticeable
742
+ 'primary_direction': 'top_down',
743
+ 'secondary_start': 'right'
744
+ }
745
+ N_NODES = 10 # Number of nodes in the example graph
746
+
747
+ # === Rustworkx Example ===
748
+ try:
749
+ import rustworkx as rx
750
+ print("\n--- Rustworkx Example ---")
751
+
752
+ # Generate graph (Path graph)
753
+ G_rx = rx.generators.path_graph(N_NODES)
754
+ print(f"Rustworkx graph generated: {G_rx.num_nodes()} nodes, {G_rx.num_edges()} edges")
755
+
756
+ # Calculate layout
757
+ print("Calculating Keçeci Layout...")
758
+ # Call the layout function from the imported module
759
+ pos_rx = kl.kececi_layout_v4(G_rx, **LAYOUT_PARAMS)
760
+ # print("Rustworkx positions:", pos_rx) # Debug print if needed
761
+
762
+ # Plot using Matplotlib directly (Rustworkx doesn't have a built-in draw)
763
+ print("Plotting graph using Matplotlib...")
764
+ plt.figure(figsize=(6, 8))
765
+ ax = plt.gca() # Get current axes
766
+
767
+ node_indices_rx = G_rx.node_indices() # Get node indices [0, 1, ...]
768
+
769
+ # Check if all nodes have positions
770
+ if not all(idx in pos_rx for idx in node_indices_rx):
771
+ print("ERROR: Rustworkx positions dictionary does not cover all nodes!")
772
+ # Decide how to handle: exit, plot partial, etc.
773
+ else:
774
+ # Draw nodes
775
+ x_coords_rx = [pos_rx[i][0] for i in node_indices_rx]
776
+ y_coords_rx = [pos_rx[i][1] for i in node_indices_rx]
777
+ ax.scatter(x_coords_rx, y_coords_rx, s=700, c='#88CCEE', zorder=2, label='Nodes') # Skyblue color
778
+
779
+ # Draw labels
780
+ for i in node_indices_rx:
781
+ ax.text(pos_rx[i][0], pos_rx[i][1], str(i), ha='center', va='center', fontsize=10, zorder=3)
782
+
783
+ # Draw edges using LineCollection for efficiency
784
+ edge_lines = []
785
+ for u, v in G_rx.edge_list(): # Get list of edges (node index pairs)
786
+ if u in pos_rx and v in pos_rx:
787
+ # Segment format: [(x1, y1), (x2, y2)]
788
+ edge_lines.append([pos_rx[u], pos_rx[v]])
789
+ else:
790
+ print(f"Warning: Position not found for edge ({u},{v}) in Rustworkx graph.")
791
+
792
+ if edge_lines:
793
+ lc = LineCollection(edge_lines, colors='gray', linewidths=1.0, zorder=1, label='Edges')
794
+ ax.add_collection(lc) # Add edges to the plot axes
795
+
796
+ plt.title(f"Rustworkx ({N_NODES} Nodes) with Keçeci Layout (Matplotlib)") # Plot title
797
+ plt.xlabel("X Coordinate") # X-axis label
798
+ plt.ylabel("Y Coordinate") # Y-axis label
799
+ plt.axis('equal') # Ensure equal aspect ratio
800
+ plt.grid(False) # Ensure grid is off
801
+ plt.show() # Display the plot
275
802
 
276
- ## 🇹🇷 Türkçe
803
+ except ImportError:
804
+ print("Rustworkx is not installed. Skipping this example.")
805
+ except Exception as e:
806
+ print(f"An error occurred in the Rustworkx example: {e}")
807
+ import traceback
808
+ traceback.print_exc()
277
809
 
278
- ### Keçeci Yerleşimi (Kececi Layout)
810
+ print("\n--- Rustworkx Example Finished ---")
811
+ ```
279
812
 
280
- **KececiLayout**, doğrusal veya ardışık yapıları görselleştirmek için tasarlanmış, karakteristik bir "zıgzag" veya "yılanvari" desen oluşturan deterministik bir graf yerleşim algoritmasıdır.
813
+ ![RustworkX Örneği](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/rx-1.png?raw=true)
281
814
 
282
- *Graf görselleştirme için Keçeci yerleşim algoritmasının Python uygulaması.*
815
+ #### Networkit ile Örnek
283
816
 
284
- ---
817
+ ```python
818
+ import matplotlib.pyplot as plt
819
+ from matplotlib.collections import LineCollection # Efficient edge drawing
820
+ import math
821
+ import networkit as nk
822
+ import kececilayout as kl
823
+ import random
285
824
 
286
- ### Açıklama
825
+ try:
826
+ import kececilayout as kl
827
+ except ImportError:
828
+ print("Error: 'kececi_layout.py' not found or could not be imported.")
829
+ print("Please ensure the file containing kececi_layout_v4 is accessible.")
830
+ exit()
287
831
 
288
- Bu algoritma, düğümleri birincil eksen boyunca sıralı olarak yerleştirir ve ikincil eksen boyunca dönüşümlü olarak kaydırır. Yol grafları, zincirler veya ilerlemeyi göstermek için özellikle kullanışlıdır.
832
+ # --- General Layout Parameters ---
833
+ LAYOUT_PARAMS = {
834
+ 'primary_spacing': 1.0,
835
+ 'secondary_spacing': 0.6, # Make the zigzag noticeable
836
+ 'primary_direction': 'top_down',
837
+ 'secondary_start': 'right'
838
+ }
839
+ N_NODES = 10 # Number of nodes in the example graph
289
840
 
290
- **Temel Özellikler:**
291
- * **Doğrusal Odak:** Yollar, zincirler veya sıralı süreçler için idealdir.
292
- * **Deterministik:** Aynı giriş için her zaman aynı çıktıyı üretir.
293
- * **Çakışmayı Azaltma:** Düğümleri eksenler boyunca yayarak çakışmaları önler.
294
- * **Parametrik:** `primary_spacing`, `secondary_spacing`, `primary_direction`, `secondary_start` gibi parametrelerle özelleştirilebilir.
841
+ # === Networkit Example ===
842
+ try:
843
+ import networkit as nk
844
+ print("\n--- Networkit Example ---")
295
845
 
296
- => **v0.2.7**: Eğri, şeffaf, 3B ve `expanding=True` stilleri desteklenir.
846
+ # Generate graph (Path graph, manually)
847
+ G_nk = nk.graph.Graph(N_NODES, weighted=False, directed=False) # Generate empty graph container
848
+ print("Empty Networkit graph generated.")
849
+ # Add nodes first (Networkit often requires this)
850
+ for i in range(N_NODES):
851
+ if not G_nk.hasNode(i): # Check if node already exists (good practice)
852
+ G_nk.addNode()
853
+ print(f"{G_nk.numberOfNodes()} nodes added.")
854
+ # Add edges
855
+ for i in range(N_NODES - 1):
856
+ G_nk.addEdge(i, i+1) # Add edges 0-1, 1-2, ...
857
+ print(f"Networkit graph constructed: {G_nk.numberOfNodes()} nodes, {G_nk.numberOfEdges()} edges")
297
858
 
298
- ---
859
+ # Calculate layout
860
+ print("Calculating Keçeci Layout...")
861
+ # Call the layout function from the imported module
862
+ pos_nk = kl.kececi_layout_v4(G_nk, **LAYOUT_PARAMS)
863
+ # print("Networkit positions:", pos_nk) # Debug print if needed
299
864
 
300
- ### Kurulum
865
+ # Plot using Matplotlib directly (Networkit doesn't have a simple built-in draw)
866
+ print("Plotting graph using Matplotlib...")
867
+ plt.figure(figsize=(6, 8))
868
+ ax = plt.gca() # Get current axes
301
869
 
302
- ```bash
303
- conda install bilgi::kececilayout -y
304
- pip install kececilayout
305
- ```
870
+ node_indices_nk = sorted(list(G_nk.iterNodes())) # Get node indices [0, 1, ...]
306
871
 
307
- 🔗 [PyPI](https://pypi.org/project/kececilayout/) | [Conda](https://anaconda.org/bilgi/kececilayout) | [GitHub](https://github.com/WhiteSymmetry/kececilayout)
872
+ # Check if all nodes have positions
873
+ if not all(idx in pos_nk for idx in node_indices_nk):
874
+ print("ERROR: Networkit positions dictionary does not cover all nodes!")
875
+ else:
876
+ # Draw nodes
877
+ x_coords_nk = [pos_nk[i][0] for i in node_indices_nk]
878
+ y_coords_nk = [pos_nk[i][1] for i in node_indices_nk]
879
+ ax.scatter(x_coords_nk, y_coords_nk, s=700, c='coral', zorder=2, label='Nodes')
308
880
 
309
- ---
881
+ # Draw labels
882
+ for i in node_indices_nk:
883
+ ax.text(pos_nk[i][0], pos_nk[i][1], str(i), ha='center', va='center', fontsize=10, zorder=3)
310
884
 
311
- ### Kullanım
885
+ # Draw edges using LineCollection
886
+ edge_lines_nk = []
887
+ for u, v in G_nk.iterEdges(): # Iterate through edges
888
+ if u in pos_nk and v in pos_nk:
889
+ edge_lines_nk.append([pos_nk[u], pos_nk[v]])
890
+ else:
891
+ print(f"Warning: Position not found for edge ({u},{v}) in Networkit graph.")
312
892
 
313
- #### NetworkX ile Örnek
893
+ if edge_lines_nk:
894
+ lc_nk = LineCollection(edge_lines_nk, colors='gray', linewidths=1.0, zorder=1, label='Edges')
895
+ ax.add_collection(lc_nk)
314
896
 
315
- ```python
316
- import networkx as nx
317
- import matplotlib.pyplot as plt
318
- import kececilayout as kl
897
+ plt.title(f"Networkit ({N_NODES} Nodes) with Keçeci Layout (Matplotlib)") # Plot title
898
+ plt.xlabel("X Coordinate") # X-axis label
899
+ plt.ylabel("Y Coordinate") # Y-axis label
900
+ plt.axis('equal') # Ensure equal aspect ratio
901
+ plt.grid(False) # Ensure grid is off
902
+ plt.show() # Display the plot
319
903
 
320
- G = nx.path_graph(10)
321
- pos = kl.kececi_layout_v4(
322
- G,
323
- primary_spacing=1.0,
324
- secondary_spacing=0.5,
325
- primary_direction='top-down',
326
- secondary_start='right'
327
- )
904
+ except ImportError:
905
+ print("Networkit is not installed. Skipping this example.")
906
+ except Exception as e:
907
+ print(f"An error occurred in the Networkit example: {e}")
908
+ import traceback
909
+ traceback.print_exc()
328
910
 
329
- plt.figure(figsize=(6, 8))
330
- nx.draw(G, pos=pos, with_labels=True, node_color='skyblue', node_size=500)
331
- plt.title("Kececi Layout with NetworkX")
332
- plt.axis('equal')
333
- plt.show()
911
+ print("\n--- Networkit Example Finished ---")
334
912
  ```
335
913
 
336
- ![NetworkX Örneği](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/nx-1.png?raw=true)
914
+ ![Networkit Örneği](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/nk-1.png?raw=true)
337
915
 
338
- #### iGraph ile Örnek
916
+ #### Graphillion ile Örnek
339
917
 
340
918
  ```python
341
- import igraph as ig
342
919
  import matplotlib.pyplot as plt
343
- from kececilayout import kececi_layout_v4_igraph
920
+ from matplotlib.collections import LineCollection # Efficient edge drawing
921
+ import math
922
+ import itertools # Graphillion might implicitly need itertools if find_max_node_id uses it internally
923
+ import graphillion as gg
924
+ import kececilayout as kl
925
+ import random
344
926
 
345
- G = ig.Graph.Ring(10, circular=False)
346
- pos_list = kececi_layout_v4_igraph(G, primary_direction='left-to-right', secondary_start='up')
347
- layout = ig.Layout(pos_list)
348
927
 
349
- fig, ax = plt.subplots(figsize=(8, 6))
350
- ig.plot(G, target=ax, layout=layout, vertex_label=[f"N{i}" for i in range(10)])
351
- ax.set_aspect('equal')
352
- plt.show()
353
- ```
928
+ try:
929
+ import kececilayout as kl
930
+ except ImportError:
931
+ print("Error: 'kececi_layout.py' not found or could not be imported.")
932
+ print("Please ensure the file containing kececi_layout_v4 is accessible.")
933
+ exit()
354
934
 
355
- ![iGraph Örneği](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/ig-1.png?raw=true)
935
+ # --- General Layout Parameters ---
936
+ LAYOUT_PARAMS = {
937
+ 'primary_spacing': 1.0,
938
+ 'secondary_spacing': 0.6, # Make the zigzag noticeable
939
+ 'primary_direction': 'top_down',
940
+ 'secondary_start': 'right'
941
+ }
942
+ N_NODES = 10 # Number of nodes in the example graph (will be 1 to N_NODES)
356
943
 
357
- #### RustworkX ile Örnek
944
+ # === Graphillion Example ===
945
+ try:
946
+ import graphillion as gg
947
+ print("\n--- Graphillion Example ---")
358
948
 
359
- ```python
360
- import rustworkx as rx
361
- import kececilayout as kl
362
- import matplotlib.pyplot as plt
949
+ # Define the universe of possible edges (Path graph, 1-based indexing common)
950
+ universe = []
951
+ # Edges (1,2), (2,3), ..., (N_NODES-1, N_NODES)
952
+ for i in range(1, N_NODES):
953
+ universe.append((i, i + 1))
954
+ gg.GraphSet.set_universe(universe)
955
+ max_node_gg = N_NODES # We know the max node ID for this simple case
956
+ print(f"Graphillion universe defined: {len(universe)} edges, max node ID {max_node_gg}")
363
957
 
364
- G = rx.generators.path_graph(10)
365
- pos = kl.kececi_layout_v4(G, primary_direction='bottom-up')
366
- # Matplotlib ile çizim yapılabilir
367
- ```
958
+ # Generate a GraphSet object (can be empty, layout function uses the universe)
959
+ # The layout function provided seems to derive nodes from the universe edges.
960
+ gs = gg.GraphSet()
368
961
 
369
- ![RustworkX Örneği](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/rx-1.png?raw=true)
962
+ # Calculate layout
963
+ print("Calculating Keçeci Layout...")
964
+ # Call the layout function; it should handle the Graphillion GraphSet object
965
+ # and likely use 1-based indexing based on the universe.
966
+ pos_gg = kl.kececi_layout_v4(gs, **LAYOUT_PARAMS)
967
+ # print("Graphillion positions:", pos_gg) # Debug print if needed
370
968
 
371
- #### Networkit ile Örnek
969
+ # Plot using Matplotlib directly (Graphillion has no plotting)
970
+ print("Plotting graph using Matplotlib...")
971
+ plt.figure(figsize=(6, 8))
972
+ ax = plt.gca() # Get current axes
372
973
 
373
- ```python
374
- import networkit as nk
375
- import kececilayout as kl
376
- import matplotlib.pyplot as plt
974
+ # Node indices are expected to be 1, 2, ... N_NODES from the universe
975
+ node_indices_gg = sorted(pos_gg.keys())
377
976
 
378
- G = nk.graph.Graph(10)
379
- for i in range(9):
380
- G.addEdge(i, i+1)
381
- pos = kl.kececi_layout_v4(G)
382
- # Matplotlib ile çizim
383
- ```
977
+ # Check if all expected nodes (1 to N_NODES) have positions
978
+ expected_nodes = set(range(1, N_NODES + 1))
979
+ if not expected_nodes.issubset(set(node_indices_gg)):
980
+ print(f"ERROR: Graphillion positions missing expected nodes. Found: {node_indices_gg}, Expected: {list(expected_nodes)}")
981
+ else:
982
+ # Draw nodes
983
+ x_coords_gg = [pos_gg[i][0] for i in node_indices_gg]
984
+ y_coords_gg = [pos_gg[i][1] for i in node_indices_gg]
985
+ ax.scatter(x_coords_gg, y_coords_gg, s=700, c='gold', zorder=2, label='Nodes')
384
986
 
385
- ![Networkit Örneği](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/nk-1.png?raw=true)
987
+ # Draw labels (using the 1-based indices)
988
+ for i in node_indices_gg:
989
+ ax.text(pos_gg[i][0], pos_gg[i][1], str(i), ha='center', va='center', fontsize=10, zorder=3)
386
990
 
387
- #### Graphillion ile Örnek
991
+ # Draw edges using LineCollection (from the defined universe)
992
+ edge_lines_gg = []
993
+ for u, v in universe: # Use the universe edges
994
+ if u in pos_gg and v in pos_gg:
995
+ edge_lines_gg.append([pos_gg[u], pos_gg[v]])
996
+ else:
997
+ print(f"Warning: Position not found for universe edge ({u},{v}) in Graphillion.")
388
998
 
389
- ```python
390
- import graphillion as gg
391
- import kececilayout as kl
392
- import matplotlib.pyplot as plt
999
+ if edge_lines_gg:
1000
+ lc_gg = LineCollection(edge_lines_gg, colors='gray', linewidths=1.0, zorder=1, label='Edges')
1001
+ ax.add_collection(lc_gg)
1002
+
1003
+ plt.title(f"Graphillion ({N_NODES} Nodes) with Keçeci Layout (Matplotlib)") # Plot title
1004
+ plt.xlabel("X Coordinate") # X-axis label
1005
+ plt.ylabel("Y Coordinate") # Y-axis label
1006
+ plt.axis('equal') # Ensure equal aspect ratio
1007
+ plt.grid(False) # Ensure grid is off
1008
+ plt.show() # Display the plot
1009
+
1010
+ except ImportError:
1011
+ print("Graphillion is not installed. Skipping this example.")
1012
+ except Exception as e:
1013
+ print(f"An error occurred in the Graphillion example: {e}")
1014
+ import traceback
1015
+ traceback.print_exc()
393
1016
 
394
- universe = [(i, i+1) for i in range(1, 10)]
395
- gg.GraphSet.set_universe(universe)
396
- gs = gg.GraphSet()
397
- pos = kl.kececi_layout_v4(gs)
398
- # Matplotlib ile çizim
1017
+ print("\n--- Graphillion Example Finished ---")
399
1018
  ```
400
1019
 
401
1020
  ![Graphillion Örneği](https://github.com/WhiteSymmetry/kececilayout/blob/main/examples/gg-1.png?raw=true)
@@ -559,7 +1178,7 @@ A deterministic node placement algorithm used in graph visualization. In this la
559
1178
  * **Linear Focus:** Particularly useful for visualizing linear or sequential structures, such as paths, chains, or ordered processes.
560
1179
  * **Deterministic:** Produces the exact same layout for the same graph and parameters every time.
561
1180
  * **Overlap Reduction:** Helps prevent node collisions by spreading nodes out away from the primary axis.
562
- * **Parametric:** Can be customized using parameters such as the primary direction (e.g., `top-down`), the starting side for the secondary offset (e.g., `start_right`), and the spacing along both axes (`primary_spacing`, `secondary_spacing`).
1181
+ * **Parametric:** Can be customized using parameters such as the primary direction (e.g., `top_down`), the starting side for the secondary offset (e.g., `start_right`), and the spacing along both axes (`primary_spacing`, `secondary_spacing`).
563
1182
 
564
1183
  ---
565
1184
 
@@ -573,7 +1192,7 @@ Graf görselleştirmede kullanılan deterministik bir düğüm yerleştirme algo
573
1192
  * **Doğrusal Odak:** Özellikle yollar (paths), zincirler veya sıralı süreçler gibi doğrusal veya ardışık yapıları görselleştirmek için kullanışlıdır.
574
1193
  * **Deterministik:** Aynı graf ve parametrelerle her zaman aynı sonucu üretir.
575
1194
  * **Çakışmayı Azaltma:** Düğümleri ana eksenden uzağa yayarak çakışmaları önlemeye yardımcı olur.
576
- * **Parametrik:** Ana eksenin yönü (örn. `top-down`), ikincil kaydırmanın başlangıç yönü (örn. `start_right`) ve eksenler arası boşluklar (`primary_spacing`, `secondary_spacing`) gibi parametrelerle özelleştirilebilir.
1195
+ * **Parametrik:** Ana eksenin yönü (örn. `top_down`), ikincil kaydırmanın başlangıç yönü (örn. `start_right`) ve eksenler arası boşluklar (`primary_spacing`, `secondary_spacing`) gibi parametrelerle özelleştirilebilir.
577
1196
 
578
1197
  ---
579
1198
 
@@ -616,7 +1235,7 @@ G = nx.path_graph(10)
616
1235
  pos = kl.kececi_layout_v4(G,
617
1236
  primary_spacing=1.0,
618
1237
  secondary_spacing=0.5,
619
- primary_direction='top-down',
1238
+ primary_direction='top_down',
620
1239
  secondary_start='right')
621
1240
 
622
1241
  # Draw the graph
@@ -645,7 +1264,7 @@ except ImportError:
645
1264
  LAYOUT_PARAMS = {
646
1265
  'primary_spacing': 1.0,
647
1266
  'secondary_spacing': 0.6, # Make the zigzag noticeable
648
- 'primary_direction': 'top-down',
1267
+ 'primary_direction': 'top_down',
649
1268
  'secondary_start': 'right'
650
1269
  }
651
1270
  N_NODES = 10 # Number of nodes in the example graph
@@ -750,7 +1369,7 @@ except ImportError:
750
1369
  LAYOUT_PARAMS = {
751
1370
  'primary_spacing': 1.0,
752
1371
  'secondary_spacing': 0.6, # Make the zigzag noticeable
753
- 'primary_direction': 'top-down',
1372
+ 'primary_direction': 'top_down',
754
1373
  'secondary_start': 'right'
755
1374
  }
756
1375
  N_NODES = 10 # Number of nodes in the example graph
@@ -843,7 +1462,7 @@ except ImportError:
843
1462
  LAYOUT_PARAMS = {
844
1463
  'primary_spacing': 1.0,
845
1464
  'secondary_spacing': 0.6, # Make the zigzag noticeable
846
- 'primary_direction': 'top-down',
1465
+ 'primary_direction': 'top_down',
847
1466
  'secondary_start': 'right'
848
1467
  }
849
1468
  N_NODES = 10 # Number of nodes in the example graph
@@ -939,7 +1558,7 @@ except ImportError:
939
1558
  LAYOUT_PARAMS = {
940
1559
  'primary_spacing': 1.0,
941
1560
  'secondary_spacing': 0.6, # Make the zigzag noticeable
942
- 'primary_direction': 'top-down',
1561
+ 'primary_direction': 'top_down',
943
1562
  'secondary_start': 'right'
944
1563
  }
945
1564
  N_NODES = 10 # Number of nodes in the example graph
@@ -1044,7 +1663,7 @@ except ImportError:
1044
1663
  LAYOUT_PARAMS = {
1045
1664
  'primary_spacing': 1.0,
1046
1665
  'secondary_spacing': 0.6, # Make the zigzag noticeable
1047
- 'primary_direction': 'top-down',
1666
+ 'primary_direction': 'top_down',
1048
1667
  'secondary_start': 'right'
1049
1668
  }
1050
1669
  N_NODES = 10 # Number of nodes in the example graph (will be 1 to N_NODES)
@@ -1241,13 +1860,3 @@ Keçeci, Mehmet. "Kececilayout". Open Science Articles (OSAs), Zenodo, 2025. htt
1241
1860
 
1242
1861
  Keçeci, Mehmet. "Keçeci Layout". Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.15314328.
1243
1862
  ```
1244
-
1245
-
1246
-
1247
-
1248
-
1249
-
1250
-
1251
-
1252
-
1253
-
@@ -0,0 +1,8 @@
1
+ kececilayout/__init__.py,sha256=J8gDPZhZ6EinF_2-jSaC6ZDJ8HyFZ3lgmHqILsAQFhA,4230
2
+ kececilayout/_version.py,sha256=ag7QDMboOIiBZKouMZEt0w5P2Q6kBDW7IyQLv4YqTAE,813
3
+ kececilayout/kececi_layout.py,sha256=KWPOvtPjzUbxzfDAAstBgvjoidtgGkixkfmoQNa7tgw,65990
4
+ kececilayout-0.4.5.dist-info/licenses/LICENSE,sha256=NJZsJEbQuKzxn1mWPWCbRx8jRUqGS22thl8wwuRQJ9c,1071
5
+ kececilayout-0.4.5.dist-info/METADATA,sha256=DUd0YVpaKenyD3nJ74729kWXziDAsLt0TsSyy33ljpg,73243
6
+ kececilayout-0.4.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ kececilayout-0.4.5.dist-info/top_level.txt,sha256=OBzN_wm4q-iwSkeACF4E8ET_LFLJKBTldSH3D1jG2hA,13
8
+ kececilayout-0.4.5.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- kececilayout/__init__.py,sha256=ya1f1Hx9MbS04zu8jpjW_Lq82H-zIYu7R-NzLL2mx40,4226
2
- kececilayout/_version.py,sha256=fN2LSPj9YZtOf8U7dE1dA-uf9QAQ_GmUWm8UlLIsI7I,823
3
- kececilayout/kececi_layout.py,sha256=KWPOvtPjzUbxzfDAAstBgvjoidtgGkixkfmoQNa7tgw,65990
4
- kececilayout-0.4.3.dist-info/licenses/LICENSE,sha256=NJZsJEbQuKzxn1mWPWCbRx8jRUqGS22thl8wwuRQJ9c,1071
5
- kececilayout-0.4.3.dist-info/METADATA,sha256=O1Ei8SPX7kFv-MplHzbsI0OUfgPo6P2PatoQ0-xxTho,48622
6
- kececilayout-0.4.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
- kececilayout-0.4.3.dist-info/top_level.txt,sha256=OBzN_wm4q-iwSkeACF4E8ET_LFLJKBTldSH3D1jG2hA,13
8
- kececilayout-0.4.3.dist-info/RECORD,,