phylogenie 2.1.16__tar.gz → 2.1.18__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.
Potentially problematic release.
This version of phylogenie might be problematic. Click here for more details.
- {phylogenie-2.1.16 → phylogenie-2.1.18}/PKG-INFO +1 -1
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/plot.py +47 -6
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/tree.py +1 -1
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/utils.py +1 -1
- {phylogenie-2.1.16 → phylogenie-2.1.18}/pyproject.toml +1 -1
- {phylogenie-2.1.16 → phylogenie-2.1.18}/LICENSE.txt +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/README.md +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/__init__.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/generators/__init__.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/generators/alisim.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/generators/configs.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/generators/dataset.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/generators/factories.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/generators/trees.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/generators/typeguards.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/io.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/main.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/models.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/msa.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/py.typed +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/skyline/__init__.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/skyline/matrix.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/skyline/parameter.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/skyline/vector.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/treesimulator/__init__.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/treesimulator/events/__init__.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/treesimulator/events/contact_tracing.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/treesimulator/events/core.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/treesimulator/events/mutations.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/treesimulator/features.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/treesimulator/gillespie.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/treesimulator/model.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/typeguards.py +0 -0
- {phylogenie-2.1.16 → phylogenie-2.1.18}/phylogenie/typings.py +0 -0
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
|
+
from typing import Any
|
|
2
3
|
|
|
3
4
|
import matplotlib.colors as mcolors
|
|
4
5
|
import matplotlib.patches as mpatches
|
|
5
6
|
import matplotlib.pyplot as plt
|
|
6
7
|
from matplotlib.axes import Axes
|
|
8
|
+
from mpl_toolkits.axes_grid1.inset_locator import inset_axes # pyright: ignore
|
|
7
9
|
|
|
8
10
|
from phylogenie.tree import Tree
|
|
9
11
|
from phylogenie.utils import get_node_depth_levels, get_node_depths
|
|
@@ -22,7 +24,10 @@ def plot_tree(
|
|
|
22
24
|
coloring: str | Coloring | None = None,
|
|
23
25
|
cmap: str | None = None,
|
|
24
26
|
show_legend: bool = True,
|
|
25
|
-
|
|
27
|
+
show_hist: bool = True,
|
|
28
|
+
hist_kwargs: dict[str, Any] | None = None,
|
|
29
|
+
hist_axes_kwargs: dict[str, Any] | None = None,
|
|
30
|
+
) -> Axes | tuple[Axes, Axes]:
|
|
26
31
|
if ax is None:
|
|
27
32
|
ax = plt.gca()
|
|
28
33
|
|
|
@@ -34,7 +39,8 @@ def plot_tree(
|
|
|
34
39
|
ys = {node: i for i, node in enumerate(tree.inorder_traversal())}
|
|
35
40
|
|
|
36
41
|
if color_by is not None:
|
|
37
|
-
features =
|
|
42
|
+
features = [node.get(color_by) for node in tree if color_by in node.features]
|
|
43
|
+
|
|
38
44
|
if coloring is None and any(isinstance(f, float) for f in features):
|
|
39
45
|
coloring = Coloring.CONTINUOUS
|
|
40
46
|
elif coloring is None:
|
|
@@ -47,7 +53,7 @@ def plot_tree(
|
|
|
47
53
|
)
|
|
48
54
|
colormap = plt.get_cmap("tab20" if cmap is None else cmap)
|
|
49
55
|
feature_colors = {
|
|
50
|
-
f: mcolors.to_hex(colormap(i)) for i, f in enumerate(features)
|
|
56
|
+
f: mcolors.to_hex(colormap(i)) for i, f in enumerate(set(features))
|
|
51
57
|
}
|
|
52
58
|
colors = {
|
|
53
59
|
node: (
|
|
@@ -61,7 +67,7 @@ def plot_tree(
|
|
|
61
67
|
if show_legend:
|
|
62
68
|
legend_handles = [
|
|
63
69
|
mpatches.Patch(color=feature_colors[f], label=str(f))
|
|
64
|
-
for f in
|
|
70
|
+
for f in feature_colors
|
|
65
71
|
]
|
|
66
72
|
if any(color_by not in node.features for node in tree):
|
|
67
73
|
legend_handles.append(
|
|
@@ -81,8 +87,34 @@ def plot_tree(
|
|
|
81
87
|
for node in tree
|
|
82
88
|
}
|
|
83
89
|
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
if show_hist:
|
|
91
|
+
default_hist_axes_kwargs = {
|
|
92
|
+
"width": "25%",
|
|
93
|
+
"height": "25%",
|
|
94
|
+
"loc": "lower left",
|
|
95
|
+
"borderpad": 3,
|
|
96
|
+
}
|
|
97
|
+
if hist_axes_kwargs is not None:
|
|
98
|
+
default_hist_axes_kwargs.update(hist_axes_kwargs)
|
|
99
|
+
hist_ax = inset_axes(ax, **default_hist_axes_kwargs) # pyright: ignore
|
|
100
|
+
|
|
101
|
+
hist_kwargs = {} if hist_kwargs is None else hist_kwargs
|
|
102
|
+
_, bins, patches = hist_ax.hist( # pyright: ignore
|
|
103
|
+
features, **hist_kwargs
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
for patch, b0, b1 in zip( # pyright: ignore
|
|
107
|
+
patches, bins[:-1], bins[1:] # pyright: ignore
|
|
108
|
+
):
|
|
109
|
+
midpoint = (b0 + b1) / 2 # pyright: ignore
|
|
110
|
+
patch.set_facecolor(colormap(norm(midpoint))) # pyright: ignore
|
|
111
|
+
|
|
112
|
+
hist_ax.set_xlabel(color_by.capitalize(), fontsize=8) # pyright: ignore
|
|
113
|
+
hist_ax.set_ylabel("Count", fontsize=8) # pyright: ignore
|
|
114
|
+
hist_ax.tick_params(axis="both", labelsize=6) # pyright: ignore
|
|
115
|
+
else:
|
|
116
|
+
sm = plt.cm.ScalarMappable(cmap=colormap, norm=norm)
|
|
117
|
+
ax.get_figure().colorbar(sm, ax=ax) # pyright: ignore
|
|
86
118
|
|
|
87
119
|
else:
|
|
88
120
|
raise ValueError(
|
|
@@ -100,5 +132,14 @@ def plot_tree(
|
|
|
100
132
|
ax.vlines(x=x0, ymin=y0, ymax=y1, color=colors[node]) # pyright: ignore
|
|
101
133
|
ax.hlines(y=y1, xmin=x0, xmax=x1, color=colors[node]) # pyright: ignore
|
|
102
134
|
|
|
135
|
+
for node in tree:
|
|
136
|
+
x1, y1 = xs[node], ys[node]
|
|
137
|
+
if node.parent is None:
|
|
138
|
+
ax.hlines(y=y1, xmin=0, xmax=x1, color=colors[node]) # pyright: ignore
|
|
139
|
+
continue
|
|
140
|
+
x0, y0 = xs[node.parent], ys[node.parent]
|
|
141
|
+
ax.vlines(x=x0, ymin=y0, ymax=y1, color=colors[node]) # pyright: ignore
|
|
142
|
+
ax.hlines(y=y1, xmin=x0, xmax=x1, color=colors[node]) # pyright: ignore
|
|
143
|
+
|
|
103
144
|
ax.set_yticks([]) # pyright: ignore
|
|
104
145
|
return ax
|
|
@@ -26,7 +26,7 @@ class Tree:
|
|
|
26
26
|
@property
|
|
27
27
|
def depth(self) -> float:
|
|
28
28
|
if self.parent is None:
|
|
29
|
-
return 0.
|
|
29
|
+
return 0 if self.branch_length is None else self.branch_length
|
|
30
30
|
if self.branch_length is None:
|
|
31
31
|
raise ValueError(f"Branch length of node {self.name} is not set.")
|
|
32
32
|
return self.parent.depth + self.branch_length
|
|
@@ -22,7 +22,7 @@ def get_node_depths(tree: Tree) -> dict[Tree, float]:
|
|
|
22
22
|
depths: dict[Tree, float] = {}
|
|
23
23
|
for node in tree:
|
|
24
24
|
if node.parent is None:
|
|
25
|
-
depths[node] = 0
|
|
25
|
+
depths[node] = 0 if node.branch_length is None else node.branch_length
|
|
26
26
|
else:
|
|
27
27
|
if node.branch_length is None:
|
|
28
28
|
raise ValueError(f"Branch length of node {node.name} is not set.")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|