d3graph 2.7.0__tar.gz → 2.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {d3graph-2.7.0/d3graph.egg-info → d3graph-2.8.0}/PKG-INFO +2 -2
- {d3graph-2.7.0 → d3graph-2.8.0}/d3graph/__init__.py +6 -4
- {d3graph-2.7.0 → d3graph-2.8.0}/d3graph/d3graph.py +148 -65
- d3graph-2.8.0/d3graph/d3js/d3graphscript.js +540 -0
- {d3graph-2.7.0 → d3graph-2.8.0}/d3graph/d3js/index.html.j2 +2 -1
- {d3graph-2.7.0 → d3graph-2.8.0}/d3graph/d3js/style.css +7 -2
- {d3graph-2.7.0 → d3graph-2.8.0}/d3graph/examples.py +80 -1
- {d3graph-2.7.0 → d3graph-2.8.0/d3graph.egg-info}/PKG-INFO +2 -2
- {d3graph-2.7.0 → d3graph-2.8.0}/d3graph.egg-info/requires.txt +1 -1
- {d3graph-2.7.0 → d3graph-2.8.0}/pyproject.toml +1 -1
- d3graph-2.7.0/d3graph/d3js/d3graphscript.js +0 -361
- {d3graph-2.7.0 → d3graph-2.8.0}/LICENSE +0 -0
- {d3graph-2.7.0 → d3graph-2.8.0}/MANIFEST.in +0 -0
- {d3graph-2.7.0 → d3graph-2.8.0}/README.md +0 -0
- {d3graph-2.7.0 → d3graph-2.8.0}/d3graph/d3js/d3.v3.js +0 -0
- {d3graph-2.7.0 → d3graph-2.8.0}/d3graph/examples_docs.py +0 -0
- {d3graph-2.7.0 → d3graph-2.8.0}/d3graph.egg-info/SOURCES.txt +0 -0
- {d3graph-2.7.0 → d3graph-2.8.0}/d3graph.egg-info/dependency_links.txt +0 -0
- {d3graph-2.7.0 → d3graph-2.8.0}/d3graph.egg-info/top_level.txt +0 -0
- {d3graph-2.7.0 → d3graph-2.8.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: d3graph
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.8.0
|
|
4
4
|
Summary: Python package to create interactive network based on d3js.
|
|
5
5
|
Author-email: Erdogan Taskesen <erdogant@gmail.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -24,7 +24,7 @@ Requires-Dist: networkx>2
|
|
|
24
24
|
Requires-Dist: ismember
|
|
25
25
|
Requires-Dist: jinja2
|
|
26
26
|
Requires-Dist: packaging
|
|
27
|
-
Requires-Dist: markupsafe
|
|
27
|
+
Requires-Dist: markupsafe
|
|
28
28
|
Requires-Dist: python-louvain
|
|
29
29
|
Requires-Dist: datazets
|
|
30
30
|
Dynamic: license-file
|
|
@@ -11,11 +11,13 @@ from d3graph.d3graph import (
|
|
|
11
11
|
adjmat2dict,
|
|
12
12
|
data_checks,
|
|
13
13
|
check_logger,
|
|
14
|
+
get_hex_color,
|
|
15
|
+
import_example,
|
|
14
16
|
)
|
|
15
17
|
|
|
16
18
|
__author__ = 'Erdogan Tasksen'
|
|
17
19
|
__email__ = 'erdogant@gmail.com'
|
|
18
|
-
__version__ = '2.
|
|
20
|
+
__version__ = '2.8.0'
|
|
19
21
|
|
|
20
22
|
# Setup root logger
|
|
21
23
|
_logger = logging.getLogger('d3graph')
|
|
@@ -39,13 +41,13 @@ The ouput is a html file that is interactive and stand alone.
|
|
|
39
41
|
|
|
40
42
|
Examples
|
|
41
43
|
--------
|
|
42
|
-
>>> from d3graph import d3graph, vec2adjmat
|
|
44
|
+
>>> from d3graph import d3graph, vec2adjmat, import_example
|
|
43
45
|
>>>
|
|
44
46
|
>>> # Initialize
|
|
45
47
|
>>> d3 = d3graph()
|
|
46
48
|
>>>
|
|
47
49
|
>>> # Load karate example
|
|
48
|
-
>>> df =
|
|
50
|
+
>>> df = import_example('energy')
|
|
49
51
|
>>> adjmat = vec2adjmat(source=df['source'], target=df['target'], weight=df['weight'])
|
|
50
52
|
>>>
|
|
51
53
|
>>> # Initialize
|
|
@@ -58,7 +60,7 @@ Examples
|
|
|
58
60
|
>>> d3.set_edge_properties(directed=True)
|
|
59
61
|
>>>
|
|
60
62
|
>>> # Plot
|
|
61
|
-
>>> d3.show()
|
|
63
|
+
>>> d3.show(node_text_inside=True)
|
|
62
64
|
|
|
63
65
|
References
|
|
64
66
|
----------
|
|
@@ -21,6 +21,7 @@ import colourmap as cm
|
|
|
21
21
|
import networkx as nx
|
|
22
22
|
import numpy as np
|
|
23
23
|
import pandas as pd
|
|
24
|
+
from pandas.arrays import StringArray
|
|
24
25
|
from ismember import ismember
|
|
25
26
|
from jinja2 import Environment, PackageLoader
|
|
26
27
|
from packaging import version
|
|
@@ -119,6 +120,7 @@ class d3graph:
|
|
|
119
120
|
save_button: bool = True,
|
|
120
121
|
link_tension: float = None,
|
|
121
122
|
sticky: bool = None,
|
|
123
|
+
node_text_inside: bool = False,
|
|
122
124
|
) -> None:
|
|
123
125
|
"""Build and show the graph.
|
|
124
126
|
|
|
@@ -185,6 +187,8 @@ class d3graph:
|
|
|
185
187
|
self.config['save_button'] = save_button
|
|
186
188
|
self.config['background_color'] = background_color
|
|
187
189
|
self.config['dark_mode'] = dark_mode
|
|
190
|
+
self.config['node_text_inside'] = node_text_inside
|
|
191
|
+
|
|
188
192
|
# Allow show() to override the link_tension set at __init__ time
|
|
189
193
|
if link_tension is not None:
|
|
190
194
|
self.config['link_tension'] = link_tension
|
|
@@ -192,7 +196,8 @@ class d3graph:
|
|
|
192
196
|
if sticky is not None:
|
|
193
197
|
self.config['sticky'] = sticky
|
|
194
198
|
# if self.config.get('filepath', None) != 'd3graph.html':
|
|
195
|
-
self.config
|
|
199
|
+
if filepath is not None or self.config.get('filepath') is None:
|
|
200
|
+
self.set_path(filepath)
|
|
196
201
|
|
|
197
202
|
# Create dataframe from co-occurrence matrix
|
|
198
203
|
self.G = make_graph(self.node_properties, self.edge_properties)
|
|
@@ -394,7 +399,8 @@ class d3graph:
|
|
|
394
399
|
* ['label 1','label 2','label 3', ...]
|
|
395
400
|
marker : list of markers (default: 'circle')
|
|
396
401
|
The marker that is used for the Node.
|
|
397
|
-
*
|
|
402
|
+
* 'circle' or 'hexagon' etc
|
|
403
|
+
* ['circle', 'star', 'diamond', 'square', 'pentagon', 'hexagon', 'rectangle', 'triangle-down', 'triangle']
|
|
398
404
|
tooltip : list of names (default: None)
|
|
399
405
|
The text that is shown when hovering over the Node.
|
|
400
406
|
If not specified, the text will inherit from the label.
|
|
@@ -480,13 +486,13 @@ class d3graph:
|
|
|
480
486
|
nodecount = self.adjmat.shape[0]
|
|
481
487
|
group = np.zeros_like(node_names).astype(int)
|
|
482
488
|
# Check validity of color.
|
|
483
|
-
_check_hex_color(color, nodecount)
|
|
489
|
+
color = _check_hex_color(color, nodecount, cmap=cmap)
|
|
484
490
|
# Store in config
|
|
485
491
|
self.config['cmap'] = 'Paired' if cmap is None else cmap
|
|
486
492
|
self.config['node_scaler'] = scaler
|
|
487
493
|
|
|
488
494
|
# ############ Set node label #############
|
|
489
|
-
if isinstance(label, list):
|
|
495
|
+
if isinstance(label, (list, np.ndarray, pd.Series, pd.Series, StringArray)):
|
|
490
496
|
label = np.array(label).astype(str)
|
|
491
497
|
elif 'numpy' in str(type(label)):
|
|
492
498
|
pass
|
|
@@ -499,7 +505,7 @@ class d3graph:
|
|
|
499
505
|
if len(label) != nodecount: raise ValueError("[label] must be of same length as the number of nodes")
|
|
500
506
|
|
|
501
507
|
# ############ tooltip text #############
|
|
502
|
-
if isinstance(tooltip, list):
|
|
508
|
+
if isinstance(tooltip, (list, np.ndarray, pd.Series, StringArray)):
|
|
503
509
|
tooltip = np.array(tooltip).astype(str)
|
|
504
510
|
elif 'numpy' in str(type(tooltip)):
|
|
505
511
|
pass
|
|
@@ -512,7 +518,7 @@ class d3graph:
|
|
|
512
518
|
if len(tooltip) != nodecount: raise ValueError("[tooltip text] must be of same length as the number of nodes")
|
|
513
519
|
|
|
514
520
|
# ############ Set node color #############
|
|
515
|
-
if isinstance(color, list) and len(color) == nodecount:
|
|
521
|
+
if isinstance(color, (list, np.ndarray, pd.Series, StringArray)) and len(color) == nodecount:
|
|
516
522
|
color = np.array(color)
|
|
517
523
|
elif 'numpy' in str(type(color)):
|
|
518
524
|
color = _get_hexcolor(color, cmap=self.config['cmap'])
|
|
@@ -542,7 +548,7 @@ class d3graph:
|
|
|
542
548
|
fontsize = _set_node_fontsize(self, fontsize, nodecount)
|
|
543
549
|
|
|
544
550
|
# ########## Set node color edge #############
|
|
545
|
-
if isinstance(edge_color, list):
|
|
551
|
+
if isinstance(edge_color, (list, np.ndarray, pd.Series, StringArray)):
|
|
546
552
|
edge_color = np.array(edge_color)
|
|
547
553
|
elif 'numpy' in str(type(edge_color)):
|
|
548
554
|
pass
|
|
@@ -574,7 +580,7 @@ class d3graph:
|
|
|
574
580
|
marker = _set_marker(self, marker, nodecount)
|
|
575
581
|
|
|
576
582
|
# ############ Set node edge size #############
|
|
577
|
-
if isinstance(edge_size, list):
|
|
583
|
+
if isinstance(edge_size, (list, np.ndarray, pd.Series, StringArray)):
|
|
578
584
|
edge_size = np.array(edge_size)
|
|
579
585
|
elif 'numpy' in str(type(edge_size)):
|
|
580
586
|
pass
|
|
@@ -597,16 +603,16 @@ class d3graph:
|
|
|
597
603
|
'marker': marker[i],
|
|
598
604
|
'label': label[i],
|
|
599
605
|
'tooltip': tooltip[i],
|
|
600
|
-
'color': color[i]
|
|
601
|
-
'opacity': opacity[i]
|
|
602
|
-
'fontcolor': fontcolor[i]
|
|
603
|
-
'fontsize': fontsize[i]
|
|
606
|
+
'color': str(color[i]),
|
|
607
|
+
'opacity': str(opacity[i]),
|
|
608
|
+
'fontcolor': str(fontcolor[i]),
|
|
609
|
+
'fontsize': str(fontsize[i]),
|
|
604
610
|
'size': size[i],
|
|
605
611
|
'edge_size': edge_size[i],
|
|
606
612
|
'edge_color': edge_color[i],
|
|
607
613
|
'group': group[i]}
|
|
608
614
|
|
|
609
|
-
logger.info('Number of unique nodes:
|
|
615
|
+
logger.info(f'Number of unique nodes: {len(self.node_properties.keys())}')
|
|
610
616
|
|
|
611
617
|
# compute clusters
|
|
612
618
|
def get_cluster_color(self, node_names: list = None, color: str = '#000080') -> tuple:
|
|
@@ -713,13 +719,13 @@ class d3graph:
|
|
|
713
719
|
|
|
714
720
|
Examples
|
|
715
721
|
--------
|
|
716
|
-
>>> from d3graph import d3graph
|
|
722
|
+
>>> from d3graph import d3graph, import_example
|
|
717
723
|
>>>
|
|
718
724
|
>>> # Initialize
|
|
719
725
|
>>> d3 = d3graph()
|
|
720
726
|
>>>
|
|
721
727
|
>>> # Load karate example
|
|
722
|
-
>>> adjmat, df =
|
|
728
|
+
>>> adjmat, df = import_example('karate')
|
|
723
729
|
>>>
|
|
724
730
|
>>> # Initialize
|
|
725
731
|
>>> d3.graph(adjmat)
|
|
@@ -793,6 +799,7 @@ class d3graph:
|
|
|
793
799
|
'collision': self.config['collision'],
|
|
794
800
|
'link_tension': self.config.get('link_tension', 1.0),
|
|
795
801
|
'sticky': self.config.get('sticky', False),
|
|
802
|
+
'node_text_inside': self.config.get('node_text_inside', False),
|
|
796
803
|
'CLICK_COMMENT': CLICK_COMMENT,
|
|
797
804
|
'CLICK_FILL': click_properties['fill'],
|
|
798
805
|
'CLICK_STROKE': click_properties['stroke'],
|
|
@@ -863,7 +870,8 @@ class d3graph:
|
|
|
863
870
|
os.makedirs(dirname, exist_ok=True)
|
|
864
871
|
filepath = os.path.abspath(os.path.join(dirname, filename))
|
|
865
872
|
logger.debug(f'filepath is set to [{filepath}]')
|
|
866
|
-
|
|
873
|
+
# Set to config
|
|
874
|
+
self.config['filepath'] = Path(filepath)
|
|
867
875
|
|
|
868
876
|
def import_example(self, data='energy', url=None, sep=','):
|
|
869
877
|
"""Import example dataset from github source.
|
|
@@ -887,38 +895,7 @@ class d3graph:
|
|
|
887
895
|
* https://github.com/erdogant/datazets
|
|
888
896
|
|
|
889
897
|
"""
|
|
890
|
-
|
|
891
|
-
source = ['node A', 'node F', 'node B', 'node B', 'node B', 'node A', 'node C', 'node Z']
|
|
892
|
-
target = ['node F', 'node B', 'node J', 'node F', 'node F', 'node M', 'node M', 'node A']
|
|
893
|
-
weight = [5.56, 0.5, 0.64, 0.23, 0.9, 3.28, 0.5, 0.45]
|
|
894
|
-
adjmat = vec2adjmat(source, target, weight=weight)
|
|
895
|
-
return adjmat, None
|
|
896
|
-
elif data == 'bigbang':
|
|
897
|
-
df = dz.get(data=data)
|
|
898
|
-
adjmat = vec2adjmat(df['source'], df['target'], weight=df['weight'])
|
|
899
|
-
return adjmat
|
|
900
|
-
elif data == 'karate':
|
|
901
|
-
import scipy
|
|
902
|
-
if version.parse(scipy.__version__) < version.parse('1.8.0'):
|
|
903
|
-
raise ImportError(
|
|
904
|
-
'[d3graph] >Error: This release requires scipy version >= 1.8.0. Try: pip install -U scipy>=1.8.0')
|
|
905
|
-
|
|
906
|
-
G = nx.karate_club_graph()
|
|
907
|
-
adjmat = nx.adjacency_matrix(G).todense()
|
|
908
|
-
adjmat = pd.DataFrame(index=range(adjmat.shape[0]), data=adjmat, columns=range(adjmat.shape[0]))
|
|
909
|
-
adjmat.columns = adjmat.columns.astype(str)
|
|
910
|
-
adjmat.index = adjmat.index.astype(str)
|
|
911
|
-
adjmat.iloc[3, 4] = 5
|
|
912
|
-
adjmat.iloc[4, 5] = 6
|
|
913
|
-
adjmat.iloc[5, 6] = 7
|
|
914
|
-
|
|
915
|
-
df = pd.DataFrame(index=adjmat.index)
|
|
916
|
-
df['degree'] = np.array([*G.degree()])[:, 1]
|
|
917
|
-
df['label'] = [G.nodes[i]['club'] for i in range(len(G.nodes))]
|
|
918
|
-
|
|
919
|
-
return adjmat, df
|
|
920
|
-
else:
|
|
921
|
-
return dz.get(data=data, url=url, sep=sep)
|
|
898
|
+
return import_example(data=data, url=url, sep=sep)
|
|
922
899
|
|
|
923
900
|
|
|
924
901
|
# %%
|
|
@@ -1427,6 +1404,8 @@ def _get_hexcolor(label, cmap: str = 'Paired'):
|
|
|
1427
1404
|
|
|
1428
1405
|
return label
|
|
1429
1406
|
|
|
1407
|
+
def get_hex_color(labels, cmap='Set1', opaque_type='per_class', gradient=None):
|
|
1408
|
+
return cm.fromlist(labels, scheme='hex', opaque_type=opaque_type, gradient=gradient)
|
|
1430
1409
|
|
|
1431
1410
|
# %% Do checks
|
|
1432
1411
|
def library_compatibility_checks() -> None:
|
|
@@ -1437,7 +1416,7 @@ def library_compatibility_checks() -> None:
|
|
|
1437
1416
|
None.
|
|
1438
1417
|
|
|
1439
1418
|
"""
|
|
1440
|
-
if not version.parse(nx.__version__) >= version.parse('2.5'):
|
|
1419
|
+
if not version.parse(nx.__version__) >= version.parse('2.5.0'):
|
|
1441
1420
|
logger.error('Networkx version should be >= 2.5')
|
|
1442
1421
|
logger.info('Hint: pip install -U networkx')
|
|
1443
1422
|
|
|
@@ -1623,15 +1602,21 @@ def adjmat2vec(adjmat, min_weight: float = 1.0) -> pd.DataFrame:
|
|
|
1623
1602
|
return adjmat
|
|
1624
1603
|
|
|
1625
1604
|
|
|
1626
|
-
def _check_hex_color(color, n=None):
|
|
1627
|
-
if isinstance(color, str) and len(color) != 7:
|
|
1628
|
-
'Input parameter [color] has wrong format. Must be like color="#000000"')
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
if (
|
|
1634
|
-
|
|
1605
|
+
def _check_hex_color(color, n=None, cmap='Set1'):
|
|
1606
|
+
if isinstance(color, str) and len(color) != 7:
|
|
1607
|
+
logger.warning('Input parameter [color] has wrong format. Must be like color="#000000" <auto-fixing>')
|
|
1608
|
+
return get_hex_color(color, cmap=cmap)[0]
|
|
1609
|
+
if isinstance(color, (list, np.ndarray, pd.Series, pd.Series, StringArray)) and len(color) == 0:
|
|
1610
|
+
logger.warning('Input parameter [color] has wrong format and length. Must be like: color=["#000000", "...", "#000000"] <auto-fixing>')
|
|
1611
|
+
return get_hex_color(color, cmap=cmap)[0]
|
|
1612
|
+
if isinstance(color, (list, np.ndarray, pd.Series, pd.Series, StringArray)) and (not np.all(list(map(lambda x: len(x) == 7, color)))):
|
|
1613
|
+
logger.warning('[color] contains incorrect hex-colors. Hex must be of length 7: ["#000000", "#000000", etc] <auto-fixing>')
|
|
1614
|
+
return get_hex_color(color, cmap=cmap)[0]
|
|
1615
|
+
if (n is not None) and isinstance(color, (list, np.ndarray, pd.Series, pd.Series, StringArray)) and len(color) != n:
|
|
1616
|
+
logger.warning(f'Input parameter [color] has wrong length. Must be of length: {str(n)} <auto-fixing>')
|
|
1617
|
+
return get_hex_color(color, cmap=cmap)[0]
|
|
1618
|
+
# Return original input
|
|
1619
|
+
return color
|
|
1635
1620
|
|
|
1636
1621
|
|
|
1637
1622
|
def _set_opacity(self, opacity, nodecount, node_names):
|
|
@@ -1673,20 +1658,63 @@ def _compute_centrality(adjmat):
|
|
|
1673
1658
|
# opacity = opacity[:-2]
|
|
1674
1659
|
return opacity
|
|
1675
1660
|
|
|
1661
|
+
MARKERS_SUPPORTED = {
|
|
1662
|
+
'circle',
|
|
1663
|
+
'ellipse',
|
|
1664
|
+
'rect', 'rectangle', 'square',
|
|
1665
|
+
'rect-wide', 'rectangle-wide',
|
|
1666
|
+
'triangle', 'triangle-up', 'triangle-down',
|
|
1667
|
+
'diamond',
|
|
1668
|
+
'star',
|
|
1669
|
+
'hexagon',
|
|
1670
|
+
'pentagon',
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
|
|
1676
1674
|
def _set_marker(self, marker, nodecount):
|
|
1677
|
-
|
|
1675
|
+
"""Validate and broadcast the node marker/shape.
|
|
1676
|
+
|
|
1677
|
+
Supported shapes
|
|
1678
|
+
----------------
|
|
1679
|
+
'circle' : Circle (default)
|
|
1680
|
+
'ellipse' : Ellipse (wider than tall)
|
|
1681
|
+
'rect' / 'rectangle' / 'square' : Square
|
|
1682
|
+
'rect-wide' / 'rectangle-wide' : Wide rectangle
|
|
1683
|
+
'triangle' / 'triangle-up' : Triangle pointing up
|
|
1684
|
+
'triangle-down' : Triangle pointing down
|
|
1685
|
+
'diamond' : Diamond (rotated square)
|
|
1686
|
+
'star' : 5-pointed star
|
|
1687
|
+
'hexagon' : Regular hexagon
|
|
1688
|
+
'pentagon' : Regular pentagon
|
|
1689
|
+
"""
|
|
1690
|
+
if marker is None:
|
|
1678
1691
|
marker = 'circle'
|
|
1679
1692
|
|
|
1680
|
-
if isinstance(marker, list) and len(marker)==nodecount:
|
|
1681
|
-
marker = np.array(marker)
|
|
1682
|
-
|
|
1693
|
+
if isinstance(marker, (list, np.ndarray, pd.Series)) and len(marker) == nodecount:
|
|
1694
|
+
marker = np.array([str(m).lower() for m in marker])
|
|
1695
|
+
invalid = set(marker) - MARKERS_SUPPORTED
|
|
1696
|
+
if invalid:
|
|
1697
|
+
logger.warning(
|
|
1698
|
+
'Unknown marker(s) %s. Supported: %s. Falling back to "circle" for those.',
|
|
1699
|
+
sorted(invalid), sorted(MARKERS_SUPPORTED)
|
|
1700
|
+
)
|
|
1701
|
+
marker = np.where(np.isin(marker, list(MARKERS_SUPPORTED)), marker, 'circle')
|
|
1702
|
+
elif 'numpy' in str(type(marker)) and len(marker) == nodecount:
|
|
1683
1703
|
pass
|
|
1684
1704
|
elif isinstance(marker, str):
|
|
1705
|
+
marker = marker.lower()
|
|
1706
|
+
if marker not in MARKERS_SUPPORTED:
|
|
1707
|
+
logger.warning(
|
|
1708
|
+
'Unknown marker "%s". Supported: %s. Falling back to "circle".',
|
|
1709
|
+
marker, sorted(MARKERS_SUPPORTED)
|
|
1710
|
+
)
|
|
1711
|
+
marker = 'circle'
|
|
1685
1712
|
marker = np.repeat(marker, nodecount)
|
|
1713
|
+
else:
|
|
1714
|
+
marker = np.repeat('circle', nodecount)
|
|
1686
1715
|
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
# Return
|
|
1716
|
+
if len(marker) != nodecount:
|
|
1717
|
+
raise ValueError("Node marker must be of same length as the number of nodes")
|
|
1690
1718
|
return marker
|
|
1691
1719
|
|
|
1692
1720
|
def _set_node_size(self, size, minmax, nodecount):
|
|
@@ -1755,6 +1783,61 @@ def _set_node_fontcolor(self, fontcolor, color, node_names, nodecount):
|
|
|
1755
1783
|
# return
|
|
1756
1784
|
return fontcolor
|
|
1757
1785
|
|
|
1786
|
+
def import_example(data='energy', url=None, sep=','):
|
|
1787
|
+
"""Import example dataset from github source.
|
|
1788
|
+
|
|
1789
|
+
Import one of the few datasets from github source or specify your own download url link.
|
|
1790
|
+
|
|
1791
|
+
Parameters
|
|
1792
|
+
----------
|
|
1793
|
+
data : str
|
|
1794
|
+
Name of datasets: 'sprinkler', 'titanic', 'student', 'fifa', 'cancer', 'waterpump', 'retail'
|
|
1795
|
+
url : str
|
|
1796
|
+
url link to to dataset.
|
|
1797
|
+
|
|
1798
|
+
Returns
|
|
1799
|
+
-------
|
|
1800
|
+
pd.DataFrame()
|
|
1801
|
+
Dataset containing mixed features.
|
|
1802
|
+
|
|
1803
|
+
References
|
|
1804
|
+
----------
|
|
1805
|
+
* https://github.com/erdogant/datazets
|
|
1806
|
+
|
|
1807
|
+
"""
|
|
1808
|
+
if data == 'small':
|
|
1809
|
+
source = ['node A', 'node F', 'node B', 'node B', 'node B', 'node A', 'node C', 'node Z']
|
|
1810
|
+
target = ['node F', 'node B', 'node J', 'node F', 'node F', 'node M', 'node M', 'node A']
|
|
1811
|
+
weight = [5.56, 0.5, 0.64, 0.23, 0.9, 3.28, 0.5, 0.45]
|
|
1812
|
+
adjmat = vec2adjmat(source, target, weight=weight)
|
|
1813
|
+
return adjmat, None
|
|
1814
|
+
elif data == 'bigbang':
|
|
1815
|
+
df = dz.get(data=data)
|
|
1816
|
+
adjmat = vec2adjmat(df['source'], df['target'], weight=df['weight'])
|
|
1817
|
+
return adjmat
|
|
1818
|
+
elif data == 'karate':
|
|
1819
|
+
import scipy
|
|
1820
|
+
if version.parse(scipy.__version__) < version.parse('1.8.0'):
|
|
1821
|
+
raise ImportError(
|
|
1822
|
+
'[d3graph] >Error: This release requires scipy version >= 1.8.0. Try: pip install -U scipy>=1.8.0')
|
|
1823
|
+
|
|
1824
|
+
G = nx.karate_club_graph()
|
|
1825
|
+
adjmat = nx.adjacency_matrix(G).todense()
|
|
1826
|
+
adjmat = pd.DataFrame(index=range(adjmat.shape[0]), data=adjmat, columns=range(adjmat.shape[0]))
|
|
1827
|
+
adjmat.columns = adjmat.columns.astype(str)
|
|
1828
|
+
adjmat.index = adjmat.index.astype(str)
|
|
1829
|
+
adjmat.iloc[3, 4] = 5
|
|
1830
|
+
adjmat.iloc[4, 5] = 6
|
|
1831
|
+
adjmat.iloc[5, 6] = 7
|
|
1832
|
+
|
|
1833
|
+
df = pd.DataFrame(index=adjmat.index)
|
|
1834
|
+
df['degree'] = np.array([*G.degree()])[:, 1]
|
|
1835
|
+
df['label'] = [G.nodes[i]['club'] for i in range(len(G.nodes))]
|
|
1836
|
+
|
|
1837
|
+
return adjmat, df
|
|
1838
|
+
else:
|
|
1839
|
+
return dz.get(data=data, url=url, sep=sep)
|
|
1840
|
+
|
|
1758
1841
|
|
|
1759
1842
|
def get_support(support):
|
|
1760
1843
|
"""Support."""
|