iplotx 0.1.0__py3-none-any.whl → 0.2.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.
iplotx/heuristics.py DELETED
@@ -1,114 +0,0 @@
1
- from collections import defaultdict
2
- import numpy as np
3
- import pandas as pd
4
-
5
- from .importing import igraph, networkx
6
- from .typing import GraphType, GroupingType, LayoutType
7
-
8
-
9
- def network_library(
10
- network: GraphType,
11
- ) -> str:
12
- if igraph is not None and isinstance(network, igraph.Graph):
13
- return "igraph"
14
- if networkx is not None:
15
- if isinstance(network, networkx.Graph):
16
- return "networkx"
17
- if isinstance(network, networkx.DiGraph):
18
- return "networkx"
19
- if isinstance(network, networkx.MultiGraph):
20
- return "networkx"
21
- if isinstance(network, networkx.MultiDiGraph):
22
- return "networkx"
23
- raise TypeError("Unsupported graph type. Supported types are igraph and networkx.")
24
-
25
-
26
- def detect_directedness(
27
- network: GraphType,
28
- ) -> np.ndarray:
29
- """Detect if the network is directed or not."""
30
- if network_library(network) == "igraph":
31
- return network.is_directed()
32
- if isinstance(network, (networkx.DiGraph, networkx.MultiDiGraph)):
33
- return True
34
- return False
35
-
36
-
37
- def normalise_layout(layout):
38
- """Normalise the layout to a pandas.DataFrame."""
39
- if layout is None:
40
- return None
41
- if isinstance(layout, dict):
42
- layout = pd.DataFrame(layout).T
43
- if isinstance(layout, str):
44
- raise NotImplementedError("Layout as a string is not supported yet.")
45
- if isinstance(layout, (list, tuple)):
46
- return pd.DataFrame(np.array(layout))
47
- if isinstance(layout, pd.DataFrame):
48
- return layout
49
- if isinstance(layout, np.ndarray):
50
- return pd.DataFrame(layout)
51
- raise TypeError(
52
- "Layout must be a string, list, tuple, numpy array or pandas DataFrame."
53
- )
54
-
55
-
56
- def normalise_grouping(
57
- grouping: GroupingType,
58
- layout: LayoutType,
59
- ) -> dict[set]:
60
-
61
- if len(grouping) == 0:
62
- return {}
63
-
64
- if isinstance(grouping, dict):
65
- val0 = next(iter(grouping.values()))
66
- # If already the right data type or compatible, leave as is
67
- if isinstance(val0, (set, frozenset)):
68
- return grouping
69
-
70
- # If a dict of integers or strings, assume each key is a vertex id and each value is a
71
- # group, convert (i.e. invert the dict)
72
- if isinstance(val0, (int, str)):
73
- group_dic = defaultdict(set)
74
- for key, val in grouping.items():
75
- group_dic[val].add(key)
76
- return group_dic
77
-
78
- # If an igraph object, convert to a dict of sets
79
- if igraph is not None:
80
- if isinstance(grouping, igraph.clustering.Clustering):
81
- layout = normalise_layout(layout)
82
- group_dic = defaultdict(set)
83
- for i, member in enumerate(grouping.membership):
84
- group_dic[member].add(i)
85
- return group_dic
86
-
87
- if isinstance(grouping, igraph.clustering.Cover):
88
- layout = normalise_layout(layout)
89
- group_dic = defaultdict(set)
90
- for i, members in enumerate(grouping.membership):
91
- for member in members:
92
- group_dic[member].add(i)
93
- return group_dic
94
-
95
- # Assume it's a sequence, so convert to list
96
- grouping = list(grouping)
97
-
98
- # If the values are already sets, assume group indices are integers
99
- # and values are as is
100
- if isinstance(grouping[0], set):
101
- group_dic = {i: val for i, val in enumerate(grouping)}
102
- return group_dic
103
-
104
- # If the values are integers or strings, assume each key is a vertex id and each value is a
105
- # group, convert to dict of sets
106
- if isinstance(grouping[0], (int, str)):
107
- group_dic = defaultdict(set)
108
- for i, val in enumerate(grouping):
109
- group_dic[val].add(i)
110
- return group_dic
111
-
112
- raise TypeError(
113
- "Could not standardise grouping from object.",
114
- )
iplotx/importing.py DELETED
@@ -1,13 +0,0 @@
1
- try:
2
- import igraph
3
- except ImportError:
4
- igraph = None
5
-
6
- try:
7
- import networkx
8
- except ImportError:
9
- networkx = None
10
-
11
- if igraph is None and networkx is None:
12
- raise ImportError("At least one of igraph or networkx must be installed to use this module.")
13
-
iplotx/styles.py DELETED
@@ -1,186 +0,0 @@
1
- from typing import Union, Sequence, Hashable
2
- from copy import deepcopy
3
- from contextlib import contextmanager
4
- import numpy as np
5
- import pandas as pd
6
-
7
-
8
- style_leaves = (
9
- "edgecolor",
10
- "facecolor",
11
- "linewidth",
12
- "linestyle",
13
- "alpha",
14
- "zorder",
15
- )
16
-
17
-
18
- default = {
19
- "vertex": {
20
- "size": 20,
21
- "facecolor": "black",
22
- "marker": "o",
23
- "label": {
24
- "horizontalalignment": "center",
25
- "verticalalignment": "center",
26
- "hpadding": 18,
27
- "vpadding": 12,
28
- },
29
- },
30
- "edge": {
31
- "linewidth": 1.5,
32
- "linestyle": "-",
33
- "color": "black",
34
- "curved": False,
35
- "offset": 3,
36
- "tension": 1,
37
- "label": {
38
- "horizontalalignment": "center",
39
- "verticalalignment": "center",
40
- },
41
- },
42
- "arrow": {
43
- "marker": "|>",
44
- "width": 8,
45
- "color": "black",
46
- },
47
- "grouping": {
48
- "facecolor": ["grey", "steelblue", "tomato"],
49
- "edgecolor": "black",
50
- "linewidth": 1.5,
51
- "alpha": 0.5,
52
- "vertexpadding": 25,
53
- },
54
- }
55
-
56
- hollow = deepcopy(default)
57
- hollow["vertex"]["color"] = None
58
- hollow["vertex"]["facecolor"] = "none"
59
- hollow["vertex"]["edgecolor"] = "black"
60
- hollow["vertex"]["linewidth"] = 1.5
61
- hollow["vertex"]["marker"] = "r"
62
- hollow["vertex"]["size"] = "label"
63
-
64
-
65
- styles = {
66
- "default": default,
67
- "hollow": hollow,
68
- }
69
-
70
-
71
- stylename = "default"
72
-
73
-
74
- current = deepcopy(styles["default"])
75
-
76
-
77
- def get_stylename():
78
- """Return the name of the current iplotx style."""
79
- return str(stylename)
80
-
81
-
82
- def get_style(name: str = ""):
83
- namelist = name.split(".")
84
- style = styles
85
- for i, namei in enumerate(namelist):
86
- if (i == 0) and (namei == ""):
87
- style = current
88
- else:
89
- try:
90
- style = style[namei]
91
- except KeyError:
92
- raise KeyError(f"Style not found: {name}")
93
-
94
- style = deepcopy(style)
95
- return style
96
-
97
-
98
- # The following is inspired by matplotlib's style library
99
- # https://github.com/matplotlib/matplotlib/blob/v3.10.3/lib/matplotlib/style/core.py#L45
100
- def use(style: Union[str, dict, Sequence]):
101
- """Use iplotx style setting for a style specification.
102
-
103
- The style name of 'default' is reserved for reverting back to
104
- the default style settings.
105
-
106
- Parameters:
107
- style: A style specification, currently either a name of an existing style
108
- or a dict with specific parts of the style to override. The string
109
- "default" resets the style to the default one. If this is a sequence,
110
- each style is applied in order.
111
- """
112
- global current
113
-
114
- def _update(style: dict, current: dict):
115
- for key, value in style.items():
116
- if key not in current:
117
- current[key] = value
118
- continue
119
-
120
- # Style leaves are by definition not to be recurred into
121
- if isinstance(value, dict) and (key not in style_leaves):
122
- _update(value, current[key])
123
- elif value is None:
124
- del current[key]
125
- else:
126
- current[key] = value
127
-
128
- if isinstance(style, (dict, str)):
129
- styles = [style]
130
- else:
131
- styles = style
132
-
133
- for style in styles:
134
- if style == "default":
135
- reset()
136
- else:
137
- if isinstance(style, str):
138
- current = get_style(style)
139
- else:
140
- _update(style, current)
141
-
142
-
143
- def reset():
144
- """Reset to default style."""
145
- global current
146
- current = deepcopy(styles["default"])
147
-
148
-
149
- @contextmanager
150
- def stylecontext(style: Union[str, dict, Sequence]):
151
- current = get_style()
152
- try:
153
- use(style)
154
- yield
155
- finally:
156
- use(current)
157
-
158
-
159
- def rotate_style(
160
- style,
161
- index: Union[int, None] = None,
162
- id: Union[Hashable, None] = None,
163
- props=style_leaves,
164
- ):
165
- if (index is None) and (id is None):
166
- raise ValueError(
167
- "At least one of 'index' or 'id' must be provided to rotate_style."
168
- )
169
-
170
- style = deepcopy(style)
171
-
172
- for prop in props:
173
- val = style.get(prop, None)
174
- if val is None:
175
- continue
176
- # NOTE: this assumes that these properties are leaves of the style tree
177
- # Btw: dict includes defaultdict, Couter, etc.
178
- if (id is not None) and isinstance(val, (dict, pd.Series)):
179
- # This works on both dict-like and Series
180
- style[prop] = val[id]
181
- elif (index is not None) and isinstance(
182
- val, (tuple, list, np.ndarray, pd.Index, pd.Series)
183
- ):
184
- style[prop] = np.asarray(val)[index % len(val)]
185
-
186
- return style
@@ -1,20 +0,0 @@
1
- iplotx/__init__.py,sha256=VrbOJwPlhb_wEeyCU0OcfiNde_SJqYmHwa1Qh2trHvE,60
2
- iplotx/groups.py,sha256=PplZgemEEg7b285fwV--08yIIomRTgg0xxyvvHeoBp8,4289
3
- iplotx/heuristics.py,sha256=bnfetQRxZA-Ii2V61XH7VYnvvG6DyKqiH2iOsA5la9o,3810
4
- iplotx/importing.py,sha256=GCzbQ4X8BAk0Cv9Nue-B-3vHiCmGHmF6pVPIVRUhGI8,267
5
- iplotx/network.py,sha256=jipKjV6NtVteUoqeSTRc1kfkmRfTT0L8uEPCLt_ipJ4,18070
6
- iplotx/plotting.py,sha256=wyPrDPMNscuiCdO0Md--ZSU6_uJ3XnCTJg8yKIYnm5g,3481
7
- iplotx/styles.py,sha256=lHn-NRQ0CkG7dWe-J1wuGa-rH8ut4dqBa8rLGbqk1Ig,4679
8
- iplotx/typing.py,sha256=0RrZqEKsC9rSnPQIKg-br1g2w5wDVpTzrlx04rKnN0Y,1304
9
- iplotx/version.py,sha256=kUR5RAFc7HCeiqdlX36dZOHkUI5wI6V_43RpEcD8b-0,22
10
- iplotx/vertex.py,sha256=qP6V9eAoC6zb9uD00sxUlIWnEPbMxLeQRJoiKVCubLU,3485
11
- iplotx/edge/arrow.py,sha256=gUvTXVFG8e9G0qeztljqHVTZwYSCrhIDj0HGq3anenk,3876
12
- iplotx/edge/common.py,sha256=62CCsA_1z9qhKIgSEbnfxzj9elKxPDv0REbLewKnnqo,1445
13
- iplotx/edge/directed.py,sha256=zUU0vJApasNcvIApNGYy_x0NDnVyStgCKJn5J6U3tW4,5059
14
- iplotx/edge/label.py,sha256=rutePN_WEIT8IR7FSRrvsoIJw2WoFWDSHCh0dmHeJTI,1407
15
- iplotx/edge/undirected.py,sha256=LfDHqUP5zEBuf69lyOhUU_tk5ZGCJyw5xL3eZnTk7OU,14799
16
- iplotx/utils/geometry.py,sha256=3HIsH_Nek_m41vL7twvgmDYfhlJURYd5TbMaa15nyt8,7804
17
- iplotx/utils/matplotlib.py,sha256=I4Lw6vMPIgKMyqcR6RQBiRPKnmi5ko_GAtG04cT5XPw,3972
18
- iplotx-0.1.0.dist-info/METADATA,sha256=UMVggqiCw-xHPHY7s5ACPBnjIeWLl-COy01CjB0MEyw,2252
19
- iplotx-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
20
- iplotx-0.1.0.dist-info/RECORD,,
File without changes