topologicpy 0.8.10__py3-none-any.whl → 0.8.11__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.
- topologicpy/Face.py +55 -0
- topologicpy/Graph.py +213 -214
- topologicpy/Matrix.py +211 -5
- topologicpy/Plotly.py +8 -9
- topologicpy/Topology.py +341 -397
- topologicpy/Vector.py +71 -22
- topologicpy/Vertex.py +57 -0
- topologicpy/Wire.py +0 -119
- topologicpy/version.py +1 -1
- {topologicpy-0.8.10.dist-info → topologicpy-0.8.11.dist-info}/METADATA +1 -1
- {topologicpy-0.8.10.dist-info → topologicpy-0.8.11.dist-info}/RECORD +14 -14
- {topologicpy-0.8.10.dist-info → topologicpy-0.8.11.dist-info}/LICENSE +0 -0
- {topologicpy-0.8.10.dist-info → topologicpy-0.8.11.dist-info}/WHEEL +0 -0
- {topologicpy-0.8.10.dist-info → topologicpy-0.8.11.dist-info}/top_level.txt +0 -0
topologicpy/Face.py
CHANGED
@@ -3411,6 +3411,61 @@ class Face():
|
|
3411
3411
|
return None
|
3412
3412
|
return Face.ByWire(wire, tolerance=tolerance)
|
3413
3413
|
|
3414
|
+
|
3415
|
+
@staticmethod
|
3416
|
+
def ThirdVertex(face, tolerance: float = 0.0001, silent: bool = False):
|
3417
|
+
"""
|
3418
|
+
Returns a third vertex on the input face to enable rotation matrix creation.
|
3419
|
+
|
3420
|
+
Parameters
|
3421
|
+
----------
|
3422
|
+
face : topologic_core.Face
|
3423
|
+
The input face.
|
3424
|
+
tolerance : float , optional
|
3425
|
+
The desired tolerance. The default is 0.0001.
|
3426
|
+
silent : bool , optional
|
3427
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
3428
|
+
|
3429
|
+
Returns
|
3430
|
+
-------
|
3431
|
+
topologic_core.Face
|
3432
|
+
The created face.
|
3433
|
+
|
3434
|
+
"""
|
3435
|
+
from topologicpy.Vector import Vector
|
3436
|
+
from topologicpy.Vertex import Vertex
|
3437
|
+
from topologicpy.Topology import Topology
|
3438
|
+
|
3439
|
+
if not Topology.IsInstance(face, "Face"):
|
3440
|
+
if not silent:
|
3441
|
+
print("Face.ThirdVertex - Error: The input face parameter is not a valid face. Returning None.")
|
3442
|
+
return None
|
3443
|
+
# Retrieve all vertices of the face
|
3444
|
+
vertices = Face.Vertices(face)
|
3445
|
+
centroid = Topology.Centroid(face)
|
3446
|
+
normal = Face.Normal(face)
|
3447
|
+
for vertex in vertices:
|
3448
|
+
# Skip the centroid itself
|
3449
|
+
if Vertex.Distance(centroid, vertex) <= tolerance:
|
3450
|
+
continue
|
3451
|
+
|
3452
|
+
# Vector from the centroid to the current vertex
|
3453
|
+
vector_to_vertex = Vector.ByVertices(centroid, vertex)
|
3454
|
+
vector_to_vertex_normalized = Vector.Normalize(vector_to_vertex)
|
3455
|
+
|
3456
|
+
|
3457
|
+
# Check if the vector_to_vertex is collinear with the normal direction
|
3458
|
+
if Vector.IsCollinear(vector_to_vertex_normalized, normal, tolerance):
|
3459
|
+
continue
|
3460
|
+
|
3461
|
+
# If not collinear, return this vertex
|
3462
|
+
return vertex
|
3463
|
+
|
3464
|
+
# No valid third vertex found
|
3465
|
+
if not silent:
|
3466
|
+
print("Face.ThirdVertex - Warning: No valid third vertex could be found. Returning None.")
|
3467
|
+
return None
|
3468
|
+
|
3414
3469
|
@staticmethod
|
3415
3470
|
def Trapezoid(origin= None, widthA: float = 1.0, widthB: float = 0.75, offsetA: float = 0.0, offsetB: float = 0.0, length: float = 1.0, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001):
|
3416
3471
|
"""
|
topologicpy/Graph.py
CHANGED
@@ -1352,7 +1352,7 @@ class Graph:
|
|
1352
1352
|
return bot_graph.serialize(format=format)
|
1353
1353
|
|
1354
1354
|
@staticmethod
|
1355
|
-
def BetweennessCentrality(graph, key: str = "betweenness_centrality",
|
1355
|
+
def BetweennessCentrality(graph, method: str = "vertex", weightKey="length", normalize: bool = False, nx: bool = False, key: str = "betweenness_centrality", colorKey="bc_color", colorScale="viridis", mantissa: int = 6, tolerance: float = 0.001, silent: bool = False):
|
1356
1356
|
"""
|
1357
1357
|
Returns the betweenness centrality of the input graph. The order of the returned list is the same as the order of vertices/edges. See https://en.wikipedia.org/wiki/Betweenness_centrality.
|
1358
1358
|
|
@@ -1360,10 +1360,24 @@ class Graph:
|
|
1360
1360
|
----------
|
1361
1361
|
graph : topologic_core.Graph
|
1362
1362
|
The input graph.
|
1363
|
-
key : str , optional
|
1364
|
-
The dictionary key under which to store the betweeness centrality score. The default is "betweenness_centrality".
|
1365
1363
|
method : str , optional
|
1366
1364
|
The method of computing the betweenness centrality. The options are "vertex" or "edge". The default is "vertex".
|
1365
|
+
weightKey : str , optional
|
1366
|
+
If None, all edge weights are considered equal. Otherwise holds the name of the edge dictionary key to be used as weight.
|
1367
|
+
Weights are used to calculate weighted shortest paths, so they are interpreted as distances.
|
1368
|
+
If you wish to use the actual length of the edge, then use the "length" as key. the default is "length".
|
1369
|
+
normalize : bool , optional
|
1370
|
+
If set to True, the values are normalized to be in the range 0 to 1. Otherwise they are not. The default is False.
|
1371
|
+
nx : bool , optional
|
1372
|
+
If set to True, and normalize input parameter is also set to True, the values are set to be identical to NetworkX values. Otherwise, they are normalized between 0 and 1. The default is False.
|
1373
|
+
key : str , optional
|
1374
|
+
The desired dictionary key under which to store the betweeness centrality score. The default is "betweenness_centrality".
|
1375
|
+
colorKey : str , optional
|
1376
|
+
The desired dictionary key under which to store the betweeness centrality color. The default is "betweenness_centrality".
|
1377
|
+
colorScale : str , optional
|
1378
|
+
The desired type of plotly color scales to use (e.g. "viridis", "plasma"). The default is "viridis". For a full list of names, see https://plotly.com/python/builtin-colorscales/.
|
1379
|
+
In addition to these, three color-blind friendly scales are included. These are "protanopia", "deuteranopia", and "tritanopia" for red, green, and blue colorblindness respectively.
|
1380
|
+
|
1367
1381
|
mantissa : int , optional
|
1368
1382
|
The desired length of the mantissa. The default is 6.
|
1369
1383
|
tolerance : float , optional
|
@@ -1375,163 +1389,55 @@ class Graph:
|
|
1375
1389
|
The betweenness centrality of the input list of vertices within the input graph. The values are in the range 0 to 1.
|
1376
1390
|
|
1377
1391
|
"""
|
1378
|
-
|
1379
|
-
queue = [(source, [source])]
|
1380
|
-
while queue:
|
1381
|
-
(vertex, path) = queue.pop(0)
|
1382
|
-
for next in set(py_graph[vertex]) - set(path):
|
1383
|
-
queue.append((next, path + [next]))
|
1384
|
-
yield path + [next]
|
1385
|
-
|
1386
|
-
def shortest_paths_count(source):
|
1387
|
-
paths = list(bfs_paths(source))
|
1388
|
-
shortest_paths = {v: [] for v in py_graph}
|
1389
|
-
for path in paths:
|
1390
|
-
shortest_paths[path[-1]].append(path)
|
1391
|
-
return shortest_paths
|
1392
|
-
|
1393
|
-
def calculate_vertex_betweenness():
|
1394
|
-
betweenness = {v: 0.0 for v in py_graph}
|
1395
|
-
for s in py_graph:
|
1396
|
-
shortest_paths = shortest_paths_count(s)
|
1397
|
-
dependency = {v: 0.0 for v in py_graph}
|
1398
|
-
for t in py_graph:
|
1399
|
-
if t != s:
|
1400
|
-
for path in shortest_paths[t]:
|
1401
|
-
for v in path[1:-1]:
|
1402
|
-
dependency[v] += 1.0 / len(shortest_paths[t])
|
1403
|
-
for v in py_graph:
|
1404
|
-
if v != s:
|
1405
|
-
betweenness[v] += dependency[v]
|
1406
|
-
return betweenness
|
1407
|
-
|
1408
|
-
def calculate_edge_betweenness(graph_adj_matrix):
|
1409
|
-
n = len(graph_adj_matrix)
|
1410
|
-
edge_betweenness_scores = {}
|
1411
|
-
|
1412
|
-
# Iterate over all node pairs as source and target nodes
|
1413
|
-
for source in range(n):
|
1414
|
-
# Initialize the 'distance' and 'predecessors' for each node
|
1415
|
-
distance = [-1] * n
|
1416
|
-
predecessors = [[] for _ in range(n)]
|
1417
|
-
distance[source] = 0
|
1418
|
-
stack = []
|
1419
|
-
queue = [source]
|
1420
|
-
|
1421
|
-
# Breadth-first search to find shortest paths
|
1422
|
-
while queue:
|
1423
|
-
current_node = queue.pop(0)
|
1424
|
-
stack.append(current_node)
|
1425
|
-
for neighbor in range(n):
|
1426
|
-
if graph_adj_matrix[current_node][neighbor] == 1:
|
1427
|
-
if distance[neighbor] == -1: # First time visiting neighbor
|
1428
|
-
distance[neighbor] = distance[current_node] + 1
|
1429
|
-
queue.append(neighbor)
|
1430
|
-
if distance[neighbor] == distance[current_node] + 1: # Shortest path
|
1431
|
-
predecessors[neighbor].append(current_node)
|
1432
|
-
|
1433
|
-
# Initialize the dependency values for each node
|
1434
|
-
dependency = [0] * n
|
1435
|
-
|
1436
|
-
# Process the nodes in reverse order of discovery
|
1437
|
-
while stack:
|
1438
|
-
current_node = stack.pop()
|
1439
|
-
for pred in predecessors[current_node]:
|
1440
|
-
dependency[pred] += (1 + dependency[current_node]) / len(predecessors[current_node])
|
1441
|
-
|
1442
|
-
# Update edge betweenness scores
|
1443
|
-
if pred < current_node:
|
1444
|
-
edge = (pred, current_node)
|
1445
|
-
else:
|
1446
|
-
edge = (current_node, pred)
|
1447
|
-
|
1448
|
-
if edge not in edge_betweenness_scores:
|
1449
|
-
edge_betweenness_scores[edge] = 0
|
1450
|
-
edge_betweenness_scores[edge] += dependency[current_node]
|
1451
|
-
|
1452
|
-
# Normalize edge betweenness scores by dividing by 2 (since each edge is counted twice)
|
1453
|
-
for edge in edge_betweenness_scores:
|
1454
|
-
edge_betweenness_scores[edge] /= 2
|
1392
|
+
import warnings
|
1455
1393
|
|
1456
|
-
|
1394
|
+
try:
|
1395
|
+
import networkx as nx
|
1396
|
+
except:
|
1397
|
+
print("Graph.BetwennessCentrality - Information: Installing required networkx library.")
|
1398
|
+
try:
|
1399
|
+
os.system("pip install networkx")
|
1400
|
+
except:
|
1401
|
+
os.system("pip install networkx --user")
|
1402
|
+
try:
|
1403
|
+
import networkx as nx
|
1404
|
+
print("Graph.BetwennessCentrality - Infromation: networkx library installed correctly.")
|
1405
|
+
except:
|
1406
|
+
warnings.warn("Graph.BetwennessCentrality - Error: Could not import networkx. Please try to install networkx manually. Returning None.")
|
1407
|
+
return None
|
1457
1408
|
|
1458
|
-
from topologicpy.Topology import Topology
|
1459
1409
|
from topologicpy.Dictionary import Dictionary
|
1410
|
+
from topologicpy.Color import Color
|
1411
|
+
from topologicpy.Topology import Topology
|
1412
|
+
from topologicpy.Helper import Helper
|
1460
1413
|
|
1461
|
-
if
|
1462
|
-
if
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
return [1.0]
|
1478
|
-
|
1479
|
-
py_graph = Graph.AdjacencyDictionary(graph)
|
1480
|
-
vertex_betweenness = calculate_vertex_betweenness()
|
1481
|
-
for v in vertex_betweenness:
|
1482
|
-
vertex_betweenness[v] /= 2.0 # Each shortest path is counted twice
|
1483
|
-
|
1484
|
-
min_betweenness = min(vertex_betweenness.values())
|
1485
|
-
max_betweenness = max(vertex_betweenness.values())
|
1486
|
-
if (max_betweenness - min_betweenness) > 0:
|
1487
|
-
for v in vertex_betweenness:
|
1488
|
-
vertex_betweenness[v] = (vertex_betweenness[v] - min_betweenness)/ (max_betweenness - min_betweenness) # Normalize to [0, 1]
|
1489
|
-
|
1490
|
-
|
1491
|
-
vertex_betweenness_scores = [0]*len(vertices)
|
1492
|
-
for i, score in vertex_betweenness.items():
|
1493
|
-
vertex = vertices[int(i)]
|
1494
|
-
d = Topology.Dictionary(vertex)
|
1495
|
-
d = Dictionary.SetValueAtKey(d, key, round(score, mantissa))
|
1496
|
-
vertex = Topology.SetDictionary(vertex, d)
|
1497
|
-
vertex_betweenness_scores[int(i)] = round(score, mantissa)
|
1498
|
-
|
1499
|
-
return vertex_betweenness_scores
|
1414
|
+
if weightKey:
|
1415
|
+
if "len" in weightKey.lower():
|
1416
|
+
weightKey = "length"
|
1417
|
+
nx_graph = Graph.NetworkXGraph(graph)
|
1418
|
+
if "vert" in method.lower():
|
1419
|
+
elements = Graph.Vertices(graph)
|
1420
|
+
elements_dict = nx.betweenness_centrality(nx_graph, normalized=normalize, weight=weightKey)
|
1421
|
+
values = list(elements_dict.values())
|
1422
|
+
else:
|
1423
|
+
elements = Graph.Edges(graph)
|
1424
|
+
elements_dict = nx.edge_betweenness_centrality(nx_graph, normalized=normalize, weight=weightKey)
|
1425
|
+
values = list(elements_dict.values())
|
1426
|
+
if nx == False:
|
1427
|
+
values = Helper.Normalize(values)
|
1428
|
+
min_value = 0
|
1429
|
+
max_value = 1
|
1500
1430
|
else:
|
1501
|
-
graph_edges = Graph.Edges(graph)
|
1502
|
-
adj_matrix = Graph.AdjacencyMatrix(graph)
|
1503
|
-
meshData = Graph.MeshData(graph)
|
1504
|
-
edges = meshData["edges"]
|
1505
|
-
if len(graph_edges) < 1:
|
1506
|
-
if not silent:
|
1507
|
-
print("Graph.BetweenessCentrality - Error: The input graph does not contain any edges. Returning None.")
|
1508
|
-
return None
|
1509
|
-
if len(graph_edges) == 1:
|
1510
|
-
d = Topology.Dictionary(graph_edges[0])
|
1511
|
-
d = Dictionary.SetValueAtKey(d, key, 1.0)
|
1512
|
-
graph_edges[0] = Topology.SetDictionary(graph_edges[0], d)
|
1513
|
-
return [1.0]
|
1514
|
-
|
1515
|
-
edge_betweenness = calculate_edge_betweenness(adj_matrix)
|
1516
|
-
keys = list(edge_betweenness.keys())
|
1517
|
-
values = list(edge_betweenness.values())
|
1518
1431
|
min_value = min(values)
|
1519
1432
|
max_value = max(values)
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
score = 0
|
1529
|
-
score = (score - min_value)/(max_value - min_value)
|
1530
|
-
edge_betweenness_scores.append(round(score, mantissa))
|
1531
|
-
d = Topology.Dictionary(graph_edges[i])
|
1532
|
-
d = Dictionary.SetValueAtKey(d, key, round(score, mantissa))
|
1533
|
-
graph_edges[i] = Topology.SetDictionary(graph_edges[i], d)
|
1534
|
-
return edge_betweenness_scores
|
1433
|
+
|
1434
|
+
for i, value in enumerate(values):
|
1435
|
+
d = Topology.Dictionary(elements[i])
|
1436
|
+
color = Color.AnyToHex(Color.ByValueInRange(value, minValue=min_value, maxValue=max_value, colorScale=colorScale))
|
1437
|
+
d = Dictionary.SetValuesAtKeys(d, [key, colorKey], [value, color])
|
1438
|
+
elements[i] = Topology.SetDictionary(elements[i], d)
|
1439
|
+
|
1440
|
+
return values
|
1535
1441
|
|
1536
1442
|
@staticmethod
|
1537
1443
|
def BetweennessPartition(graph, n=2, m=10, key="partition", tolerance=0.0001, silent=False):
|
@@ -4771,94 +4677,92 @@ class Graph:
|
|
4771
4677
|
graph = Graph.RemoveVertex(graph,ev, tolerance=tolerance)
|
4772
4678
|
return graph
|
4773
4679
|
|
4680
|
+
|
4774
4681
|
@staticmethod
|
4775
|
-
def ClosenessCentrality(graph,
|
4682
|
+
def ClosenessCentrality(graph, weightKey="length", normalize: bool = False, nx: bool = True, key: str = "closeness_centrality", colorKey="cc_color", colorScale="viridis", mantissa: int = 6, tolerance: float = 0.001, silent: bool = False):
|
4776
4683
|
"""
|
4777
|
-
|
4684
|
+
Returns the closeness centrality of the input graph. The order of the returned list is the same as the order of vertices/edges. See https://en.wikipedia.org/wiki/Betweenness_centrality.
|
4778
4685
|
|
4779
4686
|
Parameters
|
4780
4687
|
----------
|
4781
4688
|
graph : topologic_core.Graph
|
4782
4689
|
The input graph.
|
4783
|
-
|
4784
|
-
|
4690
|
+
weightKey : str , optional
|
4691
|
+
If None, all edge weights are considered equal. Otherwise holds the name of the edge dictionary key to be used as weight.
|
4692
|
+
Weights are used to calculate weighted shortest paths, so they are interpreted as distances.
|
4693
|
+
If you wish to use the actual length of the edge, then use the "length" as key. the default is "length".
|
4694
|
+
normalize : bool , optional
|
4695
|
+
If set to True, the values are normalized to be in the range 0 to 1. Otherwise they are not. The default is False.
|
4696
|
+
nx : bool , optional
|
4697
|
+
If set to True, use networkX to scale by the fraction of nodes reachable. This gives the Wasserman and Faust improved formula.
|
4698
|
+
For single component graphs it is the same as the original formula.
|
4785
4699
|
key : str , optional
|
4786
|
-
The dictionary key under which to store the closeness centrality score. The default is "closeness_centrality".
|
4700
|
+
The desired dictionary key under which to store the closeness centrality score. The default is "closeness_centrality".
|
4701
|
+
colorKey : str , optional
|
4702
|
+
The desired dictionary key under which to store the closeness centrality color. The default is "cc_color".
|
4703
|
+
colorScale : str , optional
|
4704
|
+
The desired type of plotly color scales to use (e.g. "viridis", "plasma"). The default is "viridis". For a full list of names, see https://plotly.com/python/builtin-colorscales/.
|
4705
|
+
In addition to these, three color-blind friendly scales are included. These are "protanopia", "deuteranopia", and "tritanopia" for red, green, and blue colorblindness respectively.
|
4787
4706
|
mantissa : int , optional
|
4788
4707
|
The desired length of the mantissa. The default is 6.
|
4789
4708
|
tolerance : float , optional
|
4790
4709
|
The desired tolerance. The default is 0.0001.
|
4791
|
-
silent : bool , optional
|
4792
|
-
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
4793
4710
|
|
4794
4711
|
Returns
|
4795
4712
|
-------
|
4796
4713
|
list
|
4797
|
-
The
|
4714
|
+
The betweenness centrality of the input list of vertices within the input graph. The values are in the range 0 to 1.
|
4798
4715
|
|
4799
4716
|
"""
|
4717
|
+
import warnings
|
4800
4718
|
|
4801
|
-
|
4802
|
-
|
4803
|
-
|
4804
|
-
|
4805
|
-
|
4806
|
-
|
4807
|
-
|
4808
|
-
|
4809
|
-
|
4810
|
-
|
4811
|
-
|
4812
|
-
|
4813
|
-
|
4814
|
-
|
4815
|
-
centralities = []
|
4816
|
-
for v in keys:
|
4817
|
-
total_distance = 0
|
4818
|
-
reachable_count = 0
|
4819
|
-
|
4820
|
-
for u in keys:
|
4821
|
-
if v != u:
|
4822
|
-
distance = Graph._topological_distance(g, v, u)
|
4823
|
-
if distance != None:
|
4824
|
-
total_distance += distance
|
4825
|
-
reachable_count += 1
|
4826
|
-
|
4827
|
-
if reachable_count > 0: # Avoid division by zero
|
4828
|
-
centrality = (reachable_count / total_distance)
|
4829
|
-
else:
|
4830
|
-
centrality = 0.0 # Isolated vertex
|
4831
|
-
|
4832
|
-
centralities.append(centrality)
|
4833
|
-
return centralities
|
4719
|
+
try:
|
4720
|
+
import networkx as nx
|
4721
|
+
except:
|
4722
|
+
print("Graph.BetwennessCentrality - Information: Installing required networkx library.")
|
4723
|
+
try:
|
4724
|
+
os.system("pip install networkx")
|
4725
|
+
except:
|
4726
|
+
os.system("pip install networkx --user")
|
4727
|
+
try:
|
4728
|
+
import networkx as nx
|
4729
|
+
print("Graph.ClosenessCentrality - Infromation: networkx library installed correctly.")
|
4730
|
+
except:
|
4731
|
+
warnings.warn("Graph.ClosenessCentrality - Error: Could not import networkx. Please try to install networkx manually. Returning None.")
|
4732
|
+
return None
|
4834
4733
|
|
4835
|
-
from topologicpy.Vertex import Vertex
|
4836
|
-
from topologicpy.Topology import Topology
|
4837
4734
|
from topologicpy.Dictionary import Dictionary
|
4735
|
+
from topologicpy.Color import Color
|
4736
|
+
from topologicpy.Topology import Topology
|
4838
4737
|
from topologicpy.Helper import Helper
|
4839
4738
|
|
4840
|
-
if not Topology.IsInstance(graph, "
|
4739
|
+
if not Topology.IsInstance(graph, "graph"):
|
4841
4740
|
if not silent:
|
4842
4741
|
print("Graph.ClosenessCentrality - Error: The input graph is not a valid graph. Returning None.")
|
4843
4742
|
return None
|
4844
|
-
|
4845
|
-
|
4846
|
-
|
4847
|
-
|
4848
|
-
|
4849
|
-
|
4850
|
-
|
4851
|
-
|
4852
|
-
|
4743
|
+
|
4744
|
+
if weightKey:
|
4745
|
+
if "len" in weightKey.lower():
|
4746
|
+
weightKey = "length"
|
4747
|
+
nx_graph = Graph.NetworkXGraph(graph)
|
4748
|
+
elements = Graph.Vertices(graph)
|
4749
|
+
elements_dict = nx.closeness_centrality(nx_graph, distance=weightKey, wf_improved=nx)
|
4750
|
+
values = list(elements_dict.values())
|
4751
|
+
if normalize == True:
|
4752
|
+
values = Helper.Normalize(values)
|
4753
|
+
min_value = 0
|
4754
|
+
max_value = 1
|
4853
4755
|
else:
|
4854
|
-
|
4855
|
-
|
4856
|
-
|
4857
|
-
|
4858
|
-
|
4859
|
-
|
4860
|
-
|
4861
|
-
|
4756
|
+
min_value = min(values)
|
4757
|
+
max_value = max(values)
|
4758
|
+
|
4759
|
+
for i, value in enumerate(values):
|
4760
|
+
d = Topology.Dictionary(elements[i])
|
4761
|
+
color = Color.AnyToHex(Color.ByValueInRange(value, minValue=min_value, maxValue=max_value, colorScale=colorScale))
|
4762
|
+
d = Dictionary.SetValuesAtKeys(d, [key, colorKey], [value, color])
|
4763
|
+
elements[i] = Topology.SetDictionary(elements[i], d)
|
4764
|
+
|
4765
|
+
return values
|
4862
4766
|
|
4863
4767
|
@staticmethod
|
4864
4768
|
def Community(graph, key: str = "partition", mantissa: int = 6, tolerance: float = 0.0001, silent: bool = False):
|
@@ -9264,6 +9168,101 @@ class Graph:
|
|
9264
9168
|
from topologicpy.Vertex import Vertex
|
9265
9169
|
from topologicpy.Topology import Topology
|
9266
9170
|
from topologicpy.Dictionary import Dictionary
|
9171
|
+
import warnings
|
9172
|
+
|
9173
|
+
try:
|
9174
|
+
import networkx as nx
|
9175
|
+
except:
|
9176
|
+
print("Graph.NetworkXGraph - Information: Installing required networkx library.")
|
9177
|
+
try:
|
9178
|
+
os.system("pip install networkx")
|
9179
|
+
except:
|
9180
|
+
os.system("pip install networkx --user")
|
9181
|
+
try:
|
9182
|
+
import networkx as nx
|
9183
|
+
print("Graph.NetworkXGraph - Information: networkx library installed correctly.")
|
9184
|
+
except:
|
9185
|
+
warnings.warn("Graph - Error: Could not import networkx. Please try to install networkx manually. Returning None.")
|
9186
|
+
return None
|
9187
|
+
|
9188
|
+
if not Topology.IsInstance(graph, "Graph"):
|
9189
|
+
if not silent:
|
9190
|
+
print("Graph.NetworkXGraph - Error: The input graph is not a valid graph. Returning None.")
|
9191
|
+
return None
|
9192
|
+
|
9193
|
+
nxGraph = nx.Graph()
|
9194
|
+
vertices = Graph.Vertices(graph)
|
9195
|
+
edges = Graph.Edges(graph)
|
9196
|
+
mesh_data = Graph.MeshData(graph)
|
9197
|
+
order = len(vertices)
|
9198
|
+
nodes = []
|
9199
|
+
for i in range(order):
|
9200
|
+
v = vertices[i]
|
9201
|
+
d = Topology.Dictionary(vertices[i])
|
9202
|
+
if d:
|
9203
|
+
keys = Dictionary.Keys(d)
|
9204
|
+
if not keys:
|
9205
|
+
keys = []
|
9206
|
+
values = Dictionary.Values(d)
|
9207
|
+
if not values:
|
9208
|
+
values = []
|
9209
|
+
keys += [xKey, yKey, zKey]
|
9210
|
+
values += [Vertex.X(v, mantissa=mantissa), Vertex.Y(v, mantissa=mantissa), Vertex.Z(v, mantissa=mantissa)]
|
9211
|
+
d = Dictionary.ByKeysValues(keys, values)
|
9212
|
+
pythonD = Dictionary.PythonDictionary(d)
|
9213
|
+
nodes.append((i, pythonD))
|
9214
|
+
else:
|
9215
|
+
nodes.append((i, {"name": str(i)}))
|
9216
|
+
nxGraph.add_nodes_from(nodes)
|
9217
|
+
|
9218
|
+
mesh_edges = mesh_data['edges']
|
9219
|
+
for i, mesh_edge in enumerate(mesh_edges):
|
9220
|
+
sv_i = mesh_edge[0]
|
9221
|
+
ev_i = mesh_edge[1]
|
9222
|
+
sv = vertices[sv_i]
|
9223
|
+
ev = vertices[ev_i]
|
9224
|
+
edge_length = Vertex.Distance(sv, ev, mantissa=mantissa)
|
9225
|
+
edge_dict = Topology.Dictionary(edges[i])
|
9226
|
+
edge_attributes = Dictionary.PythonDictionary(edge_dict) if edge_dict else {}
|
9227
|
+
edge_attributes['length'] = edge_length
|
9228
|
+
nxGraph.add_edge(sv_i, ev_i, **edge_attributes)
|
9229
|
+
|
9230
|
+
pos = nx.spring_layout(nxGraph, k=0.2)
|
9231
|
+
nx.set_node_attributes(nxGraph, pos, "pos")
|
9232
|
+
return nxGraph
|
9233
|
+
|
9234
|
+
@staticmethod
|
9235
|
+
def NetworkXGraph_old(graph, xKey='x', yKey='y', zKey='z', mantissa: int = 6, tolerance: float = 0.0001, silent: bool = False):
|
9236
|
+
"""
|
9237
|
+
Converts the input graph into a NetworkX Graph. See http://networkx.org
|
9238
|
+
|
9239
|
+
Parameters
|
9240
|
+
----------
|
9241
|
+
graph : topologic_core.Graph
|
9242
|
+
The input graph.
|
9243
|
+
xKey : str , optional
|
9244
|
+
The dictionary key under which to store the X-Coordinate of the vertex. The default is 'x'.
|
9245
|
+
yKey : str , optional
|
9246
|
+
The dictionary key under which to store the Y-Coordinate of the vertex. The default is 'y'.
|
9247
|
+
zKey : str , optional
|
9248
|
+
The dictionary key under which to store the Z-Coordinate of the vertex. The default is 'z'.
|
9249
|
+
mantissa : int , optional
|
9250
|
+
The desired length of the mantissa. The default is 6.
|
9251
|
+
tolerance : float , optional
|
9252
|
+
The desired tolerance. The default is 0.0001.
|
9253
|
+
silent : bool , optional
|
9254
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
9255
|
+
|
9256
|
+
Returns
|
9257
|
+
-------
|
9258
|
+
networkX Graph
|
9259
|
+
The created networkX Graph
|
9260
|
+
|
9261
|
+
"""
|
9262
|
+
from topologicpy.Vertex import Vertex
|
9263
|
+
from topologicpy.Topology import Topology
|
9264
|
+
from topologicpy.Dictionary import Dictionary
|
9265
|
+
import warnings
|
9267
9266
|
|
9268
9267
|
try:
|
9269
9268
|
import networkx as nx
|