iplotx 0.6.5__py3-none-any.whl → 0.6.7__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/edge/__init__.py +3 -0
- iplotx/ingest/providers/network/networkx.py +7 -1
- iplotx/ingest/typing.py +7 -5
- iplotx/network.py +15 -8
- iplotx/plotting.py +50 -13
- iplotx/version.py +1 -1
- iplotx/vertex.py +4 -1
- {iplotx-0.6.5.dist-info → iplotx-0.6.7.dist-info}/METADATA +1 -1
- {iplotx-0.6.5.dist-info → iplotx-0.6.7.dist-info}/RECORD +10 -10
- {iplotx-0.6.5.dist-info → iplotx-0.6.7.dist-info}/WHEEL +0 -0
iplotx/edge/__init__.py
CHANGED
|
@@ -101,7 +101,13 @@ class NetworkXDataProvider(NetworkDataProvider):
|
|
|
101
101
|
else:
|
|
102
102
|
if len(edge_labels) != len(edge_df):
|
|
103
103
|
raise ValueError("Edge labels must be the same length as the number of edges.")
|
|
104
|
-
|
|
104
|
+
if isinstance(edge_labels, dict):
|
|
105
|
+
edge_labels = pd.Series(edge_labels)
|
|
106
|
+
edge_df["label"] = edge_labels.loc[
|
|
107
|
+
edge_df.set_index(["_ipx_source", "_ipx_target"]).index
|
|
108
|
+
].values
|
|
109
|
+
else:
|
|
110
|
+
edge_df["label"] = edge_labels
|
|
105
111
|
|
|
106
112
|
network_data = {
|
|
107
113
|
"vertex_df": vertex_df,
|
iplotx/ingest/typing.py
CHANGED
|
@@ -138,11 +138,13 @@ class TreeDataProvider(Protocol):
|
|
|
138
138
|
|
|
139
139
|
Note: This is a default implemntation that can be overridden by the provider.
|
|
140
140
|
"""
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
if hasattr(self.tree, "root"):
|
|
142
|
+
root_attr = self.tree.root
|
|
143
|
+
if callable(root_attr):
|
|
144
|
+
return root_attr()
|
|
145
|
+
else:
|
|
146
|
+
return root_attr
|
|
147
|
+
return self.tree.get_root()
|
|
146
148
|
|
|
147
149
|
def get_leaves(self) -> Sequence[Any]:
|
|
148
150
|
"""Get the tree leaves/tips in a provider-specific data structure.
|
iplotx/network.py
CHANGED
|
@@ -140,7 +140,10 @@ class NetworkArtist(mpl.artist.Artist):
|
|
|
140
140
|
return self
|
|
141
141
|
|
|
142
142
|
def get_children(self):
|
|
143
|
-
|
|
143
|
+
if hasattr(self, "_edges"):
|
|
144
|
+
return (self._vertices, self._edges)
|
|
145
|
+
else:
|
|
146
|
+
return (self._vertices,)
|
|
144
147
|
|
|
145
148
|
def set_figure(self, fig):
|
|
146
149
|
super().set_figure(fig)
|
|
@@ -184,12 +187,14 @@ class NetworkArtist(mpl.artist.Artist):
|
|
|
184
187
|
if len(layout) == 0:
|
|
185
188
|
return mpl.transforms.Bbox([[0, 0], [1, 1]])
|
|
186
189
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
+
bboxes = [
|
|
191
|
+
self._vertices.get_datalim(transData),
|
|
192
|
+
]
|
|
193
|
+
if hasattr(self, "_edges"):
|
|
194
|
+
bboxes.append(
|
|
190
195
|
self._edges.get_datalim(transData),
|
|
191
|
-
|
|
192
|
-
)
|
|
196
|
+
)
|
|
197
|
+
bbox = mpl.transforms.Bbox.union(bboxes)
|
|
193
198
|
|
|
194
199
|
bbox = bbox.expanded(sw=(1.0 + pad), sh=(1.0 + pad))
|
|
195
200
|
return bbox
|
|
@@ -241,6 +246,9 @@ class NetworkArtist(mpl.artist.Artist):
|
|
|
241
246
|
|
|
242
247
|
edge_df = self._ipx_internal_data["edge_df"].set_index(["_ipx_source", "_ipx_target"])
|
|
243
248
|
|
|
249
|
+
if len(edge_df) == 0:
|
|
250
|
+
return
|
|
251
|
+
|
|
244
252
|
if "cmap" in edge_style:
|
|
245
253
|
cmap_fun = _build_cmap_fun(
|
|
246
254
|
edge_style,
|
|
@@ -313,8 +321,7 @@ class NetworkArtist(mpl.artist.Artist):
|
|
|
313
321
|
if not self.get_visible():
|
|
314
322
|
return
|
|
315
323
|
|
|
316
|
-
#
|
|
317
|
-
# this is kind of funny actually
|
|
324
|
+
# Handle zorder manually, just like in AxesBase in mpl
|
|
318
325
|
children = list(self.get_children())
|
|
319
326
|
children.sort(key=lambda x: x.zorder)
|
|
320
327
|
for art in children:
|
iplotx/plotting.py
CHANGED
|
@@ -28,6 +28,8 @@ def network(
|
|
|
28
28
|
title: Optional[str] = None,
|
|
29
29
|
aspect: Optional[str | float] = None,
|
|
30
30
|
margins: float | tuple[float, float] = 0,
|
|
31
|
+
strip_axes: bool = True,
|
|
32
|
+
figsize: Optional[tuple[float, float]] = None,
|
|
31
33
|
**kwargs,
|
|
32
34
|
) -> list[mpl.artist.Artist]:
|
|
33
35
|
"""Plot this network and/or vertex grouping using the specified layout.
|
|
@@ -53,6 +55,10 @@ def network(
|
|
|
53
55
|
used as a quick fix when some vertex shapes reach beyond the plot edge. This is
|
|
54
56
|
a fraction of the data limits, so 0.1 means 10% of the data limits will be left
|
|
55
57
|
as margin.
|
|
58
|
+
strip_axes: If True, remove axis spines and ticks.
|
|
59
|
+
figsize: If ax is None, a new matplotlib Figure is created. This argument specifies
|
|
60
|
+
the (width, height) dimension of the figure in inches. If ax is not None, this
|
|
61
|
+
argument is ignored. If None, the default matplotlib figure size is used.
|
|
56
62
|
kwargs: Additional arguments are treated as an alternate way to specify style. If
|
|
57
63
|
both "style" and additional **kwargs are provided, they are both applied in that
|
|
58
64
|
order (style, then **kwargs).
|
|
@@ -69,7 +75,7 @@ def network(
|
|
|
69
75
|
raise ValueError("At least one of network or grouping must be provided.")
|
|
70
76
|
|
|
71
77
|
if ax is None:
|
|
72
|
-
fig, ax = plt.subplots()
|
|
78
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
73
79
|
|
|
74
80
|
artists = []
|
|
75
81
|
if network is not None:
|
|
@@ -110,7 +116,7 @@ def network(
|
|
|
110
116
|
if aspect is not None:
|
|
111
117
|
ax.set_aspect(aspect)
|
|
112
118
|
|
|
113
|
-
|
|
119
|
+
_postprocess_axes(ax, artists, strip=strip_axes)
|
|
114
120
|
|
|
115
121
|
if np.isscalar(margins):
|
|
116
122
|
margins = (margins, margins)
|
|
@@ -132,6 +138,8 @@ def tree(
|
|
|
132
138
|
title: Optional[str] = None,
|
|
133
139
|
aspect: Optional[str | float] = None,
|
|
134
140
|
margins: float | tuple[float, float] = 0,
|
|
141
|
+
strip_axes: bool = True,
|
|
142
|
+
figsize: Optional[tuple[float, float]] = None,
|
|
135
143
|
**kwargs,
|
|
136
144
|
) -> TreeArtist:
|
|
137
145
|
"""Plot a tree using the specified layout.
|
|
@@ -140,9 +148,37 @@ def tree(
|
|
|
140
148
|
tree: The tree to plot. Can be a BioPython.Phylo.Tree object.
|
|
141
149
|
layout: The layout to use for plotting.
|
|
142
150
|
directed: If False, do not draw arrows.
|
|
151
|
+
vertex_labels: The labels for the vertices. If None or False, no vertex labels. Also
|
|
152
|
+
read leaf_labels for leaf nodes.
|
|
153
|
+
leaf_labels: The labels for the leaf nodes. If None or False, no leaf labels are used
|
|
154
|
+
except if vertex_labels are specified for leaf nodes. This argument and the
|
|
155
|
+
previous vertex_labels provide somewhat redundant functionality but have quite
|
|
156
|
+
different default behaviours for distinct use cases. This argument is typically
|
|
157
|
+
useful for labels that are specific to leaf nodes only (e.g. species in a
|
|
158
|
+
phylogenetic tree), whereas vertex_labels is typically used for labels that apply
|
|
159
|
+
to internal nodes too (e.g. branch support values). This redundancy is left on
|
|
160
|
+
purpose to allow for maximal style flexibility.
|
|
143
161
|
show_support: If True, show the support values for the nodes (assumed to be from 0 to 100,
|
|
144
162
|
rounded to nearest integer). If both this parameter and vertex_labels are set,
|
|
145
163
|
show_support takes precedence and hides the vertex labels.
|
|
164
|
+
ax: The axis to plot on. If None, a new figure and axis will be created. Defaults to
|
|
165
|
+
None.
|
|
166
|
+
style: Apply this style for the objects to plot. This can be a sequence (e.g. list)
|
|
167
|
+
of styles and they will be applied in order.
|
|
168
|
+
title: If not None, set the axes title to this value.
|
|
169
|
+
aspect: If not None, set the aspect ratio of the axis to this value. The most common
|
|
170
|
+
value is 1.0, which proportionates x- and y-axes.
|
|
171
|
+
margins: How much margin to leave around the plot. A higher value (e.g. 0.1) can be
|
|
172
|
+
used as a quick fix when some vertex shapes reach beyond the plot edge. This is
|
|
173
|
+
a fraction of the data limits, so 0.1 means 10% of the data limits will be left
|
|
174
|
+
as margin.
|
|
175
|
+
strip_axes: If True, remove axis spines and ticks.
|
|
176
|
+
figsize: If ax is None, a new matplotlib Figure is created. This argument specifies
|
|
177
|
+
the (width, height) dimension of the figure in inches. If ax is not None, this
|
|
178
|
+
argument is ignored. If None, the default matplotlib figure size is used.
|
|
179
|
+
kwargs: Additional arguments are treated as an alternate way to specify style. If
|
|
180
|
+
both "style" and additional **kwargs are provided, they are both applied in that
|
|
181
|
+
order (style, then **kwargs).
|
|
146
182
|
|
|
147
183
|
Returns:
|
|
148
184
|
A TreeArtist object, set as a direct child of the matplotlib Axes.
|
|
@@ -151,7 +187,7 @@ def tree(
|
|
|
151
187
|
|
|
152
188
|
with stylecontext:
|
|
153
189
|
if ax is None:
|
|
154
|
-
fig, ax = plt.subplots()
|
|
190
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
155
191
|
|
|
156
192
|
artist = TreeArtist(
|
|
157
193
|
tree=tree,
|
|
@@ -173,7 +209,7 @@ def tree(
|
|
|
173
209
|
if aspect is not None:
|
|
174
210
|
ax.set_aspect(aspect)
|
|
175
211
|
|
|
176
|
-
|
|
212
|
+
_postprocess_axes(ax, [artist], strip=strip_axes)
|
|
177
213
|
|
|
178
214
|
if np.isscalar(margins):
|
|
179
215
|
margins = (margins, margins)
|
|
@@ -184,18 +220,19 @@ def tree(
|
|
|
184
220
|
|
|
185
221
|
|
|
186
222
|
# INTERNAL ROUTINES
|
|
187
|
-
def
|
|
223
|
+
def _postprocess_axes(ax, artists, strip=True):
|
|
188
224
|
"""Postprocess axis after plotting."""
|
|
189
225
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
226
|
+
if strip:
|
|
227
|
+
# Despine
|
|
228
|
+
ax.spines["right"].set_visible(False)
|
|
229
|
+
ax.spines["top"].set_visible(False)
|
|
230
|
+
ax.spines["left"].set_visible(False)
|
|
231
|
+
ax.spines["bottom"].set_visible(False)
|
|
195
232
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
233
|
+
# Remove axis ticks
|
|
234
|
+
ax.set_xticks([])
|
|
235
|
+
ax.set_yticks([])
|
|
199
236
|
|
|
200
237
|
# Set new data limits
|
|
201
238
|
bboxes = []
|
iplotx/version.py
CHANGED
iplotx/vertex.py
CHANGED
|
@@ -68,7 +68,7 @@ class VertexCollection(PatchCollection):
|
|
|
68
68
|
"""
|
|
69
69
|
|
|
70
70
|
self._index = layout.index
|
|
71
|
-
self._style = style
|
|
71
|
+
self._style = style if style is not None else {}
|
|
72
72
|
self._layout = layout
|
|
73
73
|
self._layout_coordinate_system = layout_coordinate_system
|
|
74
74
|
|
|
@@ -94,6 +94,9 @@ class VertexCollection(PatchCollection):
|
|
|
94
94
|
if self._labels is not None:
|
|
95
95
|
self._compute_label_collection()
|
|
96
96
|
|
|
97
|
+
zorder = self._style.get("zorder", 1)
|
|
98
|
+
self.set_zorder(zorder)
|
|
99
|
+
|
|
97
100
|
def __len__(self):
|
|
98
101
|
"""Return the number of vertices in the collection."""
|
|
99
102
|
return len(self.get_paths())
|
|
@@ -4,22 +4,22 @@ iplotx/cascades.py,sha256=OPqF7Huls-HFmDA5MCF6DEZlUeRVaXsbQcHBoKAgNJs,8182
|
|
|
4
4
|
iplotx/groups.py,sha256=_9KdIiTAi1kXtd2mDywgBJCbqoRq2z-5fzOPf76Wgb8,6287
|
|
5
5
|
iplotx/label.py,sha256=6am3a0ejcW_bWEXSOODE1Ke3AyCU1lJ45RfnXNbHAQw,8923
|
|
6
6
|
iplotx/layout.py,sha256=KxmRLqjo8AYCBAmXez8rIiLU2sM34qhb6ox9AHYwRyE,4839
|
|
7
|
-
iplotx/network.py,sha256=
|
|
8
|
-
iplotx/plotting.py,sha256=
|
|
7
|
+
iplotx/network.py,sha256=LaW9zQZ4sKiDVb25_icnquGNnN7HrKC7NO07o6PSmGI,11527
|
|
8
|
+
iplotx/plotting.py,sha256=IEUxW1xzTljLjBfsVP2BNsOPCDpj5bEPZ99bzvD5-mo,10066
|
|
9
9
|
iplotx/tree.py,sha256=Zzz7nCPZrSjh9_yHXFdd8hjbF-FYURTZs00rUHc4OT8,27304
|
|
10
10
|
iplotx/typing.py,sha256=QLdzV358IiD1CFe88MVp0D77FSx5sSAVUmM_2WPPE8I,1463
|
|
11
|
-
iplotx/version.py,sha256=
|
|
12
|
-
iplotx/vertex.py,sha256
|
|
13
|
-
iplotx/edge/__init__.py,sha256=
|
|
11
|
+
iplotx/version.py,sha256=1Mi-AUAfWTkSNROfIn7bWkeZBzSl_j_A7HmbA4LSs0c,66
|
|
12
|
+
iplotx/vertex.py,sha256=-JZaQPjIAWWP8Wap1HyR4g4HXLNGLwjf4v6jyo994Tk,14671
|
|
13
|
+
iplotx/edge/__init__.py,sha256=HlxeIs88RbRrTetJNLcoq9gjV7cBhOdqQoiVZFFylFc,27081
|
|
14
14
|
iplotx/edge/arrow.py,sha256=C4XoHGCYou1z2alz5Q2VhdaWYEzgebtEF70zVYY_frk,15533
|
|
15
15
|
iplotx/edge/geometry.py,sha256=tiaF4PzvsNBoROrEgcCsw0YdxxZr3oBxF4ord_k4ThA,15069
|
|
16
16
|
iplotx/edge/leaf.py,sha256=SyGMv2PIOoH0pey8-aMVaZheK3hNe1Qz_okcyWbc4E4,4268
|
|
17
17
|
iplotx/edge/ports.py,sha256=BpkbiEhX4mPBBAhOv4jcKFG4Y8hxXz5GRtVLCC0jbtI,1235
|
|
18
18
|
iplotx/ingest/__init__.py,sha256=S0YfnXcFKseB7ZBQc4yRt0cNDsLlhqdom0TmSY3OY2E,4756
|
|
19
19
|
iplotx/ingest/heuristics.py,sha256=715VqgfKek5LOJnu1vTo7RqPgCl-Bb8Cf6o7_Tt57fA,5797
|
|
20
|
-
iplotx/ingest/typing.py,sha256
|
|
20
|
+
iplotx/ingest/typing.py,sha256=61LwNwrTHVh8eqqC778Gr81zPYcUKW61mDgGCCsuGSk,14181
|
|
21
21
|
iplotx/ingest/providers/network/igraph.py,sha256=8dWeaQ_ZNdltC098V2YeLXsGdJHQnBa6shF1GAfl0Zg,2973
|
|
22
|
-
iplotx/ingest/providers/network/networkx.py,sha256=
|
|
22
|
+
iplotx/ingest/providers/network/networkx.py,sha256=4sPFOx87ipOYlXu0hjJl25Z4So_RnhO1CYYozGp-wJg,4626
|
|
23
23
|
iplotx/ingest/providers/network/simple.py,sha256=e_aHhiHhN9DrMoNrt7tEMPURXGhQ1TYRPzsxDEptUlc,3766
|
|
24
24
|
iplotx/ingest/providers/tree/biopython.py,sha256=4N_54cVyHHPcASJZGr6pHKE2p5R3i8Cm307SLlSLHLA,1480
|
|
25
25
|
iplotx/ingest/providers/tree/cogent3.py,sha256=JmELbDK7LyybiJzFNbmeqZ4ySJoDajvFfJebpNfFKWo,1073
|
|
@@ -33,6 +33,6 @@ iplotx/utils/geometry.py,sha256=6RrC6qaB0-1vIk1LhGA4CfsiMd-9JNniSPyL_l9mshE,9245
|
|
|
33
33
|
iplotx/utils/internal.py,sha256=WWfcZDGK8Ut1y_tOHRGg9wSqY1bwSeLQO7dHM_8Tvwo,107
|
|
34
34
|
iplotx/utils/matplotlib.py,sha256=wELE73quQv10-1w9uA5eDTgkZkylJvjg7pd3K5tZPOo,6294
|
|
35
35
|
iplotx/utils/style.py,sha256=wMWxJykxBD-JmcN8-rSKlWcV6pMfwKgR4EzSpk_NX8k,547
|
|
36
|
-
iplotx-0.6.
|
|
37
|
-
iplotx-0.6.
|
|
38
|
-
iplotx-0.6.
|
|
36
|
+
iplotx-0.6.7.dist-info/METADATA,sha256=O3tkLhtN4pM3FxyONC75a3CYvf1Ba6iU8bHRTgtBzgM,4908
|
|
37
|
+
iplotx-0.6.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
38
|
+
iplotx-0.6.7.dist-info/RECORD,,
|
|
File without changes
|