topologicpy 0.5.4__py3-none-any.whl → 0.5.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.
topologicpy/Plotly.py CHANGED
@@ -1,2025 +1,2025 @@
1
- # Copyright (C) 2024
2
- # Wassim Jabi <wassim.jabi@gmail.com>
3
- #
4
- # This program is free software: you can redistribute it and/or modify it under
5
- # the terms of the GNU Affero General Public License as published by the Free Software
6
- # Foundation, either version 3 of the License, or (at your option) any later
7
- # version.
8
- #
9
- # This program is distributed in the hope that it will be useful, but WITHOUT
10
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
- # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
12
- # details.
13
- #
14
- # You should have received a copy of the GNU Affero General Public License along with
15
- # this program. If not, see <https://www.gnu.org/licenses/>.
16
-
17
- import topologicpy
18
- import topologic
19
-
20
- from topologicpy.Wire import Wire
21
- from topologicpy.Face import Face
22
- import os
23
- import warnings
24
-
25
- try:
26
- import numpy as np
27
- except:
28
- print("Plotly - Installing required numpy library.")
29
- try:
30
- os.system("pip install numpy")
31
- except:
32
- os.system("pip install numpy --user")
33
- try:
34
- import numpy as np
35
- except:
36
- warnings.warn("Plotly - Error: Could not import numpy.")
37
-
38
- try:
39
- import pandas as pd
40
- except:
41
- print("Plotly - Installing required pandas library.")
42
- try:
43
- os.system("pip install pandas")
44
- except:
45
- os.system("pip install pandas --user")
46
- try:
47
- import pandas as pd
48
- except:
49
- warnings.warn("Plotly - Error: Could not import pandas.")
50
-
51
- try:
52
- import plotly
53
- import plotly.graph_objects as go
54
- import plotly.offline as ofl
55
- except:
56
- print("Plotly - Installing required plotly library.")
57
- try:
58
- os.system("pip install plotly")
59
- except:
60
- os.system("pip install plotly --user")
61
- try:
62
- import plotly
63
- import plotly.graph_objects as go
64
- import plotly.offline as ofl
65
- except:
66
- warnings.warn("Plotly - Error: Could not import plotly.")
67
-
68
- class Plotly:
69
- @staticmethod
70
- def AddColorBar(figure, values=[], nTicks=5, xPosition=-0.15, width=15, outlineWidth=0, title="", subTitle="", units="", colorScale="viridis", mantissa: int = 6):
71
- """
72
- Adds a color bar to the input figure
73
-
74
- Parameters
75
- ----------
76
- figure : plotly.graph_objs._figure.Figure
77
- The input plotly figure.
78
- values : list , optional
79
- The input list of values to use for the color bar. The default is [].
80
- nTicks : int , optional
81
- The number of ticks to use on the color bar. The default is 5.
82
- xPosition : float , optional
83
- The x location of the color bar. The default is -0.15.
84
- width : int , optional
85
- The width in pixels of the color bar. The default is 15
86
- outlineWidth : int , optional
87
- The width in pixels of the outline of the color bar. The default is 0.
88
- title : str , optional
89
- The title of the color bar. The default is "".
90
- subTitle : str , optional
91
- The subtitle of the color bar. The default is "".
92
- units: str , optional
93
- The units used in the color bar. The default is ""
94
- colorScale : str , optional
95
- 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/.
96
- mantissa : int , optional
97
- The desired length of the mantissa for the values listed on the color bar. The default is 6.
98
- Returns
99
- -------
100
- plotly.graph_objs._figure.Figure
101
- The input figure with the color bar added.
102
-
103
- """
104
- if not isinstance(figure, plotly.graph_objs._figure.Figure):
105
- return None
106
- if units:
107
- units = "Units: "+units
108
- minValue = min(values)
109
- maxValue = max(values)
110
- step = (maxValue - minValue)/float(nTicks-1)
111
- r = [round(minValue+i*step, mantissa) for i in range(nTicks)]
112
- r[-1] = round(maxValue, mantissa)
113
- # Define the minimum and maximum range of the colorbar
114
- rs = [str(x) for x in r]
115
-
116
- # Define the colorbar as a trace with no data, x or y coordinates
117
- colorbar_trace = go.Scatter(
118
- x=[0],
119
- y=[0],
120
- mode="markers",
121
- showlegend=False,
122
- marker=dict(
123
- size=0,
124
- colorscale=colorScale, # choose the colorscale
125
- cmin=minValue,
126
- cmax=maxValue,
127
- color=['rgba(0,0,0,0)'],
128
- colorbar=dict(
129
- x=xPosition,
130
- title="<b>"+title+"</b><br>"+subTitle+"<br>"+units, # title of the colorbar
131
- ticks="outside", # position of the ticks
132
- tickvals=r, # values of the ticks
133
- ticktext=rs, # text of the ticks
134
- tickmode="array",
135
- thickness=width,
136
- outlinewidth=outlineWidth,
137
-
138
- )
139
- )
140
- )
141
- figure.add_trace(colorbar_trace)
142
- return figure
143
-
144
- @staticmethod
145
- def Colors():
146
- """
147
- Returns the list of named CSS colors that plotly can use.
148
-
149
- Returns
150
- -------
151
- list
152
- The list of named CSS colors.
153
- """
154
- return ["aliceblue","antiquewhite","aqua",
155
- "aquamarine","azure","beige",
156
- "bisque","black","blanchedalmond",
157
- "blue","blueviolet","brown",
158
- "burlywood","cadetblue",
159
- "chartreuse","chocolate",
160
- "coral","cornflowerblue","cornsilk",
161
- "crimson","cyan","darkblue",
162
- "darkcyan","darkgoldenrod","darkgray",
163
- "darkgrey","darkgreen","darkkhaki",
164
- "darkmagenta","darkolivegreen","darkorange",
165
- "darkorchid","darkred","darksalmon",
166
- "darkseagreen","darkslateblue","darkslategray",
167
- "darkslategrey","darkturquoise","darkviolet",
168
- "deeppink","deepskyblue","dimgray",
169
- "dimgrey","dodgerblue","firebrick",
170
- "floralwhite","forestgreen","fuchsia",
171
- "gainsboro","ghostwhite","gold",
172
- "goldenrod","gray","grey",
173
- "green"," greenyellow","honeydew",
174
- "hotpink","indianred","indigo",
175
- "ivory","khaki","lavender",
176
- "lavenderblush","lawngreen","lemonchiffon",
177
- "lightblue","lightcoral","lightcyan",
178
- "lightgoldenrodyellow","lightgray","lightgrey",
179
- "lightgreen","lightpink","lightsalmon",
180
- "lightseagreen","lightskyblue","lightslategray",
181
- "lightslategrey","lightsteelblue","lightyellow",
182
- "lime","limegreen","linen",
183
- "magenta","maroon","mediumaquamarine",
184
- "mediumblue","mediumorchid","mediumpurple",
185
- "mediumseagreen","mediumslateblue","mediumspringgreen",
186
- "mediumturquoise","mediumvioletred","midnightblue",
187
- "mintcream","mistyrose","moccasin",
188
- "navajowhite","navy","oldlace",
189
- "olive","olivedrab","orange",
190
- "orangered","orchid","palegoldenrod",
191
- "palegreen","paleturquoise","palevioletred",
192
- "papayawhip","peachpuff","peru",
193
- "pink","plum","powderblue",
194
- "purple","red","rosybrown",
195
- "royalblue","rebeccapurple","saddlebrown",
196
- "salmon","sandybrown","seagreen",
197
- "seashell","sienna","silver",
198
- "skyblue","slateblue","slategray",
199
- "slategrey","snow","springgreen",
200
- "steelblue","tan","teal",
201
- "thistle","tomato","turquoise",
202
- "violet","wheat","white",
203
- "whitesmoke","yellow","yellowgreen"]
204
-
205
-
206
- @staticmethod
207
- def DataByDGL(data, labels):
208
- """
209
- Returns a data frame from the DGL data.
210
-
211
- Parameters
212
- ----------
213
- data : list
214
- The data to display.
215
- labels : list
216
- The labels to use for the data. The data with the labels in this list will be extracted and used in the returned dataFrame.
217
-
218
- Returns
219
- -------
220
- pd.DataFrame
221
- A pandas dataFrame
222
-
223
- """
224
-
225
- if isinstance(data[labels[0]][0], int):
226
- xAxis_list = list(range(1, data[labels[0]][0]+1))
227
- else:
228
- xAxis_list = data[labels[0]][0]
229
- plot_data = [xAxis_list]
230
- for i in range(1,len(labels)):
231
- plot_data.append(data[labels[i]][0][:len(xAxis_list)])
232
-
233
- dlist = list(map(list, zip(*plot_data)))
234
- df = pd.DataFrame(dlist, columns=labels)
235
- return df
236
-
237
- @staticmethod
238
- def DataByGraph(graph, vertexColor="black", vertexSize=6, vertexLabelKey=None, vertexGroupKey=None, vertexGroups=[], showVertices=True, showVertexLegend=False, edgeColor="black", edgeWidth=1, edgeLabelKey=None, edgeGroupKey=None, edgeGroups=[], showEdges=True, showEdgeLegend=False, colorScale="viridis"):
239
- """
240
- Creates plotly vertex and edge data from the input graph.
241
-
242
- Parameters
243
- ----------
244
- graph : topologic.Graph
245
- The input graph.
246
- vertexColor : str , optional
247
- The desired color of the output vertices. This can be any plotly color string and may be specified as:
248
- - A hex string (e.g. '#ff0000')
249
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
250
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
251
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
252
- - A named CSS color.
253
- The default is "black".
254
- vertexSize : float , optional
255
- The desired size of the vertices. The default is 6.
256
- vertexLabelKey : str , optional
257
- The dictionary key to use to display the vertex label. The default is None.
258
- vertexGroupKey : str , optional
259
- The dictionary key to use to display the vertex group. The default is None.
260
- vertexGroups : list , optional
261
- The list of vertex groups against which to index the color of the vertex. The default is [].
262
- showVertices : bool , optional
263
- If set to True the vertices will be drawn. Otherwise, they will not be drawn. The default is True.
264
- showVertexLegend : bool , optional
265
- If set to True the vertex legend will be drawn. Otherwise, it will not be drawn. The default is False.
266
- edgeColor : str , optional
267
- The desired color of the output edges. This can be any plotly color string and may be specified as:
268
- - A hex string (e.g. '#ff0000')
269
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
270
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
271
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
272
- - A named CSS color.
273
- The default is "black".
274
- edgeWidth : float , optional
275
- The desired thickness of the output edges. The default is 1.
276
- edgeLabelKey : str , optional
277
- The dictionary key to use to display the edge label. The default is None.
278
- edgeGroupKey : str , optional
279
- The dictionary key to use to display the edge group. The default is None.
280
- edgeGroups : list , optional
281
- The list of groups to use for indexing the color of edges. The default is None.
282
- showEdges : bool , optional
283
- If set to True the edges will be drawn. Otherwise, they will not be drawn. The default is True.
284
- showEdgeLegend : bool , optional
285
- If set to True the edge legend will be drawn. Otherwise, it will not be drawn. The default is False.
286
- colorScale : str , optional
287
- 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/.
288
- Returns
289
- -------
290
- list
291
- The vertex and edge data list.
292
-
293
- """
294
- from topologicpy.Vertex import Vertex
295
- from topologicpy.Edge import Edge
296
- from topologicpy.Dictionary import Dictionary
297
- from topologicpy.Topology import Topology
298
- from topologicpy.Graph import Graph
299
- import plotly.graph_objs as go
300
-
301
- if not isinstance(graph, topologic.Graph):
302
- return None
303
- v_labels = []
304
- v_groupList = []
305
- data = []
306
- if showVertices:
307
- vertices = Graph.Vertices(graph)
308
- if vertexLabelKey or vertexGroupKey:
309
- for v in vertices:
310
- Xn=[round(Vertex.X(v), 4) for v in vertices] # x-coordinates of nodes
311
- Yn=[round(Vertex.Y(v), 4) for v in vertices] # y-coordinates of nodes
312
- Zn=[round(Vertex.Z(v), 4) for v in vertices] # x-coordinates of nodes
313
- v_label = ""
314
- v_group = ""
315
- d = Topology.Dictionary(v)
316
- if d:
317
- try:
318
- v_label = str(Dictionary.ValueAtKey(d, key=vertexLabelKey)) or ""
319
- except:
320
- v_label = ""
321
- try:
322
- v_group = Dictionary.ValueAtKey(d, key=vertexGroupKey)
323
- except:
324
- v_group = None
325
- try:
326
- v_groupList.append(vertexGroups.index(v_group))
327
- except:
328
- v_groupList.append(len(vertexGroups))
329
- if not v_label == "" and not v_group == "":
330
- if v_group == 0:
331
- v_label = v_label+" (0)"
332
- else:
333
- v_label = v_label+" ("+str(v_group)+")"
334
- v_labels.append(v_label)
335
- else:
336
- for v in vertices:
337
- Xn=[round(Vertex.X(v), 4) for v in vertices] # x-coordinates of nodes
338
- Yn=[round(Vertex.Y(v), 4) for v in vertices] # y-coordinates of nodes
339
- Zn=[round(Vertex.Z(v), 4) for v in vertices] # x-coordinates of nodes
340
- if len(list(set(v_groupList))) < 2:
341
- v_groupList = vertexColor
342
- if len(v_labels) < 1:
343
- v_labels = ""
344
- v_trace=go.Scatter3d(x=Xn,
345
- y=Yn,
346
- z=Zn,
347
- mode='markers',
348
- name='Graph Vertices',
349
- legendgroup=4,
350
- legendrank=4,
351
- showlegend=showVertexLegend,
352
- marker=dict(symbol='circle',
353
- size=vertexSize,
354
- color=v_groupList,
355
- colorscale=colorScale,
356
- line=dict(color=edgeColor, width=0.5)
357
- ),
358
- text=v_labels,
359
- hoverinfo='text'
360
- )
361
- data.append(v_trace)
362
-
363
- if showEdges:
364
- Xe=[]
365
- Ye=[]
366
- Ze=[]
367
- e_labels = []
368
- e_groupList = []
369
- edges = Graph.Edges(graph)
370
-
371
- if edgeLabelKey or edgeGroupKey:
372
- for e in edges:
373
- sv = Edge.StartVertex(e)
374
- ev = Edge.EndVertex(e)
375
- Xe+=[round(Vertex.X(sv), 4), round(Vertex.X(ev), 4), None] # x-coordinates of edge ends
376
- Ye+=[round(Vertex.Y(sv), 4), round(Vertex.Y(ev), 4), None] # y-coordinates of edge ends
377
- Ze+=[round(Vertex.Z(sv), 4), round(Vertex.Z(ev), 4), None] # z-coordinates of edge ends
378
- e_label = ""
379
- e_group = ""
380
- d = Topology.Dictionary(e)
381
- if d:
382
- try:
383
- e_label = str(Dictionary.ValueAtKey(d, key=edgeLabelKey)) or ""
384
- except:
385
- e_label = ""
386
- try:
387
- e_group = str(Dictionary.ValueAtKey(d, key=edgeGroupKey)) or ""
388
- except:
389
- e_group = ""
390
- try:
391
- e_groupList.append(edgeGroups.index(e_group))
392
- except:
393
- e_groupList.append(len(edgeGroups))
394
- if not e_label == "" and not e_group == "":
395
- e_label = e_label+" ("+e_group+")"
396
- e_labels.append(e_label)
397
- else:
398
- for e in edges:
399
- sv = Edge.StartVertex(e)
400
- ev = Edge.EndVertex(e)
401
- Xe+=[round(Vertex.X(sv), 4), round(Vertex.X(ev), 4), None] # x-coordinates of edge ends
402
- Ye+=[round(Vertex.Y(sv), 4), round(Vertex.Y(ev), 4), None] # y-coordinates of edge ends
403
- Ze+=[round(Vertex.Z(sv), 4), round(Vertex.Z(ev), 4), None] # z-coordinates of edge ends
404
-
405
- if len(list(set(e_groupList))) < 2:
406
- e_groupList = edgeColor
407
- if len(e_labels) < 1:
408
- e_labels = ""
409
-
410
- e_trace=go.Scatter3d(x=Xe,
411
- y=Ye,
412
- z=Ze,
413
- mode='lines',
414
- name='Graph Edges',
415
- legendgroup=5,
416
- legendrank=5,
417
- showlegend=showEdgeLegend,
418
- line=dict(color=e_groupList, width=edgeWidth),
419
- text=e_labels,
420
- hoverinfo='text'
421
- )
422
- data.append(e_trace)
423
-
424
- return data
425
-
426
-
427
-
428
-
429
-
430
-
431
-
432
-
433
-
434
- @staticmethod
435
- def DataByTopology(topology,
436
- showVertices=True, vertexSize=1.1, vertexColor="black",
437
- vertexLabelKey=None, vertexGroupKey=None, vertexGroups=[],
438
- vertexMinGroup=None, vertexMaxGroup=None,
439
- showVertexLegend=False, vertexLegendLabel="Topology Vertices", vertexLegendRank=1,
440
- vertexLegendGroup=1,
441
- showEdges=True, edgeWidth=1, edgeColor="black",
442
- edgeLabelKey=None, edgeGroupKey=None, edgeGroups=[],
443
- edgeMinGroup=None, edgeMaxGroup=None,
444
- showEdgeLegend=False, edgeLegendLabel="Topology Edges", edgeLegendRank=2,
445
- edgeLegendGroup=2,
446
- showFaces=True, faceOpacity=0.5, faceColor="#FAFAFA",
447
- faceLabelKey=None, faceGroupKey=None, faceGroups=[],
448
- faceMinGroup=None, faceMaxGroup=None,
449
- showFaceLegend=False, faceLegendLabel="Topology Faces", faceLegendRank=3,
450
- faceLegendGroup=3,
451
- intensityKey=None, intensities=[], colorScale="Viridis", mantissa=6, tolerance=0.0001):
452
- """
453
- Creates plotly face, edge, and vertex data.
454
-
455
- Parameters
456
- ----------
457
- topology : topologic.Topology
458
- The input topology. This must contain faces and or edges.
459
-
460
- showVertices : bool , optional
461
- If set to True the vertices will be drawn. Otherwise, they will not be drawn. The default is True.
462
- vertexSize : float , optional
463
- The desired size of the vertices. The default is 1.1.
464
- vertexColor : str , optional
465
- The desired color of the output vertices. This can be any plotly color string and may be specified as:
466
- - A hex string (e.g. '#ff0000')
467
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
468
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
469
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
470
- - A named CSS color.
471
- The default is "black".
472
- vertexLabelKey : str , optional
473
- The dictionary key to use to display the vertex label. The default is None.
474
- vertexGroupKey : str , optional
475
- The dictionary key to use to display the vertex group. The default is None.
476
- vertexGroups : list , optional
477
- The list of vertex groups against which to index the color of the vertex. The default is [].
478
- vertexMinGroup : int or float , optional
479
- For numeric vertexGroups, vertexMinGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the vertexGroupKey. If set to None, it is set to the minimum value in vertexGroups. The default is None.
480
- vertexMaxGroup : int or float , optional
481
- For numeric vertexGroups, vertexMaxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the vertexGroupKey. If set to None, it is set to the maximum value in vertexGroups. The default is None.
482
- showVertexLegend : bool, optional
483
- If set to True, the legend for the vertices of this topology is shown. Otherwise, it isn't. The default is False.
484
- vertexLegendLabel : str , optional
485
- The legend label string used to identify vertices. The default is "Topology Vertices".
486
- vertexLegendRank : int , optional
487
- The legend rank order of the vertices of this topology. The default is 1.
488
- vertexLegendGroup : int , optional
489
- The number of the vertex legend group to which the vertices of this topology belong. The default is 1.
490
-
491
- showEdges : bool , optional
492
- If set to True the edges will be drawn. Otherwise, they will not be drawn. The default is True.
493
- edgeWidth : float , optional
494
- The desired thickness of the output edges. The default is 1.
495
- edgeColor : str , optional
496
- The desired color of the output edges. This can be any plotly color string and may be specified as:
497
- - A hex string (e.g. '#ff0000')
498
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
499
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
500
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
501
- - A named CSS color.
502
- The default is "black".
503
- edgeLabelKey : str , optional
504
- The dictionary key to use to display the edge label. The default is None.
505
- edgeGroupKey : str , optional
506
- The dictionary key to use to display the edge group. The default is None.
507
- edgeGroups : list , optional
508
- The list of edge groups against which to index the color of the edge. The default is [].
509
- edgeMinGroup : int or float , optional
510
- For numeric edgeGroups, edgeMinGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the edgeGroupKey. If set to None, it is set to the minimum value in edgeGroups. The default is None.
511
- edgeMaxGroup : int or float , optional
512
- For numeric edgeGroups, edgeMaxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the edgeGroupKey. If set to None, it is set to the maximum value in edgeGroups. The default is None.
513
- showEdgeLegend : bool, optional
514
- If set to True, the legend for the edges of this topology is shown. Otherwise, it isn't. The default is False.
515
- edgeLegendLabel : str , optional
516
- The legend label string used to identify edges. The default is "Topology Edges".
517
- edgeLegendRank : int , optional
518
- The legend rank order of the edges of this topology. The default is 2.
519
- edgeLegendGroup : int , optional
520
- The number of the edge legend group to which the edges of this topology belong. The default is 2.
521
-
522
- showFaces : bool , optional
523
- If set to True the faces will be drawn. Otherwise, they will not be drawn. The default is True.
524
- faceOpacity : float , optional
525
- The desired opacity of the output faces (0=transparent, 1=opaque). The default is 0.5.
526
- faceColor : str , optional
527
- The desired color of the output faces. This can be any plotly color string and may be specified as:
528
- - A hex string (e.g. '#ff0000')
529
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
530
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
531
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
532
- - A named CSS color.
533
- The default is "#FAFAFA".
534
- faceLabelKey : str , optional
535
- The dictionary key to use to display the face label. The default is None.
536
- faceGroupKey : str , optional
537
- The dictionary key to use to display the face group. The default is None.
538
- faceGroups : list , optional
539
- The list of face groups against which to index the color of the face. This can bhave numeric or string values. This should match the type of value associated with the faceGroupKey. The default is [].
540
- faceMinGroup : int or float , optional
541
- For numeric faceGroups, minGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the faceGroupKey. If set to None, it is set to the minimum value in faceGroups. The default is None.
542
- faceMaxGroup : int or float , optional
543
- For numeric faceGroups, maxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the faceGroupKey. If set to None, it is set to the maximum value in faceGroups. The default is None.
544
- showFaceLegend : bool, optional
545
- If set to True, the legend for the faces of this topology is shown. Otherwise, it isn't. The default is False.
546
- faceLegendLabel : str , optional
547
- The legend label string used to idenitfy edges. The default is "Topology Faces".
548
- faceLegendRank : int , optional
549
- The legend rank order of the faces of this topology. The default is 3.
550
- faceLegendGroup : int , optional
551
- The number of the face legend group to which the faces of this topology belong. The default is 3.
552
- intensityKey: str, optional
553
- If not None, the dictionary of each vertex is searched for the value associated with the intensity key. This value is then used to color-code the vertex based on the colorScale. The default is None.
554
- intensities : list , optional
555
- The list of intensities against which to index the intensity of the vertex. The default is [].
556
- colorScale : str , optional
557
- 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/.
558
- mantissa : int , optional
559
- The desired length of the mantissa. The default is 6.
560
- tolerance : float , optional
561
- The desired tolerance. The default is 0.0001.
562
-
563
- Returns
564
- -------
565
- list
566
- The vertex, edge, and face data list.
567
-
568
- """
569
- from topologicpy.Topology import Topology
570
- from topologicpy.Dictionary import Dictionary
571
- from topologicpy.Color import Color
572
- from time import time
573
-
574
- def closest_index(input_value, values):
575
- return int(min(range(len(values)), key=lambda i: abs(values[i] - input_value)))
576
-
577
- def vertexData(vertices, dictionaries=[], color="black", size=1.1, labelKey=None, groupKey=None, minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Vertices", legendGroup=1, legendRank=1, showLegend=True, colorScale="Viridis"):
578
- x = []
579
- y = []
580
- z = []
581
- labels = []
582
- groupList = []
583
- label = ""
584
- group = ""
585
- if labelKey or groupKey:
586
- if groups:
587
- if len(groups) > 0:
588
- if type(groups[0]) == int or type(groups[0]) == float:
589
- if not minGroup:
590
- minGroup = min(groups)
591
- if not maxGroup:
592
- maxGroup = max(groups)
593
- else:
594
- minGroup = 0
595
- maxGroup = len(groups) - 1
596
- else:
597
- minGroup = 0
598
- maxGroup = 1
599
- for m, v in enumerate(vertices):
600
- x.append(round(v[0], mantissa))
601
- y.append(round(v[1], mantissa))
602
- z.append(round(v[2], mantissa))
603
- label = ""
604
- group = ""
605
- if len(dictionaries) > 0:
606
- d = dictionaries[m]
607
- if d:
608
- try:
609
- label = str(Dictionary.ValueAtKey(d, key=labelKey)) or ""
610
- except:
611
- label = ""
612
- try:
613
- group = Dictionary.ValueAtKey(d, key=groupKey) or None
614
- except:
615
- group = ""
616
- try:
617
- if type(group) == int or type(group) == float:
618
- if group < minGroup:
619
- group = minGroup
620
- if group > maxGroup:
621
- group = maxGroup
622
- color = Color.ByValueInRange(group, minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
623
- else:
624
- color = Color.ByValueInRange(groups.index(group), minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
625
- color = "rgb("+str(color[0])+","+str(color[1])+","+str(color[2])+")"
626
- groupList.append(color)
627
- except:
628
- groupList.append(len(groups))
629
- labels.append(label)
630
- else:
631
- for v in vertices:
632
- x.append(round(v[0], mantissa))
633
- y.append(round(v[1], mantissa))
634
- z.append(round(v[2], mantissa))
635
-
636
- if len(list(set(groupList))) < 2:
637
- groupList = color
638
- if len(labels) < 1:
639
- labels = ""
640
- vData= go.Scatter3d(x=x,
641
- y=y,
642
- z=z,
643
- name=legendLabel,
644
- showlegend=showLegend,
645
- marker=dict(color=groupList, size=vertexSize),
646
- mode='markers',
647
- legendgroup=legendGroup,
648
- legendrank=legendRank,
649
- text=labels,
650
- hoverinfo='text',
651
- hovertext=labels
652
- )
653
- return vData
654
-
655
- def edgeData(vertices, edges, dictionaries=None, color="black", width=1, labelKey=None, groupKey=None, minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Edges", legendGroup=2, legendRank=2, showLegend=True, colorScale="Viridis"):
656
- x = []
657
- y = []
658
- z = []
659
- labels = []
660
- groupList = []
661
- label = ""
662
- group = ""
663
- if labelKey or groupKey:
664
- if groups:
665
- if len(groups) > 0:
666
- if type(groups[0]) == int or type(groups[0]) == float:
667
- if not minGroup:
668
- minGroup = min(groups)
669
- if not maxGroup:
670
- maxGroup = max(groups)
671
- else:
672
- minGroup = 0
673
- maxGroup = len(groups) - 1
674
- else:
675
- minGroup = 0
676
- maxGroup = 1
677
- for m, e in enumerate(edges):
678
- sv = vertices[e[0]]
679
- ev = vertices[e[1]]
680
- x+=[round(sv[0], mantissa),round(ev[0], mantissa), None] # x-coordinates of edge ends
681
- y+=[round(sv[1], mantissa),round(ev[1], mantissa), None] # y-coordinates of edge ends
682
- z+=[round(sv[2], mantissa),round(ev[2], mantissa), None] # z-coordinates of edge ends
683
- label = ""
684
- group = ""
685
- if len(dictionaries) > 0:
686
- d = dictionaries[m]
687
- if d:
688
- try:
689
- label = str(Dictionary.ValueAtKey(d, key=labelKey)) or ""
690
- except:
691
- label = ""
692
- try:
693
- group = Dictionary.ValueAtKey(d, key=groupKey) or None
694
- except:
695
- group = ""
696
- try:
697
- if type(group) == int or type(group) == float:
698
- if group < minGroup:
699
- group = minGroup
700
- if group > maxGroup:
701
- group = maxGroup
702
- color = Color.ByValueInRange(group, minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
703
- else:
704
- color = Color.ByValueInRange(groups.index(group), minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
705
- color = "rgb("+str(color[0])+","+str(color[1])+","+str(color[2])+")"
706
- groupList.append(color)
707
- except:
708
- groupList.append(len(groups))
709
- labels.append(label)
710
- else:
711
- for e in edges:
712
- sv = vertices[e[0]]
713
- ev = vertices[e[1]]
714
- x+=[round(sv[0],mantissa),round(ev[0],mantissa), None] # x-coordinates of edge ends
715
- y+=[round(sv[1],mantissa),round(ev[1],mantissa), None] # y-coordinates of edge ends
716
- z+=[round(sv[2],mantissa),round(ev[2],mantissa), None] # z-coordinates of edge ends
717
-
718
- if len(list(set(groupList))) < 2:
719
- groupList = color
720
- if len(labels) < 1:
721
- labels = ""
722
- eData = go.Scatter3d(x=x,
723
- y=y,
724
- z=z,
725
- name=legendLabel,
726
- showlegend=showLegend,
727
- marker_size=0,
728
- mode="lines",
729
- line=dict(color=groupList, width=edgeWidth),
730
- legendgroup=legendGroup,
731
- legendrank=legendRank,
732
- text=labels,
733
- hoverinfo='text')
734
- return eData
735
-
736
-
737
- def faceData(vertices, faces, dictionaries=None, color="#FAFAFA",
738
- opacity=0.5, labelKey=None, groupKey=None,
739
- minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Faces",
740
- legendGroup=3, legendRank=3, showLegend=True, intensities=None, colorScale="Viridis"):
741
- x = []
742
- y = []
743
- z = []
744
- for v in vertices:
745
- x.append(round(v[0], mantissa))
746
- y.append(round(v[1], mantissa))
747
- z.append(round(v[2], mantissa))
748
- i = []
749
- j = []
750
- k = []
751
- labels = []
752
- groupList = []
753
- label = ""
754
- group = ""
755
- if labelKey or groupKey:
756
- if groups:
757
- if len(groups) > 0:
758
- if type(groups[0]) == int or type(groups[0]) == float:
759
- if not minGroup:
760
- minGroup = min(groups)
761
- if not maxGroup:
762
- maxGroup = max(groups)
763
- else:
764
- minGroup = 0
765
- maxGroup = len(groups) - 1
766
- else:
767
- minGroup = 0
768
- maxGroup = 1
769
- for m, f in enumerate(faces):
770
- i.append(f[0])
771
- j.append(f[1])
772
- k.append(f[2])
773
- label = ""
774
- group = ""
775
- if len(dictionaries) > 0:
776
- d = dictionaries[m]
777
- if d:
778
- try:
779
- label = str(Dictionary.ValueAtKey(d, key=labelKey)) or ""
780
- except:
781
- label = ""
782
- try:
783
- group = Dictionary.ValueAtKey(d, key=groupKey) or None
784
- except:
785
- group = ""
786
- try:
787
- if type(group) == int or type(group) == float:
788
- if group < minGroup:
789
- group = minGroup
790
- if group > maxGroup:
791
- group = maxGroup
792
- color = Color.ByValueInRange(group, minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
793
- else:
794
- color = Color.ByValueInRange(groups.index(group), minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
795
- color = "rgb("+str(color[0])+","+str(color[1])+","+str(color[2])+")"
796
- groupList.append(color)
797
- except:
798
- groupList.append(len(groups))
799
- labels.append(label)
800
- else:
801
- for f in faces:
802
- i.append(f[0])
803
- j.append(f[1])
804
- k.append(f[2])
805
-
806
- if len(list(set(groupList))) < 2:
807
- groupList = None
808
- if len(labels) < 1:
809
- labels = ""
810
- fData = go.Mesh3d(
811
- x = x,
812
- y = y,
813
- z = z,
814
- i = i,
815
- j = j,
816
- k = k,
817
- name = legendLabel,
818
- showlegend = showLegend,
819
- legendgroup = legendGroup,
820
- legendrank = legendRank,
821
- color = color,
822
- facecolor = groupList,
823
- colorscale = colorScale,
824
- cmin = 0,
825
- cmax = 1,
826
- intensity = intensities,
827
- opacity = opacity,
828
- hoverinfo = 'text',
829
- text = labels,
830
- hovertext = labels,
831
- flatshading = True,
832
- showscale = False,
833
- lighting = {"facenormalsepsilon": 0},
834
- )
835
- return fData
836
-
837
- from topologicpy.Cluster import Cluster
838
- from topologicpy.Topology import Topology
839
- from topologicpy.Dictionary import Dictionary
840
- from time import time
841
- if not isinstance(topology, topologic.Topology):
842
- return None
843
-
844
- intensityList = []
845
- alt_intensities = []
846
- data = []
847
- v_list = []
848
-
849
- if topology.Type() == topologic.Vertex.Type():
850
- tp_vertices = [topology]
851
- else:
852
- tp_vertices = Topology.Vertices(topology)
853
-
854
- if isinstance(intensities, list):
855
- if len(intensities) == 0:
856
- intensities = None
857
-
858
- if not (tp_vertices == None or tp_vertices == []):
859
- vertices = []
860
- v_dictionaries = []
861
- intensityList = []
862
-
863
- if intensityKey:
864
- for i, tp_v in enumerate(tp_vertices):
865
- vertices.append([tp_v.X(), tp_v.Y(), tp_v.Z()])
866
- d = Topology.Dictionary(tp_v)
867
- if d:
868
- v = Dictionary.ValueAtKey(d, key=intensityKey)
869
- if not v == None:
870
- alt_intensities.append(v)
871
- v_list.append(v)
872
- else:
873
- alt_intensities.append(0)
874
- v_list.append(0)
875
- else:
876
- alt_intensities.append(0)
877
- v_list.append(0)
878
- alt_intensities = list(set(alt_intensities))
879
- alt_intensities.sort()
880
- if isinstance(intensities, list):
881
- if len(intensities) > 0:
882
- alt_intensities = intensities
883
- min_i = min(alt_intensities)
884
- max_i = max(alt_intensities)
885
- for i, tp_v in enumerate(tp_vertices):
886
- v = v_list[i]
887
- ci = closest_index(v_list[i], alt_intensities)
888
- value = intensities[ci]
889
- if (max_i - min_i) == 0:
890
- value = 0
891
- else:
892
- value = (value - min_i)/(max_i - min_i)
893
- intensityList.append(value)
894
- if all(x == 0 for x in intensityList):
895
- intensityList = None
896
- if showVertices:
897
- if len(vertices) == 0:
898
- for i, tp_v in enumerate(tp_vertices):
899
- if vertexLabelKey or vertexGroupKey:
900
- d = Topology.Dictionary(tp_v)
901
- v_dictionaries.append(d)
902
- vertices.append([tp_v.X(), tp_v.Y(), tp_v.Z()])
903
- data.append(vertexData(vertices, dictionaries=v_dictionaries, color=vertexColor, size=vertexSize, labelKey=vertexLabelKey, groupKey=vertexGroupKey, minGroup=vertexMinGroup, maxGroup=vertexMaxGroup, groups=vertexGroups, legendLabel=vertexLegendLabel, legendGroup=vertexLegendGroup, legendRank=vertexLegendRank, showLegend=showVertexLegend, colorScale=colorScale))
904
-
905
- if showEdges and topology.Type() > topologic.Vertex.Type():
906
- if topology.Type() == topologic.Edge.Type():
907
- tp_edges = [topology]
908
- else:
909
- tp_edges = Topology.Edges(topology)
910
- if not (tp_edges == None or tp_edges == []):
911
- e_dictionaries = []
912
- if edgeLabelKey or edgeGroupKey:
913
- for tp_edge in tp_edges:
914
- e_dictionaries.append(Topology.Dictionary(tp_edge))
915
- e_cluster = Cluster.ByTopologies(tp_edges)
916
- geo = Topology.Geometry(e_cluster, mantissa=mantissa)
917
- vertices = geo['vertices']
918
- edges = geo['edges']
919
- data.append(edgeData(vertices, edges, dictionaries=e_dictionaries, color=edgeColor, width=edgeWidth, labelKey=edgeLabelKey, groupKey=edgeGroupKey, minGroup=edgeMinGroup, maxGroup=edgeMaxGroup, groups=edgeGroups, legendLabel=edgeLegendLabel, legendGroup=edgeLegendGroup, legendRank=edgeLegendRank, showLegend=showEdgeLegend, colorScale=colorScale))
920
-
921
- if showFaces and topology.Type() >= topologic.Face.Type():
922
- if isinstance(topology, topologic.Face):
923
- tp_faces = [topology]
924
- else:
925
- tp_faces = Topology.Faces(topology)
926
- if not(tp_faces == None or tp_faces == []):
927
- # rebuild faces to remove any degenerate faces
928
- #new_faces = []
929
- #for i, f in enumerate(tp_faces):
930
- #eb = Face.ExternalBoundary(f)
931
- #eb = Topology.RemoveCollinearEdges(eb)
932
- #if not eb == None:
933
- #ibList = Face.InternalBoundaries(f)
934
- #ibList = [Wire.RemoveCollinearEdges(ib) for ib in ibList]
935
- #ibList = [ib for ib in ibList if not ib == None]
936
- #new_f = Face.ByWires(eb, ibList, silent=False)
937
- #if isinstance(new_f, topologic.Face):
938
- #if faceLabelKey or faceGroupKey:
939
- #d = Topology.Dictionary(tp_faces[i])
940
- #keys = Dictionary.Keys(d)
941
- #if len(keys) > 0:
942
- #new_f = Topology.SetDictionary(new_f, d)
943
- #new_faces.append(new_f)
944
-
945
- f_dictionaries = []
946
- all_triangles = []
947
- for tp_face in tp_faces:
948
- triangles = Face.Triangulate(tp_face, tolerance=tolerance)
949
- if isinstance(triangles, list):
950
- for tri in triangles:
951
- if faceLabelKey or faceGroupKey:
952
- d = Topology.Dictionary(tp_face)
953
- f_dictionaries.append(d)
954
- if d:
955
- _ = Topology.SetDictionary(tri, d)
956
- all_triangles.append(tri)
957
- if len(all_triangles) > 0:
958
- f_cluster = Cluster.ByTopologies(all_triangles)
959
- geo = Topology.Geometry(f_cluster, mantissa=mantissa)
960
- vertices = geo['vertices']
961
- faces = geo['faces']
962
- data.append(faceData(vertices, faces, dictionaries=f_dictionaries, color=faceColor, opacity=faceOpacity, labelKey=faceLabelKey, groupKey=faceGroupKey, minGroup=faceMinGroup, maxGroup=faceMaxGroup, groups=faceGroups, legendLabel=faceLegendLabel, legendGroup=faceLegendGroup, legendRank=faceLegendRank, showLegend=showFaceLegend, intensities=intensityList, colorScale=colorScale))
963
- return data
964
-
965
- @staticmethod
966
- def FigureByConfusionMatrix(matrix,
967
- categories=[],
968
- minValue=None,
969
- maxValue=None,
970
- title="Confusion Matrix",
971
- xTitle = "Actual",
972
- yTitle = "Predicted",
973
- width=950,
974
- height=500,
975
- showScale = True,
976
- colorScale='Viridis',
977
- colorSamples=10,
978
- backgroundColor='rgba(0,0,0,0)',
979
- marginLeft=0,
980
- marginRight=0,
981
- marginTop=40,
982
- marginBottom=0):
983
- """
984
- Returns a Plotly Figure of the input confusion matrix. Actual categories are displayed on the X-Axis, Predicted categories are displayed on the Y-Axis.
985
-
986
- Parameters
987
- ----------
988
- matrix : list or numpy.array
989
- The matrix to display.
990
- categories : list
991
- The list of categories to use on the X and Y axes.
992
- minValue : float , optional
993
- The desired minimum value to use for the color scale. If set to None, the minmum value found in the input matrix will be used. The default is None.
994
- maxValue : float , optional
995
- The desired maximum value to use for the color scale. If set to None, the maximum value found in the input matrix will be used. The default is None.
996
- title : str , optional
997
- The desired title to display. The default is "Confusion Matrix".
998
- xTitle : str , optional
999
- The desired X-axis title to display. The default is "Actual".
1000
- yTitle : str , optional
1001
- The desired Y-axis title to display. The default is "Predicted".
1002
- width : int , optional
1003
- The desired width of the figure. The default is 950.
1004
- height : int , optional
1005
- The desired height of the figure. The default is 500.
1006
- showScale : bool , optional
1007
- If set to True, a color scale is shown on the right side of the figure. The default is True.
1008
- colorScale : str , optional
1009
- 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/.
1010
- colorSamples : int , optional
1011
- The number of discrete color samples to use for displaying the data. The default is 10.
1012
- backgroundColor : str , optional
1013
- The desired background color. This can be any plotly color string and may be specified as:
1014
- - A hex string (e.g. '#ff0000')
1015
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1016
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1017
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1018
- - A named CSS color.
1019
- The default is 'rgba(0,0,0,0)' (transparent).
1020
- marginLeft : int , optional
1021
- The desired left margin in pixels. The default is 0.
1022
- marginRight : int , optional
1023
- The desired right margin in pixels. The default is 0.
1024
- marginTop : int , optional
1025
- The desired top margin in pixels. The default is 40.
1026
- marginBottom : int , optional
1027
- The desired bottom margin in pixels. The default is 0.
1028
-
1029
- """
1030
- if not isinstance(matrix, list) and not isinstance(matrix, np.ndarray):
1031
- print("Plotly.FigureByConfusionMatrix - Error: The input matrix is not of the correct type. Returning None.")
1032
- return None
1033
- figure = Plotly.FigureByMatrix(matrix,
1034
- xCategories=categories,
1035
- minValue=minValue,
1036
- maxValue=maxValue,
1037
- title=title,
1038
- xTitle=xTitle,
1039
- yTitle=yTitle,
1040
- width=width,
1041
- height=height,
1042
- showScale=showScale,
1043
- colorScale=colorScale,
1044
- colorSamples=colorSamples,
1045
- backgroundColor=backgroundColor,
1046
- marginLeft=marginLeft,
1047
- marginRight=marginRight,
1048
- marginTop=marginTop,
1049
- marginBottom=marginBottom)
1050
- layout = {
1051
- "yaxis": {"autorange": "reversed"},
1052
- }
1053
- figure.update_layout(layout)
1054
- return figure
1055
-
1056
- @staticmethod
1057
- def FigureByMatrix(matrix,
1058
- xCategories=[],
1059
- yCategories=[],
1060
- minValue=None,
1061
- maxValue=None,
1062
- title="Matrix",
1063
- xTitle = "X Axis",
1064
- yTitle = "Y Axis",
1065
- width=950,
1066
- height=950,
1067
- showScale = False,
1068
- colorScale='gray',
1069
- colorSamples=10,
1070
- backgroundColor='rgba(0,0,0,0)',
1071
- marginLeft=0,
1072
- marginRight=0,
1073
- marginTop=40,
1074
- marginBottom=0,
1075
- mantissa: int = 6):
1076
- """
1077
- Returns a Plotly Figure of the input matrix.
1078
-
1079
- Parameters
1080
- ----------
1081
- matrix : list or numpy.array
1082
- The matrix to display.
1083
- categories : list
1084
- The list of categories to use on the X and Y axes.
1085
- minValue : float , optional
1086
- The desired minimum value to use for the color scale. If set to None, the minmum value found in the input matrix will be used. The default is None.
1087
- maxValue : float , optional
1088
- The desired maximum value to use for the color scale. If set to None, the maximum value found in the input matrix will be used. The default is None.
1089
- title : str , optional
1090
- The desired title to display. The default is "Confusion Matrix".
1091
- xTitle : str , optional
1092
- The desired X-axis title to display. The default is "Actual".
1093
- yTitle : str , optional
1094
- The desired Y-axis title to display. The default is "Predicted".
1095
- width : int , optional
1096
- The desired width of the figure. The default is 950.
1097
- height : int , optional
1098
- The desired height of the figure. The default is 500.
1099
- showScale : bool , optional
1100
- If set to True, a color scale is shown on the right side of the figure. The default is True.
1101
- colorScale : str , optional
1102
- 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/.
1103
- colorSamples : int , optional
1104
- The number of discrete color samples to use for displaying the data. The default is 10.
1105
- backgroundColor : str , optional
1106
- The desired background color. This can be any plotly color string and may be specified as:
1107
- - A hex string (e.g. '#ff0000')
1108
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1109
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1110
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1111
- - A named CSS color.
1112
- The default is 'rgba(0,0,0,0)' (transparent).
1113
- marginLeft : int , optional
1114
- The desired left margin in pixels. The default is 0.
1115
- marginRight : int , optional
1116
- The desired right margin in pixels. The default is 0.
1117
- marginTop : int , optional
1118
- The desired top margin in pixels. The default is 40.
1119
- marginBottom : int , optional
1120
- The desired bottom margin in pixels. The default is 0.
1121
- mantissa : int , optional
1122
- The desired number of digits of the mantissa. The default is 4.
1123
-
1124
- """
1125
- #import plotly.figure_factory as ff
1126
- import plotly.graph_objects as go
1127
- import plotly.express as px
1128
-
1129
- if not isinstance(matrix, list) and not isinstance(matrix, np.ndarray):
1130
- print("Plotly.FigureByMatrix - Error: The input matrix is not of the correct type. Returning None.")
1131
- return None
1132
-
1133
- annotations = []
1134
-
1135
- if isinstance(matrix, list):
1136
- matrix = np.array(matrix)
1137
- colors = px.colors.sample_colorscale(colorScale, [n/(colorSamples -1) for n in range(colorSamples)])
1138
-
1139
- if not xCategories:
1140
- xCategories = [x for x in range(len(matrix[0]))]
1141
- if not yCategories:
1142
- yCategories = [y for y in range(len(matrix))]
1143
-
1144
- if not maxValue or not minValue:
1145
- max_values = []
1146
- min_values = []
1147
- for i in range(len(matrix)):
1148
- row = matrix[i]
1149
- max_values.append(max(row))
1150
- min_values.append(min(row))
1151
- for j, value in enumerate(row):
1152
- annotations.append(
1153
- {
1154
- "x": xCategories[j],
1155
- "y": yCategories[i],
1156
- "font": {"color": "black"},
1157
- "bgcolor": "white",
1158
- "opacity": 0.5,
1159
- "text": str(round(value, mantissa)),
1160
- "xref": "x1",
1161
- "yref": "y1",
1162
- "showarrow": False
1163
- }
1164
- )
1165
- if not minValue:
1166
- minValueB = min(min_values)
1167
- if not maxValue:
1168
- maxValue = max(max_values)
1169
- else:
1170
- for i in range(len(matrix)):
1171
- row = matrix[i]
1172
- for j, value in enumerate(row):
1173
- annotations.append(
1174
- {
1175
- "x": xCategories[j],
1176
- "y": yCategories[i],
1177
- "font": {"color": "black"},
1178
- "bgcolor": "white",
1179
- "opacity": 0.5,
1180
- "text": str(round(value,mantissa)),
1181
- "xref": "x1",
1182
- "yref": "y1",
1183
- "showarrow": False
1184
- }
1185
- )
1186
- new_matrix = []
1187
- for i in range(len(matrix)):
1188
- row = matrix[i]
1189
- new_row = []
1190
- maxRow = sum(row)
1191
- for j in range(len(row)):
1192
- if maxRow == 0:
1193
- new_row.append(round(0, mantissa))
1194
- else:
1195
- new_row.append(round(float(row[j])/float(maxRow), mantissa))
1196
- new_matrix.append(new_row)
1197
- data = go.Heatmap(z=new_matrix, y=yCategories, x=xCategories, zmin=minValue, zmax=maxValue, showscale=showScale, colorscale=colors)
1198
-
1199
- layout = {
1200
- "width": width,
1201
- "height": height,
1202
- "title": title,
1203
- "xaxis": {"title": xTitle},
1204
- "yaxis": {"title": yTitle, "autorange": "reversed"},
1205
- "annotations": annotations,
1206
- "paper_bgcolor": backgroundColor,
1207
- "plot_bgcolor": backgroundColor,
1208
- "margin":dict(l=marginLeft, r=marginRight, t=marginTop, b=marginBottom)
1209
- }
1210
- fig = go.Figure(data=data, layout=layout)
1211
- fig.update_xaxes( tickvals=xCategories)
1212
- fig.update_yaxes( tickvals=yCategories)
1213
- return fig
1214
-
1215
- @staticmethod
1216
- def FigureByDataFrame(dataFrame,
1217
- labels=[],
1218
- width=950,
1219
- height=500,
1220
- title="Untitled",
1221
- xTitle="X Axis",
1222
- xSpacing=1,
1223
- yTitle="Y Axis",
1224
- ySpacing=1.0,
1225
- useMarkers=False,
1226
- chartType="Line",
1227
- backgroundColor='rgba(0,0,0,0)',
1228
- gridColor = 'lightgray',
1229
- marginLeft=0,
1230
- marginRight=0,
1231
- marginTop=40,
1232
- marginBottom=0):
1233
-
1234
- """
1235
- Returns a Plotly Figure of the input dataframe
1236
-
1237
- Parameters
1238
- ----------
1239
- df : pandas.df
1240
- The pandas dataframe to display.
1241
- data_labels : list
1242
- The labels to use for the data.
1243
- width : int , optional
1244
- The desired width of the figure. The default is 950.
1245
- height : int , optional
1246
- The desired height of the figure. The default is 500.
1247
- title : str , optional
1248
- The chart title. The default is "Training and Testing Results".
1249
- xTitle : str , optional
1250
- The X-axis title. The default is "Epochs".
1251
- xSpacing : float , optional
1252
- The X-axis spacing. The default is 1.0.
1253
- yTitle : str , optional
1254
- The Y-axis title. The default is "Accuracy and Loss".
1255
- ySpacing : float , optional
1256
- The Y-axis spacing. The default is 0.1.
1257
- useMarkers : bool , optional
1258
- If set to True, markers will be displayed. The default is False.
1259
- chartType : str , optional
1260
- The desired type of chart. The options are "Line", "Bar", or "Scatter". It is case insensitive. The default is "Line".
1261
- backgroundColor : str , optional
1262
- The desired background color. This can be any plotly color string and may be specified as:
1263
- - A hex string (e.g. '#ff0000')
1264
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1265
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1266
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1267
- - A named CSS color.
1268
- The default is 'rgba(0,0,0,0)' (transparent).
1269
- grid : str , optional
1270
- The desired background color. This can be any plotly color string and may be specified as:
1271
- - A hex string (e.g. '#ff0000')
1272
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1273
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1274
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1275
- - A named CSS color.
1276
- The default is 'lightgray'
1277
- marginLeft : int , optional
1278
- The desired left margin in pixels. The default is 0.
1279
- marginRight : int , optional
1280
- The desired right margin in pixels. The default is 0.
1281
- marginTop : int , optional
1282
- The desired top margin in pixels. The default is 40.
1283
- marginBottom : int , optional
1284
- The desired bottom margin in pixels. The default is 0.
1285
-
1286
- Returns
1287
- -------
1288
- None.
1289
-
1290
- """
1291
- import plotly.express as px
1292
-
1293
- if chartType.lower() == "line":
1294
- figure = px.line(dataFrame, x=labels[0], y=labels[1:], title=title, markers=useMarkers)
1295
- elif chartType.lower() == "bar":
1296
- figure = px.bar(dataFrame, x=labels[0], y=labels[1:], title=title)
1297
- elif chartType.lower() == "scatter":
1298
- figure = px.scatter(dataFrame, x=labels[0], y=labels[1:], title=title)
1299
- else:
1300
- raise NotImplementedError
1301
-
1302
- layout = {
1303
- "width": width,
1304
- "height": height,
1305
- "title": title,
1306
- "xaxis": {"title": xTitle, "dtick": xSpacing, 'gridcolor': gridColor},
1307
- "yaxis": {"title": yTitle, "dtick": ySpacing, 'gridcolor': gridColor},
1308
- "paper_bgcolor": backgroundColor,
1309
- "plot_bgcolor": backgroundColor,
1310
- "margin":dict(l=marginLeft, r=marginRight, t=marginTop, b=marginBottom)
1311
- }
1312
- figure.update_layout(layout)
1313
- return figure
1314
-
1315
-
1316
- @staticmethod
1317
- def FigureByData(data, width=950, height=500,
1318
- xAxis=False, yAxis=False, zAxis=False,
1319
- axisSize=1, backgroundColor='rgba(0,0,0,0)',
1320
- marginLeft=0, marginRight=0,
1321
- marginTop=20, marginBottom=0,
1322
- tolerance = 0.0001):
1323
- """
1324
- Creates a plotly figure.
1325
-
1326
- Parameters
1327
- ----------
1328
- data : list
1329
- The input list of plotly data.
1330
- width : int , optional
1331
- The width in pixels of the figure. The default value is 950.
1332
- height : int , optional
1333
- The height in pixels of the figure. The default value is 950.
1334
- xAxis : bool , optional
1335
- If set to True the x axis is drawn. Otherwise it is not drawn. The default is False.
1336
- yAxis : bool , optional
1337
- If set to True the y axis is drawn. Otherwise it is not drawn. The default is False.
1338
- zAxis : bool , optional
1339
- If set to True the z axis is drawn. Otherwise it is not drawn. The default is False.
1340
- axisSize : float , optional
1341
- The size of the X, Y, Z, axes. The default is 1.
1342
- backgroundColor : str , optional
1343
- The desired color of the background. This can be any plotly color string and may be specified as:
1344
- - A hex string (e.g. '#ff0000')
1345
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1346
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1347
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1348
- - A named CSS color.
1349
- The default is "rgba(0,0,0,0)".
1350
- marginLeft : int , optional
1351
- The size in pixels of the left margin. The default value is 0.
1352
- marginRight : int , optional
1353
- The size in pixels of the right margin. The default value is 0.
1354
- marginTop : int , optional
1355
- The size in pixels of the top margin. The default value is 20.
1356
- marginBottom : int , optional
1357
- The size in pixels of the bottom margin. The default value is 0.
1358
- tolerance : float , optional
1359
- The desired tolerance. The default is 0.0001.
1360
-
1361
- Returns
1362
- -------
1363
- plotly.graph_objs._figure.Figure
1364
- The created plotly figure.
1365
-
1366
- """
1367
- from topologicpy.Vertex import Vertex
1368
- from topologicpy.Edge import Edge
1369
- from topologicpy.Wire import Wire
1370
- if not isinstance(data, list):
1371
- return None
1372
-
1373
- v0 = Vertex.ByCoordinates(0, 0, 0)
1374
- v1 = Vertex.ByCoordinates(axisSize,0,0)
1375
- v2 = Vertex.ByCoordinates(0,axisSize,0)
1376
- v3 = Vertex.ByCoordinates(0,0,axisSize)
1377
-
1378
- if xAxis:
1379
- xEdge = Edge.ByVertices([v0,v1], tolerance=tolerance)
1380
- xData = Plotly.DataByTopology(xEdge, edgeColor="red", edgeWidth=6, showFaces=False, showEdges=True, showVertices=False, edgeLegendLabel="X-Axis")
1381
- data = data + xData
1382
- if yAxis:
1383
- yEdge = Edge.ByVertices([v0,v2], tolerance=tolerance)
1384
- yData = Plotly.DataByTopology(yEdge, edgeColor="green", edgeWidth=6, showFaces=False, showEdges=True, showVertices=False, edgeLegendLabel="Y-Axis")
1385
- data = data + yData
1386
- if zAxis:
1387
- zEdge = Edge.ByVertices([v0,v3], tolerance=tolerance)
1388
- zData = Plotly.DataByTopology(zEdge, edgeColor="blue", edgeWidth=6, showFaces=False, showEdges=True, showVertices=False, edgeLegendLabel="Z-Axis")
1389
- data = data + zData
1390
-
1391
- figure = go.Figure(data=data)
1392
- figure.update_layout(
1393
- width=width,
1394
- height=height,
1395
- showlegend=True,
1396
- scene = dict(
1397
- xaxis = dict(visible=False),
1398
- yaxis = dict(visible=False),
1399
- zaxis =dict(visible=False),
1400
- ),
1401
- scene_aspectmode='data',
1402
- paper_bgcolor=backgroundColor,
1403
- plot_bgcolor=backgroundColor,
1404
- margin=dict(l=marginLeft, r=marginRight, t=marginTop, b=marginBottom),
1405
- )
1406
- figure.update_xaxes(showgrid=False, zeroline=False, visible=False)
1407
- figure.update_yaxes(showgrid=False, zeroline=False, visible=False)
1408
- return figure
1409
-
1410
- @staticmethod
1411
- def FigureByJSONFile(file):
1412
- """
1413
- Imports a plotly figure from a JSON file.
1414
-
1415
- Parameters
1416
- ----------
1417
- file : file object
1418
- The JSON file.
1419
-
1420
- Returns
1421
- -------
1422
- plotly.graph_objs._figure.Figure
1423
- The imported figure.
1424
-
1425
- """
1426
- figure = None
1427
- if not file:
1428
- return None
1429
- figure = plotly.io.read_json(file, output_type='Figure', skip_invalid=True, engine=None)
1430
- file.close()
1431
- return figure
1432
-
1433
- @staticmethod
1434
- def FigureByJSONPath(path):
1435
- """
1436
- Imports a plotly figure from a JSON file path.
1437
-
1438
- Parameters
1439
- ----------
1440
- path : str
1441
- The path to the BRep file.
1442
-
1443
- Returns
1444
- -------
1445
- plotly.graph_objs._figure.Figure
1446
- The imported figure.
1447
-
1448
- """
1449
- if not path:
1450
- return None
1451
- try:
1452
- file = open(path)
1453
- except:
1454
- print("Plotly.FigureByJSONPath - Error: the JSON file is not a valid file. Returning None.")
1455
- return None
1456
- return Plotly.FigureByJSONFile(file)
1457
-
1458
- @staticmethod
1459
- def FigureByPieChart(data, values, names):
1460
- """
1461
- Creates a plotly pie chart figure.
1462
-
1463
- Parameters
1464
- ----------
1465
- data : list
1466
- The input list of plotly data.
1467
- values : list
1468
- The input list of values.
1469
- names : list
1470
- The input list of names.
1471
- """
1472
-
1473
- import plotly.express as px
1474
- dlist = list(map(list, zip(*data)))
1475
- df = pd.DataFrame(dlist, columns=data['names'])
1476
- fig = px.pie(df, values=values, names=names)
1477
- return fig
1478
-
1479
- @staticmethod
1480
- def FigureByTopology(topology,
1481
- showVertices=True, vertexSize=1.1, vertexColor="black",
1482
- vertexLabelKey=None, vertexGroupKey=None, vertexGroups=[],
1483
- vertexMinGroup=None, vertexMaxGroup=None,
1484
- showVertexLegend=False, vertexLegendLabel="Topology Vertices", vertexLegendRank=1,
1485
- vertexLegendGroup=1,
1486
-
1487
- showEdges=True, edgeWidth=1, edgeColor="black",
1488
- edgeLabelKey=None, edgeGroupKey=None, edgeGroups=[],
1489
- edgeMinGroup=None, edgeMaxGroup=None,
1490
- showEdgeLegend=False, edgeLegendLabel="Topology Edges", edgeLegendRank=2,
1491
- edgeLegendGroup=2,
1492
-
1493
- showFaces=True, faceOpacity=0.5, faceColor="#FAFAFA",
1494
- faceLabelKey=None, faceGroupKey=None, faceGroups=[],
1495
- faceMinGroup=None, faceMaxGroup=None,
1496
- showFaceLegend=False, faceLegendLabel="Topology Faces", faceLegendRank=3,
1497
- faceLegendGroup=3,
1498
- intensityKey=None,
1499
-
1500
- width=950, height=500,
1501
- xAxis=False, yAxis=False, zAxis=False, axisSize=1, backgroundColor='rgba(0,0,0,0)',
1502
- marginLeft=0, marginRight=0, marginTop=20, marginBottom=0, showScale=False,
1503
-
1504
- cbValues=[], cbTicks=5, cbX=-0.15, cbWidth=15, cbOutlineWidth=0, cbTitle="",
1505
- cbSubTitle="", cbUnits="", colorScale="Viridis", mantissa=6, tolerance=0.0001):
1506
- """
1507
- Creates a figure from the input topology.
1508
-
1509
- Parameters
1510
- ----------
1511
- topology : topologic.Topology
1512
- The input topology. This must contain faces and or edges.
1513
-
1514
- showVertices : bool , optional
1515
- If set to True the vertices will be drawn. Otherwise, they will not be drawn. The default is True.
1516
- vertexSize : float , optional
1517
- The desired size of the vertices. The default is 1.1.
1518
- vertexColor : str , optional
1519
- The desired color of the output vertices. This can be any plotly color string and may be specified as:
1520
- - A hex string (e.g. '#ff0000')
1521
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1522
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1523
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1524
- - A named CSS color.
1525
- The default is "black".
1526
- vertexLabelKey : str , optional
1527
- The dictionary key to use to display the vertex label. The default is None.
1528
- vertexGroupKey : str , optional
1529
- The dictionary key to use to display the vertex group. The default is None.
1530
- vertexGroups : list , optional
1531
- The list of vertex groups against which to index the color of the vertex. The default is [].
1532
- vertexMinGroup : int or float , optional
1533
- For numeric vertexGroups, vertexMinGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the vertexGroupKey. If set to None, it is set to the minimum value in vertexGroups. The default is None.
1534
- edgeMaxGroup : int or float , optional
1535
- For numeric vertexGroups, vertexMaxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the vertexGroupKey. If set to None, it is set to the maximum value in vertexGroups. The default is None.
1536
- showVertexLegend : bool, optional
1537
- If set to True, the legend for the vertices of this topology is shown. Otherwise, it isn't. The default is False.
1538
- vertexLegendLabel : str , optional
1539
- The legend label string used to identify vertices. The default is "Topology Vertices".
1540
- vertexLegendRank : int , optional
1541
- The legend rank order of the vertices of this topology. The default is 1.
1542
- vertexLegendGroup : int , optional
1543
- The number of the vertex legend group to which the vertices of this topology belong. The default is 1.
1544
-
1545
- showEdges : bool , optional
1546
- If set to True the edges will be drawn. Otherwise, they will not be drawn. The default is True.
1547
- edgeWidth : float , optional
1548
- The desired thickness of the output edges. The default is 1.
1549
- edgeColor : str , optional
1550
- The desired color of the output edges. This can be any plotly color string and may be specified as:
1551
- - A hex string (e.g. '#ff0000')
1552
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1553
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1554
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1555
- - A named CSS color.
1556
- The default is "black".
1557
- edgeLabelKey : str , optional
1558
- The dictionary key to use to display the edge label. The default is None.
1559
- edgeGroupKey : str , optional
1560
- The dictionary key to use to display the edge group. The default is None.
1561
- edgeGroups : list , optional
1562
- The list of edge groups against which to index the color of the edge. The default is [].
1563
- edgeMinGroup : int or float , optional
1564
- For numeric edgeGroups, edgeMinGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the edgeGroupKey. If set to None, it is set to the minimum value in edgeGroups. The default is None.
1565
- edgeMaxGroup : int or float , optional
1566
- For numeric edgeGroups, edgeMaxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the edgeGroupKey. If set to None, it is set to the maximum value in edgeGroups. The default is None.
1567
- showEdgeLegend : bool, optional
1568
- If set to True, the legend for the edges of this topology is shown. Otherwise, it isn't. The default is False.
1569
- edgeLegendLabel : str , optional
1570
- The legend label string used to identify edges. The default is "Topology Edges".
1571
- edgeLegendRank : int , optional
1572
- The legend rank order of the edges of this topology. The default is 2.
1573
- edgeLegendGroup : int , optional
1574
- The number of the edge legend group to which the edges of this topology belong. The default is 2.
1575
-
1576
- showFaces : bool , optional
1577
- If set to True the faces will be drawn. Otherwise, they will not be drawn. The default is True.
1578
- faceOpacity : float , optional
1579
- The desired opacity of the output faces (0=transparent, 1=opaque). The default is 0.5.
1580
- faceColor : str , optional
1581
- The desired color of the output faces. This can be any plotly color string and may be specified as:
1582
- - A hex string (e.g. '#ff0000')
1583
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1584
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1585
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1586
- - A named CSS color.
1587
- The default is "#FAFAFA".
1588
- faceLabelKey : str , optional
1589
- The dictionary key to use to display the face label. The default is None.
1590
- faceGroupKey : str , optional
1591
- The dictionary key to use to display the face group. The default is None.
1592
- faceGroups : list , optional
1593
- The list of face groups against which to index the color of the face. This can bhave numeric or string values. This should match the type of value associated with the faceGroupKey. The default is [].
1594
- faceMinGroup : int or float , optional
1595
- For numeric faceGroups, minGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the faceGroupKey. If set to None, it is set to the minimum value in faceGroups. The default is None.
1596
- faceMaxGroup : int or float , optional
1597
- For numeric faceGroups, maxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the faceGroupKey. If set to None, it is set to the maximum value in faceGroups. The default is None.
1598
- showFaceLegend : bool, optional
1599
- If set to True, the legend for the faces of this topology is shown. Otherwise, it isn't. The default is False.
1600
- faceLegendLabel : str , optional
1601
- The legend label string used to idenitfy edges. The default is "Topology Faces".
1602
- faceLegendRank : int , optional
1603
- The legend rank order of the faces of this topology. The default is 3.
1604
- faceLegendGroup : int , optional
1605
- The number of the face legend group to which the faces of this topology belong. The default is 3.
1606
- width : int , optional
1607
- The width in pixels of the figure. The default value is 950.
1608
- height : int , optional
1609
- The height in pixels of the figure. The default value is 950.
1610
- xAxis : bool , optional
1611
- If set to True the x axis is drawn. Otherwise it is not drawn. The default is False.
1612
- yAxis : bool , optional
1613
- If set to True the y axis is drawn. Otherwise it is not drawn. The default is False.
1614
- zAxis : bool , optional
1615
- If set to True the z axis is drawn. Otherwise it is not drawn. The default is False.
1616
- backgroundColor : str , optional
1617
- The desired color of the background. This can be any plotly color string and may be specified as:
1618
- - A hex string (e.g. '#ff0000')
1619
- - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1620
- - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1621
- - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1622
- - A named CSS color.
1623
- The default is "rgba(0,0,0,0)".
1624
- marginLeft : int , optional
1625
- The size in pixels of the left margin. The default value is 0.
1626
- marginRight : int , optional
1627
- The size in pixels of the right margin. The default value is 0.
1628
- marginTop : int , optional
1629
- The size in pixels of the top margin. The default value is 20.
1630
- marginBottom : int , optional
1631
- The size in pixels of the bottom margin. The default value is 0.
1632
- camera : list , optional
1633
- The desired location of the camera). The default is [-1.25, -1.25, 1.25].
1634
- center : list , optional
1635
- The desired center (camera target). The default is [0, 0, 0].
1636
- up : list , optional
1637
- The desired up vector. The default is [0, 0, 1].
1638
- renderer : str , optional
1639
- The desired renderer. See Plotly.Renderers(). The default is "notebook".
1640
- intensityKey : str , optional
1641
- If not None, the dictionary of each vertex is searched for the value associated with the intensity key. This value is then used to color-code the vertex based on the colorScale. The default is None.
1642
- showScale : bool , optional
1643
- If set to True, the colorbar is shown. The default is False.
1644
- cbValues : list , optional
1645
- The input list of values to use for the colorbar. The default is [].
1646
- cbTicks : int , optional
1647
- The number of ticks to use on the colorbar. The default is 5.
1648
- cbX : float , optional
1649
- The x location of the colorbar. The default is -0.15.
1650
- cbWidth : int , optional
1651
- The width in pixels of the colorbar. The default is 15
1652
- cbOutlineWidth : int , optional
1653
- The width in pixels of the outline of the colorbar. The default is 0.
1654
- cbTitle : str , optional
1655
- The title of the colorbar. The default is "".
1656
- cbSubTitle : str , optional
1657
- The subtitle of the colorbar. The default is "".
1658
- cbUnits: str , optional
1659
- The units used in the colorbar. The default is ""
1660
- colorScale : str , optional
1661
- 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/.
1662
- mantissa : int , optional
1663
- The desired length of the mantissa for the values listed on the colorbar. The default is 6.
1664
- tolerance : float , optional
1665
- The desired tolerance. The default is 0.0001.
1666
-
1667
- Returns
1668
- -------
1669
- Plotly figure
1670
-
1671
- """
1672
- if not isinstance(topology, topologic.Topology):
1673
- print("Plotly.FigureByTopology - Error: the input topology is not a valid topology. Returning None.")
1674
- return None
1675
- data = Plotly.DataByTopology(topology=topology,
1676
- showVertices=showVertices, vertexSize=vertexSize, vertexColor=vertexColor,
1677
- vertexLabelKey=vertexLabelKey, vertexGroupKey=vertexGroupKey, vertexGroups=vertexGroups,
1678
- vertexMinGroup=vertexMinGroup, vertexMaxGroup=vertexMaxGroup,
1679
- showVertexLegend=showVertexLegend, vertexLegendLabel=vertexLegendLabel, vertexLegendRank=vertexLegendRank,
1680
- vertexLegendGroup=vertexLegendGroup,
1681
- showEdges=showEdges, edgeWidth=edgeWidth, edgeColor=edgeColor,
1682
- edgeLabelKey=edgeLabelKey, edgeGroupKey=edgeGroupKey, edgeGroups=edgeGroups,
1683
- edgeMinGroup=edgeMinGroup, edgeMaxGroup=edgeMaxGroup,
1684
- showEdgeLegend=showEdgeLegend, edgeLegendLabel=edgeLegendLabel, edgeLegendRank=edgeLegendRank,
1685
- edgeLegendGroup=edgeLegendGroup,
1686
- showFaces=showFaces, faceOpacity=faceOpacity, faceColor=faceColor,
1687
- faceLabelKey=faceLabelKey, faceGroupKey=faceGroupKey, faceGroups=faceGroups,
1688
- faceMinGroup=faceMinGroup, faceMaxGroup=faceMaxGroup,
1689
- showFaceLegend=showFaceLegend, faceLegendLabel=faceLegendLabel, faceLegendRank=faceLegendRank,
1690
- faceLegendGroup=faceLegendGroup,
1691
- intensityKey=intensityKey, colorScale=colorScale, tolerance=tolerance)
1692
- figure = Plotly.FigureByData(data=data, width=width, height=height,
1693
- xAxis=xAxis, yAxis=yAxis, zAxis=zAxis, axisSize=axisSize,
1694
- backgroundColor=backgroundColor,
1695
- marginLeft=marginLeft, marginRight=marginRight,
1696
- marginTop=marginTop, marginBottom=marginBottom,
1697
- tolerance=tolerance)
1698
- if showScale:
1699
- figure = Plotly.AddColorBar(figure, values=cbValues, nTicks=cbTicks, xPosition=cbX, width=cbWidth, outlineWidth=cbOutlineWidth, title=cbTitle, subTitle=cbSubTitle, units=cbUnits, colorScale=colorScale, mantissa=mantissa)
1700
- return figure
1701
-
1702
- @staticmethod
1703
- def FigureExportToJSON(figure, path, overwrite=False):
1704
- """
1705
- Exports the input plotly figure to a JSON file.
1706
-
1707
- Parameters
1708
- ----------
1709
- figure : plotly.graph_objs._figure.Figure
1710
- The input plotly figure.
1711
- path : str
1712
- The input file path.
1713
- overwrite : bool , optional
1714
- If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't.
1715
-
1716
- Returns
1717
- -------
1718
- bool
1719
- True if the export operation is successful. False otherwise.
1720
-
1721
- """
1722
- if not isinstance(figure, plotly.graph_objs._figure.Figure):
1723
- print("Plotly.FigureExportToJSON - Error: The input figure is not a plolty figure. Returning None.")
1724
- return None
1725
- if not isinstance(path, str):
1726
- print("Plotly.FigureExportToJSON - Error: The input path is not a string. Returning None.")
1727
- return None
1728
- # Make sure the file extension is .json
1729
- ext = path[len(path)-5:len(path)]
1730
- if ext.lower() != ".json":
1731
- path = path+".json"
1732
- f = None
1733
- try:
1734
- if overwrite == True:
1735
- f = open(path, "w")
1736
- else:
1737
- f = open(path, "x") # Try to create a new File
1738
- except:
1739
- print("Plotly.FigureExportToJSON - Error: Could not create a new file at the following location: "+path+". Returning None.")
1740
- return None
1741
- if (f):
1742
- plotly.io.write_json(figure, f, validate=True, pretty=False, remove_uids=True, engine=None)
1743
- f.close()
1744
- return True
1745
- if f:
1746
- try:
1747
- f.close()
1748
- except:
1749
- pass
1750
- return False
1751
-
1752
- @staticmethod
1753
- def FigureExportToPDF(figure, path, width=1920, height=1200, overwrite=False):
1754
- """
1755
- Exports the input plotly figure to a PDF file.
1756
-
1757
- Parameters
1758
- ----------
1759
- figure : plotly.graph_objs._figure.Figure
1760
- The input plotly figure.
1761
- path : str
1762
- The input file path.
1763
- width : int, optional
1764
- The width of the exported image in pixels. The default is 1920.
1765
- height : int , optional
1766
- The height of the exported image in pixels. The default is 1200.
1767
- overwrite : bool , optional
1768
- If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't.
1769
-
1770
- Returns
1771
- -------
1772
- bool
1773
- True if the export operation is successful. False otherwise.
1774
-
1775
- """
1776
- import os
1777
- if not isinstance(figure, plotly.graph_objs._figure.Figure):
1778
- print("Plotly.FigureExportToPNG - Error: The input figure is not a plolty figure. Returning None.")
1779
- return None
1780
- if not isinstance(path, str):
1781
- print("Plotly.FigureExportToPNG - Error: The input path is not a string. Returning None.")
1782
- return None
1783
- # Make sure the file extension is .pdf
1784
- ext = path[len(path)-4:len(path)]
1785
- if ext.lower() != ".pdf":
1786
- path = path+".pdf"
1787
-
1788
- if overwrite == False and os.path.exists(path):
1789
- print("Plotly.FigureExportToPDF - Error: A file already exists at this location and overwrite is set to False. Returning None.")
1790
- return None
1791
-
1792
- plotly.io.write_image(figure, path, format='pdf', scale=1, width=width, height=height, validate=True, engine='auto')
1793
- return True
1794
-
1795
- @staticmethod
1796
- def FigureExportToPNG(figure, path, width=1920, height=1200, overwrite=False):
1797
- """
1798
- Exports the input plotly figure to a PNG file.
1799
-
1800
- Parameters
1801
- ----------
1802
- figure : plotly.graph_objs._figure.Figure
1803
- The input plotly figure.
1804
- path : str
1805
- The input file path.
1806
- width : int, optional
1807
- The width of the exported image in pixels. The default is 1920.
1808
- height : int , optional
1809
- The height of the exported image in pixels. The default is 1200.
1810
- overwrite : bool , optional
1811
- If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't.
1812
-
1813
- Returns
1814
- -------
1815
- bool
1816
- True if the export operation is successful. False otherwise.
1817
-
1818
- """
1819
- import os
1820
- if not isinstance(figure, plotly.graph_objs._figure.Figure):
1821
- print("Plotly.FigureExportToPNG - Error: The input figure is not a plolty figure. Returning None.")
1822
- return None
1823
- if not isinstance(path, str):
1824
- print("Plotly.FigureExportToPNG - Error: The input path is not a string. Returning None.")
1825
- return None
1826
- # Make sure the file extension is .png
1827
- ext = path[len(path)-4:len(path)]
1828
- if ext.lower() != ".png":
1829
- path = path+".png"
1830
-
1831
- if overwrite == False and os.path.exists(path):
1832
- print("Plotly.FigureExportToPNG - Error: A file already exists at this location and overwrite is set to False. Returning None.")
1833
- return None
1834
-
1835
- plotly.io.write_image(figure, path, format='png', scale=1, width=width, height=height, validate=True, engine='auto')
1836
- return True
1837
-
1838
- @staticmethod
1839
- def FigureExportToSVG(figure, path, width=1920, height=1200, overwrite=False):
1840
- """
1841
- Exports the input plotly figure to a SVG file.
1842
-
1843
- Parameters
1844
- ----------
1845
- figure : plotly.graph_objs._figure.Figure
1846
- The input plotly figure.
1847
- path : str
1848
- The input file path.
1849
- width : int, optional
1850
- The width of the exported image in pixels. The default is 1920.
1851
- height : int , optional
1852
- The height of the exported image in pixels. The default is 1200.
1853
- overwrite : bool , optional
1854
- If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't.
1855
-
1856
- Returns
1857
- -------
1858
- bool
1859
- True if the export operation is successful. False otherwise.
1860
-
1861
- """
1862
- import os
1863
- if not isinstance(figure, plotly.graph_objs._figure.Figure):
1864
- print("Plotly.FigureExportToSVG - Error: The input figure is not a plolty figure. Returning None.")
1865
- return None
1866
- if not isinstance(path, str):
1867
- print("Plotly.FigureExportToSVG - Error: The input path is not a string. Returning None.")
1868
- return None
1869
- # Make sure the file extension is .svg
1870
- ext = path[len(path)-4:len(path)]
1871
- if ext.lower() != ".svg":
1872
- path = path+".svg"
1873
-
1874
- if overwrite == False and os.path.exists(path):
1875
- print("Plotly.FigureExportToSVG - Error: A file already exists at this location and overwrite is set to False. Returning None.")
1876
- return None
1877
-
1878
- plotly.io.write_image(figure, path, format='svg', scale=1, width=width, height=height, validate=True, engine='auto')
1879
- return True
1880
-
1881
- @staticmethod
1882
- def SetCamera(figure, camera=[-1.25, -1.25, 1.25], center=[0, 0, 0], up=[0, 0, 1], projection="perspective"):
1883
- """
1884
- Sets the camera for the input figure.
1885
-
1886
- Parameters
1887
- ----------
1888
- figure : plotly.graph_objs._figure.Figure
1889
- The input plotly figure.
1890
- camera : list , optional
1891
- The desired location of the camera. The default is [-1.25, -1.25, 1.25].
1892
- center : list , optional
1893
- The desired center (camera target). The default is [0, 0, 0].
1894
- up : list , optional
1895
- The desired up vector. The default is [0, 0, 1].
1896
- projection : str , optional
1897
- The desired type of projection. The options are "orthographic" or "perspective". It is case insensitive. The default is "perspective"
1898
-
1899
- Returns
1900
- -------
1901
- plotly.graph_objs._figure.Figure
1902
- The updated figure
1903
-
1904
- """
1905
- if not isinstance(camera, list):
1906
- camera = [-1.25, -1.25, 1.25]
1907
- if not isinstance(center, list):
1908
- center = [0, 0, 0]
1909
- if not isinstance(up, list):
1910
- up = [0, 0, 1]
1911
- projection = projection.lower()
1912
- if projection in "orthographic":
1913
- projection = "orthographic"
1914
- else:
1915
- projection = "perspective"
1916
- scene_camera = dict(
1917
- up=dict(x=up[0], y=up[1], z=up[2]),
1918
- eye=dict(x=camera[0], y=camera[1], z=camera[2]),
1919
- center=dict(x=center[0], y=center[1], z=center[2]),
1920
- projection=dict(type=projection)
1921
- )
1922
- figure.update_layout(scene_camera=scene_camera)
1923
- return figure
1924
-
1925
- @staticmethod
1926
- def Show(figure, camera=[-1.25, -1.25, 1.25], center=[0, 0, 0], up=[0, 0, 1], renderer="notebook", projection="perspective"):
1927
- """
1928
- Shows the input figure.
1929
-
1930
- Parameters
1931
- ----------
1932
- figure : plotly.graph_objs._figure.Figure
1933
- The input plotly figure.
1934
- camera : list , optional
1935
- The desired location of the camera. The default is [0, 0, 0].
1936
- center : list , optional
1937
- The desired center (camera target). The default is [0, 0, 0].
1938
- up : list , optional
1939
- The desired up vector. The default is [0, 0, 1].
1940
- renderer : str , optional
1941
- The desired rendered. See Plotly.Renderers(). The default is "notebook".
1942
- projection : str, optional
1943
- The desired type of projection. The options are "orthographic" or "perspective". It is case insensitive. The default is "perspective"
1944
-
1945
-
1946
- Returns
1947
- -------
1948
- None
1949
-
1950
- """
1951
- if figure == None:
1952
- print("Plotly.Show - Error: The input is NULL. Returning None.")
1953
- return None
1954
- if not isinstance(figure, plotly.graph_objs._figure.Figure):
1955
- print("Plotly.Show - Error: The input is not a figure. Returning None.")
1956
- return None
1957
- if not renderer.lower() in Plotly.Renderers():
1958
- print("Plotly.Show - Error: The input renderer is not in the approved list of renderers. Returning None.")
1959
- return None
1960
- if not camera == None and not center == None and not up == None:
1961
- figure = Plotly.SetCamera(figure, camera=camera, center=center, up=up, projection=projection)
1962
- if renderer.lower() == "offline":
1963
- ofl.plot(figure)
1964
- else:
1965
- figure.show(renderer=renderer)
1966
- return None
1967
-
1968
- @staticmethod
1969
- def Renderers():
1970
- """
1971
- Returns a list of the available plotly renderers.
1972
-
1973
- Parameters
1974
- ----------
1975
-
1976
- Returns
1977
- -------
1978
- list
1979
- The list of the available plotly renderers.
1980
-
1981
- """
1982
- return ['plotly_mimetype', 'jupyterlab', 'nteract', 'vscode',
1983
- 'notebook', 'notebook_connected', 'kaggle', 'azure', 'colab',
1984
- 'cocalc', 'databricks', 'json', 'png', 'jpeg', 'jpg', 'svg',
1985
- 'pdf', 'browser', 'firefox', 'chrome', 'chromium', 'iframe',
1986
- 'iframe_connected', 'sphinx_gallery', 'sphinx_gallery_png', 'offline']
1987
-
1988
- @staticmethod
1989
- def ExportToImage(figure, path, format="png", width="1920", height="1080"):
1990
- """
1991
- Exports the plotly figure to an image.
1992
-
1993
- Parameters
1994
- ----------
1995
- figure : plotly.graph_objs._figure.Figure
1996
- The input plotly figure.
1997
- path : str
1998
- The image file path.
1999
- format : str , optional
2000
- The desired format. This can be any of "jpg", "jpeg", "pdf", "png", "svg", or "webp". It is case insensitive. The default is "png".
2001
- width : int , optional
2002
- The width in pixels of the figure. The default value is 1920.
2003
- height : int , optional
2004
- The height in pixels of the figure. The default value is 1080.
2005
-
2006
- Returns
2007
- -------
2008
- bool
2009
- True if the image was exported sucessfully. False otherwise.
2010
-
2011
- """
2012
- if not isinstance(figure, plotly.graph_objs._figure.Figure):
2013
- return None
2014
- if not isinstance(path, str):
2015
- return None
2016
- if not format.lower() in ["jpg", "jpeg", "pdf", "png", "svg", "webp"]:
2017
- return None
2018
- returnStatus = False
2019
- try:
2020
- plotly.io.write_image(figure, path, format=format.lower(), scale=None, width=width, height=height, validate=True, engine='auto')
2021
- returnStatus = True
2022
- except:
2023
- returnStatus = False
2024
- return returnStatus
2025
-
1
+ # Copyright (C) 2024
2
+ # Wassim Jabi <wassim.jabi@gmail.com>
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify it under
5
+ # the terms of the GNU Affero General Public License as published by the Free Software
6
+ # Foundation, either version 3 of the License, or (at your option) any later
7
+ # version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful, but WITHOUT
10
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
12
+ # details.
13
+ #
14
+ # You should have received a copy of the GNU Affero General Public License along with
15
+ # this program. If not, see <https://www.gnu.org/licenses/>.
16
+
17
+ import topologicpy
18
+ import topologic
19
+
20
+ from topologicpy.Wire import Wire
21
+ from topologicpy.Face import Face
22
+ import os
23
+ import warnings
24
+
25
+ try:
26
+ import numpy as np
27
+ except:
28
+ print("Plotly - Installing required numpy library.")
29
+ try:
30
+ os.system("pip install numpy")
31
+ except:
32
+ os.system("pip install numpy --user")
33
+ try:
34
+ import numpy as np
35
+ except:
36
+ warnings.warn("Plotly - Error: Could not import numpy.")
37
+
38
+ try:
39
+ import pandas as pd
40
+ except:
41
+ print("Plotly - Installing required pandas library.")
42
+ try:
43
+ os.system("pip install pandas")
44
+ except:
45
+ os.system("pip install pandas --user")
46
+ try:
47
+ import pandas as pd
48
+ except:
49
+ warnings.warn("Plotly - Error: Could not import pandas.")
50
+
51
+ try:
52
+ import plotly
53
+ import plotly.graph_objects as go
54
+ import plotly.offline as ofl
55
+ except:
56
+ print("Plotly - Installing required plotly library.")
57
+ try:
58
+ os.system("pip install plotly")
59
+ except:
60
+ os.system("pip install plotly --user")
61
+ try:
62
+ import plotly
63
+ import plotly.graph_objects as go
64
+ import plotly.offline as ofl
65
+ except:
66
+ warnings.warn("Plotly - Error: Could not import plotly.")
67
+
68
+ class Plotly:
69
+ @staticmethod
70
+ def AddColorBar(figure, values=[], nTicks=5, xPosition=-0.15, width=15, outlineWidth=0, title="", subTitle="", units="", colorScale="viridis", mantissa: int = 6):
71
+ """
72
+ Adds a color bar to the input figure
73
+
74
+ Parameters
75
+ ----------
76
+ figure : plotly.graph_objs._figure.Figure
77
+ The input plotly figure.
78
+ values : list , optional
79
+ The input list of values to use for the color bar. The default is [].
80
+ nTicks : int , optional
81
+ The number of ticks to use on the color bar. The default is 5.
82
+ xPosition : float , optional
83
+ The x location of the color bar. The default is -0.15.
84
+ width : int , optional
85
+ The width in pixels of the color bar. The default is 15
86
+ outlineWidth : int , optional
87
+ The width in pixels of the outline of the color bar. The default is 0.
88
+ title : str , optional
89
+ The title of the color bar. The default is "".
90
+ subTitle : str , optional
91
+ The subtitle of the color bar. The default is "".
92
+ units: str , optional
93
+ The units used in the color bar. The default is ""
94
+ colorScale : str , optional
95
+ 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/.
96
+ mantissa : int , optional
97
+ The desired length of the mantissa for the values listed on the color bar. The default is 6.
98
+ Returns
99
+ -------
100
+ plotly.graph_objs._figure.Figure
101
+ The input figure with the color bar added.
102
+
103
+ """
104
+ if not isinstance(figure, plotly.graph_objs._figure.Figure):
105
+ return None
106
+ if units:
107
+ units = "Units: "+units
108
+ minValue = min(values)
109
+ maxValue = max(values)
110
+ step = (maxValue - minValue)/float(nTicks-1)
111
+ r = [round(minValue+i*step, mantissa) for i in range(nTicks)]
112
+ r[-1] = round(maxValue, mantissa)
113
+ # Define the minimum and maximum range of the colorbar
114
+ rs = [str(x) for x in r]
115
+
116
+ # Define the colorbar as a trace with no data, x or y coordinates
117
+ colorbar_trace = go.Scatter(
118
+ x=[0],
119
+ y=[0],
120
+ mode="markers",
121
+ showlegend=False,
122
+ marker=dict(
123
+ size=0,
124
+ colorscale=colorScale, # choose the colorscale
125
+ cmin=minValue,
126
+ cmax=maxValue,
127
+ color=['rgba(0,0,0,0)'],
128
+ colorbar=dict(
129
+ x=xPosition,
130
+ title="<b>"+title+"</b><br>"+subTitle+"<br>"+units, # title of the colorbar
131
+ ticks="outside", # position of the ticks
132
+ tickvals=r, # values of the ticks
133
+ ticktext=rs, # text of the ticks
134
+ tickmode="array",
135
+ thickness=width,
136
+ outlinewidth=outlineWidth,
137
+
138
+ )
139
+ )
140
+ )
141
+ figure.add_trace(colorbar_trace)
142
+ return figure
143
+
144
+ @staticmethod
145
+ def Colors():
146
+ """
147
+ Returns the list of named CSS colors that plotly can use.
148
+
149
+ Returns
150
+ -------
151
+ list
152
+ The list of named CSS colors.
153
+ """
154
+ return ["aliceblue","antiquewhite","aqua",
155
+ "aquamarine","azure","beige",
156
+ "bisque","black","blanchedalmond",
157
+ "blue","blueviolet","brown",
158
+ "burlywood","cadetblue",
159
+ "chartreuse","chocolate",
160
+ "coral","cornflowerblue","cornsilk",
161
+ "crimson","cyan","darkblue",
162
+ "darkcyan","darkgoldenrod","darkgray",
163
+ "darkgrey","darkgreen","darkkhaki",
164
+ "darkmagenta","darkolivegreen","darkorange",
165
+ "darkorchid","darkred","darksalmon",
166
+ "darkseagreen","darkslateblue","darkslategray",
167
+ "darkslategrey","darkturquoise","darkviolet",
168
+ "deeppink","deepskyblue","dimgray",
169
+ "dimgrey","dodgerblue","firebrick",
170
+ "floralwhite","forestgreen","fuchsia",
171
+ "gainsboro","ghostwhite","gold",
172
+ "goldenrod","gray","grey",
173
+ "green"," greenyellow","honeydew",
174
+ "hotpink","indianred","indigo",
175
+ "ivory","khaki","lavender",
176
+ "lavenderblush","lawngreen","lemonchiffon",
177
+ "lightblue","lightcoral","lightcyan",
178
+ "lightgoldenrodyellow","lightgray","lightgrey",
179
+ "lightgreen","lightpink","lightsalmon",
180
+ "lightseagreen","lightskyblue","lightslategray",
181
+ "lightslategrey","lightsteelblue","lightyellow",
182
+ "lime","limegreen","linen",
183
+ "magenta","maroon","mediumaquamarine",
184
+ "mediumblue","mediumorchid","mediumpurple",
185
+ "mediumseagreen","mediumslateblue","mediumspringgreen",
186
+ "mediumturquoise","mediumvioletred","midnightblue",
187
+ "mintcream","mistyrose","moccasin",
188
+ "navajowhite","navy","oldlace",
189
+ "olive","olivedrab","orange",
190
+ "orangered","orchid","palegoldenrod",
191
+ "palegreen","paleturquoise","palevioletred",
192
+ "papayawhip","peachpuff","peru",
193
+ "pink","plum","powderblue",
194
+ "purple","red","rosybrown",
195
+ "royalblue","rebeccapurple","saddlebrown",
196
+ "salmon","sandybrown","seagreen",
197
+ "seashell","sienna","silver",
198
+ "skyblue","slateblue","slategray",
199
+ "slategrey","snow","springgreen",
200
+ "steelblue","tan","teal",
201
+ "thistle","tomato","turquoise",
202
+ "violet","wheat","white",
203
+ "whitesmoke","yellow","yellowgreen"]
204
+
205
+
206
+ @staticmethod
207
+ def DataByDGL(data, labels):
208
+ """
209
+ Returns a data frame from the DGL data.
210
+
211
+ Parameters
212
+ ----------
213
+ data : list
214
+ The data to display.
215
+ labels : list
216
+ The labels to use for the data. The data with the labels in this list will be extracted and used in the returned dataFrame.
217
+
218
+ Returns
219
+ -------
220
+ pd.DataFrame
221
+ A pandas dataFrame
222
+
223
+ """
224
+
225
+ if isinstance(data[labels[0]][0], int):
226
+ xAxis_list = list(range(1, data[labels[0]][0]+1))
227
+ else:
228
+ xAxis_list = data[labels[0]][0]
229
+ plot_data = [xAxis_list]
230
+ for i in range(1,len(labels)):
231
+ plot_data.append(data[labels[i]][0][:len(xAxis_list)])
232
+
233
+ dlist = list(map(list, zip(*plot_data)))
234
+ df = pd.DataFrame(dlist, columns=labels)
235
+ return df
236
+
237
+ @staticmethod
238
+ def DataByGraph(graph, vertexColor="black", vertexSize=6, vertexLabelKey=None, vertexGroupKey=None, vertexGroups=[], showVertices=True, showVertexLegend=False, edgeColor="black", edgeWidth=1, edgeLabelKey=None, edgeGroupKey=None, edgeGroups=[], showEdges=True, showEdgeLegend=False, colorScale="viridis"):
239
+ """
240
+ Creates plotly vertex and edge data from the input graph.
241
+
242
+ Parameters
243
+ ----------
244
+ graph : topologic.Graph
245
+ The input graph.
246
+ vertexColor : str , optional
247
+ The desired color of the output vertices. This can be any plotly color string and may be specified as:
248
+ - A hex string (e.g. '#ff0000')
249
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
250
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
251
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
252
+ - A named CSS color.
253
+ The default is "black".
254
+ vertexSize : float , optional
255
+ The desired size of the vertices. The default is 6.
256
+ vertexLabelKey : str , optional
257
+ The dictionary key to use to display the vertex label. The default is None.
258
+ vertexGroupKey : str , optional
259
+ The dictionary key to use to display the vertex group. The default is None.
260
+ vertexGroups : list , optional
261
+ The list of vertex groups against which to index the color of the vertex. The default is [].
262
+ showVertices : bool , optional
263
+ If set to True the vertices will be drawn. Otherwise, they will not be drawn. The default is True.
264
+ showVertexLegend : bool , optional
265
+ If set to True the vertex legend will be drawn. Otherwise, it will not be drawn. The default is False.
266
+ edgeColor : str , optional
267
+ The desired color of the output edges. This can be any plotly color string and may be specified as:
268
+ - A hex string (e.g. '#ff0000')
269
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
270
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
271
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
272
+ - A named CSS color.
273
+ The default is "black".
274
+ edgeWidth : float , optional
275
+ The desired thickness of the output edges. The default is 1.
276
+ edgeLabelKey : str , optional
277
+ The dictionary key to use to display the edge label. The default is None.
278
+ edgeGroupKey : str , optional
279
+ The dictionary key to use to display the edge group. The default is None.
280
+ edgeGroups : list , optional
281
+ The list of groups to use for indexing the color of edges. The default is None.
282
+ showEdges : bool , optional
283
+ If set to True the edges will be drawn. Otherwise, they will not be drawn. The default is True.
284
+ showEdgeLegend : bool , optional
285
+ If set to True the edge legend will be drawn. Otherwise, it will not be drawn. The default is False.
286
+ colorScale : str , optional
287
+ 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/.
288
+ Returns
289
+ -------
290
+ list
291
+ The vertex and edge data list.
292
+
293
+ """
294
+ from topologicpy.Vertex import Vertex
295
+ from topologicpy.Edge import Edge
296
+ from topologicpy.Dictionary import Dictionary
297
+ from topologicpy.Topology import Topology
298
+ from topologicpy.Graph import Graph
299
+ import plotly.graph_objs as go
300
+
301
+ if not isinstance(graph, topologic.Graph):
302
+ return None
303
+ v_labels = []
304
+ v_groupList = []
305
+ data = []
306
+ if showVertices:
307
+ vertices = Graph.Vertices(graph)
308
+ if vertexLabelKey or vertexGroupKey:
309
+ for v in vertices:
310
+ Xn=[round(Vertex.X(v), 4) for v in vertices] # x-coordinates of nodes
311
+ Yn=[round(Vertex.Y(v), 4) for v in vertices] # y-coordinates of nodes
312
+ Zn=[round(Vertex.Z(v), 4) for v in vertices] # x-coordinates of nodes
313
+ v_label = ""
314
+ v_group = ""
315
+ d = Topology.Dictionary(v)
316
+ if d:
317
+ try:
318
+ v_label = str(Dictionary.ValueAtKey(d, key=vertexLabelKey)) or ""
319
+ except:
320
+ v_label = ""
321
+ try:
322
+ v_group = Dictionary.ValueAtKey(d, key=vertexGroupKey)
323
+ except:
324
+ v_group = None
325
+ try:
326
+ v_groupList.append(vertexGroups.index(v_group))
327
+ except:
328
+ v_groupList.append(len(vertexGroups))
329
+ if not v_label == "" and not v_group == "":
330
+ if v_group == 0:
331
+ v_label = v_label+" (0)"
332
+ else:
333
+ v_label = v_label+" ("+str(v_group)+")"
334
+ v_labels.append(v_label)
335
+ else:
336
+ for v in vertices:
337
+ Xn=[round(Vertex.X(v), 4) for v in vertices] # x-coordinates of nodes
338
+ Yn=[round(Vertex.Y(v), 4) for v in vertices] # y-coordinates of nodes
339
+ Zn=[round(Vertex.Z(v), 4) for v in vertices] # x-coordinates of nodes
340
+ if len(list(set(v_groupList))) < 2:
341
+ v_groupList = vertexColor
342
+ if len(v_labels) < 1:
343
+ v_labels = ""
344
+ v_trace=go.Scatter3d(x=Xn,
345
+ y=Yn,
346
+ z=Zn,
347
+ mode='markers',
348
+ name='Graph Vertices',
349
+ legendgroup=4,
350
+ legendrank=4,
351
+ showlegend=showVertexLegend,
352
+ marker=dict(symbol='circle',
353
+ size=vertexSize,
354
+ color=v_groupList,
355
+ colorscale=colorScale,
356
+ line=dict(color=edgeColor, width=0.5)
357
+ ),
358
+ text=v_labels,
359
+ hoverinfo='text'
360
+ )
361
+ data.append(v_trace)
362
+
363
+ if showEdges:
364
+ Xe=[]
365
+ Ye=[]
366
+ Ze=[]
367
+ e_labels = []
368
+ e_groupList = []
369
+ edges = Graph.Edges(graph)
370
+
371
+ if edgeLabelKey or edgeGroupKey:
372
+ for e in edges:
373
+ sv = Edge.StartVertex(e)
374
+ ev = Edge.EndVertex(e)
375
+ Xe+=[round(Vertex.X(sv), 4), round(Vertex.X(ev), 4), None] # x-coordinates of edge ends
376
+ Ye+=[round(Vertex.Y(sv), 4), round(Vertex.Y(ev), 4), None] # y-coordinates of edge ends
377
+ Ze+=[round(Vertex.Z(sv), 4), round(Vertex.Z(ev), 4), None] # z-coordinates of edge ends
378
+ e_label = ""
379
+ e_group = ""
380
+ d = Topology.Dictionary(e)
381
+ if d:
382
+ try:
383
+ e_label = str(Dictionary.ValueAtKey(d, key=edgeLabelKey)) or ""
384
+ except:
385
+ e_label = ""
386
+ try:
387
+ e_group = str(Dictionary.ValueAtKey(d, key=edgeGroupKey)) or ""
388
+ except:
389
+ e_group = ""
390
+ try:
391
+ e_groupList.append(edgeGroups.index(e_group))
392
+ except:
393
+ e_groupList.append(len(edgeGroups))
394
+ if not e_label == "" and not e_group == "":
395
+ e_label = e_label+" ("+e_group+")"
396
+ e_labels.append(e_label)
397
+ else:
398
+ for e in edges:
399
+ sv = Edge.StartVertex(e)
400
+ ev = Edge.EndVertex(e)
401
+ Xe+=[round(Vertex.X(sv), 4), round(Vertex.X(ev), 4), None] # x-coordinates of edge ends
402
+ Ye+=[round(Vertex.Y(sv), 4), round(Vertex.Y(ev), 4), None] # y-coordinates of edge ends
403
+ Ze+=[round(Vertex.Z(sv), 4), round(Vertex.Z(ev), 4), None] # z-coordinates of edge ends
404
+
405
+ if len(list(set(e_groupList))) < 2:
406
+ e_groupList = edgeColor
407
+ if len(e_labels) < 1:
408
+ e_labels = ""
409
+
410
+ e_trace=go.Scatter3d(x=Xe,
411
+ y=Ye,
412
+ z=Ze,
413
+ mode='lines',
414
+ name='Graph Edges',
415
+ legendgroup=5,
416
+ legendrank=5,
417
+ showlegend=showEdgeLegend,
418
+ line=dict(color=e_groupList, width=edgeWidth),
419
+ text=e_labels,
420
+ hoverinfo='text'
421
+ )
422
+ data.append(e_trace)
423
+
424
+ return data
425
+
426
+
427
+
428
+
429
+
430
+
431
+
432
+
433
+
434
+ @staticmethod
435
+ def DataByTopology(topology,
436
+ showVertices=True, vertexSize=1.1, vertexColor="black",
437
+ vertexLabelKey=None, vertexGroupKey=None, vertexGroups=[],
438
+ vertexMinGroup=None, vertexMaxGroup=None,
439
+ showVertexLegend=False, vertexLegendLabel="Topology Vertices", vertexLegendRank=1,
440
+ vertexLegendGroup=1,
441
+ showEdges=True, edgeWidth=1, edgeColor="black",
442
+ edgeLabelKey=None, edgeGroupKey=None, edgeGroups=[],
443
+ edgeMinGroup=None, edgeMaxGroup=None,
444
+ showEdgeLegend=False, edgeLegendLabel="Topology Edges", edgeLegendRank=2,
445
+ edgeLegendGroup=2,
446
+ showFaces=True, faceOpacity=0.5, faceColor="#FAFAFA",
447
+ faceLabelKey=None, faceGroupKey=None, faceGroups=[],
448
+ faceMinGroup=None, faceMaxGroup=None,
449
+ showFaceLegend=False, faceLegendLabel="Topology Faces", faceLegendRank=3,
450
+ faceLegendGroup=3,
451
+ intensityKey=None, intensities=[], colorScale="Viridis", mantissa=6, tolerance=0.0001):
452
+ """
453
+ Creates plotly face, edge, and vertex data.
454
+
455
+ Parameters
456
+ ----------
457
+ topology : topologic.Topology
458
+ The input topology. This must contain faces and or edges.
459
+
460
+ showVertices : bool , optional
461
+ If set to True the vertices will be drawn. Otherwise, they will not be drawn. The default is True.
462
+ vertexSize : float , optional
463
+ The desired size of the vertices. The default is 1.1.
464
+ vertexColor : str , optional
465
+ The desired color of the output vertices. This can be any plotly color string and may be specified as:
466
+ - A hex string (e.g. '#ff0000')
467
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
468
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
469
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
470
+ - A named CSS color.
471
+ The default is "black".
472
+ vertexLabelKey : str , optional
473
+ The dictionary key to use to display the vertex label. The default is None.
474
+ vertexGroupKey : str , optional
475
+ The dictionary key to use to display the vertex group. The default is None.
476
+ vertexGroups : list , optional
477
+ The list of vertex groups against which to index the color of the vertex. The default is [].
478
+ vertexMinGroup : int or float , optional
479
+ For numeric vertexGroups, vertexMinGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the vertexGroupKey. If set to None, it is set to the minimum value in vertexGroups. The default is None.
480
+ vertexMaxGroup : int or float , optional
481
+ For numeric vertexGroups, vertexMaxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the vertexGroupKey. If set to None, it is set to the maximum value in vertexGroups. The default is None.
482
+ showVertexLegend : bool, optional
483
+ If set to True, the legend for the vertices of this topology is shown. Otherwise, it isn't. The default is False.
484
+ vertexLegendLabel : str , optional
485
+ The legend label string used to identify vertices. The default is "Topology Vertices".
486
+ vertexLegendRank : int , optional
487
+ The legend rank order of the vertices of this topology. The default is 1.
488
+ vertexLegendGroup : int , optional
489
+ The number of the vertex legend group to which the vertices of this topology belong. The default is 1.
490
+
491
+ showEdges : bool , optional
492
+ If set to True the edges will be drawn. Otherwise, they will not be drawn. The default is True.
493
+ edgeWidth : float , optional
494
+ The desired thickness of the output edges. The default is 1.
495
+ edgeColor : str , optional
496
+ The desired color of the output edges. This can be any plotly color string and may be specified as:
497
+ - A hex string (e.g. '#ff0000')
498
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
499
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
500
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
501
+ - A named CSS color.
502
+ The default is "black".
503
+ edgeLabelKey : str , optional
504
+ The dictionary key to use to display the edge label. The default is None.
505
+ edgeGroupKey : str , optional
506
+ The dictionary key to use to display the edge group. The default is None.
507
+ edgeGroups : list , optional
508
+ The list of edge groups against which to index the color of the edge. The default is [].
509
+ edgeMinGroup : int or float , optional
510
+ For numeric edgeGroups, edgeMinGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the edgeGroupKey. If set to None, it is set to the minimum value in edgeGroups. The default is None.
511
+ edgeMaxGroup : int or float , optional
512
+ For numeric edgeGroups, edgeMaxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the edgeGroupKey. If set to None, it is set to the maximum value in edgeGroups. The default is None.
513
+ showEdgeLegend : bool, optional
514
+ If set to True, the legend for the edges of this topology is shown. Otherwise, it isn't. The default is False.
515
+ edgeLegendLabel : str , optional
516
+ The legend label string used to identify edges. The default is "Topology Edges".
517
+ edgeLegendRank : int , optional
518
+ The legend rank order of the edges of this topology. The default is 2.
519
+ edgeLegendGroup : int , optional
520
+ The number of the edge legend group to which the edges of this topology belong. The default is 2.
521
+
522
+ showFaces : bool , optional
523
+ If set to True the faces will be drawn. Otherwise, they will not be drawn. The default is True.
524
+ faceOpacity : float , optional
525
+ The desired opacity of the output faces (0=transparent, 1=opaque). The default is 0.5.
526
+ faceColor : str , optional
527
+ The desired color of the output faces. This can be any plotly color string and may be specified as:
528
+ - A hex string (e.g. '#ff0000')
529
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
530
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
531
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
532
+ - A named CSS color.
533
+ The default is "#FAFAFA".
534
+ faceLabelKey : str , optional
535
+ The dictionary key to use to display the face label. The default is None.
536
+ faceGroupKey : str , optional
537
+ The dictionary key to use to display the face group. The default is None.
538
+ faceGroups : list , optional
539
+ The list of face groups against which to index the color of the face. This can bhave numeric or string values. This should match the type of value associated with the faceGroupKey. The default is [].
540
+ faceMinGroup : int or float , optional
541
+ For numeric faceGroups, minGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the faceGroupKey. If set to None, it is set to the minimum value in faceGroups. The default is None.
542
+ faceMaxGroup : int or float , optional
543
+ For numeric faceGroups, maxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the faceGroupKey. If set to None, it is set to the maximum value in faceGroups. The default is None.
544
+ showFaceLegend : bool, optional
545
+ If set to True, the legend for the faces of this topology is shown. Otherwise, it isn't. The default is False.
546
+ faceLegendLabel : str , optional
547
+ The legend label string used to idenitfy edges. The default is "Topology Faces".
548
+ faceLegendRank : int , optional
549
+ The legend rank order of the faces of this topology. The default is 3.
550
+ faceLegendGroup : int , optional
551
+ The number of the face legend group to which the faces of this topology belong. The default is 3.
552
+ intensityKey: str, optional
553
+ If not None, the dictionary of each vertex is searched for the value associated with the intensity key. This value is then used to color-code the vertex based on the colorScale. The default is None.
554
+ intensities : list , optional
555
+ The list of intensities against which to index the intensity of the vertex. The default is [].
556
+ colorScale : str , optional
557
+ 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/.
558
+ mantissa : int , optional
559
+ The desired length of the mantissa. The default is 6.
560
+ tolerance : float , optional
561
+ The desired tolerance. The default is 0.0001.
562
+
563
+ Returns
564
+ -------
565
+ list
566
+ The vertex, edge, and face data list.
567
+
568
+ """
569
+ from topologicpy.Topology import Topology
570
+ from topologicpy.Dictionary import Dictionary
571
+ from topologicpy.Color import Color
572
+ from time import time
573
+
574
+ def closest_index(input_value, values):
575
+ return int(min(range(len(values)), key=lambda i: abs(values[i] - input_value)))
576
+
577
+ def vertexData(vertices, dictionaries=[], color="black", size=1.1, labelKey=None, groupKey=None, minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Vertices", legendGroup=1, legendRank=1, showLegend=True, colorScale="Viridis"):
578
+ x = []
579
+ y = []
580
+ z = []
581
+ labels = []
582
+ groupList = []
583
+ label = ""
584
+ group = ""
585
+ if labelKey or groupKey:
586
+ if groups:
587
+ if len(groups) > 0:
588
+ if type(groups[0]) == int or type(groups[0]) == float:
589
+ if not minGroup:
590
+ minGroup = min(groups)
591
+ if not maxGroup:
592
+ maxGroup = max(groups)
593
+ else:
594
+ minGroup = 0
595
+ maxGroup = len(groups) - 1
596
+ else:
597
+ minGroup = 0
598
+ maxGroup = 1
599
+ for m, v in enumerate(vertices):
600
+ x.append(round(v[0], mantissa))
601
+ y.append(round(v[1], mantissa))
602
+ z.append(round(v[2], mantissa))
603
+ label = ""
604
+ group = ""
605
+ if len(dictionaries) > 0:
606
+ d = dictionaries[m]
607
+ if d:
608
+ try:
609
+ label = str(Dictionary.ValueAtKey(d, key=labelKey)) or ""
610
+ except:
611
+ label = ""
612
+ try:
613
+ group = Dictionary.ValueAtKey(d, key=groupKey) or None
614
+ except:
615
+ group = ""
616
+ try:
617
+ if type(group) == int or type(group) == float:
618
+ if group < minGroup:
619
+ group = minGroup
620
+ if group > maxGroup:
621
+ group = maxGroup
622
+ color = Color.ByValueInRange(group, minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
623
+ else:
624
+ color = Color.ByValueInRange(groups.index(group), minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
625
+ color = "rgb("+str(color[0])+","+str(color[1])+","+str(color[2])+")"
626
+ groupList.append(color)
627
+ except:
628
+ groupList.append(len(groups))
629
+ labels.append(label)
630
+ else:
631
+ for v in vertices:
632
+ x.append(round(v[0], mantissa))
633
+ y.append(round(v[1], mantissa))
634
+ z.append(round(v[2], mantissa))
635
+
636
+ if len(list(set(groupList))) < 2:
637
+ groupList = color
638
+ if len(labels) < 1:
639
+ labels = ""
640
+ vData= go.Scatter3d(x=x,
641
+ y=y,
642
+ z=z,
643
+ name=legendLabel,
644
+ showlegend=showLegend,
645
+ marker=dict(color=groupList, size=vertexSize),
646
+ mode='markers',
647
+ legendgroup=legendGroup,
648
+ legendrank=legendRank,
649
+ text=labels,
650
+ hoverinfo='text',
651
+ hovertext=labels
652
+ )
653
+ return vData
654
+
655
+ def edgeData(vertices, edges, dictionaries=None, color="black", width=1, labelKey=None, groupKey=None, minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Edges", legendGroup=2, legendRank=2, showLegend=True, colorScale="Viridis"):
656
+ x = []
657
+ y = []
658
+ z = []
659
+ labels = []
660
+ groupList = []
661
+ label = ""
662
+ group = ""
663
+ if labelKey or groupKey:
664
+ if groups:
665
+ if len(groups) > 0:
666
+ if type(groups[0]) == int or type(groups[0]) == float:
667
+ if not minGroup:
668
+ minGroup = min(groups)
669
+ if not maxGroup:
670
+ maxGroup = max(groups)
671
+ else:
672
+ minGroup = 0
673
+ maxGroup = len(groups) - 1
674
+ else:
675
+ minGroup = 0
676
+ maxGroup = 1
677
+ for m, e in enumerate(edges):
678
+ sv = vertices[e[0]]
679
+ ev = vertices[e[1]]
680
+ x+=[round(sv[0], mantissa),round(ev[0], mantissa), None] # x-coordinates of edge ends
681
+ y+=[round(sv[1], mantissa),round(ev[1], mantissa), None] # y-coordinates of edge ends
682
+ z+=[round(sv[2], mantissa),round(ev[2], mantissa), None] # z-coordinates of edge ends
683
+ label = ""
684
+ group = ""
685
+ if len(dictionaries) > 0:
686
+ d = dictionaries[m]
687
+ if d:
688
+ try:
689
+ label = str(Dictionary.ValueAtKey(d, key=labelKey)) or ""
690
+ except:
691
+ label = ""
692
+ try:
693
+ group = Dictionary.ValueAtKey(d, key=groupKey) or None
694
+ except:
695
+ group = ""
696
+ try:
697
+ if type(group) == int or type(group) == float:
698
+ if group < minGroup:
699
+ group = minGroup
700
+ if group > maxGroup:
701
+ group = maxGroup
702
+ color = Color.ByValueInRange(group, minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
703
+ else:
704
+ color = Color.ByValueInRange(groups.index(group), minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
705
+ color = "rgb("+str(color[0])+","+str(color[1])+","+str(color[2])+")"
706
+ groupList.append(color)
707
+ except:
708
+ groupList.append(len(groups))
709
+ labels.append(label)
710
+ else:
711
+ for e in edges:
712
+ sv = vertices[e[0]]
713
+ ev = vertices[e[1]]
714
+ x+=[round(sv[0],mantissa),round(ev[0],mantissa), None] # x-coordinates of edge ends
715
+ y+=[round(sv[1],mantissa),round(ev[1],mantissa), None] # y-coordinates of edge ends
716
+ z+=[round(sv[2],mantissa),round(ev[2],mantissa), None] # z-coordinates of edge ends
717
+
718
+ if len(list(set(groupList))) < 2:
719
+ groupList = color
720
+ if len(labels) < 1:
721
+ labels = ""
722
+ eData = go.Scatter3d(x=x,
723
+ y=y,
724
+ z=z,
725
+ name=legendLabel,
726
+ showlegend=showLegend,
727
+ marker_size=0,
728
+ mode="lines",
729
+ line=dict(color=groupList, width=edgeWidth),
730
+ legendgroup=legendGroup,
731
+ legendrank=legendRank,
732
+ text=labels,
733
+ hoverinfo='text')
734
+ return eData
735
+
736
+
737
+ def faceData(vertices, faces, dictionaries=None, color="#FAFAFA",
738
+ opacity=0.5, labelKey=None, groupKey=None,
739
+ minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Faces",
740
+ legendGroup=3, legendRank=3, showLegend=True, intensities=None, colorScale="Viridis"):
741
+ x = []
742
+ y = []
743
+ z = []
744
+ for v in vertices:
745
+ x.append(round(v[0], mantissa))
746
+ y.append(round(v[1], mantissa))
747
+ z.append(round(v[2], mantissa))
748
+ i = []
749
+ j = []
750
+ k = []
751
+ labels = []
752
+ groupList = []
753
+ label = ""
754
+ group = ""
755
+ if labelKey or groupKey:
756
+ if groups:
757
+ if len(groups) > 0:
758
+ if type(groups[0]) == int or type(groups[0]) == float:
759
+ if not minGroup:
760
+ minGroup = min(groups)
761
+ if not maxGroup:
762
+ maxGroup = max(groups)
763
+ else:
764
+ minGroup = 0
765
+ maxGroup = len(groups) - 1
766
+ else:
767
+ minGroup = 0
768
+ maxGroup = 1
769
+ for m, f in enumerate(faces):
770
+ i.append(f[0])
771
+ j.append(f[1])
772
+ k.append(f[2])
773
+ label = ""
774
+ group = ""
775
+ if len(dictionaries) > 0:
776
+ d = dictionaries[m]
777
+ if d:
778
+ try:
779
+ label = str(Dictionary.ValueAtKey(d, key=labelKey)) or ""
780
+ except:
781
+ label = ""
782
+ try:
783
+ group = Dictionary.ValueAtKey(d, key=groupKey) or None
784
+ except:
785
+ group = ""
786
+ try:
787
+ if type(group) == int or type(group) == float:
788
+ if group < minGroup:
789
+ group = minGroup
790
+ if group > maxGroup:
791
+ group = maxGroup
792
+ color = Color.ByValueInRange(group, minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
793
+ else:
794
+ color = Color.ByValueInRange(groups.index(group), minValue=minGroup, maxValue=maxGroup, colorScale=colorScale)
795
+ color = "rgb("+str(color[0])+","+str(color[1])+","+str(color[2])+")"
796
+ groupList.append(color)
797
+ except:
798
+ groupList.append(len(groups))
799
+ labels.append(label)
800
+ else:
801
+ for f in faces:
802
+ i.append(f[0])
803
+ j.append(f[1])
804
+ k.append(f[2])
805
+
806
+ if len(list(set(groupList))) < 2:
807
+ groupList = None
808
+ if len(labels) < 1:
809
+ labels = ""
810
+ fData = go.Mesh3d(
811
+ x = x,
812
+ y = y,
813
+ z = z,
814
+ i = i,
815
+ j = j,
816
+ k = k,
817
+ name = legendLabel,
818
+ showlegend = showLegend,
819
+ legendgroup = legendGroup,
820
+ legendrank = legendRank,
821
+ color = color,
822
+ facecolor = groupList,
823
+ colorscale = colorScale,
824
+ cmin = 0,
825
+ cmax = 1,
826
+ intensity = intensities,
827
+ opacity = opacity,
828
+ hoverinfo = 'text',
829
+ text = labels,
830
+ hovertext = labels,
831
+ flatshading = True,
832
+ showscale = False,
833
+ lighting = {"facenormalsepsilon": 0},
834
+ )
835
+ return fData
836
+
837
+ from topologicpy.Cluster import Cluster
838
+ from topologicpy.Topology import Topology
839
+ from topologicpy.Dictionary import Dictionary
840
+ from time import time
841
+ if not isinstance(topology, topologic.Topology):
842
+ return None
843
+
844
+ intensityList = []
845
+ alt_intensities = []
846
+ data = []
847
+ v_list = []
848
+
849
+ if topology.Type() == topologic.Vertex.Type():
850
+ tp_vertices = [topology]
851
+ else:
852
+ tp_vertices = Topology.Vertices(topology)
853
+
854
+ if isinstance(intensities, list):
855
+ if len(intensities) == 0:
856
+ intensities = None
857
+
858
+ if not (tp_vertices == None or tp_vertices == []):
859
+ vertices = []
860
+ v_dictionaries = []
861
+ intensityList = []
862
+
863
+ if intensityKey:
864
+ for i, tp_v in enumerate(tp_vertices):
865
+ vertices.append([tp_v.X(), tp_v.Y(), tp_v.Z()])
866
+ d = Topology.Dictionary(tp_v)
867
+ if d:
868
+ v = Dictionary.ValueAtKey(d, key=intensityKey)
869
+ if not v == None:
870
+ alt_intensities.append(v)
871
+ v_list.append(v)
872
+ else:
873
+ alt_intensities.append(0)
874
+ v_list.append(0)
875
+ else:
876
+ alt_intensities.append(0)
877
+ v_list.append(0)
878
+ alt_intensities = list(set(alt_intensities))
879
+ alt_intensities.sort()
880
+ if isinstance(intensities, list):
881
+ if len(intensities) > 0:
882
+ alt_intensities = intensities
883
+ min_i = min(alt_intensities)
884
+ max_i = max(alt_intensities)
885
+ for i, tp_v in enumerate(tp_vertices):
886
+ v = v_list[i]
887
+ ci = closest_index(v_list[i], alt_intensities)
888
+ value = intensities[ci]
889
+ if (max_i - min_i) == 0:
890
+ value = 0
891
+ else:
892
+ value = (value - min_i)/(max_i - min_i)
893
+ intensityList.append(value)
894
+ if all(x == 0 for x in intensityList):
895
+ intensityList = None
896
+ if showVertices:
897
+ if len(vertices) == 0:
898
+ for i, tp_v in enumerate(tp_vertices):
899
+ if vertexLabelKey or vertexGroupKey:
900
+ d = Topology.Dictionary(tp_v)
901
+ v_dictionaries.append(d)
902
+ vertices.append([tp_v.X(), tp_v.Y(), tp_v.Z()])
903
+ data.append(vertexData(vertices, dictionaries=v_dictionaries, color=vertexColor, size=vertexSize, labelKey=vertexLabelKey, groupKey=vertexGroupKey, minGroup=vertexMinGroup, maxGroup=vertexMaxGroup, groups=vertexGroups, legendLabel=vertexLegendLabel, legendGroup=vertexLegendGroup, legendRank=vertexLegendRank, showLegend=showVertexLegend, colorScale=colorScale))
904
+
905
+ if showEdges and topology.Type() > topologic.Vertex.Type():
906
+ if topology.Type() == topologic.Edge.Type():
907
+ tp_edges = [topology]
908
+ else:
909
+ tp_edges = Topology.Edges(topology)
910
+ if not (tp_edges == None or tp_edges == []):
911
+ e_dictionaries = []
912
+ if edgeLabelKey or edgeGroupKey:
913
+ for tp_edge in tp_edges:
914
+ e_dictionaries.append(Topology.Dictionary(tp_edge))
915
+ e_cluster = Cluster.ByTopologies(tp_edges)
916
+ geo = Topology.Geometry(e_cluster, mantissa=mantissa)
917
+ vertices = geo['vertices']
918
+ edges = geo['edges']
919
+ data.append(edgeData(vertices, edges, dictionaries=e_dictionaries, color=edgeColor, width=edgeWidth, labelKey=edgeLabelKey, groupKey=edgeGroupKey, minGroup=edgeMinGroup, maxGroup=edgeMaxGroup, groups=edgeGroups, legendLabel=edgeLegendLabel, legendGroup=edgeLegendGroup, legendRank=edgeLegendRank, showLegend=showEdgeLegend, colorScale=colorScale))
920
+
921
+ if showFaces and topology.Type() >= topologic.Face.Type():
922
+ if isinstance(topology, topologic.Face):
923
+ tp_faces = [topology]
924
+ else:
925
+ tp_faces = Topology.Faces(topology)
926
+ if not(tp_faces == None or tp_faces == []):
927
+ # rebuild faces to remove any degenerate faces
928
+ #new_faces = []
929
+ #for i, f in enumerate(tp_faces):
930
+ #eb = Face.ExternalBoundary(f)
931
+ #eb = Topology.RemoveCollinearEdges(eb)
932
+ #if not eb == None:
933
+ #ibList = Face.InternalBoundaries(f)
934
+ #ibList = [Wire.RemoveCollinearEdges(ib) for ib in ibList]
935
+ #ibList = [ib for ib in ibList if not ib == None]
936
+ #new_f = Face.ByWires(eb, ibList, silent=False)
937
+ #if isinstance(new_f, topologic.Face):
938
+ #if faceLabelKey or faceGroupKey:
939
+ #d = Topology.Dictionary(tp_faces[i])
940
+ #keys = Dictionary.Keys(d)
941
+ #if len(keys) > 0:
942
+ #new_f = Topology.SetDictionary(new_f, d)
943
+ #new_faces.append(new_f)
944
+
945
+ f_dictionaries = []
946
+ all_triangles = []
947
+ for tp_face in tp_faces:
948
+ triangles = Face.Triangulate(tp_face, tolerance=tolerance)
949
+ if isinstance(triangles, list):
950
+ for tri in triangles:
951
+ if faceLabelKey or faceGroupKey:
952
+ d = Topology.Dictionary(tp_face)
953
+ f_dictionaries.append(d)
954
+ if d:
955
+ _ = Topology.SetDictionary(tri, d)
956
+ all_triangles.append(tri)
957
+ if len(all_triangles) > 0:
958
+ f_cluster = Cluster.ByTopologies(all_triangles)
959
+ geo = Topology.Geometry(f_cluster, mantissa=mantissa)
960
+ vertices = geo['vertices']
961
+ faces = geo['faces']
962
+ data.append(faceData(vertices, faces, dictionaries=f_dictionaries, color=faceColor, opacity=faceOpacity, labelKey=faceLabelKey, groupKey=faceGroupKey, minGroup=faceMinGroup, maxGroup=faceMaxGroup, groups=faceGroups, legendLabel=faceLegendLabel, legendGroup=faceLegendGroup, legendRank=faceLegendRank, showLegend=showFaceLegend, intensities=intensityList, colorScale=colorScale))
963
+ return data
964
+
965
+ @staticmethod
966
+ def FigureByConfusionMatrix(matrix,
967
+ categories=[],
968
+ minValue=None,
969
+ maxValue=None,
970
+ title="Confusion Matrix",
971
+ xTitle = "Actual",
972
+ yTitle = "Predicted",
973
+ width=950,
974
+ height=500,
975
+ showScale = True,
976
+ colorScale='Viridis',
977
+ colorSamples=10,
978
+ backgroundColor='rgba(0,0,0,0)',
979
+ marginLeft=0,
980
+ marginRight=0,
981
+ marginTop=40,
982
+ marginBottom=0):
983
+ """
984
+ Returns a Plotly Figure of the input confusion matrix. Actual categories are displayed on the X-Axis, Predicted categories are displayed on the Y-Axis.
985
+
986
+ Parameters
987
+ ----------
988
+ matrix : list or numpy.array
989
+ The matrix to display.
990
+ categories : list
991
+ The list of categories to use on the X and Y axes.
992
+ minValue : float , optional
993
+ The desired minimum value to use for the color scale. If set to None, the minmum value found in the input matrix will be used. The default is None.
994
+ maxValue : float , optional
995
+ The desired maximum value to use for the color scale. If set to None, the maximum value found in the input matrix will be used. The default is None.
996
+ title : str , optional
997
+ The desired title to display. The default is "Confusion Matrix".
998
+ xTitle : str , optional
999
+ The desired X-axis title to display. The default is "Actual".
1000
+ yTitle : str , optional
1001
+ The desired Y-axis title to display. The default is "Predicted".
1002
+ width : int , optional
1003
+ The desired width of the figure. The default is 950.
1004
+ height : int , optional
1005
+ The desired height of the figure. The default is 500.
1006
+ showScale : bool , optional
1007
+ If set to True, a color scale is shown on the right side of the figure. The default is True.
1008
+ colorScale : str , optional
1009
+ 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/.
1010
+ colorSamples : int , optional
1011
+ The number of discrete color samples to use for displaying the data. The default is 10.
1012
+ backgroundColor : str , optional
1013
+ The desired background color. This can be any plotly color string and may be specified as:
1014
+ - A hex string (e.g. '#ff0000')
1015
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1016
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1017
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1018
+ - A named CSS color.
1019
+ The default is 'rgba(0,0,0,0)' (transparent).
1020
+ marginLeft : int , optional
1021
+ The desired left margin in pixels. The default is 0.
1022
+ marginRight : int , optional
1023
+ The desired right margin in pixels. The default is 0.
1024
+ marginTop : int , optional
1025
+ The desired top margin in pixels. The default is 40.
1026
+ marginBottom : int , optional
1027
+ The desired bottom margin in pixels. The default is 0.
1028
+
1029
+ """
1030
+ if not isinstance(matrix, list) and not isinstance(matrix, np.ndarray):
1031
+ print("Plotly.FigureByConfusionMatrix - Error: The input matrix is not of the correct type. Returning None.")
1032
+ return None
1033
+ figure = Plotly.FigureByMatrix(matrix,
1034
+ xCategories=categories,
1035
+ minValue=minValue,
1036
+ maxValue=maxValue,
1037
+ title=title,
1038
+ xTitle=xTitle,
1039
+ yTitle=yTitle,
1040
+ width=width,
1041
+ height=height,
1042
+ showScale=showScale,
1043
+ colorScale=colorScale,
1044
+ colorSamples=colorSamples,
1045
+ backgroundColor=backgroundColor,
1046
+ marginLeft=marginLeft,
1047
+ marginRight=marginRight,
1048
+ marginTop=marginTop,
1049
+ marginBottom=marginBottom)
1050
+ layout = {
1051
+ "yaxis": {"autorange": "reversed"},
1052
+ }
1053
+ figure.update_layout(layout)
1054
+ return figure
1055
+
1056
+ @staticmethod
1057
+ def FigureByMatrix(matrix,
1058
+ xCategories=[],
1059
+ yCategories=[],
1060
+ minValue=None,
1061
+ maxValue=None,
1062
+ title="Matrix",
1063
+ xTitle = "X Axis",
1064
+ yTitle = "Y Axis",
1065
+ width=950,
1066
+ height=950,
1067
+ showScale = False,
1068
+ colorScale='gray',
1069
+ colorSamples=10,
1070
+ backgroundColor='rgba(0,0,0,0)',
1071
+ marginLeft=0,
1072
+ marginRight=0,
1073
+ marginTop=40,
1074
+ marginBottom=0,
1075
+ mantissa: int = 6):
1076
+ """
1077
+ Returns a Plotly Figure of the input matrix.
1078
+
1079
+ Parameters
1080
+ ----------
1081
+ matrix : list or numpy.array
1082
+ The matrix to display.
1083
+ categories : list
1084
+ The list of categories to use on the X and Y axes.
1085
+ minValue : float , optional
1086
+ The desired minimum value to use for the color scale. If set to None, the minmum value found in the input matrix will be used. The default is None.
1087
+ maxValue : float , optional
1088
+ The desired maximum value to use for the color scale. If set to None, the maximum value found in the input matrix will be used. The default is None.
1089
+ title : str , optional
1090
+ The desired title to display. The default is "Confusion Matrix".
1091
+ xTitle : str , optional
1092
+ The desired X-axis title to display. The default is "Actual".
1093
+ yTitle : str , optional
1094
+ The desired Y-axis title to display. The default is "Predicted".
1095
+ width : int , optional
1096
+ The desired width of the figure. The default is 950.
1097
+ height : int , optional
1098
+ The desired height of the figure. The default is 500.
1099
+ showScale : bool , optional
1100
+ If set to True, a color scale is shown on the right side of the figure. The default is True.
1101
+ colorScale : str , optional
1102
+ 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/.
1103
+ colorSamples : int , optional
1104
+ The number of discrete color samples to use for displaying the data. The default is 10.
1105
+ backgroundColor : str , optional
1106
+ The desired background color. This can be any plotly color string and may be specified as:
1107
+ - A hex string (e.g. '#ff0000')
1108
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1109
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1110
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1111
+ - A named CSS color.
1112
+ The default is 'rgba(0,0,0,0)' (transparent).
1113
+ marginLeft : int , optional
1114
+ The desired left margin in pixels. The default is 0.
1115
+ marginRight : int , optional
1116
+ The desired right margin in pixels. The default is 0.
1117
+ marginTop : int , optional
1118
+ The desired top margin in pixels. The default is 40.
1119
+ marginBottom : int , optional
1120
+ The desired bottom margin in pixels. The default is 0.
1121
+ mantissa : int , optional
1122
+ The desired number of digits of the mantissa. The default is 4.
1123
+
1124
+ """
1125
+ #import plotly.figure_factory as ff
1126
+ import plotly.graph_objects as go
1127
+ import plotly.express as px
1128
+
1129
+ if not isinstance(matrix, list) and not isinstance(matrix, np.ndarray):
1130
+ print("Plotly.FigureByMatrix - Error: The input matrix is not of the correct type. Returning None.")
1131
+ return None
1132
+
1133
+ annotations = []
1134
+
1135
+ if isinstance(matrix, list):
1136
+ matrix = np.array(matrix)
1137
+ colors = px.colors.sample_colorscale(colorScale, [n/(colorSamples -1) for n in range(colorSamples)])
1138
+
1139
+ if not xCategories:
1140
+ xCategories = [x for x in range(len(matrix[0]))]
1141
+ if not yCategories:
1142
+ yCategories = [y for y in range(len(matrix))]
1143
+
1144
+ if not maxValue or not minValue:
1145
+ max_values = []
1146
+ min_values = []
1147
+ for i in range(len(matrix)):
1148
+ row = matrix[i]
1149
+ max_values.append(max(row))
1150
+ min_values.append(min(row))
1151
+ for j, value in enumerate(row):
1152
+ annotations.append(
1153
+ {
1154
+ "x": xCategories[j],
1155
+ "y": yCategories[i],
1156
+ "font": {"color": "black"},
1157
+ "bgcolor": "white",
1158
+ "opacity": 0.5,
1159
+ "text": str(round(value, mantissa)),
1160
+ "xref": "x1",
1161
+ "yref": "y1",
1162
+ "showarrow": False
1163
+ }
1164
+ )
1165
+ if not minValue:
1166
+ minValueB = min(min_values)
1167
+ if not maxValue:
1168
+ maxValue = max(max_values)
1169
+ else:
1170
+ for i in range(len(matrix)):
1171
+ row = matrix[i]
1172
+ for j, value in enumerate(row):
1173
+ annotations.append(
1174
+ {
1175
+ "x": xCategories[j],
1176
+ "y": yCategories[i],
1177
+ "font": {"color": "black"},
1178
+ "bgcolor": "white",
1179
+ "opacity": 0.5,
1180
+ "text": str(round(value,mantissa)),
1181
+ "xref": "x1",
1182
+ "yref": "y1",
1183
+ "showarrow": False
1184
+ }
1185
+ )
1186
+ new_matrix = []
1187
+ for i in range(len(matrix)):
1188
+ row = matrix[i]
1189
+ new_row = []
1190
+ maxRow = sum(row)
1191
+ for j in range(len(row)):
1192
+ if maxRow == 0:
1193
+ new_row.append(round(0, mantissa))
1194
+ else:
1195
+ new_row.append(round(float(row[j])/float(maxRow), mantissa))
1196
+ new_matrix.append(new_row)
1197
+ data = go.Heatmap(z=new_matrix, y=yCategories, x=xCategories, zmin=minValue, zmax=maxValue, showscale=showScale, colorscale=colors)
1198
+
1199
+ layout = {
1200
+ "width": width,
1201
+ "height": height,
1202
+ "title": title,
1203
+ "xaxis": {"title": xTitle},
1204
+ "yaxis": {"title": yTitle, "autorange": "reversed"},
1205
+ "annotations": annotations,
1206
+ "paper_bgcolor": backgroundColor,
1207
+ "plot_bgcolor": backgroundColor,
1208
+ "margin":dict(l=marginLeft, r=marginRight, t=marginTop, b=marginBottom)
1209
+ }
1210
+ fig = go.Figure(data=data, layout=layout)
1211
+ fig.update_xaxes( tickvals=xCategories)
1212
+ fig.update_yaxes( tickvals=yCategories)
1213
+ return fig
1214
+
1215
+ @staticmethod
1216
+ def FigureByDataFrame(dataFrame,
1217
+ labels=[],
1218
+ width=950,
1219
+ height=500,
1220
+ title="Untitled",
1221
+ xTitle="X Axis",
1222
+ xSpacing=1,
1223
+ yTitle="Y Axis",
1224
+ ySpacing=1.0,
1225
+ useMarkers=False,
1226
+ chartType="Line",
1227
+ backgroundColor='rgba(0,0,0,0)',
1228
+ gridColor = 'lightgray',
1229
+ marginLeft=0,
1230
+ marginRight=0,
1231
+ marginTop=40,
1232
+ marginBottom=0):
1233
+
1234
+ """
1235
+ Returns a Plotly Figure of the input dataframe
1236
+
1237
+ Parameters
1238
+ ----------
1239
+ df : pandas.df
1240
+ The pandas dataframe to display.
1241
+ data_labels : list
1242
+ The labels to use for the data.
1243
+ width : int , optional
1244
+ The desired width of the figure. The default is 950.
1245
+ height : int , optional
1246
+ The desired height of the figure. The default is 500.
1247
+ title : str , optional
1248
+ The chart title. The default is "Training and Testing Results".
1249
+ xTitle : str , optional
1250
+ The X-axis title. The default is "Epochs".
1251
+ xSpacing : float , optional
1252
+ The X-axis spacing. The default is 1.0.
1253
+ yTitle : str , optional
1254
+ The Y-axis title. The default is "Accuracy and Loss".
1255
+ ySpacing : float , optional
1256
+ The Y-axis spacing. The default is 0.1.
1257
+ useMarkers : bool , optional
1258
+ If set to True, markers will be displayed. The default is False.
1259
+ chartType : str , optional
1260
+ The desired type of chart. The options are "Line", "Bar", or "Scatter". It is case insensitive. The default is "Line".
1261
+ backgroundColor : str , optional
1262
+ The desired background color. This can be any plotly color string and may be specified as:
1263
+ - A hex string (e.g. '#ff0000')
1264
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1265
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1266
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1267
+ - A named CSS color.
1268
+ The default is 'rgba(0,0,0,0)' (transparent).
1269
+ grid : str , optional
1270
+ The desired background color. This can be any plotly color string and may be specified as:
1271
+ - A hex string (e.g. '#ff0000')
1272
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1273
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1274
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1275
+ - A named CSS color.
1276
+ The default is 'lightgray'
1277
+ marginLeft : int , optional
1278
+ The desired left margin in pixels. The default is 0.
1279
+ marginRight : int , optional
1280
+ The desired right margin in pixels. The default is 0.
1281
+ marginTop : int , optional
1282
+ The desired top margin in pixels. The default is 40.
1283
+ marginBottom : int , optional
1284
+ The desired bottom margin in pixels. The default is 0.
1285
+
1286
+ Returns
1287
+ -------
1288
+ None.
1289
+
1290
+ """
1291
+ import plotly.express as px
1292
+
1293
+ if chartType.lower() == "line":
1294
+ figure = px.line(dataFrame, x=labels[0], y=labels[1:], title=title, markers=useMarkers)
1295
+ elif chartType.lower() == "bar":
1296
+ figure = px.bar(dataFrame, x=labels[0], y=labels[1:], title=title)
1297
+ elif chartType.lower() == "scatter":
1298
+ figure = px.scatter(dataFrame, x=labels[0], y=labels[1:], title=title)
1299
+ else:
1300
+ raise NotImplementedError
1301
+
1302
+ layout = {
1303
+ "width": width,
1304
+ "height": height,
1305
+ "title": title,
1306
+ "xaxis": {"title": xTitle, "dtick": xSpacing, 'gridcolor': gridColor},
1307
+ "yaxis": {"title": yTitle, "dtick": ySpacing, 'gridcolor': gridColor},
1308
+ "paper_bgcolor": backgroundColor,
1309
+ "plot_bgcolor": backgroundColor,
1310
+ "margin":dict(l=marginLeft, r=marginRight, t=marginTop, b=marginBottom)
1311
+ }
1312
+ figure.update_layout(layout)
1313
+ return figure
1314
+
1315
+
1316
+ @staticmethod
1317
+ def FigureByData(data, width=950, height=500,
1318
+ xAxis=False, yAxis=False, zAxis=False,
1319
+ axisSize=1, backgroundColor='rgba(0,0,0,0)',
1320
+ marginLeft=0, marginRight=0,
1321
+ marginTop=20, marginBottom=0,
1322
+ tolerance = 0.0001):
1323
+ """
1324
+ Creates a plotly figure.
1325
+
1326
+ Parameters
1327
+ ----------
1328
+ data : list
1329
+ The input list of plotly data.
1330
+ width : int , optional
1331
+ The width in pixels of the figure. The default value is 950.
1332
+ height : int , optional
1333
+ The height in pixels of the figure. The default value is 950.
1334
+ xAxis : bool , optional
1335
+ If set to True the x axis is drawn. Otherwise it is not drawn. The default is False.
1336
+ yAxis : bool , optional
1337
+ If set to True the y axis is drawn. Otherwise it is not drawn. The default is False.
1338
+ zAxis : bool , optional
1339
+ If set to True the z axis is drawn. Otherwise it is not drawn. The default is False.
1340
+ axisSize : float , optional
1341
+ The size of the X, Y, Z, axes. The default is 1.
1342
+ backgroundColor : str , optional
1343
+ The desired color of the background. This can be any plotly color string and may be specified as:
1344
+ - A hex string (e.g. '#ff0000')
1345
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1346
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1347
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1348
+ - A named CSS color.
1349
+ The default is "rgba(0,0,0,0)".
1350
+ marginLeft : int , optional
1351
+ The size in pixels of the left margin. The default value is 0.
1352
+ marginRight : int , optional
1353
+ The size in pixels of the right margin. The default value is 0.
1354
+ marginTop : int , optional
1355
+ The size in pixels of the top margin. The default value is 20.
1356
+ marginBottom : int , optional
1357
+ The size in pixels of the bottom margin. The default value is 0.
1358
+ tolerance : float , optional
1359
+ The desired tolerance. The default is 0.0001.
1360
+
1361
+ Returns
1362
+ -------
1363
+ plotly.graph_objs._figure.Figure
1364
+ The created plotly figure.
1365
+
1366
+ """
1367
+ from topologicpy.Vertex import Vertex
1368
+ from topologicpy.Edge import Edge
1369
+ from topologicpy.Wire import Wire
1370
+ if not isinstance(data, list):
1371
+ return None
1372
+
1373
+ v0 = Vertex.ByCoordinates(0, 0, 0)
1374
+ v1 = Vertex.ByCoordinates(axisSize,0,0)
1375
+ v2 = Vertex.ByCoordinates(0,axisSize,0)
1376
+ v3 = Vertex.ByCoordinates(0,0,axisSize)
1377
+
1378
+ if xAxis:
1379
+ xEdge = Edge.ByVertices([v0,v1], tolerance=tolerance)
1380
+ xData = Plotly.DataByTopology(xEdge, edgeColor="red", edgeWidth=6, showFaces=False, showEdges=True, showVertices=False, edgeLegendLabel="X-Axis")
1381
+ data = data + xData
1382
+ if yAxis:
1383
+ yEdge = Edge.ByVertices([v0,v2], tolerance=tolerance)
1384
+ yData = Plotly.DataByTopology(yEdge, edgeColor="green", edgeWidth=6, showFaces=False, showEdges=True, showVertices=False, edgeLegendLabel="Y-Axis")
1385
+ data = data + yData
1386
+ if zAxis:
1387
+ zEdge = Edge.ByVertices([v0,v3], tolerance=tolerance)
1388
+ zData = Plotly.DataByTopology(zEdge, edgeColor="blue", edgeWidth=6, showFaces=False, showEdges=True, showVertices=False, edgeLegendLabel="Z-Axis")
1389
+ data = data + zData
1390
+
1391
+ figure = go.Figure(data=data)
1392
+ figure.update_layout(
1393
+ width=width,
1394
+ height=height,
1395
+ showlegend=True,
1396
+ scene = dict(
1397
+ xaxis = dict(visible=False),
1398
+ yaxis = dict(visible=False),
1399
+ zaxis =dict(visible=False),
1400
+ ),
1401
+ scene_aspectmode='data',
1402
+ paper_bgcolor=backgroundColor,
1403
+ plot_bgcolor=backgroundColor,
1404
+ margin=dict(l=marginLeft, r=marginRight, t=marginTop, b=marginBottom),
1405
+ )
1406
+ figure.update_xaxes(showgrid=False, zeroline=False, visible=False)
1407
+ figure.update_yaxes(showgrid=False, zeroline=False, visible=False)
1408
+ return figure
1409
+
1410
+ @staticmethod
1411
+ def FigureByJSONFile(file):
1412
+ """
1413
+ Imports a plotly figure from a JSON file.
1414
+
1415
+ Parameters
1416
+ ----------
1417
+ file : file object
1418
+ The JSON file.
1419
+
1420
+ Returns
1421
+ -------
1422
+ plotly.graph_objs._figure.Figure
1423
+ The imported figure.
1424
+
1425
+ """
1426
+ figure = None
1427
+ if not file:
1428
+ return None
1429
+ figure = plotly.io.read_json(file, output_type='Figure', skip_invalid=True, engine=None)
1430
+ file.close()
1431
+ return figure
1432
+
1433
+ @staticmethod
1434
+ def FigureByJSONPath(path):
1435
+ """
1436
+ Imports a plotly figure from a JSON file path.
1437
+
1438
+ Parameters
1439
+ ----------
1440
+ path : str
1441
+ The path to the BRep file.
1442
+
1443
+ Returns
1444
+ -------
1445
+ plotly.graph_objs._figure.Figure
1446
+ The imported figure.
1447
+
1448
+ """
1449
+ if not path:
1450
+ return None
1451
+ try:
1452
+ file = open(path)
1453
+ except:
1454
+ print("Plotly.FigureByJSONPath - Error: the JSON file is not a valid file. Returning None.")
1455
+ return None
1456
+ return Plotly.FigureByJSONFile(file)
1457
+
1458
+ @staticmethod
1459
+ def FigureByPieChart(data, values, names):
1460
+ """
1461
+ Creates a plotly pie chart figure.
1462
+
1463
+ Parameters
1464
+ ----------
1465
+ data : list
1466
+ The input list of plotly data.
1467
+ values : list
1468
+ The input list of values.
1469
+ names : list
1470
+ The input list of names.
1471
+ """
1472
+
1473
+ import plotly.express as px
1474
+ dlist = list(map(list, zip(*data)))
1475
+ df = pd.DataFrame(dlist, columns=data['names'])
1476
+ fig = px.pie(df, values=values, names=names)
1477
+ return fig
1478
+
1479
+ @staticmethod
1480
+ def FigureByTopology(topology,
1481
+ showVertices=True, vertexSize=1.1, vertexColor="black",
1482
+ vertexLabelKey=None, vertexGroupKey=None, vertexGroups=[],
1483
+ vertexMinGroup=None, vertexMaxGroup=None,
1484
+ showVertexLegend=False, vertexLegendLabel="Topology Vertices", vertexLegendRank=1,
1485
+ vertexLegendGroup=1,
1486
+
1487
+ showEdges=True, edgeWidth=1, edgeColor="black",
1488
+ edgeLabelKey=None, edgeGroupKey=None, edgeGroups=[],
1489
+ edgeMinGroup=None, edgeMaxGroup=None,
1490
+ showEdgeLegend=False, edgeLegendLabel="Topology Edges", edgeLegendRank=2,
1491
+ edgeLegendGroup=2,
1492
+
1493
+ showFaces=True, faceOpacity=0.5, faceColor="#FAFAFA",
1494
+ faceLabelKey=None, faceGroupKey=None, faceGroups=[],
1495
+ faceMinGroup=None, faceMaxGroup=None,
1496
+ showFaceLegend=False, faceLegendLabel="Topology Faces", faceLegendRank=3,
1497
+ faceLegendGroup=3,
1498
+ intensityKey=None,
1499
+
1500
+ width=950, height=500,
1501
+ xAxis=False, yAxis=False, zAxis=False, axisSize=1, backgroundColor='rgba(0,0,0,0)',
1502
+ marginLeft=0, marginRight=0, marginTop=20, marginBottom=0, showScale=False,
1503
+
1504
+ cbValues=[], cbTicks=5, cbX=-0.15, cbWidth=15, cbOutlineWidth=0, cbTitle="",
1505
+ cbSubTitle="", cbUnits="", colorScale="Viridis", mantissa=6, tolerance=0.0001):
1506
+ """
1507
+ Creates a figure from the input topology.
1508
+
1509
+ Parameters
1510
+ ----------
1511
+ topology : topologic.Topology
1512
+ The input topology. This must contain faces and or edges.
1513
+
1514
+ showVertices : bool , optional
1515
+ If set to True the vertices will be drawn. Otherwise, they will not be drawn. The default is True.
1516
+ vertexSize : float , optional
1517
+ The desired size of the vertices. The default is 1.1.
1518
+ vertexColor : str , optional
1519
+ The desired color of the output vertices. This can be any plotly color string and may be specified as:
1520
+ - A hex string (e.g. '#ff0000')
1521
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1522
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1523
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1524
+ - A named CSS color.
1525
+ The default is "black".
1526
+ vertexLabelKey : str , optional
1527
+ The dictionary key to use to display the vertex label. The default is None.
1528
+ vertexGroupKey : str , optional
1529
+ The dictionary key to use to display the vertex group. The default is None.
1530
+ vertexGroups : list , optional
1531
+ The list of vertex groups against which to index the color of the vertex. The default is [].
1532
+ vertexMinGroup : int or float , optional
1533
+ For numeric vertexGroups, vertexMinGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the vertexGroupKey. If set to None, it is set to the minimum value in vertexGroups. The default is None.
1534
+ edgeMaxGroup : int or float , optional
1535
+ For numeric vertexGroups, vertexMaxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the vertexGroupKey. If set to None, it is set to the maximum value in vertexGroups. The default is None.
1536
+ showVertexLegend : bool, optional
1537
+ If set to True, the legend for the vertices of this topology is shown. Otherwise, it isn't. The default is False.
1538
+ vertexLegendLabel : str , optional
1539
+ The legend label string used to identify vertices. The default is "Topology Vertices".
1540
+ vertexLegendRank : int , optional
1541
+ The legend rank order of the vertices of this topology. The default is 1.
1542
+ vertexLegendGroup : int , optional
1543
+ The number of the vertex legend group to which the vertices of this topology belong. The default is 1.
1544
+
1545
+ showEdges : bool , optional
1546
+ If set to True the edges will be drawn. Otherwise, they will not be drawn. The default is True.
1547
+ edgeWidth : float , optional
1548
+ The desired thickness of the output edges. The default is 1.
1549
+ edgeColor : str , optional
1550
+ The desired color of the output edges. This can be any plotly color string and may be specified as:
1551
+ - A hex string (e.g. '#ff0000')
1552
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1553
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1554
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1555
+ - A named CSS color.
1556
+ The default is "black".
1557
+ edgeLabelKey : str , optional
1558
+ The dictionary key to use to display the edge label. The default is None.
1559
+ edgeGroupKey : str , optional
1560
+ The dictionary key to use to display the edge group. The default is None.
1561
+ edgeGroups : list , optional
1562
+ The list of edge groups against which to index the color of the edge. The default is [].
1563
+ edgeMinGroup : int or float , optional
1564
+ For numeric edgeGroups, edgeMinGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the edgeGroupKey. If set to None, it is set to the minimum value in edgeGroups. The default is None.
1565
+ edgeMaxGroup : int or float , optional
1566
+ For numeric edgeGroups, edgeMaxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the edgeGroupKey. If set to None, it is set to the maximum value in edgeGroups. The default is None.
1567
+ showEdgeLegend : bool, optional
1568
+ If set to True, the legend for the edges of this topology is shown. Otherwise, it isn't. The default is False.
1569
+ edgeLegendLabel : str , optional
1570
+ The legend label string used to identify edges. The default is "Topology Edges".
1571
+ edgeLegendRank : int , optional
1572
+ The legend rank order of the edges of this topology. The default is 2.
1573
+ edgeLegendGroup : int , optional
1574
+ The number of the edge legend group to which the edges of this topology belong. The default is 2.
1575
+
1576
+ showFaces : bool , optional
1577
+ If set to True the faces will be drawn. Otherwise, they will not be drawn. The default is True.
1578
+ faceOpacity : float , optional
1579
+ The desired opacity of the output faces (0=transparent, 1=opaque). The default is 0.5.
1580
+ faceColor : str , optional
1581
+ The desired color of the output faces. This can be any plotly color string and may be specified as:
1582
+ - A hex string (e.g. '#ff0000')
1583
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1584
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1585
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1586
+ - A named CSS color.
1587
+ The default is "#FAFAFA".
1588
+ faceLabelKey : str , optional
1589
+ The dictionary key to use to display the face label. The default is None.
1590
+ faceGroupKey : str , optional
1591
+ The dictionary key to use to display the face group. The default is None.
1592
+ faceGroups : list , optional
1593
+ The list of face groups against which to index the color of the face. This can bhave numeric or string values. This should match the type of value associated with the faceGroupKey. The default is [].
1594
+ faceMinGroup : int or float , optional
1595
+ For numeric faceGroups, minGroup is the desired minimum value for the scaling of colors. This should match the type of value associated with the faceGroupKey. If set to None, it is set to the minimum value in faceGroups. The default is None.
1596
+ faceMaxGroup : int or float , optional
1597
+ For numeric faceGroups, maxGroup is the desired maximum value for the scaling of colors. This should match the type of value associated with the faceGroupKey. If set to None, it is set to the maximum value in faceGroups. The default is None.
1598
+ showFaceLegend : bool, optional
1599
+ If set to True, the legend for the faces of this topology is shown. Otherwise, it isn't. The default is False.
1600
+ faceLegendLabel : str , optional
1601
+ The legend label string used to idenitfy edges. The default is "Topology Faces".
1602
+ faceLegendRank : int , optional
1603
+ The legend rank order of the faces of this topology. The default is 3.
1604
+ faceLegendGroup : int , optional
1605
+ The number of the face legend group to which the faces of this topology belong. The default is 3.
1606
+ width : int , optional
1607
+ The width in pixels of the figure. The default value is 950.
1608
+ height : int , optional
1609
+ The height in pixels of the figure. The default value is 950.
1610
+ xAxis : bool , optional
1611
+ If set to True the x axis is drawn. Otherwise it is not drawn. The default is False.
1612
+ yAxis : bool , optional
1613
+ If set to True the y axis is drawn. Otherwise it is not drawn. The default is False.
1614
+ zAxis : bool , optional
1615
+ If set to True the z axis is drawn. Otherwise it is not drawn. The default is False.
1616
+ backgroundColor : str , optional
1617
+ The desired color of the background. This can be any plotly color string and may be specified as:
1618
+ - A hex string (e.g. '#ff0000')
1619
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
1620
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1621
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1622
+ - A named CSS color.
1623
+ The default is "rgba(0,0,0,0)".
1624
+ marginLeft : int , optional
1625
+ The size in pixels of the left margin. The default value is 0.
1626
+ marginRight : int , optional
1627
+ The size in pixels of the right margin. The default value is 0.
1628
+ marginTop : int , optional
1629
+ The size in pixels of the top margin. The default value is 20.
1630
+ marginBottom : int , optional
1631
+ The size in pixels of the bottom margin. The default value is 0.
1632
+ camera : list , optional
1633
+ The desired location of the camera). The default is [-1.25, -1.25, 1.25].
1634
+ center : list , optional
1635
+ The desired center (camera target). The default is [0, 0, 0].
1636
+ up : list , optional
1637
+ The desired up vector. The default is [0, 0, 1].
1638
+ renderer : str , optional
1639
+ The desired renderer. See Plotly.Renderers(). The default is "notebook".
1640
+ intensityKey : str , optional
1641
+ If not None, the dictionary of each vertex is searched for the value associated with the intensity key. This value is then used to color-code the vertex based on the colorScale. The default is None.
1642
+ showScale : bool , optional
1643
+ If set to True, the colorbar is shown. The default is False.
1644
+ cbValues : list , optional
1645
+ The input list of values to use for the colorbar. The default is [].
1646
+ cbTicks : int , optional
1647
+ The number of ticks to use on the colorbar. The default is 5.
1648
+ cbX : float , optional
1649
+ The x location of the colorbar. The default is -0.15.
1650
+ cbWidth : int , optional
1651
+ The width in pixels of the colorbar. The default is 15
1652
+ cbOutlineWidth : int , optional
1653
+ The width in pixels of the outline of the colorbar. The default is 0.
1654
+ cbTitle : str , optional
1655
+ The title of the colorbar. The default is "".
1656
+ cbSubTitle : str , optional
1657
+ The subtitle of the colorbar. The default is "".
1658
+ cbUnits: str , optional
1659
+ The units used in the colorbar. The default is ""
1660
+ colorScale : str , optional
1661
+ 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/.
1662
+ mantissa : int , optional
1663
+ The desired length of the mantissa for the values listed on the colorbar. The default is 6.
1664
+ tolerance : float , optional
1665
+ The desired tolerance. The default is 0.0001.
1666
+
1667
+ Returns
1668
+ -------
1669
+ Plotly figure
1670
+
1671
+ """
1672
+ if not isinstance(topology, topologic.Topology):
1673
+ print("Plotly.FigureByTopology - Error: the input topology is not a valid topology. Returning None.")
1674
+ return None
1675
+ data = Plotly.DataByTopology(topology=topology,
1676
+ showVertices=showVertices, vertexSize=vertexSize, vertexColor=vertexColor,
1677
+ vertexLabelKey=vertexLabelKey, vertexGroupKey=vertexGroupKey, vertexGroups=vertexGroups,
1678
+ vertexMinGroup=vertexMinGroup, vertexMaxGroup=vertexMaxGroup,
1679
+ showVertexLegend=showVertexLegend, vertexLegendLabel=vertexLegendLabel, vertexLegendRank=vertexLegendRank,
1680
+ vertexLegendGroup=vertexLegendGroup,
1681
+ showEdges=showEdges, edgeWidth=edgeWidth, edgeColor=edgeColor,
1682
+ edgeLabelKey=edgeLabelKey, edgeGroupKey=edgeGroupKey, edgeGroups=edgeGroups,
1683
+ edgeMinGroup=edgeMinGroup, edgeMaxGroup=edgeMaxGroup,
1684
+ showEdgeLegend=showEdgeLegend, edgeLegendLabel=edgeLegendLabel, edgeLegendRank=edgeLegendRank,
1685
+ edgeLegendGroup=edgeLegendGroup,
1686
+ showFaces=showFaces, faceOpacity=faceOpacity, faceColor=faceColor,
1687
+ faceLabelKey=faceLabelKey, faceGroupKey=faceGroupKey, faceGroups=faceGroups,
1688
+ faceMinGroup=faceMinGroup, faceMaxGroup=faceMaxGroup,
1689
+ showFaceLegend=showFaceLegend, faceLegendLabel=faceLegendLabel, faceLegendRank=faceLegendRank,
1690
+ faceLegendGroup=faceLegendGroup,
1691
+ intensityKey=intensityKey, colorScale=colorScale, tolerance=tolerance)
1692
+ figure = Plotly.FigureByData(data=data, width=width, height=height,
1693
+ xAxis=xAxis, yAxis=yAxis, zAxis=zAxis, axisSize=axisSize,
1694
+ backgroundColor=backgroundColor,
1695
+ marginLeft=marginLeft, marginRight=marginRight,
1696
+ marginTop=marginTop, marginBottom=marginBottom,
1697
+ tolerance=tolerance)
1698
+ if showScale:
1699
+ figure = Plotly.AddColorBar(figure, values=cbValues, nTicks=cbTicks, xPosition=cbX, width=cbWidth, outlineWidth=cbOutlineWidth, title=cbTitle, subTitle=cbSubTitle, units=cbUnits, colorScale=colorScale, mantissa=mantissa)
1700
+ return figure
1701
+
1702
+ @staticmethod
1703
+ def FigureExportToJSON(figure, path, overwrite=False):
1704
+ """
1705
+ Exports the input plotly figure to a JSON file.
1706
+
1707
+ Parameters
1708
+ ----------
1709
+ figure : plotly.graph_objs._figure.Figure
1710
+ The input plotly figure.
1711
+ path : str
1712
+ The input file path.
1713
+ overwrite : bool , optional
1714
+ If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't.
1715
+
1716
+ Returns
1717
+ -------
1718
+ bool
1719
+ True if the export operation is successful. False otherwise.
1720
+
1721
+ """
1722
+ if not isinstance(figure, plotly.graph_objs._figure.Figure):
1723
+ print("Plotly.FigureExportToJSON - Error: The input figure is not a plolty figure. Returning None.")
1724
+ return None
1725
+ if not isinstance(path, str):
1726
+ print("Plotly.FigureExportToJSON - Error: The input path is not a string. Returning None.")
1727
+ return None
1728
+ # Make sure the file extension is .json
1729
+ ext = path[len(path)-5:len(path)]
1730
+ if ext.lower() != ".json":
1731
+ path = path+".json"
1732
+ f = None
1733
+ try:
1734
+ if overwrite == True:
1735
+ f = open(path, "w")
1736
+ else:
1737
+ f = open(path, "x") # Try to create a new File
1738
+ except:
1739
+ print("Plotly.FigureExportToJSON - Error: Could not create a new file at the following location: "+path+". Returning None.")
1740
+ return None
1741
+ if (f):
1742
+ plotly.io.write_json(figure, f, validate=True, pretty=False, remove_uids=True, engine=None)
1743
+ f.close()
1744
+ return True
1745
+ if f:
1746
+ try:
1747
+ f.close()
1748
+ except:
1749
+ pass
1750
+ return False
1751
+
1752
+ @staticmethod
1753
+ def FigureExportToPDF(figure, path, width=1920, height=1200, overwrite=False):
1754
+ """
1755
+ Exports the input plotly figure to a PDF file.
1756
+
1757
+ Parameters
1758
+ ----------
1759
+ figure : plotly.graph_objs._figure.Figure
1760
+ The input plotly figure.
1761
+ path : str
1762
+ The input file path.
1763
+ width : int, optional
1764
+ The width of the exported image in pixels. The default is 1920.
1765
+ height : int , optional
1766
+ The height of the exported image in pixels. The default is 1200.
1767
+ overwrite : bool , optional
1768
+ If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't.
1769
+
1770
+ Returns
1771
+ -------
1772
+ bool
1773
+ True if the export operation is successful. False otherwise.
1774
+
1775
+ """
1776
+ import os
1777
+ if not isinstance(figure, plotly.graph_objs._figure.Figure):
1778
+ print("Plotly.FigureExportToPNG - Error: The input figure is not a plolty figure. Returning None.")
1779
+ return None
1780
+ if not isinstance(path, str):
1781
+ print("Plotly.FigureExportToPNG - Error: The input path is not a string. Returning None.")
1782
+ return None
1783
+ # Make sure the file extension is .pdf
1784
+ ext = path[len(path)-4:len(path)]
1785
+ if ext.lower() != ".pdf":
1786
+ path = path+".pdf"
1787
+
1788
+ if overwrite == False and os.path.exists(path):
1789
+ print("Plotly.FigureExportToPDF - Error: A file already exists at this location and overwrite is set to False. Returning None.")
1790
+ return None
1791
+
1792
+ plotly.io.write_image(figure, path, format='pdf', scale=1, width=width, height=height, validate=True, engine='auto')
1793
+ return True
1794
+
1795
+ @staticmethod
1796
+ def FigureExportToPNG(figure, path, width=1920, height=1200, overwrite=False):
1797
+ """
1798
+ Exports the input plotly figure to a PNG file.
1799
+
1800
+ Parameters
1801
+ ----------
1802
+ figure : plotly.graph_objs._figure.Figure
1803
+ The input plotly figure.
1804
+ path : str
1805
+ The input file path.
1806
+ width : int, optional
1807
+ The width of the exported image in pixels. The default is 1920.
1808
+ height : int , optional
1809
+ The height of the exported image in pixels. The default is 1200.
1810
+ overwrite : bool , optional
1811
+ If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't.
1812
+
1813
+ Returns
1814
+ -------
1815
+ bool
1816
+ True if the export operation is successful. False otherwise.
1817
+
1818
+ """
1819
+ import os
1820
+ if not isinstance(figure, plotly.graph_objs._figure.Figure):
1821
+ print("Plotly.FigureExportToPNG - Error: The input figure is not a plolty figure. Returning None.")
1822
+ return None
1823
+ if not isinstance(path, str):
1824
+ print("Plotly.FigureExportToPNG - Error: The input path is not a string. Returning None.")
1825
+ return None
1826
+ # Make sure the file extension is .png
1827
+ ext = path[len(path)-4:len(path)]
1828
+ if ext.lower() != ".png":
1829
+ path = path+".png"
1830
+
1831
+ if overwrite == False and os.path.exists(path):
1832
+ print("Plotly.FigureExportToPNG - Error: A file already exists at this location and overwrite is set to False. Returning None.")
1833
+ return None
1834
+
1835
+ plotly.io.write_image(figure, path, format='png', scale=1, width=width, height=height, validate=True, engine='auto')
1836
+ return True
1837
+
1838
+ @staticmethod
1839
+ def FigureExportToSVG(figure, path, width=1920, height=1200, overwrite=False):
1840
+ """
1841
+ Exports the input plotly figure to a SVG file.
1842
+
1843
+ Parameters
1844
+ ----------
1845
+ figure : plotly.graph_objs._figure.Figure
1846
+ The input plotly figure.
1847
+ path : str
1848
+ The input file path.
1849
+ width : int, optional
1850
+ The width of the exported image in pixels. The default is 1920.
1851
+ height : int , optional
1852
+ The height of the exported image in pixels. The default is 1200.
1853
+ overwrite : bool , optional
1854
+ If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't.
1855
+
1856
+ Returns
1857
+ -------
1858
+ bool
1859
+ True if the export operation is successful. False otherwise.
1860
+
1861
+ """
1862
+ import os
1863
+ if not isinstance(figure, plotly.graph_objs._figure.Figure):
1864
+ print("Plotly.FigureExportToSVG - Error: The input figure is not a plolty figure. Returning None.")
1865
+ return None
1866
+ if not isinstance(path, str):
1867
+ print("Plotly.FigureExportToSVG - Error: The input path is not a string. Returning None.")
1868
+ return None
1869
+ # Make sure the file extension is .svg
1870
+ ext = path[len(path)-4:len(path)]
1871
+ if ext.lower() != ".svg":
1872
+ path = path+".svg"
1873
+
1874
+ if overwrite == False and os.path.exists(path):
1875
+ print("Plotly.FigureExportToSVG - Error: A file already exists at this location and overwrite is set to False. Returning None.")
1876
+ return None
1877
+
1878
+ plotly.io.write_image(figure, path, format='svg', scale=1, width=width, height=height, validate=True, engine='auto')
1879
+ return True
1880
+
1881
+ @staticmethod
1882
+ def SetCamera(figure, camera=[-1.25, -1.25, 1.25], center=[0, 0, 0], up=[0, 0, 1], projection="perspective"):
1883
+ """
1884
+ Sets the camera for the input figure.
1885
+
1886
+ Parameters
1887
+ ----------
1888
+ figure : plotly.graph_objs._figure.Figure
1889
+ The input plotly figure.
1890
+ camera : list , optional
1891
+ The desired location of the camera. The default is [-1.25, -1.25, 1.25].
1892
+ center : list , optional
1893
+ The desired center (camera target). The default is [0, 0, 0].
1894
+ up : list , optional
1895
+ The desired up vector. The default is [0, 0, 1].
1896
+ projection : str , optional
1897
+ The desired type of projection. The options are "orthographic" or "perspective". It is case insensitive. The default is "perspective"
1898
+
1899
+ Returns
1900
+ -------
1901
+ plotly.graph_objs._figure.Figure
1902
+ The updated figure
1903
+
1904
+ """
1905
+ if not isinstance(camera, list):
1906
+ camera = [-1.25, -1.25, 1.25]
1907
+ if not isinstance(center, list):
1908
+ center = [0, 0, 0]
1909
+ if not isinstance(up, list):
1910
+ up = [0, 0, 1]
1911
+ projection = projection.lower()
1912
+ if projection in "orthographic":
1913
+ projection = "orthographic"
1914
+ else:
1915
+ projection = "perspective"
1916
+ scene_camera = dict(
1917
+ up=dict(x=up[0], y=up[1], z=up[2]),
1918
+ eye=dict(x=camera[0], y=camera[1], z=camera[2]),
1919
+ center=dict(x=center[0], y=center[1], z=center[2]),
1920
+ projection=dict(type=projection)
1921
+ )
1922
+ figure.update_layout(scene_camera=scene_camera)
1923
+ return figure
1924
+
1925
+ @staticmethod
1926
+ def Show(figure, camera=[-1.25, -1.25, 1.25], center=[0, 0, 0], up=[0, 0, 1], renderer="notebook", projection="perspective"):
1927
+ """
1928
+ Shows the input figure.
1929
+
1930
+ Parameters
1931
+ ----------
1932
+ figure : plotly.graph_objs._figure.Figure
1933
+ The input plotly figure.
1934
+ camera : list , optional
1935
+ The desired location of the camera. The default is [0, 0, 0].
1936
+ center : list , optional
1937
+ The desired center (camera target). The default is [0, 0, 0].
1938
+ up : list , optional
1939
+ The desired up vector. The default is [0, 0, 1].
1940
+ renderer : str , optional
1941
+ The desired rendered. See Plotly.Renderers(). The default is "notebook".
1942
+ projection : str, optional
1943
+ The desired type of projection. The options are "orthographic" or "perspective". It is case insensitive. The default is "perspective"
1944
+
1945
+
1946
+ Returns
1947
+ -------
1948
+ None
1949
+
1950
+ """
1951
+ if figure == None:
1952
+ print("Plotly.Show - Error: The input is NULL. Returning None.")
1953
+ return None
1954
+ if not isinstance(figure, plotly.graph_objs._figure.Figure):
1955
+ print("Plotly.Show - Error: The input is not a figure. Returning None.")
1956
+ return None
1957
+ if not renderer.lower() in Plotly.Renderers():
1958
+ print("Plotly.Show - Error: The input renderer is not in the approved list of renderers. Returning None.")
1959
+ return None
1960
+ if not camera == None and not center == None and not up == None:
1961
+ figure = Plotly.SetCamera(figure, camera=camera, center=center, up=up, projection=projection)
1962
+ if renderer.lower() == "offline":
1963
+ ofl.plot(figure)
1964
+ else:
1965
+ figure.show(renderer=renderer)
1966
+ return None
1967
+
1968
+ @staticmethod
1969
+ def Renderers():
1970
+ """
1971
+ Returns a list of the available plotly renderers.
1972
+
1973
+ Parameters
1974
+ ----------
1975
+
1976
+ Returns
1977
+ -------
1978
+ list
1979
+ The list of the available plotly renderers.
1980
+
1981
+ """
1982
+ return ['plotly_mimetype', 'jupyterlab', 'nteract', 'vscode',
1983
+ 'notebook', 'notebook_connected', 'kaggle', 'azure', 'colab',
1984
+ 'cocalc', 'databricks', 'json', 'png', 'jpeg', 'jpg', 'svg',
1985
+ 'pdf', 'browser', 'firefox', 'chrome', 'chromium', 'iframe',
1986
+ 'iframe_connected', 'sphinx_gallery', 'sphinx_gallery_png', 'offline']
1987
+
1988
+ @staticmethod
1989
+ def ExportToImage(figure, path, format="png", width="1920", height="1080"):
1990
+ """
1991
+ Exports the plotly figure to an image.
1992
+
1993
+ Parameters
1994
+ ----------
1995
+ figure : plotly.graph_objs._figure.Figure
1996
+ The input plotly figure.
1997
+ path : str
1998
+ The image file path.
1999
+ format : str , optional
2000
+ The desired format. This can be any of "jpg", "jpeg", "pdf", "png", "svg", or "webp". It is case insensitive. The default is "png".
2001
+ width : int , optional
2002
+ The width in pixels of the figure. The default value is 1920.
2003
+ height : int , optional
2004
+ The height in pixels of the figure. The default value is 1080.
2005
+
2006
+ Returns
2007
+ -------
2008
+ bool
2009
+ True if the image was exported sucessfully. False otherwise.
2010
+
2011
+ """
2012
+ if not isinstance(figure, plotly.graph_objs._figure.Figure):
2013
+ return None
2014
+ if not isinstance(path, str):
2015
+ return None
2016
+ if not format.lower() in ["jpg", "jpeg", "pdf", "png", "svg", "webp"]:
2017
+ return None
2018
+ returnStatus = False
2019
+ try:
2020
+ plotly.io.write_image(figure, path, format=format.lower(), scale=None, width=width, height=height, validate=True, engine='auto')
2021
+ returnStatus = True
2022
+ except:
2023
+ returnStatus = False
2024
+ return returnStatus
2025
+