coolbox 0.3.7__tar.gz → 0.3.9__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 coolbox might be problematic. Click here for more details.
- {coolbox-0.3.7/coolbox.egg-info → coolbox-0.3.9}/PKG-INFO +34 -4
- {coolbox-0.3.7 → coolbox-0.3.9}/README.md +18 -2
- coolbox-0.3.9/coolbox/__init__.py +1 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/cli.py +0 -2
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/browser/base.py +5 -2
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/coverage/__init__.py +1 -1
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/coverage/highlights.py +4 -4
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/frame/frame.py +16 -6
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/__init__.py +2 -1
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/arcs/plot.py +6 -2
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/bed/__init__.py +0 -1
- coolbox-0.3.9/coolbox/core/track/bed/base.py +152 -0
- coolbox-0.3.9/coolbox/core/track/bed/bed.py +62 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/bed/fetch.py +1 -1
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/bed/plot.py +71 -221
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/gtf.py +11 -9
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hicmat/base.py +12 -9
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hicmat/cool.py +6 -5
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hicmat/dothic.py +4 -3
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hicmat/hicmat.py +8 -9
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hicmat/plot.py +12 -6
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hist/__init__.py +10 -3
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hist/bigwig.py +0 -16
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hist/plot.py +13 -5
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/ideogram.py +19 -10
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/pseudo.py +6 -2
- coolbox-0.3.9/coolbox/core/track/tad.py +237 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/bed.py +1 -1
- coolbox-0.3.9/coolbox/utilities/hic/straw.py +812 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/hic/wrap.py +55 -24
- {coolbox-0.3.7 → coolbox-0.3.9/coolbox.egg-info}/PKG-INFO +34 -4
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox.egg-info/SOURCES.txt +9 -2
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox.egg-info/requires.txt +2 -1
- {coolbox-0.3.7 → coolbox-0.3.9}/requirements.txt +2 -1
- {coolbox-0.3.7 → coolbox-0.3.9}/setup.py +9 -0
- coolbox-0.3.9/tests/test_add_rule.py +71 -0
- coolbox-0.3.9/tests/test_browser.py +31 -0
- coolbox-0.3.9/tests/test_cli.py +70 -0
- coolbox-0.3.9/tests/test_coverage.py +52 -0
- coolbox-0.3.9/tests/test_frame.py +39 -0
- coolbox-0.3.9/tests/test_superframe.py +37 -0
- coolbox-0.3.9/tests/test_track.py +242 -0
- coolbox-0.3.7/coolbox/__init__.py +0 -1
- coolbox-0.3.7/coolbox/core/track/bed/base.py +0 -144
- coolbox-0.3.7/coolbox/core/track/bed/bed.py +0 -41
- coolbox-0.3.7/coolbox/core/track/bed/tad.py +0 -18
- coolbox-0.3.7/coolbox/utilities/hic/straw.py +0 -609
- {coolbox-0.3.7 → coolbox-0.3.9}/LICENSE +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/MANIFEST.in +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/api.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/__init__.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/browser/__init__.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/browser/widgets/__init__.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/browser/widgets/base.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/browser/widgets/full.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/browser/widgets/navigation.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/browser/widgets/simple.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/coverage/base.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/coverage/hlines.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/coverage/vlines.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/feature.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/frame/__init__.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/frame/base.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/frame/superframe/__init__.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/frame/superframe/base.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/frame/superframe/jointview.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/arcs/__init__.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/arcs/base.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/arcs/bedpe.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/arcs/fetch.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/arcs/hicpeaks.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/arcs/pairs.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/bam.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/base.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hicmat/__init__.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hicmat/hicdiff/__init__.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hicmat/hicdiff/diff.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hicmat/hicdiff/selfish.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hicmat/process.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hist/bam.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hist/base.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hist/bedgraph.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hist/hicfeature.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/core/track/hist/snp.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/genome/hg19.txt +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/genome/hg38.txt +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/genome/mm10.txt +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/genome/mm9.txt +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/__init__.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/bam.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/doctool.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/figtools.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/filetool.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/fmtconvert.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/genome.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/hic/__init__.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/hic/tools.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox/utilities/logtools.py +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox.egg-info/dependency_links.txt +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox.egg-info/not-zip-safe +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/coolbox.egg-info/top_level.txt +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/scripts/coolbox +0 -0
- {coolbox-0.3.7 → coolbox-0.3.9}/setup.cfg +0 -0
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
Metadata-Version:
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: coolbox
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.9
|
|
4
4
|
Summary: Jupyter notebook based genomic data visulization toolkit.
|
|
5
5
|
Home-page: https://github.com/GangCaoLab/CoolBox
|
|
6
6
|
Author: Weize Xu
|
|
7
7
|
Author-email: vet.xwz@gmail.com
|
|
8
8
|
License: GPLv3
|
|
9
|
-
Description: See https://github.com/GangCaoLab/CoolBox
|
|
10
9
|
Keywords: genomics,bioinformatics,visualization,Jupyter
|
|
11
|
-
Platform: UNKNOWN
|
|
12
10
|
Classifier: Development Status :: 3 - Alpha
|
|
13
11
|
Classifier: Operating System :: POSIX
|
|
14
12
|
Classifier: Programming Language :: Python
|
|
@@ -21,3 +19,35 @@ Classifier: Intended Audience :: Science/Research
|
|
|
21
19
|
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
22
20
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
23
21
|
Requires-Python: >=3.7, <4
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: scipy>=1.0.0
|
|
24
|
+
Requires-Dist: numpy
|
|
25
|
+
Requires-Dist: pandas>=1.0.0
|
|
26
|
+
Requires-Dist: statsmodels
|
|
27
|
+
Requires-Dist: matplotlib>=3.8.4
|
|
28
|
+
Requires-Dist: jupyter>=1.0.0
|
|
29
|
+
Requires-Dist: ipywidgets>=7.5.1
|
|
30
|
+
Requires-Dist: nbformat
|
|
31
|
+
Requires-Dist: voila
|
|
32
|
+
Requires-Dist: svgutils
|
|
33
|
+
Requires-Dist: intervaltree
|
|
34
|
+
Requires-Dist: dna_features_viewer
|
|
35
|
+
Requires-Dist: h5py
|
|
36
|
+
Requires-Dist: cooler
|
|
37
|
+
Requires-Dist: pybbi
|
|
38
|
+
Requires-Dist: numpydoc
|
|
39
|
+
Requires-Dist: fire
|
|
40
|
+
Requires-Dist: pytest
|
|
41
|
+
Requires-Dist: strawC
|
|
42
|
+
Dynamic: author
|
|
43
|
+
Dynamic: author-email
|
|
44
|
+
Dynamic: classifier
|
|
45
|
+
Dynamic: description
|
|
46
|
+
Dynamic: home-page
|
|
47
|
+
Dynamic: keywords
|
|
48
|
+
Dynamic: license
|
|
49
|
+
Dynamic: requires-dist
|
|
50
|
+
Dynamic: requires-python
|
|
51
|
+
Dynamic: summary
|
|
52
|
+
|
|
53
|
+
See https://github.com/GangCaoLab/CoolBox
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
<img src="https://github.com/GangCaoLab/coolbox/actions/workflows/python-package-conda.yml/badge.svg" alt="Build Status">
|
|
48
48
|
</a>
|
|
49
49
|
|
|
50
|
-
<a href="https://
|
|
51
|
-
<img src="https://
|
|
50
|
+
<a href="https://www.biorxiv.org/content/10.1101/2021.04.15.439923v1">
|
|
51
|
+
<img src="https://img.shields.io/badge/preprint-biorxiv-red" alt="biorxiv">
|
|
52
52
|
</a>
|
|
53
53
|
|
|
54
54
|
<a href="https://github.com/GangCaoLab/CoolBox/blob/master/LICENSE">
|
|
@@ -77,6 +77,21 @@ Interactively online demo: [binder](https://mybinder.org/v2/gh/GangCaoLab/CoolBo
|
|
|
77
77
|
|
|
78
78
|
See [CONTRIBUTING.md](https://github.com/GangCaoLab/CoolBox/blob/master/CONTRIBUTING.md)
|
|
79
79
|
|
|
80
|
+
## Citation
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
@article{xu2021coolbox,
|
|
84
|
+
title={CoolBox: A flexible toolkit for visual analysis of genomics data},
|
|
85
|
+
author={Xu, Weize and Zhong, Quan and Lin, Da and Zuo, Ya and Dai, Jinxia and Li, Guoliang and Cao, Gang},
|
|
86
|
+
journal={BMC bioinformatics},
|
|
87
|
+
volume={22},
|
|
88
|
+
number={1},
|
|
89
|
+
pages={1--9},
|
|
90
|
+
year={2021},
|
|
91
|
+
publisher={Springer}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
80
95
|
## Thanks
|
|
81
96
|
|
|
82
97
|
+ [pyGenomeTracks](https://github.com/deeptools/pyGenomeTracks),
|
|
@@ -84,6 +99,7 @@ CoolBox's plot system is fork from it.
|
|
|
84
99
|
|
|
85
100
|
### Contributors
|
|
86
101
|
This project exists thanks to all the people who contribute.
|
|
102
|
+
|
|
87
103
|
<a href="https://github.com/GangCaoLab/CoolBox/graphs/contributors">
|
|
88
104
|
<img src="https://contrib.rocks/image?repo=GangCaoLab/CoolBox" />
|
|
89
105
|
</a>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.3.9'
|
|
@@ -250,7 +250,6 @@ class CLI(object):
|
|
|
250
250
|
def print_source(self):
|
|
251
251
|
"""Print the browser composing code."""
|
|
252
252
|
print(self.source())
|
|
253
|
-
return self
|
|
254
253
|
|
|
255
254
|
def gen_notebook(self, notebook_path, notes=True, figsave=True):
|
|
256
255
|
"""Generate The notebook contain codes for run coolbox browser.
|
|
@@ -288,7 +287,6 @@ class CLI(object):
|
|
|
288
287
|
)
|
|
289
288
|
nb['cells'] = cells
|
|
290
289
|
nbf.write(nb, notebook_path)
|
|
291
|
-
return self
|
|
292
290
|
|
|
293
291
|
def run_jupyter(self, jupyter_args="--ip=0.0.0.0"):
|
|
294
292
|
"""Create a notebook according to command line, then start a jupyter process.
|
|
@@ -43,8 +43,9 @@ class Browser(object):
|
|
|
43
43
|
dpi : int, optional
|
|
44
44
|
The dpi of frame's image.
|
|
45
45
|
|
|
46
|
-
img_format :
|
|
47
|
-
|
|
46
|
+
img_format : {'svg', 'png'}
|
|
47
|
+
Image format for browser display, default svg.
|
|
48
|
+
NOTE: This argument not for saving image.
|
|
48
49
|
"""
|
|
49
50
|
|
|
50
51
|
self.dpi = dpi
|
|
@@ -251,6 +252,8 @@ class Browser(object):
|
|
|
251
252
|
def save(self, path, dpi=None):
|
|
252
253
|
"""
|
|
253
254
|
Save current frame's image to file.
|
|
255
|
+
The suffix of the path will changing the saving format.
|
|
256
|
+
For example: `bsr.save("fig.png")` will save file to 'png' format.
|
|
254
257
|
"""
|
|
255
258
|
c_fig = self.frame.show()
|
|
256
259
|
dpi = dpi or self.dpi
|
|
@@ -3,7 +3,7 @@ from .vlines import Vlines, VlinesFromFile
|
|
|
3
3
|
from .hlines import HLines
|
|
4
4
|
|
|
5
5
|
from .base import track_to_coverage
|
|
6
|
-
from ..track.
|
|
6
|
+
from ..track.tad import TAD
|
|
7
7
|
from ..track.hist import Hist, BigWig, BedGraph
|
|
8
8
|
from ..track.arcs import Arcs, Pairs, BEDPE, HiCPeaks
|
|
9
9
|
|
|
@@ -87,9 +87,9 @@ class HighLightsFromFile(Coverage, _Highlights):
|
|
|
87
87
|
"file": file_,
|
|
88
88
|
"color": "bed_rgb",
|
|
89
89
|
"alpha": 0.1,
|
|
90
|
-
"border_line":
|
|
90
|
+
"border_line": False,
|
|
91
91
|
"border_line_style": "dashed",
|
|
92
|
-
"border_line_width":
|
|
92
|
+
"border_line_width": 2,
|
|
93
93
|
"border_line_color": "#000000",
|
|
94
94
|
"border_line_alpha": 0.8,
|
|
95
95
|
}
|
|
@@ -168,9 +168,9 @@ class HighLights(Coverage, _Highlights):
|
|
|
168
168
|
"highlight_regions": highlight_regions,
|
|
169
169
|
"color": HighLights.DEFAULT_COLOR,
|
|
170
170
|
"alpha": 0.25,
|
|
171
|
-
"border_line":
|
|
171
|
+
"border_line": False,
|
|
172
172
|
"border_line_style": "dashed",
|
|
173
|
-
"border_line_width":
|
|
173
|
+
"border_line_width": 2,
|
|
174
174
|
"border_line_color": "#000000",
|
|
175
175
|
"border_line_alpha": 0.8,
|
|
176
176
|
}
|
|
@@ -137,8 +137,18 @@ class Frame(FrameBase):
|
|
|
137
137
|
heights = []
|
|
138
138
|
for track in self.tracks.values():
|
|
139
139
|
if hasattr(track, 'get_track_height'):
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
# The actual width is given by multiplying:
|
|
141
|
+
# - the actual width in units cm/inch
|
|
142
|
+
# - the fraction of the figure not covered by margins
|
|
143
|
+
# - the fraction of the grid allotted to the middle column
|
|
144
|
+
margins = self.properties["margins"]
|
|
145
|
+
margins_fraction = margins["right"] - margins["left"]
|
|
146
|
+
frame_width = (
|
|
147
|
+
self.properties["width"]
|
|
148
|
+
* self.properties["width_ratios"][1]
|
|
149
|
+
* margins_fraction
|
|
150
|
+
)
|
|
151
|
+
height = track.get_track_height(frame_width, self.current_range)
|
|
142
152
|
heights.append(height)
|
|
143
153
|
elif 'height' in track.properties:
|
|
144
154
|
heights.append(track.properties['height'])
|
|
@@ -146,7 +156,7 @@ class Frame(FrameBase):
|
|
|
146
156
|
heights.append(default_height)
|
|
147
157
|
return heights
|
|
148
158
|
|
|
149
|
-
def plot(self, *args):
|
|
159
|
+
def plot(self, *args, close_fig=True):
|
|
150
160
|
"""
|
|
151
161
|
Plot all tracks.
|
|
152
162
|
|
|
@@ -186,8 +196,7 @@ class Frame(FrameBase):
|
|
|
186
196
|
grids = matplotlib.gridspec.GridSpec(
|
|
187
197
|
len(tracks_height), 3,
|
|
188
198
|
height_ratios=tracks_height,
|
|
189
|
-
width_ratios=self.properties['width_ratios']
|
|
190
|
-
wspace=0.01)
|
|
199
|
+
width_ratios=self.properties['width_ratios'])
|
|
191
200
|
|
|
192
201
|
axis_list = []
|
|
193
202
|
for idx, track in enumerate(self.tracks.values()):
|
|
@@ -231,7 +240,8 @@ class Frame(FrameBase):
|
|
|
231
240
|
bottom=margins['bottom'],
|
|
232
241
|
top=margins['top'])
|
|
233
242
|
|
|
234
|
-
|
|
243
|
+
if close_fig:
|
|
244
|
+
plt.close()
|
|
235
245
|
|
|
236
246
|
return fig
|
|
237
247
|
|
|
@@ -3,7 +3,8 @@ from .bam import BAM
|
|
|
3
3
|
from .gtf import GTF
|
|
4
4
|
from .ideogram import Ideogram
|
|
5
5
|
from .pseudo import Spacer, HLine, XAxis, ChromName
|
|
6
|
-
from .bed import BedBase, BED
|
|
6
|
+
from .bed import BedBase, BED # no all-in class/function
|
|
7
|
+
from .tad import TAD
|
|
7
8
|
from .hicmat import HicMatBase, Cool, DotHiC, HiCDiff, Selfish, HiCMat
|
|
8
9
|
from .hist import HistBase, BedGraph, BigWig, ABCompartment, DiScore, InsuScore, Virtual4C, BAMCov, SNP, Hist
|
|
9
10
|
from .arcs import ArcsBase, Pairs, BEDPE, HiCPeaks, Arcs
|
|
@@ -103,8 +103,12 @@ class PlotContacts(object):
|
|
|
103
103
|
center = (start + end) / 2
|
|
104
104
|
ax.plot([center], [diameter])
|
|
105
105
|
arc = Arc(
|
|
106
|
-
(center, 0),
|
|
107
|
-
|
|
106
|
+
xy=(center, 0),
|
|
107
|
+
width=diameter,
|
|
108
|
+
height=height,
|
|
109
|
+
angle=0,
|
|
110
|
+
theta1=0,
|
|
111
|
+
theta2=180,
|
|
108
112
|
color=color,
|
|
109
113
|
alpha=alpha,
|
|
110
114
|
lw=line_width,
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import matplotlib
|
|
5
|
+
|
|
6
|
+
from coolbox.utilities import get_logger
|
|
7
|
+
from coolbox.utilities.bed import build_bed_index
|
|
8
|
+
from coolbox.utilities.genome import GenomeRange
|
|
9
|
+
from coolbox.core.track.base import Track
|
|
10
|
+
|
|
11
|
+
log = get_logger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BedBase(Track):
|
|
15
|
+
"""
|
|
16
|
+
BED Base track.
|
|
17
|
+
|
|
18
|
+
Parameters
|
|
19
|
+
----------
|
|
20
|
+
file: str
|
|
21
|
+
The file path of `.bed` file.
|
|
22
|
+
|
|
23
|
+
color : str, optional
|
|
24
|
+
Track color, 'bed_rgb' for auto specify color according to bed record.
|
|
25
|
+
(Default: 'bed_rgb')
|
|
26
|
+
|
|
27
|
+
border_color : str, optional
|
|
28
|
+
Border_color of gene. (Default: 'black')
|
|
29
|
+
|
|
30
|
+
max_value : float, optional
|
|
31
|
+
Max score. (Default: inf)
|
|
32
|
+
|
|
33
|
+
min_value : float, optional
|
|
34
|
+
Min score. (Default: -inf)
|
|
35
|
+
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
COLOR = "#1f78b4"
|
|
39
|
+
|
|
40
|
+
DEFAULT_PROPERTIES = {
|
|
41
|
+
'color': "bed_rgb",
|
|
42
|
+
'border_color': "#1f78b4",
|
|
43
|
+
'min_score': '-inf',
|
|
44
|
+
'max_score': 'inf',
|
|
45
|
+
'bed_type': None,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
def __init__(self, file, **kwargs):
|
|
49
|
+
properties = BedBase.DEFAULT_PROPERTIES.copy()
|
|
50
|
+
properties.update({
|
|
51
|
+
'file': file,
|
|
52
|
+
**kwargs
|
|
53
|
+
})
|
|
54
|
+
super().__init__(properties)
|
|
55
|
+
self.bgz_file = build_bed_index(file)
|
|
56
|
+
|
|
57
|
+
def fetch_data(self, gr: GenomeRange, **kwargs) -> pd.DataFrame:
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
intervals : pandas.core.frame.DataFrame
|
|
63
|
+
BED interval table. The table should be in format like:
|
|
64
|
+
|
|
65
|
+
bed_fields = ['chromosome', 'start', 'end',
|
|
66
|
+
'name', 'score', 'strand',
|
|
67
|
+
'thick_start', 'thick_end',
|
|
68
|
+
'rgb', 'block_count',
|
|
69
|
+
'block_sizes', 'block_starts']
|
|
70
|
+
The table can be in bed6/bed9/bed12 format and the trailing columns can be omited.
|
|
71
|
+
|
|
72
|
+
"""
|
|
73
|
+
return self.fetch_intervals(self.bgz_file, gr)
|
|
74
|
+
|
|
75
|
+
def init_colormap(self):
|
|
76
|
+
self.colormap = None
|
|
77
|
+
if not matplotlib.colors.is_color_like(self.properties['color']) and self.properties['color'] != 'bed_rgb':
|
|
78
|
+
if self.properties['color'] not in matplotlib.cm.datad:
|
|
79
|
+
log.debug("*WARNING* color: '{}' for Track {} is not valid. Color has "
|
|
80
|
+
"been set to {}".format(self.properties['color'], self.properties['name'],
|
|
81
|
+
self.COLOR))
|
|
82
|
+
self.properties['color'] = self.COLOR
|
|
83
|
+
else:
|
|
84
|
+
self.colormap = self.properties['color']
|
|
85
|
+
|
|
86
|
+
def set_colormap(self, df):
|
|
87
|
+
"""As min_score and max_score change every plot, we compute them for every plot"""
|
|
88
|
+
props = self.properties
|
|
89
|
+
min_score, max_score = props['min_score'], props['max_score']
|
|
90
|
+
has_score_col = props['bed_type'] in ('bed6', 'bed9', 'bed12')
|
|
91
|
+
if has_score_col and (df.shape[0] > 0):
|
|
92
|
+
min_score = (min_score != 'inf') or df['score'].min()
|
|
93
|
+
max_score = (max_score != '-inf') or df['score'].max()
|
|
94
|
+
min_score, max_score = float(min_score), float(max_score)
|
|
95
|
+
# set colormap
|
|
96
|
+
if self.colormap is not None:
|
|
97
|
+
norm = matplotlib.colors.Normalize(vmin=min_score, vmax=max_score)
|
|
98
|
+
cmap = matplotlib.cm.get_cmap(props['color'])
|
|
99
|
+
self.colormap = matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap)
|
|
100
|
+
if props['color'] == 'bed_rgb' and props['bed_type'] not in ['bed12', 'bed9']:
|
|
101
|
+
log.debug("*WARNING* Color set to 'bed_rgb', but bed file does not have the rgb field. The color has "
|
|
102
|
+
"been set to {}".format(self.COLOR))
|
|
103
|
+
self.properties['color'] = self.COLOR
|
|
104
|
+
self.colormap = None
|
|
105
|
+
|
|
106
|
+
def get_rgb_and_edge_color(self, bed):
|
|
107
|
+
# TODO need simplification
|
|
108
|
+
props = self.properties
|
|
109
|
+
rgb = props['color']
|
|
110
|
+
edgecolor = props['border_color']
|
|
111
|
+
|
|
112
|
+
if self.colormap:
|
|
113
|
+
# translate value field (in the example above is 0 or 0.2686...) into a color
|
|
114
|
+
rgb = self.colormap.to_rgba(bed.score)
|
|
115
|
+
|
|
116
|
+
# for tad coverage
|
|
117
|
+
if props.get('border_only', 'no') == 'yes':
|
|
118
|
+
rgb = 'none'
|
|
119
|
+
elif props['color'] == 'bed_rgb':
|
|
120
|
+
# if rgb is set in the bed line, this overrides the previously
|
|
121
|
+
# defined colormap
|
|
122
|
+
if props['bed_type'] in ['bed9', 'bed12'] and len(bed.rgb) == 3:
|
|
123
|
+
try:
|
|
124
|
+
rgb = [float(x) / 255 for x in bed.rgb]
|
|
125
|
+
if 'border_color' in props:
|
|
126
|
+
edgecolor = props['border_color']
|
|
127
|
+
else:
|
|
128
|
+
edgecolor = props['color']
|
|
129
|
+
except IndexError:
|
|
130
|
+
rgb = self.COLOR
|
|
131
|
+
else:
|
|
132
|
+
rgb = self.COLOR
|
|
133
|
+
return rgb, edgecolor
|
|
134
|
+
|
|
135
|
+
@staticmethod
|
|
136
|
+
def infer_bed_type(df: pd.DataFrame) -> Union[str, None]:
|
|
137
|
+
# bed_type of dataframe are store in dataframe's __dict__ in FetchBed.fetch_intervals
|
|
138
|
+
if 'bed_type' in df.__dict__:
|
|
139
|
+
bed_type = df.bed_type
|
|
140
|
+
else:
|
|
141
|
+
bed_types = {
|
|
142
|
+
12: 'bed12',
|
|
143
|
+
9: 'bed9',
|
|
144
|
+
6: 'bed6',
|
|
145
|
+
3: 'bed3'
|
|
146
|
+
}
|
|
147
|
+
num_col = len(df.columns)
|
|
148
|
+
bed_type = bed_types[num_col] if num_col in bed_types else 'bed3'
|
|
149
|
+
if bed_type == 'bed3' and num_col < 3:
|
|
150
|
+
raise ValueError(f"Invalid dataframe for bed3 with columns: {df.columns}")
|
|
151
|
+
return bed_type
|
|
152
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from coolbox.core.track.bed.fetch import FetchBed
|
|
2
|
+
from coolbox.utilities import (
|
|
3
|
+
get_logger
|
|
4
|
+
)
|
|
5
|
+
from coolbox.utilities.genome import GenomeRange
|
|
6
|
+
from .base import BedBase
|
|
7
|
+
from .plot import PlotGenes
|
|
8
|
+
|
|
9
|
+
log = get_logger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BED(BedBase, PlotGenes, FetchBed):
|
|
13
|
+
"""
|
|
14
|
+
Bed Track for plotting 1d intervals data from .bed file.
|
|
15
|
+
The input bed file can be bed3/bed6/bed9/bed12
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
gene_style: {'flybase', 'normal'}
|
|
20
|
+
|
|
21
|
+
display : {'stacked', 'interlaced', 'collapsed'}, optional
|
|
22
|
+
Display mode. (Default: 'stacked')
|
|
23
|
+
|
|
24
|
+
fontsize : int, optional
|
|
25
|
+
Font size. (Default: BED.DEFAULT_FONTSIZE)
|
|
26
|
+
|
|
27
|
+
labels : {True, False, 'auto'}, optional
|
|
28
|
+
Draw bed name or not. 'auto' for automate decision according to density.
|
|
29
|
+
(Default: 'auto')
|
|
30
|
+
|
|
31
|
+
interval_height : int, optional
|
|
32
|
+
The height of the interval. (Default: 100)
|
|
33
|
+
|
|
34
|
+
num_rows : int, optional
|
|
35
|
+
Set the max interval rows. (Default: unlimited interval rows)
|
|
36
|
+
|
|
37
|
+
row_height : float
|
|
38
|
+
Height of a row. default 0.5
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
DEFAULT_PROPERTIES = {
|
|
42
|
+
'labels': 'auto',
|
|
43
|
+
'height': 'auto',
|
|
44
|
+
'gene_style': 'flybase',
|
|
45
|
+
'display': 'stacked',
|
|
46
|
+
'fontsize': 12,
|
|
47
|
+
'interval_height': 100,
|
|
48
|
+
'num_rows': None,
|
|
49
|
+
'row_height': 0.5,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
def __init__(self, file, **kwargs):
|
|
53
|
+
properties = BED.DEFAULT_PROPERTIES.copy()
|
|
54
|
+
properties.update(kwargs)
|
|
55
|
+
super().__init__(file, **properties)
|
|
56
|
+
PlotGenes.__init__(self)
|
|
57
|
+
|
|
58
|
+
def plot(self, ax, gr: GenomeRange, **kwargs):
|
|
59
|
+
self.ax = ax
|
|
60
|
+
ov_intervals: pd.DataFrame = self.fetch_plot_data(gr, **kwargs)
|
|
61
|
+
self.plot_genes(ax, gr, ov_intervals)
|
|
62
|
+
self.plot_label()
|
|
@@ -34,7 +34,7 @@ class FetchBed(object):
|
|
|
34
34
|
try:
|
|
35
35
|
bed_iterator = ReadBed(query_bed(bgz_file, gr.chrom, gr.start, gr.end))
|
|
36
36
|
except StopIteration:
|
|
37
|
-
log.
|
|
37
|
+
log.debug(f"No records in the range {str(gr)}")
|
|
38
38
|
return [], None
|
|
39
39
|
|
|
40
40
|
intervals = [bed for bed in bed_iterator]
|