trackplot 0.5.9__tar.gz → 0.6.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.
- {trackplot-0.5.9/trackplot.egg-info → trackplot-0.6.0}/PKG-INFO +1 -1
- {trackplot-0.5.9 → trackplot-0.6.0}/pyproject.toml +1 -1
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/cli.py +3 -9
- trackplot-0.6.0/trackplot/plot/__init__.py +57 -0
- trackplot-0.6.0/trackplot/plot/coord.py +306 -0
- trackplot-0.6.0/trackplot/plot/core.py +1252 -0
- trackplot-0.6.0/trackplot/plot/info.py +163 -0
- trackplot-0.6.0/trackplot/plot/limits.py +193 -0
- trackplot-0.6.0/trackplot/plot/render.py +1263 -0
- trackplot-0.6.0/trackplot/plot/utils.py +129 -0
- trackplot-0.6.0/trackplot/plot_func.py +10 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/server.py +5 -1
- {trackplot-0.5.9 → trackplot-0.6.0/trackplot.egg-info}/PKG-INFO +1 -1
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot.egg-info/SOURCES.txt +20 -2
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot.egg-info/top_level.txt +1 -0
- trackplot-0.6.0/ui/assets/Home-B1EPE6Lq.js +1 -0
- trackplot-0.6.0/ui/assets/Home-DuHqFHEh.css +1 -0
- trackplot-0.6.0/ui/assets/Plot-CkylK0fA.css +1 -0
- trackplot-0.6.0/ui/assets/Plot-jZAsK7Tq.js +24 -0
- trackplot-0.6.0/ui/assets/_plugin-vue_export-helper-DLf8tVwz.css +1 -0
- trackplot-0.6.0/ui/assets/_plugin-vue_export-helper-IgiCOkTJ.js +1 -0
- trackplot-0.6.0/ui/assets/css-BDwM7dEv.css +1 -0
- trackplot-0.6.0/ui/assets/css-CKLNJEB6.js +4 -0
- trackplot-0.6.0/ui/assets/index-De-rfTdP.js +2 -0
- trackplot-0.6.0/ui/assets/index-Dlq_kUQH.css +1 -0
- trackplot-0.6.0/ui/index.html +16 -0
- trackplot-0.6.0/ui/vite.svg +1 -0
- trackplot-0.5.9/trackplot/plot.py +0 -1618
- trackplot-0.5.9/trackplot/plot_func.py +0 -1941
- {trackplot-0.5.9 → trackplot-0.6.0}/LICENSE +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/README.md +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/setup.cfg +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/__init__.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/anno/AxLabel.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/anno/__init__.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/anno/theme.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/base/CoordinateMap.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/base/GenomicLoci.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/base/Junction.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/base/Protein.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/base/ReadDepth.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/base/Readder.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/base/Stroke.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/base/Transcript.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/base/__init__.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/base/pyUniprot.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/conf/DomainSetting.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/conf/__init__.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/conf/config.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/conf/drawing.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/conf/ui.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/ATAC.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/Annotation.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/Bam.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/BedGraph.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/Bigwig.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/Depth.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/Fasta.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/File.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/HiCMatrixTrack.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/Junction.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/Motif.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/ReadSegments.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot/file/__init__.py +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot.egg-info/dependency_links.txt +0 -0
- {trackplot-0.5.9 → trackplot-0.6.0}/trackplot.egg-info/requires.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: trackplot
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: The trackplot is a tool for visualizing various next-generation sequencing (NGS) data, including DNA-seq, RNA-seq, single-cell RNA-seq and full-length sequencing datasets. https://sashimi.readthedocs.io/
|
|
5
5
|
Author-email: ygidtu <ygidtu@gmail.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "trackplot"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.6.0"
|
|
4
4
|
description = "The trackplot is a tool for visualizing various next-generation sequencing (NGS) data, including DNA-seq, RNA-seq, single-cell RNA-seq and full-length sequencing datasets. https://sashimi.readthedocs.io/"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "ygidtu", email = "ygidtu@gmail.com" }
|
|
@@ -16,17 +16,11 @@ from click_option_group import optgroup
|
|
|
16
16
|
from loguru import logger
|
|
17
17
|
|
|
18
18
|
from trackplot.base.GenomicLoci import GenomicLoci
|
|
19
|
-
from trackplot.conf.config import (
|
|
20
|
-
|
|
21
|
-
COLORMAP,
|
|
22
|
-
COLORS,
|
|
23
|
-
DISTANCE_METRIC,
|
|
24
|
-
IMAGE_TYPE,
|
|
25
|
-
NORMALIZATION,
|
|
26
|
-
)
|
|
19
|
+
from trackplot.conf.config import (CLUSTERING_METHOD, COLORMAP, COLORS,
|
|
20
|
+
DISTANCE_METRIC, IMAGE_TYPE, NORMALIZATION)
|
|
27
21
|
from trackplot.plot import Plot, __version__
|
|
28
22
|
from trackplot.plot_func import load_barcodes
|
|
29
|
-
from trackplot.server import __PLOT__
|
|
23
|
+
from trackplot.server import __PLOT__
|
|
30
24
|
|
|
31
25
|
|
|
32
26
|
def decode_region(region: str):
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
trackplot.plot — plot orchestration and rendering package.
|
|
5
|
+
|
|
6
|
+
Re-exports all public symbols for backward compatibility.
|
|
7
|
+
Use ``from trackplot.plot.core import Plot`` or ``from trackplot.plot.render import plot_density`` for direct access.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from trackplot.plot.coord import (init_graph_coords, set_focus,
|
|
11
|
+
set_indicator_lines, set_x_ticks,
|
|
12
|
+
set_y_ticks)
|
|
13
|
+
from trackplot.plot.core import (Plot, __author__, __email__, __version__,
|
|
14
|
+
add_object_error)
|
|
15
|
+
from trackplot.plot.info import PlotInfo
|
|
16
|
+
from trackplot.plot.limits import precompute_y_limits
|
|
17
|
+
from trackplot.plot.render import (plot_annotation, plot_density, plot_heatmap,
|
|
18
|
+
plot_hic, plot_igv_like, plot_line,
|
|
19
|
+
plot_links, plot_motif, plot_site_plot,
|
|
20
|
+
plot_stroke)
|
|
21
|
+
from trackplot.plot.utils import (__merge_exons__, cubic_bezier,
|
|
22
|
+
get_limited_index, load_barcodes,
|
|
23
|
+
make_text_elements)
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"Plot",
|
|
27
|
+
"PlotInfo",
|
|
28
|
+
"add_object_error",
|
|
29
|
+
"__version__",
|
|
30
|
+
"__author__",
|
|
31
|
+
"__email__",
|
|
32
|
+
# utils
|
|
33
|
+
"load_barcodes",
|
|
34
|
+
"get_limited_index",
|
|
35
|
+
"cubic_bezier",
|
|
36
|
+
"__merge_exons__",
|
|
37
|
+
"make_text_elements",
|
|
38
|
+
# coord
|
|
39
|
+
"init_graph_coords",
|
|
40
|
+
"set_x_ticks",
|
|
41
|
+
"set_y_ticks",
|
|
42
|
+
"set_focus",
|
|
43
|
+
"set_indicator_lines",
|
|
44
|
+
# limits
|
|
45
|
+
"precompute_y_limits",
|
|
46
|
+
# render
|
|
47
|
+
"plot_stroke",
|
|
48
|
+
"plot_annotation",
|
|
49
|
+
"plot_density",
|
|
50
|
+
"plot_site_plot",
|
|
51
|
+
"plot_heatmap",
|
|
52
|
+
"plot_hic",
|
|
53
|
+
"plot_line",
|
|
54
|
+
"plot_igv_like",
|
|
55
|
+
"plot_links",
|
|
56
|
+
"plot_motif",
|
|
57
|
+
]
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Coordinate system transformation, axis helpers, and overlay drawing.
|
|
5
|
+
|
|
6
|
+
Dependencies: GenomicLoci, Theme, utils
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import itertools
|
|
10
|
+
import math
|
|
11
|
+
from typing import Dict, List, Optional, Union
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
from loguru import logger
|
|
15
|
+
from matplotlib import pylab
|
|
16
|
+
|
|
17
|
+
from trackplot.anno.theme import Theme
|
|
18
|
+
from trackplot.base.GenomicLoci import GenomicLoci
|
|
19
|
+
from trackplot.plot.utils import __merge_exons__
|
|
20
|
+
|
|
21
|
+
# ============================================================================
|
|
22
|
+
# Coordinate system
|
|
23
|
+
# ============================================================================
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def init_graph_coords(
|
|
27
|
+
region: GenomicLoci,
|
|
28
|
+
exons: Optional[List[List[int]]] = None,
|
|
29
|
+
exon_scale=1,
|
|
30
|
+
intron_scale=0.5,
|
|
31
|
+
) -> np.ndarray:
|
|
32
|
+
"""
|
|
33
|
+
init the default
|
|
34
|
+
:param region: the plot region
|
|
35
|
+
:param exons: list of start and end sites of exons [[start, end], [start, end]]
|
|
36
|
+
:param exon_scale: the scale of exon, default set to 1
|
|
37
|
+
:param intron_scale: the scale of intron, default set to 0.5 -> the intron showed in final will be half size of real
|
|
38
|
+
"""
|
|
39
|
+
graph_coords = np.zeros(len(region), dtype=int)
|
|
40
|
+
|
|
41
|
+
if exons:
|
|
42
|
+
if intron_scale <= 1:
|
|
43
|
+
for i in range(0, exons[0][0] - region.start):
|
|
44
|
+
graph_coords[i] = (i - 0) * intron_scale
|
|
45
|
+
exons = __merge_exons__(exons)
|
|
46
|
+
for i in range(0, len(exons)):
|
|
47
|
+
exon = exons[i]
|
|
48
|
+
if i > 0:
|
|
49
|
+
intron = [exons[i - 1][1], exons[i][0]]
|
|
50
|
+
for j in range(intron[0], intron[1]):
|
|
51
|
+
if j >= region.start:
|
|
52
|
+
graph_coords[j - region.start] = (
|
|
53
|
+
graph_coords[intron[0] - region.start - 1]
|
|
54
|
+
+ (j - intron[0] + 1) * intron_scale
|
|
55
|
+
)
|
|
56
|
+
for j in range(exon[0], exon[1] + 1):
|
|
57
|
+
if j >= region.start:
|
|
58
|
+
graph_coords[j - region.start] = (
|
|
59
|
+
graph_coords[exon[0] - region.start - 1]
|
|
60
|
+
+ (j - exon[0] + 1) * exon_scale
|
|
61
|
+
)
|
|
62
|
+
intron = [exons[-1][-1], region.end]
|
|
63
|
+
for i in range(intron[0], intron[1]):
|
|
64
|
+
if i >= region.start:
|
|
65
|
+
graph_coords[i - region.start] = (
|
|
66
|
+
graph_coords[intron[0] - region.start - 1]
|
|
67
|
+
+ (i - intron[0] + 1) * intron_scale
|
|
68
|
+
)
|
|
69
|
+
else:
|
|
70
|
+
exons = __merge_exons__(exons)
|
|
71
|
+
while exons[0][1] < region.start:
|
|
72
|
+
exons = exons[1:]
|
|
73
|
+
while exons[-1][0] > region.end:
|
|
74
|
+
exons = exons[:-1]
|
|
75
|
+
exons[0][0] = max(exons[0][0], region.start)
|
|
76
|
+
exons[-1][1] = min(exons[-1][1], region.end)
|
|
77
|
+
|
|
78
|
+
for i, e in enumerate(exons):
|
|
79
|
+
exons[i][0] -= region.start
|
|
80
|
+
exons[i][1] -= region.start
|
|
81
|
+
|
|
82
|
+
steps = [float(exon_scale)] * len(region)
|
|
83
|
+
if exons[0][0] > 0:
|
|
84
|
+
step = intron_scale / exons[0][0]
|
|
85
|
+
for i in range(exons[0][0]):
|
|
86
|
+
steps[i] = step
|
|
87
|
+
for e in range(1, len(exons)):
|
|
88
|
+
interval = exons[e][0] - exons[e - 1][1] - 2
|
|
89
|
+
step = intron_scale / interval
|
|
90
|
+
for i in range(exons[e - 1][1], exons[e][0]):
|
|
91
|
+
steps[i] = step
|
|
92
|
+
|
|
93
|
+
if last_interval := len(region) - exons[-1][1] - 1:
|
|
94
|
+
step = intron_scale / last_interval
|
|
95
|
+
for i in range(exons[1][1] + 1, len(region)):
|
|
96
|
+
steps[i] = step
|
|
97
|
+
graph_coords = list(map(int, itertools.accumulate(steps)))
|
|
98
|
+
else:
|
|
99
|
+
for i, j in enumerate(range(region.start, region.end + 1)):
|
|
100
|
+
graph_coords[j - region.start] = i
|
|
101
|
+
|
|
102
|
+
if graph_coords[-1] == 0:
|
|
103
|
+
current_max = max(np.where(graph_coords == np.max(graph_coords))[-1])
|
|
104
|
+
for i in np.where(graph_coords == 0)[0]:
|
|
105
|
+
if i > current_max:
|
|
106
|
+
graph_coords[i] = max(graph_coords) + 1
|
|
107
|
+
return graph_coords
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
# ============================================================================
|
|
111
|
+
# Axis helpers
|
|
112
|
+
# ============================================================================
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def set_x_ticks(
|
|
116
|
+
ax,
|
|
117
|
+
region: GenomicLoci,
|
|
118
|
+
graph_coords: Optional[Union[Dict, np.ndarray]] = None,
|
|
119
|
+
sequence: Optional[Dict[int, str]] = None,
|
|
120
|
+
log_trans: Optional[str] = None,
|
|
121
|
+
nx_ticks: int = 4,
|
|
122
|
+
font_size: int = 6,
|
|
123
|
+
**kwargs,
|
|
124
|
+
):
|
|
125
|
+
Theme.set_theme(ax, "blank")
|
|
126
|
+
if graph_coords is None:
|
|
127
|
+
graph_coords = init_graph_coords(region)
|
|
128
|
+
|
|
129
|
+
x_label = str(region)
|
|
130
|
+
|
|
131
|
+
if log_trans:
|
|
132
|
+
if log_trans in ["2", "10"]:
|
|
133
|
+
log_trans = f"log{log_trans}"
|
|
134
|
+
x_label = f"{x_label}, y axis is {log_trans} transformed"
|
|
135
|
+
|
|
136
|
+
ax.hlines(y=0, xmin=0, xmax=max(graph_coords), color="black", lw=1)
|
|
137
|
+
ax.text(
|
|
138
|
+
x=graph_coords[len(graph_coords) // 2],
|
|
139
|
+
y=-2.8,
|
|
140
|
+
s=x_label,
|
|
141
|
+
fontsize=font_size,
|
|
142
|
+
ha="center",
|
|
143
|
+
va="top",
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
bk = 1
|
|
147
|
+
if not sequence and nx_ticks > 1:
|
|
148
|
+
bk = max(graph_coords) // (nx_ticks - 1)
|
|
149
|
+
|
|
150
|
+
reverse_graph_coords = {}
|
|
151
|
+
for i in range(1, len(graph_coords)):
|
|
152
|
+
for x, y in zip(
|
|
153
|
+
range(graph_coords[i - 1], graph_coords[i]),
|
|
154
|
+
np.linspace(i - 1, i, num=graph_coords[i] - graph_coords[i - 1]),
|
|
155
|
+
):
|
|
156
|
+
reverse_graph_coords[x] = int(y)
|
|
157
|
+
|
|
158
|
+
for i in range(graph_coords[0]):
|
|
159
|
+
reverse_graph_coords[i] = graph_coords[0]
|
|
160
|
+
|
|
161
|
+
line_space = {}
|
|
162
|
+
for i in range(nx_ticks - 1):
|
|
163
|
+
i = bk * i
|
|
164
|
+
line_space[i] = reverse_graph_coords[i] + region.start
|
|
165
|
+
line_space[max(graph_coords)] = region.end
|
|
166
|
+
|
|
167
|
+
if sequence:
|
|
168
|
+
for i, seq in sequence.items():
|
|
169
|
+
relative_i = graph_coords[i - region.start]
|
|
170
|
+
if relative_i in line_space.keys():
|
|
171
|
+
temp_txs = "{}\\n{}".format(sequence.get(i, ""), line_space[relative_i])
|
|
172
|
+
else:
|
|
173
|
+
temp_txs = "\\n{}".format(sequence.get(i, ""))
|
|
174
|
+
line_space[relative_i] = temp_txs
|
|
175
|
+
|
|
176
|
+
for x, s in line_space.items():
|
|
177
|
+
ax.vlines(x=x, ymin=-0.5, ymax=0, color="black", lw=1)
|
|
178
|
+
ax.text(x=x, y=-1, s=s, fontsize=font_size, ha="center", va="top")
|
|
179
|
+
|
|
180
|
+
ax.set_ylim(-3.5, 1)
|
|
181
|
+
ax.set_xlim(min(graph_coords), max(graph_coords))
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def set_y_ticks(
|
|
185
|
+
ax,
|
|
186
|
+
label: str,
|
|
187
|
+
graph_coords: Union[Dict, np.array],
|
|
188
|
+
max_used_y_val: Union[int, float],
|
|
189
|
+
min_used_y_val: Optional[Union[int, float]] = None,
|
|
190
|
+
distance_between_label_axis: float = 0,
|
|
191
|
+
n_y_ticks: int = 4,
|
|
192
|
+
theme: str = "ticks",
|
|
193
|
+
font_size: int = 5,
|
|
194
|
+
show_y_label: bool = True,
|
|
195
|
+
set_label_only: bool = False,
|
|
196
|
+
**kwargs,
|
|
197
|
+
):
|
|
198
|
+
"""
|
|
199
|
+
The y ticks are formatted here
|
|
200
|
+
@2019.03.31 add little check here to make sure the y-axis shows the real value
|
|
201
|
+
"""
|
|
202
|
+
Theme.set_theme(ax, theme)
|
|
203
|
+
ax.set_xlim(min(graph_coords), max(graph_coords))
|
|
204
|
+
if min_used_y_val is None:
|
|
205
|
+
min_used_y_val, _ = ax.get_ylim()
|
|
206
|
+
|
|
207
|
+
curr_y_tick_labels = []
|
|
208
|
+
if not set_label_only:
|
|
209
|
+
max_ = max_used_y_val
|
|
210
|
+
plus = 0.2
|
|
211
|
+
while max_ > 10:
|
|
212
|
+
max_ /= 10
|
|
213
|
+
plus /= 10
|
|
214
|
+
|
|
215
|
+
plus = (max_used_y_val - min_used_y_val) * plus
|
|
216
|
+
ax.set_ylim(min_used_y_val - plus, plus + max_used_y_val)
|
|
217
|
+
ax.spines["left"].set_bounds(min_used_y_val, max_used_y_val)
|
|
218
|
+
|
|
219
|
+
assign_ticks_y = [
|
|
220
|
+
int(x / (abs(min_used_y_val) + max_used_y_val) * n_y_ticks)
|
|
221
|
+
for x in [abs(min_used_y_val), abs(max_used_y_val)]
|
|
222
|
+
]
|
|
223
|
+
universal_y_ticks = pylab.linspace(min_used_y_val, 0, assign_ticks_y[0] + 1)
|
|
224
|
+
for i in pylab.linspace(0, max_used_y_val, assign_ticks_y[1] + 1):
|
|
225
|
+
universal_y_ticks = np.append(universal_y_ticks, i)
|
|
226
|
+
|
|
227
|
+
universal_y_ticks = np.unique(np.append(universal_y_ticks, 0))
|
|
228
|
+
universal_y_ticks = sorted(universal_y_ticks)
|
|
229
|
+
|
|
230
|
+
for lab in universal_y_ticks:
|
|
231
|
+
curr_y_tick_labels.append(f"{int(lab)}")
|
|
232
|
+
|
|
233
|
+
ax.set_yticks(universal_y_ticks)
|
|
234
|
+
ax.set_yticklabels(curr_y_tick_labels, fontsize=font_size)
|
|
235
|
+
ax.yaxis.set_ticks_position("left")
|
|
236
|
+
|
|
237
|
+
if show_y_label:
|
|
238
|
+
|
|
239
|
+
def __dynamic_distance__(
|
|
240
|
+
distance_between_label_axis: float, label: str, scale: int = 100
|
|
241
|
+
) -> float:
|
|
242
|
+
if distance_between_label_axis != 0:
|
|
243
|
+
return -distance_between_label_axis
|
|
244
|
+
return max(0.01, math.ceil(len(label) / 10) * 10 / scale) * -1
|
|
245
|
+
|
|
246
|
+
curr_y_tick_labels = sorted(
|
|
247
|
+
curr_y_tick_labels, key=lambda x: len(x), reverse=True
|
|
248
|
+
)
|
|
249
|
+
ax.text(
|
|
250
|
+
x=__dynamic_distance__(
|
|
251
|
+
distance_between_label_axis,
|
|
252
|
+
curr_y_tick_labels[0] if curr_y_tick_labels else "",
|
|
253
|
+
)
|
|
254
|
+
* max(graph_coords),
|
|
255
|
+
y=(max_used_y_val + min_used_y_val) / 2,
|
|
256
|
+
s=label,
|
|
257
|
+
fontsize=font_size,
|
|
258
|
+
ha="right",
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
if max_used_y_val is not None and min_used_y_val is not None:
|
|
262
|
+
ax.set_ylim(ymin=min_used_y_val, ymax=max_used_y_val)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
# ============================================================================
|
|
266
|
+
# Overlays
|
|
267
|
+
# ============================================================================
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def set_focus(ax, graph_coords: Union[Dict, np.array], focus: Dict[int, int]):
|
|
271
|
+
for left, right in focus.items():
|
|
272
|
+
try:
|
|
273
|
+
left, right = graph_coords[left], graph_coords[right]
|
|
274
|
+
fill_x = [left, right, right, left]
|
|
275
|
+
y1, y2 = ax.get_ylim()
|
|
276
|
+
fill_y = [y1, y1, y2, y2]
|
|
277
|
+
ax.fill(fill_x, fill_y, alpha=0.1, color="grey")
|
|
278
|
+
except IndexError as err:
|
|
279
|
+
logger.debug("focus region is out of bound: " + str(err))
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def set_indicator_lines(
|
|
283
|
+
ax,
|
|
284
|
+
graph_coords: Union[Dict, np.array],
|
|
285
|
+
sites: Dict[int, str],
|
|
286
|
+
min_y_used: Union[int, float] = 0,
|
|
287
|
+
max_y_used: Union[int, float] = None,
|
|
288
|
+
):
|
|
289
|
+
if sites is None:
|
|
290
|
+
return
|
|
291
|
+
|
|
292
|
+
if not max_y_used:
|
|
293
|
+
min_y_used, max_y_used = ax.get_ylim()
|
|
294
|
+
|
|
295
|
+
for site, color in sites.items():
|
|
296
|
+
try:
|
|
297
|
+
ax.vlines(
|
|
298
|
+
x=graph_coords[site],
|
|
299
|
+
ymin=min_y_used,
|
|
300
|
+
ymax=max_y_used,
|
|
301
|
+
color=color,
|
|
302
|
+
linestyles="dashed",
|
|
303
|
+
lw=0.5,
|
|
304
|
+
)
|
|
305
|
+
except IndexError as err:
|
|
306
|
+
logger.debug("Indicator line is out of bound: " + str(err))
|