iplotx 0.6.8__py3-none-any.whl → 0.7.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/edge/__init__.py +5 -3
- iplotx/edge/arrow.py +30 -5
- iplotx/edge/geometry.py +15 -15
- iplotx/style/__init__.py +22 -0
- iplotx/style/leaf_info.py +3 -1
- iplotx/style/library.py +1 -1
- iplotx/version.py +1 -1
- iplotx/vertex.py +5 -1
- {iplotx-0.6.8.dist-info → iplotx-0.7.0.dist-info}/METADATA +1 -1
- {iplotx-0.6.8.dist-info → iplotx-0.7.0.dist-info}/RECORD +11 -11
- {iplotx-0.6.8.dist-info → iplotx-0.7.0.dist-info}/WHEEL +0 -0
iplotx/edge/__init__.py
CHANGED
|
@@ -352,9 +352,9 @@ class EdgeCollection(mpl.collections.PatchCollection):
|
|
|
352
352
|
tension = 0
|
|
353
353
|
ports = None
|
|
354
354
|
|
|
355
|
-
# Scale
|
|
355
|
+
# Scale shrink by dpi
|
|
356
356
|
dpi = self.figure.dpi if hasattr(self, "figure") else 72.0
|
|
357
|
-
|
|
357
|
+
shrink = dpi / 72.0 * edge_stylei.pop("shrink", 0)
|
|
358
358
|
|
|
359
359
|
# False is a synonym for "none"
|
|
360
360
|
waypoints = edge_stylei.get("waypoints", "none")
|
|
@@ -380,7 +380,7 @@ class EdgeCollection(mpl.collections.PatchCollection):
|
|
|
380
380
|
waypoints=waypoints,
|
|
381
381
|
ports=ports,
|
|
382
382
|
layout_coordinate_system=self._vertex_collection.get_layout_coordinate_system(),
|
|
383
|
-
|
|
383
|
+
shrink=shrink,
|
|
384
384
|
)
|
|
385
385
|
|
|
386
386
|
offset = edge_stylei.get("offset", 0)
|
|
@@ -720,6 +720,8 @@ def make_stub_patch(**kwargs):
|
|
|
720
720
|
"cmap",
|
|
721
721
|
"norm",
|
|
722
722
|
"split",
|
|
723
|
+
"shrink",
|
|
724
|
+
# DEPRECATED
|
|
723
725
|
"padding",
|
|
724
726
|
]
|
|
725
727
|
for prop in forbidden_props:
|
iplotx/edge/arrow.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Module for edge arrows in iplotx.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from typing import Never
|
|
5
|
+
from typing import Never, Optional
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
import matplotlib as mpl
|
|
@@ -149,10 +149,35 @@ class EdgeArrowCollection(mpl.collections.PatchCollection):
|
|
|
149
149
|
super().draw(renderer)
|
|
150
150
|
|
|
151
151
|
|
|
152
|
-
def make_arrow_patch(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
152
|
+
def make_arrow_patch(
|
|
153
|
+
marker: str = "|>",
|
|
154
|
+
width: float = 8,
|
|
155
|
+
height: Optional[float | str] = None,
|
|
156
|
+
**kwargs,
|
|
157
|
+
):
|
|
158
|
+
"""Make a patch of the given marker shape and size.
|
|
159
|
+
|
|
160
|
+
Parameters:
|
|
161
|
+
marker: The marker shape to use. Supported markers are:
|
|
162
|
+
"|>", "|/", "|\\", ">", "<", ">>", ")>", ")", "(", "]", "[", "|",
|
|
163
|
+
"x", "s", "d", "p", "q". Dashes at the start of this string will
|
|
164
|
+
be ignored, so "->" is equivalent to ">".
|
|
165
|
+
width: The width of the marker in points. Height is by default 1.3 the
|
|
166
|
+
width, unless specified separately.
|
|
167
|
+
height: The height of the marker in points. If not specified, it is
|
|
168
|
+
1.3 times the width. This can also be the string "width", in which
|
|
169
|
+
case the height will be equal to the width.
|
|
170
|
+
**kwargs: Additional keyword arguments passed to the PathPatch.
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
A pair with the patch and the max size of the patch in points.
|
|
174
|
+
"""
|
|
175
|
+
# Forget any leading dashes
|
|
176
|
+
marker = marker.lstrip("-")
|
|
177
|
+
|
|
178
|
+
if height is None:
|
|
179
|
+
height = width * 1.3
|
|
180
|
+
elif height == "width":
|
|
156
181
|
height = width
|
|
157
182
|
|
|
158
183
|
# Normalise by the max size, this is taken care of in _transforms
|
iplotx/edge/geometry.py
CHANGED
|
@@ -64,7 +64,7 @@ def _compute_loops_per_angle(nloops, angles):
|
|
|
64
64
|
]
|
|
65
65
|
|
|
66
66
|
|
|
67
|
-
def _get_shorter_edge_coords(vpath, vsize, theta,
|
|
67
|
+
def _get_shorter_edge_coords(vpath, vsize, theta, shrink=0):
|
|
68
68
|
# Bound theta from -pi to pi (why is that not guaranteed?)
|
|
69
69
|
theta = (theta + pi) % (2 * pi) - pi
|
|
70
70
|
|
|
@@ -105,8 +105,8 @@ def _get_shorter_edge_coords(vpath, vsize, theta, padding=0):
|
|
|
105
105
|
|
|
106
106
|
ve = ve * vsize
|
|
107
107
|
|
|
108
|
-
#
|
|
109
|
-
ve +=
|
|
108
|
+
# Shrink (assuming dpi scaling is already applied to the shrink)
|
|
109
|
+
ve += shrink * np.array([np.cos(theta), np.sin(theta)])
|
|
110
110
|
|
|
111
111
|
return ve
|
|
112
112
|
|
|
@@ -145,12 +145,12 @@ def _compute_loop_path(
|
|
|
145
145
|
angle2,
|
|
146
146
|
trans_inv,
|
|
147
147
|
looptension,
|
|
148
|
-
|
|
148
|
+
shrink=0,
|
|
149
149
|
):
|
|
150
150
|
# Shorten at starting angle
|
|
151
|
-
start = _get_shorter_edge_coords(vpath, vsize, angle1,
|
|
151
|
+
start = _get_shorter_edge_coords(vpath, vsize, angle1, shrink) + vcoord_fig
|
|
152
152
|
# Shorten at end angle
|
|
153
|
-
end = _get_shorter_edge_coords(vpath, vsize, angle2,
|
|
153
|
+
end = _get_shorter_edge_coords(vpath, vsize, angle2, shrink) + vcoord_fig
|
|
154
154
|
|
|
155
155
|
aux1 = (start - vcoord_fig) * looptension + vcoord_fig
|
|
156
156
|
aux2 = (end - vcoord_fig) * looptension + vcoord_fig
|
|
@@ -182,7 +182,7 @@ def _compute_edge_path_straight(
|
|
|
182
182
|
trans,
|
|
183
183
|
trans_inv,
|
|
184
184
|
layout_coordinate_system: str = "cartesian",
|
|
185
|
-
|
|
185
|
+
shrink: float = 0,
|
|
186
186
|
**kwargs,
|
|
187
187
|
):
|
|
188
188
|
if layout_coordinate_system not in ("cartesian", "polar"):
|
|
@@ -211,11 +211,11 @@ def _compute_edge_path_straight(
|
|
|
211
211
|
theta = atan2(*((vcoord_fig[1] - vcoord_fig[0])[::-1]))
|
|
212
212
|
|
|
213
213
|
# Shorten at starting vertex
|
|
214
|
-
vs = _get_shorter_edge_coords(vpath_fig[0], vsize_fig[0], theta,
|
|
214
|
+
vs = _get_shorter_edge_coords(vpath_fig[0], vsize_fig[0], theta, shrink) + vcoord_fig[0]
|
|
215
215
|
points.append(vs)
|
|
216
216
|
|
|
217
217
|
# Shorten at end vertex
|
|
218
|
-
ve = _get_shorter_edge_coords(vpath_fig[1], vsize_fig[1], theta + pi,
|
|
218
|
+
ve = _get_shorter_edge_coords(vpath_fig[1], vsize_fig[1], theta + pi, shrink) + vcoord_fig[1]
|
|
219
219
|
points.append(ve)
|
|
220
220
|
|
|
221
221
|
codes = ["MOVETO", "LINETO"]
|
|
@@ -237,7 +237,7 @@ def _compute_edge_path_waypoints(
|
|
|
237
237
|
layout_coordinate_system: str = "cartesian",
|
|
238
238
|
points_per_curve: int = 30,
|
|
239
239
|
ports: Pair[Optional[str]] = (None, None),
|
|
240
|
-
|
|
240
|
+
shrink: float = 0,
|
|
241
241
|
**kwargs,
|
|
242
242
|
):
|
|
243
243
|
if not isinstance(waypoints, str):
|
|
@@ -263,7 +263,7 @@ def _compute_edge_path_waypoints(
|
|
|
263
263
|
|
|
264
264
|
# Shorten at vertex border
|
|
265
265
|
vshorts[i] = (
|
|
266
|
-
_get_shorter_edge_coords(vpath_fig[i], vsize_fig[i], thetas[i],
|
|
266
|
+
_get_shorter_edge_coords(vpath_fig[i], vsize_fig[i], thetas[i], shrink)
|
|
267
267
|
+ vcoord_fig[i]
|
|
268
268
|
)
|
|
269
269
|
|
|
@@ -293,7 +293,7 @@ def _compute_edge_path_waypoints(
|
|
|
293
293
|
|
|
294
294
|
# Shorten at vertex border
|
|
295
295
|
vshorts[i] = (
|
|
296
|
-
_get_shorter_edge_coords(vpath_fig[i], vsize_fig[i], thetas[i],
|
|
296
|
+
_get_shorter_edge_coords(vpath_fig[i], vsize_fig[i], thetas[i], shrink)
|
|
297
297
|
+ vcoord_fig[i]
|
|
298
298
|
)
|
|
299
299
|
|
|
@@ -343,7 +343,7 @@ def _compute_edge_path_waypoints(
|
|
|
343
343
|
|
|
344
344
|
# Shorten at vertex border
|
|
345
345
|
vshort = (
|
|
346
|
-
_get_shorter_edge_coords(vpath_fig[i], vsize_fig[i], theta,
|
|
346
|
+
_get_shorter_edge_coords(vpath_fig[i], vsize_fig[i], theta, shrink) + vcoord_fig[i]
|
|
347
347
|
)
|
|
348
348
|
thetas.append(theta)
|
|
349
349
|
vshorts.append(vshort)
|
|
@@ -391,7 +391,7 @@ def _compute_edge_path_curved(
|
|
|
391
391
|
trans,
|
|
392
392
|
trans_inv,
|
|
393
393
|
ports: Pair[Optional[str]] = (None, None),
|
|
394
|
-
|
|
394
|
+
shrink: float = 0,
|
|
395
395
|
):
|
|
396
396
|
"""Shorten the edge path along a cubic Bezier between the vertex centres.
|
|
397
397
|
|
|
@@ -445,7 +445,7 @@ def _compute_edge_path_curved(
|
|
|
445
445
|
for i in range(2):
|
|
446
446
|
thetas[i] = atan2(*((auxs[i] - vcoord_fig[i])[::-1]))
|
|
447
447
|
vs[i] = (
|
|
448
|
-
_get_shorter_edge_coords(vpath_fig[i], vsize_fig[i], thetas[i],
|
|
448
|
+
_get_shorter_edge_coords(vpath_fig[i], vsize_fig[i], thetas[i], shrink) + vcoord_fig[i]
|
|
449
449
|
)
|
|
450
450
|
|
|
451
451
|
path = {
|
iplotx/style/__init__.py
CHANGED
|
@@ -141,6 +141,27 @@ def merge_styles(
|
|
|
141
141
|
value,
|
|
142
142
|
)
|
|
143
143
|
|
|
144
|
+
def _sanitize_ambiguous(style: dict):
|
|
145
|
+
"""Fix a few ambiguous cases in the style dict."""
|
|
146
|
+
|
|
147
|
+
# Accept "node" style as "vertex" style for user flexibility
|
|
148
|
+
if "node" in style:
|
|
149
|
+
style_node = style.pop("node")
|
|
150
|
+
if "vertex" not in style:
|
|
151
|
+
style["vertex"] = style_node
|
|
152
|
+
else:
|
|
153
|
+
# "node" style applies on TOP of "vertex" style
|
|
154
|
+
_update(style_node, style["vertex"])
|
|
155
|
+
|
|
156
|
+
# NOTE: Deprecate edge_padding for edge_shrink
|
|
157
|
+
for edgekey in ["edge", "leafedge"]:
|
|
158
|
+
if "padding" in style.get(edgekey, {}):
|
|
159
|
+
# shrink takes over
|
|
160
|
+
if "shrink" in style[edgekey]:
|
|
161
|
+
del style[edgekey]["padding"]
|
|
162
|
+
else:
|
|
163
|
+
style[edgekey]["shrink"] = style[edgekey].pop("padding")
|
|
164
|
+
|
|
144
165
|
merged = {}
|
|
145
166
|
for style in styles:
|
|
146
167
|
if isinstance(style, str):
|
|
@@ -148,6 +169,7 @@ def merge_styles(
|
|
|
148
169
|
else:
|
|
149
170
|
_sanitize_leaves(style)
|
|
150
171
|
unflatten_style(style)
|
|
172
|
+
_sanitize_ambiguous(style)
|
|
151
173
|
_update(style, merged)
|
|
152
174
|
|
|
153
175
|
return merged
|
iplotx/style/leaf_info.py
CHANGED
|
@@ -22,10 +22,12 @@ rotating_leaves = (
|
|
|
22
22
|
"vpadding",
|
|
23
23
|
"hmargin",
|
|
24
24
|
"vmargin",
|
|
25
|
-
"padding",
|
|
26
25
|
"ports",
|
|
27
26
|
"width",
|
|
28
27
|
"height",
|
|
28
|
+
"shrink",
|
|
29
|
+
# DEPRECATED
|
|
30
|
+
"padding",
|
|
29
31
|
)
|
|
30
32
|
|
|
31
33
|
# These properties are also terminal style properties, but they cannot be rotated.
|
iplotx/style/library.py
CHANGED
iplotx/version.py
CHANGED
iplotx/vertex.py
CHANGED
|
@@ -247,7 +247,11 @@ class VertexCollection(PatchCollection):
|
|
|
247
247
|
patches = []
|
|
248
248
|
sizes = []
|
|
249
249
|
for i, (vid, row) in enumerate(self._layout.iterrows()):
|
|
250
|
-
|
|
250
|
+
# Use vertex labels if present as a fallback key for style rotation
|
|
251
|
+
# This way one can be very specific via the exact object or cast
|
|
252
|
+
# a looser net with the label string
|
|
253
|
+
key2 = self._labels.iloc[i] if self._labels is not None else None
|
|
254
|
+
stylei = rotate_style(style, index=i, key=vid, key2=key2)
|
|
251
255
|
if stylei.get("size", 20) == "label":
|
|
252
256
|
stylei["size"] = _get_label_width_height(
|
|
253
257
|
str(self._labels[vid]), **style.get("label", {})
|
|
@@ -8,11 +8,11 @@ iplotx/network.py,sha256=LaW9zQZ4sKiDVb25_icnquGNnN7HrKC7NO07o6PSmGI,11527
|
|
|
8
8
|
iplotx/plotting.py,sha256=IEUxW1xzTljLjBfsVP2BNsOPCDpj5bEPZ99bzvD5-mo,10066
|
|
9
9
|
iplotx/tree.py,sha256=-69lpPjisRfigY4fDQcmVxzOAf1tGwMXviUcW6mZU6U,28508
|
|
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=
|
|
14
|
-
iplotx/edge/arrow.py,sha256=
|
|
15
|
-
iplotx/edge/geometry.py,sha256=
|
|
11
|
+
iplotx/version.py,sha256=8BIMMcy91d9_BPlUuoNyMNeyj04-gejk1STd-SLsrT0,66
|
|
12
|
+
iplotx/vertex.py,sha256=hqdlD9fRBSwH5bRvlpaaPu7jgUR4z9nob1SYfPWDxtI,14966
|
|
13
|
+
iplotx/edge/__init__.py,sha256=AVnLsrDWWCkix1LVhrjpWKEKDxOp8joM4tF6RqEHC8I,27115
|
|
14
|
+
iplotx/edge/arrow.py,sha256=ZKt3UNZ7XRa2S3KxpoQfd4q_6eSUHOS476BZNqlf2pw,16462
|
|
15
|
+
iplotx/edge/geometry.py,sha256=wpFTi12-BaUaWr6Ie-nHV_SMAdSGJvjzJaqeEaSPf9w,15053
|
|
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
|
|
@@ -26,13 +26,13 @@ iplotx/ingest/providers/tree/cogent3.py,sha256=JmELbDK7LyybiJzFNbmeqZ4ySJoDajvFf
|
|
|
26
26
|
iplotx/ingest/providers/tree/ete4.py,sha256=D7usSq0MOjzrk3EoLi834IlaDGwv7_qG6Qt0ptfKqfI,928
|
|
27
27
|
iplotx/ingest/providers/tree/simple.py,sha256=aV9wGqBomJ5klM_aJQeuL_Q_J1pLCv6AFN98BPDiKUw,2593
|
|
28
28
|
iplotx/ingest/providers/tree/skbio.py,sha256=O1KUr8tYi28pZ3VVjapgO4Uj-YpMuix3GhOH5je8Lv4,822
|
|
29
|
-
iplotx/style/__init__.py,sha256=
|
|
30
|
-
iplotx/style/leaf_info.py,sha256=
|
|
31
|
-
iplotx/style/library.py,sha256=
|
|
29
|
+
iplotx/style/__init__.py,sha256=_LhOJ9WJzC3of_nbaJyAJX3k4paI8utrigTzYDZRSB8,13138
|
|
30
|
+
iplotx/style/leaf_info.py,sha256=mcd6ewZl3jC0CPshmbeUkNp2geoihJW9515roGy2T8o,1000
|
|
31
|
+
iplotx/style/library.py,sha256=58Y8BlllGLsR4pQM7_PVCP5tH6_4GkchXZvJpqGHlcg,8534
|
|
32
32
|
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.
|
|
37
|
-
iplotx-0.
|
|
38
|
-
iplotx-0.
|
|
36
|
+
iplotx-0.7.0.dist-info/METADATA,sha256=vbdamou2U35GeUBn4_fG8kzeC9fTwYRzKeg2Ik9212Q,4908
|
|
37
|
+
iplotx-0.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
38
|
+
iplotx-0.7.0.dist-info/RECORD,,
|
|
File without changes
|