visnetmap 0.1.0__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.
vistNETmap/visNM.py ADDED
@@ -0,0 +1,257 @@
1
+
2
+ from base_modes.network_visual_save_base import *
3
+ from base_modes.netmap_base import *
4
+
5
+
6
+ def remove_duplicate_dicts(dict_list):
7
+ """Remove duplicate dictionaries (deep equality) while preserving order."""
8
+ seen = set()
9
+ unique_list = []
10
+ for d in dict_list:
11
+ # Convert dict (with nested objects) to a JSON string so it's hashable
12
+ key = json.dumps(d, sort_keys=True)
13
+ if key not in seen:
14
+ seen.add(key)
15
+ unique_list.append(d)
16
+ return unique_list
17
+
18
+
19
+
20
+
21
+
22
+
23
+ def visNET(nodes,edges,network_title='Atsaniik Network', browserView=True, writeHTML='atsaniik_newtork.html', description_df=None, description_title='Peng Atsaniik', min_default_node_size=1, min_default_edge_width=0, maximum_display=20):
24
+
25
+ """ visualize your network with a save button to export selected nodes and edges to JSON files
26
+ Args:
27
+ nodes(Dataframe or List of dict): list of nodes dict e.g. {"id": 1, "label": "Start", "size": 30, "color": "red-spain", "shape": "dot-america", "title": "starting the point"}
28
+ if the shape is image should be converted to base64 through base64_from_loc(image_local_address) or base64_from_url(image_url)
29
+ edges(Dataframe or List of dict): list of edges dict e.g. {"from": 1, "to": 3, "width": 4, "color": {"color": "#C70039-europe"}, "arrows": "to", "title": "from 1 to 3"}
30
+ description_df(dataframe): a dataframe with columns "Name", "Description"
31
+ description_title(str): describe your network in short
32
+ writeHTML(str): output HTML file name
33
+ browserView(bool): whether to open the HTML in a browser
34
+ min_default_node_size(float): minimum node size for initial display
35
+ min_default_edge_width(float): minimum edge width for initial display
36
+ maximum_display(int): maximum number of nodes to display at any time
37
+ """
38
+
39
+
40
+
41
+
42
+
43
+ if isinstance(nodes, pd.DataFrame) and isinstance(edges, pd.DataFrame):
44
+
45
+ # Function to remove keys with NaN values
46
+ def clean_dict(d):
47
+ return {k: v for k, v in d.items() if not (isinstance(v, float) and pd.isna(v))}
48
+
49
+ # Convert back to list of dicts and remove NaN key-value pairs
50
+ nodes = [clean_dict(row) for row in nodes.to_dict(orient="records")]
51
+
52
+ edges = [clean_dict(row) for row in edges.to_dict(orient="records")]
53
+
54
+
55
+
56
+ elif (isinstance(nodes, list) and all(isinstance(i, dict) for i in nodes)
57
+ and isinstance(edges, list) and all(isinstance(i, dict) for i in edges)):
58
+ nodes = nodes
59
+ edges = edges
60
+
61
+
62
+ else:
63
+ print("Nodes and Edges Should be either dataframe or list of dicts in the recommended format")
64
+
65
+
66
+
67
+
68
+
69
+ nodeIDchecks = []
70
+ for node in nodes:
71
+ nodeIDcheck = node['id']
72
+ nodeIDchecks.append(nodeIDcheck)
73
+ missingNodes = []
74
+ for edge in edges:
75
+ edgeIDcheck = [edge['from'], edge['to']]
76
+ missingNode = [{"id": x} for x in edgeIDcheck if x not in nodeIDchecks]
77
+ if len(missingNode)>0:
78
+ print(f'edge {edge['from']}-{edge['to']} missing nodes description: {missingNode}')
79
+ missingNodes.extend(missingNode)
80
+
81
+ nodes_list1 = nodes + missingNodes
82
+
83
+ nodes_list1 = remove_duplicate_dicts(nodes_list1)
84
+ nodes_list1
85
+
86
+ visnet(nodes_list1, edges, network_title=network_title,description_df=description_df, description_title=description_title, browserView= browserView, writeHTML=writeHTML, min_default_node_size= min_default_node_size, min_default_edge_width=min_default_edge_width, maximum_display=maximum_display)
87
+
88
+ def mapNET(nodes,edges, title="net map", output_html_file='simple.html', maximum_nodes=2):
89
+ """
90
+ nodes (dataframe or list of dicts): {
91
+ "node": "New York", "lat": 40.7128, "lon": -74.0060, "size": 15,
92
+ "color": "red", "shape": "circle", "node_hover": "The Big Apple, USA"
93
+ }, # shape: circle, triangle, square, star
94
+ edges (dataframe or list of dicts): {
95
+ "node1": "New York", "node2": "Paris", "color": "darkblue", "width": 2,
96
+ "style": "dashed", "arrow": False, "curve": True,
97
+ "edge_hover": any text e.g. "Transatlantic flight"
98
+ "default_size": node size 5
99
+ },
100
+ maximum_nodes: maximum nodes to display initially
101
+ """
102
+
103
+
104
+
105
+
106
+ if isinstance(nodes, pd.DataFrame) and isinstance(edges, pd.DataFrame):
107
+
108
+ # Function to remove keys with NaN values
109
+ def clean_dict(d):
110
+ return {k: v for k, v in d.items() if not (isinstance(v, float) and pd.isna(v))}
111
+
112
+ # Convert back to list of dicts and remove NaN key-value pairs
113
+ nodes = [clean_dict(row) for row in nodes.to_dict(orient="records")]
114
+
115
+ edges = [clean_dict(row) for row in edges.to_dict(orient="records")]
116
+
117
+
118
+
119
+ elif (isinstance(nodes, list) and all(isinstance(i, dict) for i in nodes)
120
+ and isinstance(edges, list) and all(isinstance(i, dict) for i in edges)):
121
+ nodes = nodes
122
+ edges = edges
123
+
124
+
125
+ else:
126
+ print("Nodes and Edges Should be either dataframe or list of dicts in the recommended format")
127
+
128
+
129
+
130
+ netmap(nodes, edges, title=title, output_html_file=output_html_file, maximum_nodes=maximum_nodes)
131
+
132
+
133
+ if __name__ == "__main__":
134
+ gipuzkoa_path = "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/Escudo_de_Donostia.svg/800px-Escudo_de_Donostia.svg.png"
135
+ turku_path = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d7/Turku.vaakuna.svg/800px-Turku.vaakuna.svg.png"
136
+
137
+ turku_path2 = r"C:\PhDDocs\pythonPhD\pyBase4All\hyperlinks_scrape\scrapper\network_visual\network_visual\Turku.vaakuna.png"
138
+ gipuzkoa_path2 = r"C:\PhDDocs\pythonPhD\pyBase4All\hyperlinks_scrape\scrapper\network_visual\network_visual\Escudo_de_Donostia.png"
139
+
140
+ turku_img64 = base64_from_loc(turku_path2)
141
+ gipuzkoa_img64 = base64_from_loc(gipuzkoa_path2 )
142
+
143
+ nodes = [
144
+ {"id": 1, "label": "Start", "size": 9, "color": "red-spain", "shape": "dot", "title": "starting the point"},
145
+ {"id": 2, "label": "Process A", "size": 25, "color": "#33FF57-france", "shape": "triangle", "title": "process one"},
146
+ {"id": 3, "label": "Process B", "size": 40, "color": "#3357FF-france", "shape": "box-canada", "title": "process two"},
147
+ {"id": 4, "label": "Critical", "size": 35, "color": "#FFBD33-japan", "shape": "star-asia", "title": "critical point"},
148
+ {"id": 5, "label": "User", "size": 45, "color": "#8D33FF-germany", "shape": "icon-africa",
149
+ "icon": {"face": '"Font Awesome 5 Free"', "code": "\uf007", "size": 50, "color": "#8D33FF-germany"}},
150
+ {"id": 6, "label": "Info A", "size": 48, "color": "#33B5E5-canada", "shape": "icon-africa",
151
+ "icon": {"face": "Font Awesome 5 Brands", "code": "\uf007", "size": 40, "color": "#33B5E5-canada"}},
152
+ {"id": 7, "label": "Image Node A ", "size": 15, "shape": "image-gipuzkoa", "image": gipuzkoa_img64, "color": "#33B5E7-gipuzkoa"},
153
+ {"id": 8, "label": "Gogo", "size": 30, "color": "#FF5733-italy", "shape": "dot", "title": "I am so Alone"},
154
+ {"id": 9, "label": "comecome", "size": 8, "color": "#FF5733-italy", "shape": "dot", "title": "I am so Alone"},
155
+ {"id": 10, "label": "Image Node B", "size": 15, "shape": "image-gipuzkoa", "image": gipuzkoa_img64, "color": "#33B5E7-gipuzkoa"},
156
+ {"id": 11, "label": "Info B", "size": 48, "color": "#33B5E5-canada", "shape": "icon-australia",
157
+ "icon": {"face": "Font Awesome 5 Brands", "code": "\uf05a", "size": 40, "color": "#33B5E5-canada"}},
158
+ {"id": 12, "label": "turku", "size": 15, "shape": "image-turku", "image": turku_img64, "color": "#33B5E6-turku"},
159
+ {"id": 13, "label": "dict", "size": 9, "color": {"background": "yellow-Finland", "border": "green"}, "shape": "dot", "title": "starting the point"},
160
+ {"id":'abcdefg',"label":"abcdefg-label",'shape':'square','size':50},
161
+
162
+ ]
163
+
164
+ edges = [
165
+ {"from": 1, "to": 3, "width": 1, "color": {"color": "#C70039-europe"}, "arrows": "to", "title": "from 1 to 3"},
166
+ {"from": 1, "to": 2, "width": 2, "color": {"color": "#C70038-africa"}},
167
+ {"from": 2, "to": 4, "width": 3, "color": {"color": "#581845-africa"}, "arrows": "to", "dashes": True},
168
+ {"from": 2, "to": 5, "width": 4, "color": {"color": "#FFC300-australia"}, "arrows": "to", "smooth": {"type": "curvedCW"}},
169
+ {"from": 3, "to": 3, "width": 5, "color": {"color": "#DAF7A6-america"}, "arrows": "to"},
170
+ {"from": 4, "to": 6, "width": 6, "color": {"color": "#4CAF50-europe"}, "arrows": "to", "smooth": {"type": "curvedCCW"}},
171
+ {"from": 5, "to": 1, "width": 7, "color": {"color": "#2196F3-asia"}, "arrows": "to", "dashes": True},
172
+ {"from": 7, "to": 1, "width": 8, "color": {"color": "#FF00FF-africa"}, "arrows": "to"},
173
+ {"from":14,"to":13}
174
+ ]
175
+ visNET(nodes, edges, network_title='small Network', browserView=True, writeHTML='test_small.html', min_default_node_size=1, min_default_edge_width=0, maximum_display=10)
176
+
177
+
178
+ cities = [
179
+ {"node": "rovaniemi,finland"},
180
+ {
181
+ 'node': 'eventti.net',
182
+ 'lat': 60.1497055,
183
+ 'lon': 24.7376876,
184
+ 'size': 10,
185
+ 'color': 'blue',
186
+ 'shape': 'circle',
187
+ 'node_hover': 'eventti.net'
188
+ },
189
+ {
190
+ "node": "New York", "lat": 40.7128, "lon": -74.0060, "size": 15,
191
+ "color": "red", "shape": "circle", "node_hover": "The Big Apple, USA"
192
+ },
193
+ {
194
+ "node": "London", "lat": 51.5074, "lon": -0.1278, "size": 12,
195
+ "color": "blue", "shape": "star", "node_hover": "Capital of the UK"
196
+ },
197
+ {
198
+ "node": "Tokyo", "lat": 35.6762, "lon": 139.6503, "size": 10,
199
+ "color": "green", "shape": "square", "node_hover": "Capital of Japan"
200
+ },
201
+ {
202
+ "node": "Sydney", "lat": -33.8688, "lon": 151.2093, "size": 8,
203
+ "color": "purple", "shape": "circle", "node_hover": "Australia’s coastal gem"
204
+ },
205
+ {
206
+ "node": "Paris", "lat": 48.8566, "lon": 2.3522, "size": 11,
207
+ "color": "orange", "shape": "star", "node_hover": "City of Love"
208
+ },
209
+ ]
210
+
211
+ connections = [
212
+ {
213
+ "node1": "rovaniemi,finland", "node2": "eventti.net"
214
+ },
215
+ {
216
+ "node1": "New York", "node2": "London", "color": "black", "width": 2,
217
+ "style": "solid", "arrow": True, "curve": False,
218
+ "edge_hover": "Flight from NY to London"
219
+ },
220
+ {
221
+ "node1": "Tokyo", "node2": "London", "color": "black", "width": 2,
222
+ "style": "solid", "arrow": True, "curve": False,
223
+ "edge_hover": "Flight tokyo to London"
224
+ },
225
+ {
226
+ "node1": "London", "node2": "Tokyo", "color": "blue", "width": 3,
227
+ "style": "solid", "arrow": True, "curve": False,
228
+ "edge_hover": "From London to Tokyo"
229
+ },
230
+ {
231
+ "node1": "Tokyo", "node2": "rovaniemi,finland", "color": "red", "width": 10,
232
+ "style": "dashed", "arrow": True, "curve": True,
233
+ "edge_hover": "From Tokyo to Rovaniemi"
234
+ },
235
+ {
236
+ "node1": "Tokyo", "node2": "Sydney", "color": "blue", "width": 1,
237
+ "style": "solid", "arrow": True, "curve": False,
238
+ "edge_hover": "Trade route Tokyo ↔ Sydney"
239
+ },
240
+ {
241
+ "node1": "Sydney", "node2": "New York", "color": "green", "width": 12,
242
+ "style": "solid", "arrow": True, "curve": True,
243
+ "edge_hover": "Tourist route Sydney–NY"
244
+ },
245
+ {
246
+ "node1": "London", "node2": "Paris", "color": "brown", "width": 4,
247
+ "style": "solid", "arrow": True, "curve": False,
248
+ "edge_hover": "Eurostar connection"
249
+ },
250
+ {
251
+ "node1": "New York", "node2": "Paris", "color": "darkblue", "width": 2,
252
+ "style": "dashed", "arrow": False, "curve": False,
253
+ "edge_hover": "Transatlantic flight"
254
+ },
255
+ ]
256
+
257
+ mapNET(cities, connections, title="net map", output_html_file='simple.html', maximum_nodes=2)