kececilayout 0.4.8__tar.gz → 0.5.0__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kececilayout
3
- Version: 0.4.8
3
+ Version: 0.5.0
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
@@ -54,6 +54,7 @@ Requires-Dist: rustworkx; extra == "test"
54
54
  Requires-Dist: networkit; extra == "test"
55
55
  Requires-Dist: graphillion; extra == "test"
56
56
  Requires-Dist: graph-tool; extra == "test"
57
+ Requires-Dist: numba; extra == "test"
57
58
  Dynamic: author
58
59
  Dynamic: home-page
59
60
  Dynamic: license-file
@@ -118,6 +119,12 @@ This algorithm arranges nodes sequentially along a primary axis and offsets them
118
119
 
119
120
  => **v0.2.7**: Curved, transparent, 3D, and `expanding=True` styles supported.
120
121
 
122
+ **v0.5.0:**
123
+
124
+ layouts = ['2d', 'cylindrical', 'cubic', 'spherical', 'elliptical', 'toric']
125
+
126
+ styles = ['standard', 'default', 'curved', 'helix', '3d', 'weighted', 'colored']
127
+
121
128
  ---
122
129
 
123
130
  ### Installation
@@ -1958,3 +1965,5 @@ Keçeci, Mehmet. "Keçeci Layout". Open Science Articles (OSAs), Zenodo, 2025. h
1958
1965
 
1959
1966
 
1960
1967
 
1968
+
1969
+
@@ -55,6 +55,12 @@ This algorithm arranges nodes sequentially along a primary axis and offsets them
55
55
 
56
56
  => **v0.2.7**: Curved, transparent, 3D, and `expanding=True` styles supported.
57
57
 
58
+ **v0.5.0:**
59
+
60
+ layouts = ['2d', 'cylindrical', 'cubic', 'spherical', 'elliptical', 'toric']
61
+
62
+ styles = ['standard', 'default', 'curved', 'helix', '3d', 'weighted', 'colored']
63
+
58
64
  ---
59
65
 
60
66
  ### Installation
@@ -1895,3 +1901,5 @@ Keçeci, Mehmet. "Keçeci Layout". Open Science Articles (OSAs), Zenodo, 2025. h
1895
1901
 
1896
1902
 
1897
1903
 
1904
+
1905
+
@@ -10,7 +10,7 @@ import inspect
10
10
  import warnings
11
11
 
12
12
  # Paket sürüm numarası
13
- __version__ = "0.4.8"
13
+ __version__ = "0.5.0"
14
14
 
15
15
  # =============================================================================
16
16
  # OTOMATİK İÇE AKTARMA VE __all__ OLUŞTURMA
@@ -48,6 +48,16 @@ from .kececi_layout import ( # Veya fonksiyonların bulunduğu asıl modül
48
48
  get_text_color_for_bg,
49
49
  generate_soft_random_colors,
50
50
  generate_distinct_colors,
51
+ calculate_coordinates,
52
+ calculate_coordinates,
53
+ kececi_layout_2d,
54
+ kececi_layout_cylindrical,
55
+ kececi_layout_cubic,
56
+ kececi_layout_spherical,
57
+ kececi_layout_elliptical,
58
+ kececi_layout_toric,
59
+ draw_kececi_weighted,
60
+ draw_kececi_colored,
51
61
 
52
62
  # Drawing functions
53
63
  draw_kececi,
@@ -88,7 +98,16 @@ __all__ = [
88
98
  'get_text_color_for_bg',
89
99
  'generate_soft_random_colors',
90
100
  'generate_distinct_colors',
91
-
101
+ 'calculate_coordinates',
102
+ 'kececi_layout_2d',
103
+ 'kececi_layout_cylindrical',
104
+ 'kececi_layout_cubic',
105
+ 'kececi_layout_spherical',
106
+ 'kececi_layout_elliptical',
107
+ 'kececi_layout_toric',
108
+ 'draw_kececi_weighted',
109
+ 'draw_kececi_colored',
110
+
92
111
  # Drawing functions
93
112
  'draw_kececi',
94
113
  '_draw_internal', # <- TESTLER İÇİN GEREKLİ
@@ -138,4 +157,3 @@ def old_function_placeholder():
138
157
 
139
158
  # Eğer bu eski fonksiyonu da dışa aktarmak istiyorsanız, __all__ listesine ekleyin
140
159
  # __all__.append('old_function_placeholder')
141
-
@@ -1,11 +1,9 @@
1
1
  # _version.py
2
2
 
3
- __version__ = "0.4.8"
3
+ __version__ = "0.5.0"
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
-
@@ -16,9 +16,11 @@ from mpl_toolkits.mplot3d import Axes3D
16
16
  import networkit as nk
17
17
  import networkx as nx
18
18
  import numpy as np # rustworkx
19
+ from numba import jit
19
20
  import platform # graph_tool için
20
21
  import random
21
22
  import rustworkx as rx
23
+ from typing import Any, Dict, List, Optional, Tuple, Union
22
24
  import warnings
23
25
 
24
26
 
@@ -58,6 +60,79 @@ if platform.system() == "Linux":
58
60
  else:
59
61
  gt = None
60
62
 
63
+ """
64
+ @jit(nopython=True)
65
+ def calculate_coordinates(nodes, primary_spacing, secondary_spacing, primary_direction, secondary_start, expanding):
66
+ #Numba ile hızlandırılmış koordinat hesaplama.
67
+ pos = {}
68
+ for i, node_id in enumerate(nodes):
69
+ # Koordinat hesaplama mantığı...
70
+ pos[node_id] = (x, y)
71
+ return pos
72
+ """
73
+
74
+ @jit(nopython=True)
75
+ def calculate_coordinates(
76
+ nodes: list,
77
+ primary_spacing: float,
78
+ secondary_spacing: float,
79
+ primary_direction: str,
80
+ secondary_start: str,
81
+ expanding: bool
82
+ ) -> dict:
83
+ """
84
+ Numba ile hızlandırılmış koordinat hesaplama fonksiyonu.
85
+
86
+ Args:
87
+ nodes: Düğümlerin listesi.
88
+ primary_spacing: Birincil eksendeki düğümler arası mesafe.
89
+ secondary_spacing: İkincil eksendeki zigzag ofseti.
90
+ primary_direction: Birincil yön ('left-to-right', 'right-to-left', 'top_down', 'bottom_up').
91
+ secondary_start: Zigzag'ın başlangıç yönü ('up', 'down', 'left', 'right').
92
+ expanding: Zigzag ofsetinin büyümesi gerekip gerekmediği (True/False).
93
+
94
+ Returns:
95
+ dict: Düğümlerin koordinatlarını içeren sözlük. Örneğin: {0: (x, y), 1: (x, y), ...}.
96
+ """
97
+ pos = {}
98
+ n = len(nodes)
99
+
100
+ for i in range(n):
101
+ node_id = nodes[i]
102
+ primary_coord = 0.0
103
+ secondary_axis = ''
104
+
105
+ # Birincil eksen koordinatını hesapla
106
+ if primary_direction == 'left-to-right':
107
+ primary_coord = i * primary_spacing
108
+ secondary_axis = 'y'
109
+ elif primary_direction == 'right-to-left':
110
+ primary_coord = -i * primary_spacing
111
+ secondary_axis = 'y'
112
+ elif primary_direction == 'top_down':
113
+ primary_coord = -i * primary_spacing
114
+ secondary_axis = 'x'
115
+ elif primary_direction == 'bottom_up':
116
+ primary_coord = i * primary_spacing
117
+ secondary_axis = 'x'
118
+
119
+ # İkincil eksen ofsetini hesapla
120
+ secondary_offset = 0.0
121
+ if i > 0:
122
+ start_multiplier = 1.0 if secondary_start in ['right', 'up'] else -1.0
123
+ magnitude = math.ceil(i / 2.0) if expanding else 1.0
124
+ side = 1 if i % 2 != 0 else -1
125
+ secondary_offset = start_multiplier * magnitude * side * secondary_spacing
126
+
127
+ # Koordinatları ata
128
+ if secondary_axis == 'x':
129
+ x, y = (secondary_offset, primary_coord)
130
+ else:
131
+ x, y = (primary_coord, secondary_offset)
132
+
133
+ pos[node_id] = (x, y)
134
+
135
+ return pos
61
136
 
62
137
  def find_max_node_id(edges):
63
138
  """
@@ -1420,6 +1495,228 @@ def generate_distinct_colors(n):
1420
1495
  colors.append(adjusted_rgb)
1421
1496
  return colors
1422
1497
 
1498
+ # 2D Layout
1499
+ def kececi_layout_2d(
1500
+ nx_graph: nx.Graph,
1501
+ primary_spacing: float = 1.0,
1502
+ secondary_spacing: float = 1.0,
1503
+ primary_direction: str = 'left-to-right',
1504
+ secondary_start: str = 'up',
1505
+ expanding: bool = True
1506
+ ) -> Dict[int, Tuple[float, float]]:
1507
+ pos = {}
1508
+ nodes = sorted(list(nx_graph.nodes()))
1509
+
1510
+ for i, node_id in enumerate(nodes):
1511
+ if primary_direction == 'left-to-right':
1512
+ primary_coord, secondary_axis = i * primary_spacing, 'y'
1513
+ elif primary_direction == 'right-to-left':
1514
+ primary_coord, secondary_axis = i * -primary_spacing, 'y'
1515
+ elif primary_direction == 'top_down':
1516
+ primary_coord, secondary_axis = i * -primary_spacing, 'x'
1517
+ else: # 'bottom_up'
1518
+ primary_coord, secondary_axis = i * primary_spacing, 'x'
1519
+
1520
+ secondary_offset = 0.0
1521
+ if i > 0:
1522
+ start_multiplier = 1.0 if secondary_start in ['right', 'up'] else -1.0
1523
+ magnitude = math.ceil(i / 2.0) if expanding else 1.0
1524
+ side = 1 if i % 2 != 0 else -1
1525
+ secondary_offset = start_multiplier * magnitude * side * secondary_spacing
1526
+
1527
+ x, y = (secondary_offset, primary_coord) if secondary_axis == 'x' else (primary_coord, secondary_offset)
1528
+ pos[node_id] = (x, y)
1529
+
1530
+ return pos
1531
+
1532
+ # Silindirik Layout
1533
+ def kececi_layout_cylindrical(
1534
+ nx_graph: nx.Graph,
1535
+ radius: float = 5.0,
1536
+ height: float = 10.0
1537
+ ) -> Dict[int, Tuple[float, float, float]]:
1538
+ pos_3d = {}
1539
+ nodes = sorted(list(nx_graph.nodes()))
1540
+ num_nodes = len(nodes)
1541
+
1542
+ for i, node_id in enumerate(nodes):
1543
+ theta = 2 * np.pi * i / num_nodes
1544
+ x = radius * np.cos(theta)
1545
+ y = radius * np.sin(theta)
1546
+ z = height * i / num_nodes
1547
+ pos_3d[node_id] = (x, y, z)
1548
+
1549
+ return pos_3d
1550
+
1551
+ # Kübik Layout
1552
+ def kececi_layout_cubic(
1553
+ nx_graph: nx.Graph,
1554
+ size: float = 5.0
1555
+ ) -> Dict[int, Tuple[float, float, float]]:
1556
+ pos_3d = {}
1557
+ nodes = sorted(list(nx_graph.nodes()))
1558
+ num_nodes = len(nodes)
1559
+ cube_size = int(np.cbrt(num_nodes)) + 1
1560
+
1561
+ for i, node_id in enumerate(nodes):
1562
+ x = size * (i % cube_size)
1563
+ y = size * ((i // cube_size) % cube_size)
1564
+ z = size * ((i // (cube_size ** 2)) % cube_size)
1565
+ pos_3d[node_id] = (x, y, z)
1566
+
1567
+ return pos_3d
1568
+
1569
+ # Küresel Layout
1570
+ def kececi_layout_spherical(
1571
+ nx_graph: nx.Graph,
1572
+ radius: float = 5.0
1573
+ ) -> Dict[int, Tuple[float, float, float]]:
1574
+ pos_3d = {}
1575
+ nodes = sorted(list(nx_graph.nodes()))
1576
+ num_nodes = len(nodes)
1577
+
1578
+ for i, node_id in enumerate(nodes):
1579
+ theta = 2 * np.pi * i / num_nodes
1580
+ phi = np.arccos(1 - 2 * (i + 0.5) / num_nodes)
1581
+ x = radius * np.sin(phi) * np.cos(theta)
1582
+ y = radius * np.sin(phi) * np.sin(theta)
1583
+ z = radius * np.cos(phi)
1584
+ pos_3d[node_id] = (x, y, z)
1585
+
1586
+ return pos_3d
1587
+
1588
+ # Eliptik Layout
1589
+ def kececi_layout_elliptical(
1590
+ nx_graph: nx.Graph,
1591
+ a: float = 5.0,
1592
+ b: float = 3.0
1593
+ ) -> Dict[int, Tuple[float, float]]:
1594
+ pos = {}
1595
+ nodes = sorted(list(nx_graph.nodes()))
1596
+ num_nodes = len(nodes)
1597
+
1598
+ for i, node_id in enumerate(nodes):
1599
+ theta = 2 * np.pi * i / num_nodes
1600
+ x = a * np.cos(theta)
1601
+ y = b * np.sin(theta)
1602
+ pos[node_id] = (x, y)
1603
+
1604
+ return pos
1605
+
1606
+ # Torik (Halkasal) Layout
1607
+ def kececi_layout_toric(
1608
+ nx_graph: nx.Graph,
1609
+ major_radius: float = 5.0,
1610
+ minor_radius: float = 2.0
1611
+ ) -> Dict[int, Tuple[float, float, float]]:
1612
+ pos_3d = {}
1613
+ nodes = sorted(list(nx_graph.nodes()))
1614
+ num_nodes = len(nodes)
1615
+
1616
+ for i, node_id in enumerate(nodes):
1617
+ theta = 2 * np.pi * i / num_nodes
1618
+ phi = 2 * np.pi * i / num_nodes
1619
+ x = (major_radius + minor_radius * np.cos(phi)) * np.cos(theta)
1620
+ y = (major_radius + minor_radius * np.cos(phi)) * np.sin(theta)
1621
+ z = minor_radius * np.sin(phi)
1622
+ pos_3d[node_id] = (x, y, z)
1623
+
1624
+ return pos_3d
1625
+
1626
+ # Ağırlıklı Çizim (draw_kececi_weighted)
1627
+ def draw_kececi_weighted(
1628
+ nx_graph: nx.Graph,
1629
+ pos: Dict[int, Tuple[float, ...]],
1630
+ ax: Optional[plt.Axes] = None,
1631
+ node_size: int = 300,
1632
+ edge_width_scale: float = 2.0,
1633
+ **kwargs
1634
+ ) -> plt.Axes:
1635
+ if ax is None:
1636
+ fig = plt.figure(figsize=(10, 8))
1637
+ ax = fig.add_subplot(111)
1638
+
1639
+ weights = nx.get_edge_attributes(nx_graph, 'weight')
1640
+ if not weights:
1641
+ weights = {edge: 1.0 for edge in nx_graph.edges()}
1642
+
1643
+ nx.draw_networkx_nodes(nx_graph, pos, ax=ax, node_size=node_size, **kwargs)
1644
+
1645
+ is_3d = len(pos[next(iter(pos))]) == 3
1646
+ if is_3d:
1647
+ for node, coord in pos.items():
1648
+ ax.text(coord[0], coord[1], coord[2], f' {node}', size=10, zorder=1, color='black')
1649
+ else:
1650
+ nx.draw_networkx_labels(nx_graph, pos, ax=ax)
1651
+
1652
+ for (u, v), weight in weights.items():
1653
+ width = weight * edge_width_scale
1654
+ if is_3d:
1655
+ ax.plot(
1656
+ [pos[u][0], pos[v][0]],
1657
+ [pos[u][1], pos[v][1]],
1658
+ [pos[u][2], pos[v][2]],
1659
+ linewidth=width,
1660
+ color='gray',
1661
+ alpha=0.7
1662
+ )
1663
+ else:
1664
+ ax.plot(
1665
+ [pos[u][0], pos[v][0]],
1666
+ [pos[u][1], pos[v][1]],
1667
+ linewidth=width,
1668
+ color='gray',
1669
+ alpha=0.7
1670
+ )
1671
+
1672
+ ax.set_title("Keçeci Layout: Weighted Edges")
1673
+ return ax
1674
+
1675
+ # Renkli Çizim (draw_kececi_colored)
1676
+ def draw_kececi_colored(
1677
+ nx_graph: nx.Graph,
1678
+ pos: Dict[int, Tuple[float, ...]],
1679
+ ax: Optional[plt.Axes] = None,
1680
+ node_size: int = 300,
1681
+ **kwargs
1682
+ ) -> plt.Axes:
1683
+ if ax is None:
1684
+ fig = plt.figure(figsize=(10, 8))
1685
+ ax = fig.add_subplot(111)
1686
+
1687
+ degrees = dict(nx_graph.degree())
1688
+ max_degree = max(degrees.values()) if degrees else 1
1689
+ node_colors = [plt.cm.viridis(deg / max_degree) for deg in degrees.values()]
1690
+
1691
+ nx.draw_networkx_nodes(
1692
+ nx_graph, pos, ax=ax,
1693
+ node_color=node_colors,
1694
+ node_size=node_size,
1695
+ **kwargs
1696
+ )
1697
+
1698
+ is_3d = len(pos[next(iter(pos))]) == 3
1699
+ if is_3d:
1700
+ for node, coord in pos.items():
1701
+ ax.text(coord[0], coord[1], coord[2], f' {node}', size=10, zorder=1, color='black')
1702
+ else:
1703
+ nx.draw_networkx_labels(nx_graph, pos, ax=ax)
1704
+
1705
+ if is_3d:
1706
+ for u, v in nx_graph.edges():
1707
+ ax.plot(
1708
+ [pos[u][0], pos[v][0]],
1709
+ [pos[u][1], pos[v][1]],
1710
+ [pos[u][2], pos[v][2]],
1711
+ color='gray',
1712
+ alpha=0.5
1713
+ )
1714
+ else:
1715
+ nx.draw_networkx_edges(nx_graph, pos, ax=ax, alpha=0.5)
1716
+
1717
+ ax.set_title("Keçeci Layout: Colored Nodes")
1718
+ return ax
1719
+
1423
1720
  # =============================================================================
1424
1721
  # 3. INTERNAL DRAWING STYLE IMPLEMENTATIONS
1425
1722
  # =============================================================================
@@ -1523,9 +1820,181 @@ def _draw_internal(nx_graph, ax, style, **kwargs):
1523
1820
  # =============================================================================
1524
1821
  # 4. MAIN USER-FACING DRAWING FUNCTION
1525
1822
  # =============================================================================
1823
+ def draw_kececi(
1824
+ graph,
1825
+ pos: Optional[Dict[int, Tuple[float, ...]]] = None,
1826
+ layout: Optional[str] = None,
1827
+ style: str = 'default',
1828
+ ax: Optional[plt.Axes] = None,
1829
+ with_labels: bool = True,
1830
+ node_color: str = 'lightblue',
1831
+ node_size: int = 500,
1832
+ font_weight: str = 'bold',
1833
+ **kwargs
1834
+ ) -> plt.Axes:
1835
+ """
1836
+ Keçeci Layout ile graf çizimi.
1526
1837
 
1527
- def draw_kececi(graph, style='curved', ax=None, **kwargs):
1838
+ Args:
1839
+ graph: Graf objesi (NetworkX, igraph, vb.).
1840
+ pos: Önceden hesaplanmış koordinatlar (opsiyonel).
1841
+ layout: '2d', 'cylindrical', 'cubic', 'spherical', 'elliptical', 'toric' (opsiyonel).
1842
+ style: 'default', 'weighted', 'colored'.
1843
+ ax: Matplotlib ekseni.
1844
+ with_labels: Düğüm etiketlerini göster.
1845
+ node_color: Düğüm rengi.
1846
+ node_size: Düğüm boyutu.
1847
+ font_weight: Yazı kalınlığı.
1848
+ **kwargs: Ek parametreler.
1849
+
1850
+ Returns:
1851
+ Matplotlib ekseni.
1528
1852
  """
1853
+ nx_graph = to_networkx(graph)
1854
+
1855
+ # Eğer pos verilmemişse, layout'a göre hesapla
1856
+ if pos is None:
1857
+ if layout is None:
1858
+ layout = '2d' # Varsayılan layout
1859
+
1860
+ if layout == '2d':
1861
+ pos = kececi_layout_2d(nx_graph, **kwargs)
1862
+ elif layout == 'cylindrical':
1863
+ pos = kececi_layout_cylindrical(nx_graph, **kwargs)
1864
+ elif layout == 'cubic':
1865
+ pos = kececi_layout_cubic(nx_graph, **kwargs)
1866
+ elif layout == 'spherical':
1867
+ pos = kececi_layout_spherical(nx_graph, **kwargs)
1868
+ elif layout == 'elliptical':
1869
+ pos = kececi_layout_elliptical(nx_graph, **kwargs)
1870
+ elif layout == 'toric':
1871
+ pos = kececi_layout_toric(nx_graph, **kwargs)
1872
+ else:
1873
+ raise ValueError(f"Geçersiz layout: {layout}")
1874
+
1875
+ # 3D için eksen ayarlaması
1876
+ is_3d = len(pos[next(iter(pos))]) == 3
1877
+ if ax is None:
1878
+ fig = plt.figure(figsize=(10, 8))
1879
+ if is_3d:
1880
+ ax = fig.add_subplot(111, projection='3d')
1881
+ else:
1882
+ ax = fig.add_subplot(111)
1883
+
1884
+ # Stile göre çizim yap
1885
+ if style == 'weighted':
1886
+ draw_kececi_weighted(nx_graph, pos, ax, **kwargs)
1887
+ elif style == 'colored':
1888
+ draw_kececi_colored(nx_graph, pos, ax, **kwargs)
1889
+ else: # 'default'
1890
+ nx.draw_networkx_nodes(nx_graph, pos, ax=ax, node_color=node_color, node_size=node_size)
1891
+
1892
+ # Düğüm etiketlerini çiz
1893
+ if with_labels:
1894
+ if is_3d:
1895
+ for node, coord in pos.items():
1896
+ ax.text(coord[0], coord[1], coord[2], f' {node}', size=10, zorder=1, color='black', fontweight=font_weight)
1897
+ else:
1898
+ nx.draw_networkx_labels(nx_graph, pos, ax=ax, font_weight=font_weight)
1899
+
1900
+ # Kenarları çiz
1901
+ if is_3d:
1902
+ for u, v in nx_graph.edges():
1903
+ ax.plot(
1904
+ [pos[u][0], pos[v][0]],
1905
+ [pos[u][1], pos[v][1]],
1906
+ [pos[u][2], pos[v][2]],
1907
+ color='gray',
1908
+ alpha=0.5
1909
+ )
1910
+ else:
1911
+ nx.draw_networkx_edges(nx_graph, pos, ax=ax, alpha=0.5)
1912
+
1913
+ ax.set_title(f"Keçeci Layout: {layout.capitalize() if layout else 'Custom'} ({style})")
1914
+ return ax
1915
+ """
1916
+ def draw_kececi(
1917
+ graph,
1918
+ layout: str = '2d',
1919
+ style: str = 'default',
1920
+ ax: Optional[plt.Axes] = None,
1921
+ **kwargs
1922
+ ) -> plt.Axes:
1923
+
1924
+ Keçeci Layout ile graf çizimi.
1925
+
1926
+ Args:
1927
+ graph: Graf objesi (NetworkX, igraph, vb.).
1928
+ layout: '2d', 'cylindrical', 'cubic', 'spherical', 'elliptical', 'toric'.
1929
+ style: 'default', 'weighted', 'colored'.
1930
+ ax: Matplotlib ekseni.
1931
+ **kwargs: Ek parametreler.
1932
+
1933
+ Returns:
1934
+ Matplotlib ekseni.
1935
+
1936
+ nx_graph = to_networkx(graph)
1937
+
1938
+ # Layout'a göre koordinatları hesapla
1939
+ if layout == '2d':
1940
+ pos = kececi_layout_2d(nx_graph, **kwargs)
1941
+ elif layout == 'cylindrical':
1942
+ pos = kececi_layout_cylindrical(nx_graph, **kwargs)
1943
+ elif layout == 'cubic':
1944
+ pos = kececi_layout_cubic(nx_graph, **kwargs)
1945
+ elif layout == 'spherical':
1946
+ pos = kececi_layout_spherical(nx_graph, **kwargs)
1947
+ elif layout == 'elliptical':
1948
+ pos = kececi_layout_elliptical(nx_graph, **kwargs)
1949
+ elif layout == 'toric':
1950
+ pos = kececi_layout_toric(nx_graph, **kwargs)
1951
+ else:
1952
+ raise ValueError(f"Invalid layout: {layout}")
1953
+
1954
+ # 3D için eksen ayarlaması
1955
+ is_3d = len(pos[next(iter(pos))]) == 3
1956
+ if ax is None:
1957
+ fig = plt.figure(figsize=(10, 8))
1958
+ if is_3d:
1959
+ ax = fig.add_subplot(111, projection='3d')
1960
+ else:
1961
+ ax = fig.add_subplot(111)
1962
+
1963
+ # Stile göre çizim yap
1964
+ if style == 'weighted':
1965
+ draw_kececi_weighted(nx_graph, pos, ax, **kwargs)
1966
+ elif style == 'colored':
1967
+ draw_kececi_colored(nx_graph, pos, ax, **kwargs)
1968
+ else: # 'default'
1969
+ nx.draw_networkx_nodes(nx_graph, pos, ax=ax, **kwargs)
1970
+
1971
+ # Düğüm etiketlerini çiz
1972
+ if is_3d:
1973
+ for node, coord in pos.items():
1974
+ ax.text(coord[0], coord[1], coord[2], f' {node}', size=10, zorder=1, color='black')
1975
+ else:
1976
+ nx.draw_networkx_labels(nx_graph, pos, ax=ax)
1977
+
1978
+ # Kenarları çiz
1979
+ if is_3d:
1980
+ for u, v in nx_graph.edges():
1981
+ ax.plot(
1982
+ [pos[u][0], pos[v][0]],
1983
+ [pos[u][1], pos[v][1]],
1984
+ [pos[u][2], pos[v][2]],
1985
+ color='gray',
1986
+ alpha=0.5
1987
+ )
1988
+ else:
1989
+ nx.draw_networkx_edges(nx_graph, pos, ax=ax, alpha=0.5)
1990
+
1991
+ ax.set_title(f"Keçeci Layout: {layout.capitalize()} ({style})")
1992
+ return ax
1993
+ """
1994
+
1995
+ """
1996
+ def draw_kececi(graph, style='curved', ax=None, **kwargs):
1997
+
1529
1998
  Draws a graph using the Keçeci Layout with a specified style.
1530
1999
 
1531
2000
  This function automatically handles graphs from different libraries
@@ -1541,7 +2010,7 @@ def draw_kececi(graph, style='curved', ax=None, **kwargs):
1541
2010
 
1542
2011
  Returns:
1543
2012
  matplotlib.axis.Axis: The axis object where the graph was drawn.
1544
- """
2013
+
1545
2014
  nx_graph = to_networkx(graph)
1546
2015
  is_3d = (style.lower() == '3d')
1547
2016
 
@@ -1559,7 +2028,7 @@ def draw_kececi(graph, style='curved', ax=None, **kwargs):
1559
2028
 
1560
2029
  _draw_internal(nx_graph, ax, style.lower(), **kwargs)
1561
2030
  return ax
1562
-
2031
+ """
1563
2032
 
1564
2033
  # =============================================================================
1565
2034
  # MODULE TEST CODE
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kececilayout
3
- Version: 0.4.8
3
+ Version: 0.5.0
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
@@ -54,6 +54,7 @@ Requires-Dist: rustworkx; extra == "test"
54
54
  Requires-Dist: networkit; extra == "test"
55
55
  Requires-Dist: graphillion; extra == "test"
56
56
  Requires-Dist: graph-tool; extra == "test"
57
+ Requires-Dist: numba; extra == "test"
57
58
  Dynamic: author
58
59
  Dynamic: home-page
59
60
  Dynamic: license-file
@@ -118,6 +119,12 @@ This algorithm arranges nodes sequentially along a primary axis and offsets them
118
119
 
119
120
  => **v0.2.7**: Curved, transparent, 3D, and `expanding=True` styles supported.
120
121
 
122
+ **v0.5.0:**
123
+
124
+ layouts = ['2d', 'cylindrical', 'cubic', 'spherical', 'elliptical', 'toric']
125
+
126
+ styles = ['standard', 'default', 'curved', 'helix', '3d', 'weighted', 'colored']
127
+
121
128
  ---
122
129
 
123
130
  ### Installation
@@ -1958,3 +1965,5 @@ Keçeci, Mehmet. "Keçeci Layout". Open Science Articles (OSAs), Zenodo, 2025. h
1958
1965
 
1959
1966
 
1960
1967
 
1968
+
1969
+
@@ -14,3 +14,4 @@ rustworkx
14
14
  networkit
15
15
  graphillion
16
16
  graph-tool
17
+ numba
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "kececilayout"
9
- version = "0.4.8"
9
+ version = "0.5.0"
10
10
 
11
11
  # Diğer proje bilgileri (isteğe bağlı ama tavsiye edilir)
12
12
  authors = [
@@ -44,6 +44,7 @@ test = [
44
44
  "networkit",
45
45
  "graphillion",
46
46
  "graph-tool",
47
+ "numba",
47
48
  ]
48
49
 
49
50
  [dependency-groups]
@@ -71,6 +72,3 @@ configuration = "docs/conf.py" # Build konfigürasyonu belirtin
71
72
  "Homepage" = "https://github.com/WhiteSymmetry/kececilayout"
72
73
  "Bug Tracker" = "https://github.com/WhiteSymmetry/kececilayout/issues"
73
74
 
74
-
75
-
76
-
@@ -4,7 +4,6 @@ import re
4
4
  from setuptools import setup, find_packages
5
5
  import sys
6
6
 
7
-
8
7
  # BU SATIRLAR SORUNUN KALICI ÇÖZÜMÜDÜR.
9
8
  # Python'a, README.md dosyasını hangi işletim sisteminde olursa olsun
10
9
  # her zaman UTF-8 kodlamasıyla okumasını söylüyoruz.
@@ -13,7 +12,6 @@ with open("README.md", "r", encoding="utf-8") as fh:
13
12
 
14
13
  sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
15
14
 
16
-
17
15
  def get_version():
18
16
  with open('kececilayout/__init__.py', 'r', encoding='utf-8') as f:
19
17
  content = f.read()
@@ -42,7 +40,7 @@ setup(
42
40
  "cairocffi"
43
41
  ],
44
42
  extras_require={
45
- "all": ["cairo", "python-louvain", "python-igraph", "networkit", "rustworkx", "graphillion", "graph-tool"],
43
+ "all": ["cairo", "python-louvain", "python-igraph", "networkit", "rustworkx", "graphillion", "graph-tool", "numba"],
46
44
  },
47
45
  classifiers=[
48
46
  "Programming Language :: Python :: 3",
File without changes
File without changes
File without changes