trackplot 0.5.5__tar.gz → 0.5.6__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.
Files changed (121) hide show
  1. {trackplot-0.5.5/trackplot.egg-info → trackplot-0.5.6}/PKG-INFO +2 -2
  2. {trackplot-0.5.5 → trackplot-0.5.6}/pyproject.toml +2 -2
  3. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/base/ReadDepth.py +70 -63
  4. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/cli.py +4 -2
  5. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/Bam.py +5 -2
  6. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/Junction.py +0 -1
  7. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/plot.py +5 -2
  8. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/plot_func.py +34 -56
  9. {trackplot-0.5.5 → trackplot-0.5.6/trackplot.egg-info}/PKG-INFO +2 -2
  10. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot.egg-info/SOURCES.txt +0 -27
  11. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot.egg-info/requires.txt +1 -1
  12. trackplot-0.5.6/trackplot.egg-info/top_level.txt +2 -0
  13. trackplot-0.5.5/trackplot.egg-info/top_level.txt +0 -3
  14. trackplot-0.5.5/trackplot_issue/OA-452-DC.bam +0 -0
  15. trackplot-0.5.5/trackplot_issue/OA-452-DC.bam.bai +0 -0
  16. trackplot-0.5.5/trackplot_issue/OA-476-DC.bam +0 -0
  17. trackplot-0.5.5/trackplot_issue/OA-476-DC.bam.bai +0 -0
  18. trackplot-0.5.5/trackplot_issue/OA-479-DC.bam +0 -0
  19. trackplot-0.5.5/trackplot_issue/OA-479-DC.bam.bai +0 -0
  20. trackplot-0.5.5/trackplot_issue/OA-488-DC.bam +0 -0
  21. trackplot-0.5.5/trackplot_issue/OA-488-DC.bam.bai +0 -0
  22. trackplot-0.5.5/trackplot_issue/OA-500-DC.bam +0 -0
  23. trackplot-0.5.5/trackplot_issue/OA-500-DC.bam.bai +0 -0
  24. trackplot-0.5.5/trackplot_issue/OA-503-DC.bam +0 -0
  25. trackplot-0.5.5/trackplot_issue/OA-503-DC.bam.bai +0 -0
  26. trackplot-0.5.5/trackplot_issue/OA-506-DC.bam +0 -0
  27. trackplot-0.5.5/trackplot_issue/OA-506-DC.bam.bai +0 -0
  28. trackplot-0.5.5/trackplot_issue/OA-514-DC.bam +0 -0
  29. trackplot-0.5.5/trackplot_issue/OA-514-DC.bam.bai +0 -0
  30. trackplot-0.5.5/trackplot_issue/OA-515-DC.bam +0 -0
  31. trackplot-0.5.5/trackplot_issue/OA-515-DC.bam.bai +0 -0
  32. trackplot-0.5.5/trackplot_issue/OA-99-DC.bam +0 -0
  33. trackplot-0.5.5/trackplot_issue/OA-99-DC.bam.bai +0 -0
  34. trackplot-0.5.5/trackplot_issue/run_trackplot.sh +0 -42
  35. trackplot-0.5.5/trackplot_issue/samples.bam.tsv +0 -10
  36. trackplot-0.5.5/trackplot_issue/test.v051.pdf +0 -0
  37. trackplot-0.5.5/trackplot_issue/test.v053.included_junctions.log +0 -355
  38. trackplot-0.5.5/trackplot_issue/test.v053.included_junctions.pdf +0 -0
  39. trackplot-0.5.5/trackplot_issue/test.v053.included_junctions.png +0 -0
  40. trackplot-0.5.5/trackplot_issue/test.v053.pdf +0 -0
  41. {trackplot-0.5.5 → trackplot-0.5.6}/LICENSE +0 -0
  42. {trackplot-0.5.5 → trackplot-0.5.6}/README.md +0 -0
  43. {trackplot-0.5.5 → trackplot-0.5.6}/setup.cfg +0 -0
  44. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/__init__.py +0 -0
  45. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/anno/AxLabel.py +0 -0
  46. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/anno/__init__.py +0 -0
  47. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/anno/theme.py +0 -0
  48. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/base/CoordinateMap.py +0 -0
  49. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/base/GenomicLoci.py +0 -0
  50. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/base/Junction.py +0 -0
  51. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/base/Protein.py +0 -0
  52. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/base/Readder.py +0 -0
  53. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/base/Stroke.py +0 -0
  54. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/base/Transcript.py +0 -0
  55. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/base/__init__.py +0 -0
  56. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/base/pyUniprot.py +0 -0
  57. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/conf/DomainSetting.py +0 -0
  58. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/conf/__init__.py +0 -0
  59. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/conf/config.py +0 -0
  60. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/conf/drawing.py +0 -0
  61. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/conf/ui.py +0 -0
  62. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/ATAC.py +0 -0
  63. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/Annotation.py +0 -0
  64. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/BedGraph.py +0 -0
  65. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/Bigwig.py +0 -0
  66. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/Depth.py +0 -0
  67. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/Fasta.py +0 -0
  68. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/File.py +0 -0
  69. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/HiCMatrixTrack.py +0 -0
  70. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/Motif.py +0 -0
  71. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/ReadSegments.py +0 -0
  72. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/file/__init__.py +0 -0
  73. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/plot_tests.py +0 -0
  74. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot/server.py +0 -0
  75. {trackplot-0.5.5 → trackplot-0.5.6}/trackplot.egg-info/dependency_links.txt +0 -0
  76. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Home-7GzAh8lS.js +0 -0
  77. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Home-BV58jH3t.js +0 -0
  78. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Home-CDW3Zwoa.js +0 -0
  79. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Home-DOO13BH7.js +0 -0
  80. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Home-QmeAKOl4.js +0 -0
  81. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Home-RdVPWns6.js +0 -0
  82. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Home-jSR0MsHI.css +0 -0
  83. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Home-zRV7yePL.css +0 -0
  84. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-BALbchCV.css +0 -0
  85. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-BmqHZ4QE.css +0 -0
  86. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-BrjU8Kwg.js +0 -0
  87. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-Bvyo6ju9.css +0 -0
  88. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-COvGnprQ.css +0 -0
  89. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-CTM-EDrj.js +0 -0
  90. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-Cnt8iJB8.js +0 -0
  91. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-Cyj_LlDt.js +0 -0
  92. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-DiuFnwNK.js +0 -0
  93. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-DpL7z7tp.css +0 -0
  94. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-hvkDteAn.js +0 -0
  95. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/Plot-rbQz1TOM.css +0 -0
  96. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-BHm65SRq.css +0 -0
  97. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-BVZhQIwQ.js +0 -0
  98. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-Brt4-Qvr.js +0 -0
  99. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-BuEUMHwE.css +0 -0
  100. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-Cwxg0Ado.css +0 -0
  101. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-DcvrsrBa.css +0 -0
  102. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-IbBQ8ZK2.js +0 -0
  103. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-SYT5K-ds.css +0 -0
  104. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-VYjL3C7L.js +0 -0
  105. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-eEJXnQD5.js +0 -0
  106. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-i9JMIXVR.css +0 -0
  107. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/el-divider-u9f0bZWY.js +0 -0
  108. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-4hxJ_zbq.js +0 -0
  109. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-C4Mi9Kmf.js +0 -0
  110. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-CETGMNio.css +0 -0
  111. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-CWfdj0DH.js +0 -0
  112. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-Cexhr_fn.css +0 -0
  113. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-CrzyEb9s.js +0 -0
  114. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-D_Cw0sbX.js +0 -0
  115. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-Dd6Bavnk.js +0 -0
  116. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-DgEIiwRJ.css +0 -0
  117. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-O8P0XkxB.css +0 -0
  118. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-Sq2gI4sE.css +0 -0
  119. {trackplot-0.5.5 → trackplot-0.5.6}/ui/assets/index-ns9n7-F7.css +0 -0
  120. {trackplot-0.5.5 → trackplot-0.5.6}/ui/index.html +0 -0
  121. {trackplot-0.5.5 → trackplot-0.5.6}/ui/vite.svg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trackplot
3
- Version: 0.5.5
3
+ Version: 0.5.6
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
@@ -23,7 +23,7 @@ Requires-Dist: pysam>=0.23.3
23
23
  Requires-Dist: requests>=2.32.4
24
24
  Requires-Dist: scipy>=1.15.3
25
25
  Requires-Dist: seaborn>=0.13.2
26
- Requires-Dist: xmltodict>=0.14.2
26
+ Requires-Dist: xmltodict>=0.15.0
27
27
  Dynamic: license-file
28
28
 
29
29
  # trackplot
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "trackplot"
3
- version = "0.5.5"
3
+ version = "0.5.6"
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" }
@@ -25,7 +25,7 @@ dependencies = [
25
25
  "requests>=2.32.4",
26
26
  "scipy>=1.15.3",
27
27
  "seaborn>=0.13.2",
28
- "xmltodict>=0.14.2",
28
+ "xmltodict>=0.15.0",
29
29
  ]
30
30
 
31
31
 
@@ -21,13 +21,13 @@ class ReadDepth(object):
21
21
  """
22
22
 
23
23
  __slots__ = [
24
- "_junction_dict_plus_", "_junction_dict_minus_",
25
- "_minus_", "_plus_", "_number_of_merged_",
24
+ "__junction_dict__plus___", "__junction_dict__minus__",
25
+ "__minus__", "__plus__", "__number_of_merged__",
26
26
  "strand_aware", "site_plus", "site_minus",
27
27
  ]
28
28
 
29
29
  def __init__(self,
30
- wiggle: np.array,
30
+ wiggle: np.ndarray,
31
31
  site_plus: Optional[np.array] = None,
32
32
  site_minus: Optional[np.array] = None,
33
33
  minus: Optional[np.array] = None,
@@ -45,58 +45,65 @@ class ReadDepth(object):
45
45
  :param junction_dict_plus: these splice junction from plus strand
46
46
  :param junction_dict_minus: these splice junction from minus strand
47
47
  """
48
- self._plus_ = wiggle
48
+ self.__plus__ = wiggle
49
49
  self.strand_aware = strand_aware
50
- self._minus_ = abs(minus) if minus is not None else minus
51
- self._junction_dict_plus_ = junction_dict_plus
52
- self._junction_dict_minus_ = junction_dict_minus
50
+ self.__minus__ = abs(minus) if minus is not None else minus
51
+ self.__junction_dict__plus___ = junction_dict_plus
52
+ self.__junction_dict__minus__ = junction_dict_minus
53
53
  self.site_plus = site_plus
54
54
  self.site_minus = site_minus * -1 if site_minus is not None else site_minus
55
55
 
56
- self._number_of_merged_ = 1
56
+ self.__number_of_merged__ = 1
57
57
 
58
58
  @property
59
59
  def plus(self) -> Optional[np.array]:
60
- if self._plus_ is not None and self._number_of_merged_ > 0:
61
- return self._plus_ / self._number_of_merged_
62
- return self._plus_
60
+ if self.__plus__ is not None and self.__number_of_merged__ > 0:
61
+ return self.__plus__ / self.__number_of_merged__
62
+ return self.__plus__
63
63
 
64
64
  @property
65
65
  def minus(self) -> Optional[np.array]:
66
- if self._minus_ is not None and self._number_of_merged_ > 0:
67
- return self._minus_ / self._number_of_merged_
68
- return self._minus_
66
+ if self.__minus__ is not None and self.__number_of_merged__ > 0:
67
+ return self.__minus__ / self.__number_of_merged__
68
+ return self.__minus__
69
69
 
70
70
  @property
71
- def wiggle(self) -> np.array:
72
- if (self._plus_ is None or not self._plus_.any()) and self._minus_ is not None:
71
+ def wiggle(self) -> np.ndarray:
72
+ if (self.__plus__ is None or not self.__plus__.any()) and self.__minus__ is not None:
73
73
  return self.minus
74
74
 
75
- if self._plus_ is not None and self._minus_ is not None:
75
+ if self.__plus__ is not None and self.__minus__ is not None:
76
76
  return self.plus + self.minus
77
77
 
78
78
  return self.plus
79
79
 
80
80
  @property
81
- def junctions_plus(self) -> dict:
82
- if self._number_of_merged_ > 1:
83
- return {k: v / self._number_of_merged_ for k, v in self._junction_dict_plus_.items()}
84
- return self._junction_dict_plus_
81
+ def mean_junctions_plus(self) -> dict:
82
+ if self.__number_of_merged__ > 1:
83
+ return {k: v / self.__number_of_merged__ for k, v in self.__junction_dict__plus___.items()}
84
+ return self.__junction_dict__plus___
85
85
 
86
86
  @property
87
- def junctions_minus(self) -> dict:
88
- if self._number_of_merged_ > 1:
89
- return {k: v / self._number_of_merged_ for k, v in self._junction_dict_minus_.items()}
90
- return self._junction_dict_minus_
87
+ def mean_junctions_minus(self) -> dict:
88
+ if self.__number_of_merged__ > 1:
89
+ return {k: v / self.__number_of_merged__ for k, v in self.__junction_dict__minus__.items()}
90
+ return self.__junction_dict__minus__
91
91
 
92
- @property
93
- def junctions_dict(self) -> dict:
92
+ def junctions_dict(self, show_mean_jxn_number: bool = False) -> dict:
94
93
  res = {}
95
- if self._junction_dict_plus_:
96
- res.update(self.junctions_plus)
97
94
 
98
- if self._junction_dict_minus_:
99
- res.update(self.junctions_minus)
95
+ if show_mean_jxn_number:
96
+ if self.__junction_dict__plus___:
97
+ res.update(self.mean_junctions_plus)
98
+
99
+ if self.__junction_dict__minus__:
100
+ res.update(self.mean_junctions_minus)
101
+ else:
102
+ if self.__junction_dict__plus___:
103
+ res.update(self.__junction_dict__plus___)
104
+
105
+ if self.__junction_dict__minus__:
106
+ res.update(self.__junction_dict__minus__)
100
107
  return res
101
108
 
102
109
  @property
@@ -117,27 +124,27 @@ class ReadDepth(object):
117
124
  if len(self.wiggle) == len(other.wiggle):
118
125
  junc_plus, junc_minus = {}, {}
119
126
 
120
- for i in [self._junction_dict_plus_, other._junction_dict_plus_]:
127
+ for i in [self.__junction_dict__plus___, other.__junction_dict__plus___]:
121
128
  if i:
122
129
  junc_plus.update(i)
123
- for i in [self._junction_dict_minus_, other._junction_dict_minus_]:
130
+ for i in [self.__junction_dict__minus__, other.__junction_dict__minus__]:
124
131
  if i:
125
132
  junc_minus.update(i)
126
133
 
127
134
  minus = None
128
- if self._minus_ is not None and other._minus_ is not None:
129
- minus = self._minus_ + other._minus_
130
- elif self._minus_ is None and other._minus_ is not None:
135
+ if self.__minus__ is not None and other.__minus__ is not None:
136
+ minus = self.__minus__ + other.__minus__
137
+ elif self.__minus__ is None and other.__minus__ is not None:
131
138
  minus = other.minus
132
- elif self._minus_ is not None and other._minus_ is None:
133
- minus = self._minus_
139
+ elif self.__minus__ is not None and other.__minus__ is None:
140
+ minus = self.__minus__
134
141
 
135
142
  merged = ReadDepth(
136
- self._plus_ + other._plus_, minus=minus,
143
+ self.__plus__ + other.__plus__, minus=minus,
137
144
  junction_dict_plus=junc_plus,
138
145
  junction_dict_minus=junc_minus
139
146
  )
140
- merged._number_of_merged_ = self._number_of_merged_ + other._number_of_merged_
147
+ merged.__number_of_merged__ = self.__number_of_merged__ + other.__number_of_merged__
141
148
  return merged
142
149
  else:
143
150
  raise ValueError(f"ReadDepth objects are not equal length: {len(self.wiggle)} != {len(other.wiggle)}")
@@ -164,11 +171,11 @@ class ReadDepth(object):
164
171
  :return:
165
172
  """
166
173
 
167
- for k, v in other._junction_dict_plus_:
168
- self._junction_dict_plus_[k] = v + self._junction_dict_plus_.get(k, 0)
174
+ for k, v in other.__junction_dict__plus___:
175
+ self.__junction_dict__plus___[k] = v + self.__junction_dict__plus___.get(k, 0)
169
176
 
170
- for k, v in other._junction_dict_minus_:
171
- self._junction_dict_minus_[k] = v + self._junction_dict_minus_.get(k, 0)
177
+ for k, v in other.__junction_dict__minus__:
178
+ self.__junction_dict__minus__[k] = v + self.__junction_dict__minus__.get(k, 0)
172
179
 
173
180
  return self.junctions_dict
174
181
 
@@ -176,11 +183,11 @@ class ReadDepth(object):
176
183
  funcs = {"10": np.log10, "2": np.log2, "zscore": zscore, "e": np.log}
177
184
 
178
185
  if log_trans in funcs.keys():
179
- if self._plus_ is not None:
180
- self._plus_ = funcs[log_trans](self._plus_ + 1)
186
+ if self.__plus__ is not None:
187
+ self.__plus__ = funcs[log_trans](self.__plus__ + 1)
181
188
 
182
189
  if self.minus is not None:
183
- self._minus_ = funcs[log_trans](self._minus_ + 1)
190
+ self.__minus__ = funcs[log_trans](self.__minus__ + 1)
184
191
 
185
192
  def normalize(self, size_factor: float, format_: str = "normal", read_length: float = 0):
186
193
  u"""
@@ -192,35 +199,35 @@ class ReadDepth(object):
192
199
 
193
200
  if format_ == "rpkm" and read_length > 0:
194
201
  # for rpkm the size_factor is total reads
195
- self._plus_ = np.divide(
196
- self._plus_,
202
+ self.__plus__ = np.divide(
203
+ self.__plus__,
197
204
  np.multiply(
198
- (np.sum(self._plus_ != 0) - read_length + 1) / 1e3,
205
+ (np.sum(self.__plus__ != 0) - read_length + 1) / 1e3,
199
206
  size_factor / 1e6
200
207
  )
201
208
  )
202
- if self._minus_ is not None:
203
- self._minus_ = np.divide(
204
- self._minus_,
209
+ if self.__minus__ is not None:
210
+ self.__minus__ = np.divide(
211
+ self.__minus__,
205
212
  np.multiply(
206
- (np.sum(self._minus_ != 0) - read_length + 1) / 1e3,
213
+ (np.sum(self.__minus__ != 0) - read_length + 1) / 1e3,
207
214
  size_factor / 1e6
208
215
  )
209
216
  )
210
217
  elif format_ == "cpm" and read_length > 0:
211
218
  # for cpm the size_factor is total reads
212
- self._plus_ = np.divide(self._plus_, np.divide(size_factor, 1e6))
213
- if self._minus_ is not None:
214
- self._minus_ = np.divide(self._minus_, np.divide(size_factor, 1e6))
219
+ self.__plus__ = np.divide(self.__plus__, np.divide(size_factor, 1e6))
220
+ if self.__minus__ is not None:
221
+ self.__minus__ = np.divide(self.__minus__, np.divide(size_factor, 1e6))
215
222
  elif format_ == "cpm" and read_length > 0:
216
223
  # for cpm the size_factor is total reads
217
- self._plus_ = np.divide(self._plus_, np.divide(size_factor, 1e6))
218
- if self._minus_ is not None:
219
- self._minus_ = np.divide(self._minus_, np.divide(size_factor, 1e6))
224
+ self.__plus__ = np.divide(self.__plus__, np.divide(size_factor, 1e6))
225
+ if self.__minus__ is not None:
226
+ self.__minus__ = np.divide(self.__minus__, np.divide(size_factor, 1e6))
220
227
  elif size_factor is not None and size_factor > 0 and format_ == "atac":
221
- self._plus_ = np.divide(self._plus_, size_factor) # * 100
222
- if self._minus_ is not None:
223
- self._minus_ = np.divide(self._minus_, size_factor)
228
+ self.__plus__ = np.divide(self.__plus__, size_factor) # * 100
229
+ if self.__minus__ is not None:
230
+ self.__minus__ = np.divide(self.__minus__, size_factor)
224
231
 
225
232
 
226
233
  if __name__ == '__main__':
@@ -315,6 +315,8 @@ def process_file_list(infile: str, category: str = "density"):
315
315
  help="The junction id for including, chr1:1-100", show_default=True)
316
316
  @optgroup.option("--show-junction-num", type=click.BOOL, is_flag=True, show_default=True,
317
317
  help="Whether to show the number of junctions")
318
+ @optgroup.option("--show-mean-junction-num", type=click.BOOL, is_flag=True, show_default=True,
319
+ help="Whether to show the mean junction count averaged across multiple samples.")
318
320
  @optgroup.option("--fill-step", type=click.Choice(["pre", "post", "mid"]), default="post", show_default=True,
319
321
  help="""
320
322
  Define step if the filling should be a step function, i.e. constant in between x.
@@ -523,8 +525,6 @@ def main(**kwargs):
523
525
 
524
526
  size_factors = {}
525
527
 
526
- # add annotation
527
- # print(kwargs.keys())
528
528
  for key in kwargs.keys():
529
529
  if key in IMAGE_TYPE and kwargs[key] and os.path.exists(kwargs[key]):
530
530
  if key == "annotation":
@@ -573,6 +573,7 @@ def main(**kwargs):
573
573
  color=sc_colors.get(group, f.color),
574
574
  font_size=kwargs["font_size"],
575
575
  show_junction_number=kwargs["show_junction_num"],
576
+ show_mean_jxn_number=kwargs["show_mean_junction_num"],
576
577
  n_y_ticks=kwargs["n_y_ticks"],
577
578
  show_y_label=not kwargs["hide_y_label"],
578
579
  show_site_plot=kwargs["show_site"],
@@ -591,6 +592,7 @@ def main(**kwargs):
591
592
  color=f.color,
592
593
  font_size=kwargs["font_size"],
593
594
  show_junction_number=kwargs["show_junction_num"],
595
+ show_mean_jxn_number=kwargs["show_mean_junction_num"],
594
596
  n_y_ticks=kwargs["n_y_ticks"],
595
597
  show_y_label=not kwargs["hide_y_label"],
596
598
  show_site_plot=kwargs["show_site"],
@@ -32,7 +32,9 @@ def check_junction_exists(ref: List[Junction], dst: Junction, with_strand: bool
32
32
 
33
33
  for i in ref:
34
34
  if abs(i.start - dst.start) < 2 and abs(i.end - dst.end) < 2:
35
- logger.warning(f"1 bp mismatch between {i} (from bam file) and {dst} (user input), please check the coordinates")
35
+ if not with_strand:
36
+ # in outer code, this function will called twice, with with_strand = True and False. therefore, only print log once is enough
37
+ logger.warning(f"1 bp mismatch between {i} (from bam file) and {dst} (user input), please check the coordinates")
36
38
 
37
39
  if i.is_downstream(dst):
38
40
  return False
@@ -269,7 +271,8 @@ class Bam(SingleCell):
269
271
  logger.info(region)
270
272
  logger.info(cigar_string)
271
273
  logger.info(start, i)
272
- exit(err)
274
+ logger.error(err)
275
+ exit(1)
273
276
 
274
277
  # remove the deletion.
275
278
  if cigar not in (1, 4, 5): # I, S, H
@@ -5,7 +5,6 @@ u"""
5
5
  Handle the customized junction
6
6
  """
7
7
  import os
8
- import re
9
8
  from typing import Dict
10
9
 
11
10
  from trackplot.base.Junction import Junction
@@ -30,8 +30,8 @@ logging.getLogger('matplotlib.font_manager').setLevel(logging.ERROR)
30
30
  faulthandler.enable()
31
31
 
32
32
 
33
- __version__ = "0.5.5"
34
- __author__ = "ygidtu & Ran Zhou"
33
+ __version__ = "0.5.6"
34
+ __author__ = "Yiming Zhang & Ran Zhou"
35
35
  __email__ = "ygidtu@gmail.com"
36
36
 
37
37
 
@@ -572,6 +572,7 @@ class Plot(object):
572
572
  color="blue",
573
573
  font_size: int = 8,
574
574
  show_junction_number: bool = True,
575
+ show_mean_jxn_number: bool = False,
575
576
  junction_number_font_size: int = 5,
576
577
  n_y_ticks: int = 4,
577
578
  show_y_label: bool = True,
@@ -601,6 +602,7 @@ class Plot(object):
601
602
  :param library: should be one of [frf: "fr-firststrand", frs:"fr-secondstrand", fru:"fr-unstrand"], default: fru
602
603
  :param font_size: the font size for ticks, y-axis label and title
603
604
  :param show_junction_number: whether to show the number of junctions
605
+ :param show_mean_jxn_number:
604
606
  :param n_y_ticks: number of y ticks
605
607
  :param junction_number_font_size:
606
608
  :param color: color for this density plot
@@ -652,6 +654,7 @@ class Plot(object):
652
654
  self.plots.append(info)
653
655
  self.params[info] = {
654
656
  "show_junction_number": show_junction_number,
657
+ "show_mean_jxn_number": show_mean_jxn_number,
655
658
  "junction_number_font_size": junction_number_font_size,
656
659
  "color": color,
657
660
  "font_size": font_size,
@@ -5,10 +5,10 @@ This script contains the functions to draw different images
5
5
  Modified by AD 2025/01/13
6
6
  """
7
7
  import itertools # AD - for cumulative sum of graph_coords
8
- #import gzip
8
+ import gzip
9
9
  import math
10
10
  from copy import deepcopy
11
- #from decimal import Decimal
11
+
12
12
  from typing import Dict, List, Optional, Union, Tuple, Set
13
13
 
14
14
  import matplotlib as mpl
@@ -27,7 +27,6 @@ from matplotlib.textpath import TextPath
27
27
  from matplotlib.transforms import Affine2D
28
28
  from scipy.cluster.hierarchy import dendrogram, linkage
29
29
  from scipy.stats import gaussian_kde, zscore
30
- from scipy.stats import beta # AD
31
30
 
32
31
  from trackplot.anno.theme import Theme
33
32
  from trackplot.base.GenomicLoci import GenomicLoci
@@ -126,7 +125,7 @@ def __merge_exons__(exons: List[List[int]]):
126
125
 
127
126
 
128
127
  def init_graph_coords(region: GenomicLoci, exons: Optional[List[List[int]]] = None, exon_scale=1,
129
- intron_scale=0.5) -> np.array:
128
+ intron_scale=0.5) -> np.ndarray:
130
129
  u"""
131
130
  init the default
132
131
  :param region: the plot region
@@ -169,7 +168,7 @@ def init_graph_coords(region: GenomicLoci, exons: Optional[List[List[int]]] = No
169
168
  exons = exons[:-1]
170
169
  exons[0][0] = max(exons[0][0], region.start)
171
170
  exons[-1][1] = min(exons[-1][1], region.end)
172
- last_interval = region.end - exons[-1][1]
171
+
173
172
  for i, e in enumerate(exons):
174
173
  exons[i][0] -= region.start
175
174
  exons[i][1] -= region.start
@@ -184,7 +183,7 @@ def init_graph_coords(region: GenomicLoci, exons: Optional[List[List[int]]] = No
184
183
  step = intron_scale / interval
185
184
  for i in range(exons[e-1][1], exons[e][0]):
186
185
  steps[i] = step
187
- interval = exons[e][0] - exons[e-1][1] - 2
186
+
188
187
  if last_interval := len(region) - exons[-1][1] - 1:
189
188
  step = intron_scale / last_interval
190
189
  for i in range(exons[1][1] +1, len(region)):
@@ -204,7 +203,7 @@ def init_graph_coords(region: GenomicLoci, exons: Optional[List[List[int]]] = No
204
203
  return graph_coords
205
204
 
206
205
  def set_x_ticks(
207
- ax: mpl.axes.Axes,
206
+ ax,
208
207
  region: GenomicLoci,
209
208
  graph_coords: Optional[Union[Dict, np.ndarray]] = None,
210
209
  sequence: Optional[Dict[int, str]] = None,
@@ -263,7 +262,7 @@ def set_x_ticks(
263
262
 
264
263
 
265
264
  def set_y_ticks(
266
- ax: mpl.axes.Axes,
265
+ ax,
267
266
  label: str,
268
267
  graph_coords: Union[Dict, np.array],
269
268
  max_used_y_val: Union[int, float],
@@ -274,7 +273,6 @@ def set_y_ticks(
274
273
  font_size: int = 5,
275
274
  show_y_label: bool = True,
276
275
  set_label_only: bool = False,
277
- y_axis_skip_zero: bool = True,
278
276
  **kwargs
279
277
  ):
280
278
  u"""
@@ -355,7 +353,7 @@ def set_y_ticks(
355
353
 
356
354
 
357
355
  def set_focus(
358
- ax: mpl.axes.Axes,
356
+ ax,
359
357
  graph_coords: Union[Dict, np.array],
360
358
  focus: Dict[int, int]
361
359
  ):
@@ -372,7 +370,7 @@ def set_focus(
372
370
 
373
371
 
374
372
  def set_indicator_lines(
375
- ax: mpl.axes.Axes,
373
+ ax,
376
374
  graph_coords: Union[Dict, np.array],
377
375
  sites: Dict[int, str],
378
376
  min_y_used: Union[int, float] = 0,
@@ -399,7 +397,7 @@ def set_indicator_lines(
399
397
 
400
398
 
401
399
  def plot_stroke(
402
- ax: mpl.axes.Axes,
400
+ ax,
403
401
  data: List[Stroke],
404
402
  graph_coords: Optional[Union[Dict, np.ndarray]] = None,
405
403
  font_size: int = 5,
@@ -425,7 +423,7 @@ def plot_stroke(
425
423
 
426
424
 
427
425
  def plot_annotation(
428
- ax: mpl.axes.Axes,
426
+ ax,
429
427
  obj: Annotation,
430
428
  graph_coords: Optional[Union[Dict, np.ndarray]] = None,
431
429
  font_size: int = 5,
@@ -650,7 +648,7 @@ def plot_annotation(
650
648
 
651
649
 
652
650
  def plot_density(
653
- ax: mpl.axes.Axes,
651
+ ax,
654
652
  obj: Optional[File] = None,
655
653
  data: Optional[ReadDepth] = None,
656
654
  region: Optional[GenomicLoci] = None,
@@ -658,6 +656,7 @@ def plot_density(
658
656
  color="blue",
659
657
  font_size: int = 8,
660
658
  show_junction_number: bool = True,
659
+ show_mean_jxn_number: bool = False,
661
660
  junction_number_font_size: int = 12,
662
661
  n_y_ticks: int = 4,
663
662
  distance_between_label_axis: float = .1,
@@ -665,34 +664,11 @@ def plot_density(
665
664
  y_label: str = "",
666
665
  theme: str = "ticks_blank",
667
666
  max_used_y_val: Optional[float] = None,
668
- min_used_y_val: Optional[float] = None,
669
667
  raster: bool = False,
670
668
  fill_step: str = "post",
671
669
  **kwargs
672
670
  ):
673
- u"""
674
- draw density plot
675
- :param ax: mpl.axes.Axes
676
- :param data: File
677
- :param data: ReadDepth
678
- :param region: GenomicLoci
679
- :param graph_coords:
680
- :param font_size: the font size for ticks, y-axis label and title
681
- :param show_junction_number: whether to show the number of junctions
682
- :param distance_between_label_axis: distance between y-axis label and y-axis ticks
683
- :param n_y_ticks: number of y ticks
684
- :param junction_number_font_size:
685
- :param obj: Bam or Bigwig object
686
- :param color: color for this density plot
687
- :param show_y_label: whether to show y-axis label
688
- :param y_label: the text of y-axis title
689
- :param theme: the theme name
690
- :param max_used_y_val: used to set same max y-axis
691
- :param raster:
692
- :param fill_step:
693
- :param kwargs:
694
- :return:
695
- """
671
+ u""" draw density plot """
696
672
  # max_used_y_val is None
697
673
  # distance_between_label_axis: 0
698
674
  if obj:
@@ -711,21 +687,21 @@ def plot_density(
711
687
  data = obj.data
712
688
 
713
689
  try:
714
- jxns = data.junctions_dict
690
+ jxns = data.junctions_dict(show_mean_jxn_number)
715
691
  except AttributeError:
716
692
  # depth do not have junctions
717
693
  jxns = {}
718
-
694
+
719
695
  # AD - convert junction counts to log scale early if requested
696
+ jxn_number_log_transformed = False
720
697
  if obj.log_trans and obj.log_trans.isdigit() and int(obj.log_trans) > 0: # in ["2", "10"]:
721
-
698
+ jxn_number_log_transformed = True
722
699
  y_label += f" (log{obj.log_trans})"
723
700
  denominator = np.log(int(obj.log_trans))
724
701
  for k, v in jxns.items():
725
702
  jxns[k] = np.log1p(v) / denominator
726
703
 
727
704
  min_used_y_val = 0 # AD
728
- fixed_min_used_y = True # AD
729
705
  fixed_max_used_y, fixed_min_used_y = max_used_y_val is not None, min_used_y_val is not None
730
706
  if max_used_y_val is None:
731
707
  if isinstance(data, dict):
@@ -792,15 +768,11 @@ def plot_density(
792
768
  add two new variables to make it clear which one is index, which one is genomic site
793
769
  """
794
770
  ss1, ss2 = graph_coords[ss1_idx], graph_coords[ss2_idx]
795
- # AD = keep junction arcs on top
796
- jxn_on_top = True
797
-
798
771
  # draw junction on bottom
799
772
  if kwargs.get("density_by_strand"):
800
773
  jxn_on_top = jxn.strand == "+"
801
774
  else:
802
775
  jxn_on_top = jxn_idx % 2 == 0
803
- #jxn_on_top = True # AD - keep all junctions on same strand
804
776
  if abs(min_used_y_val) < max_used_y_val:
805
777
  min_used_y_val = -max_used_y_val
806
778
 
@@ -846,9 +818,15 @@ def plot_density(
846
818
  if show_junction_number:
847
819
  midpt = cubic_bezier(pts, .5)
848
820
 
821
+ val = jxns[jxn]
822
+ if jxn_number_log_transformed or show_mean_jxn_number:
823
+ val = round(val, 2)
824
+ else:
825
+ val = int(val)
826
+
849
827
  t = ax.text(
850
828
  midpt[0], midpt[1],
851
- '{0}'.format(round(jxns[jxn], 2)),
829
+ '{0}'.format(val),
852
830
  fontsize=junction_number_font_size,
853
831
  ha='center', va='center',
854
832
  backgroundcolor='w'
@@ -893,7 +871,7 @@ def plot_density(
893
871
 
894
872
 
895
873
  def plot_site_plot(
896
- ax: mpl.axes.Axes,
874
+ ax,
897
875
  obj: File,
898
876
  graph_coords: Optional[Union[Dict, np.ndarray]] = None,
899
877
  color="blue",
@@ -975,8 +953,8 @@ def plot_site_plot(
975
953
 
976
954
 
977
955
  def plot_heatmap(
978
- ax: mpl.axes.Axes,
979
- cbar_ax: mpl.axes.Axes,
956
+ ax,
957
+ cbar_ax,
980
958
  data: Dict[str, ReadDepth],
981
959
  graph_coords: Optional[Union[Dict, np.ndarray]] = None,
982
960
  color="viridis",
@@ -1067,8 +1045,8 @@ def plot_heatmap(
1067
1045
 
1068
1046
 
1069
1047
  def plot_hic(
1070
- ax: mpl.axes.Axes,
1071
- cbar_ax: mpl.axes.Axes,
1048
+ ax,
1049
+ cbar_ax,
1072
1050
  obj: List[HiCTrack],
1073
1051
  show_legend: bool = True,
1074
1052
  graph_coords: Optional[Union[Dict, np.ndarray]] = None,
@@ -1142,7 +1120,7 @@ def plot_hic(
1142
1120
 
1143
1121
 
1144
1122
  def plot_line(
1145
- ax: mpl.axes.Axes,
1123
+ ax,
1146
1124
  data: Dict[str, ReadDepth],
1147
1125
  graph_coords: Union[Dict, np.ndarray],
1148
1126
  font_size: int = 8,
@@ -1222,7 +1200,7 @@ def plot_line(
1222
1200
 
1223
1201
 
1224
1202
  def plot_igv_like(
1225
- ax: mpl.axes.Axes,
1203
+ ax,
1226
1204
  obj: Dict[str, ReadSegment],
1227
1205
  graph_coords: Optional[Union[Dict, np.ndarray]] = None,
1228
1206
  y_label: str = "",
@@ -1356,7 +1334,7 @@ def plot_igv_like(
1356
1334
  )
1357
1335
 
1358
1336
 
1359
- def plot_links(ax: mpl.axes.Axes,
1337
+ def plot_links(ax,
1360
1338
  data: List[Stroke],
1361
1339
  graph_coords: Optional[Union[Dict, np.ndarray]] = None,
1362
1340
  max_y: int = -10, **kwargs):
@@ -1394,7 +1372,7 @@ def make_text_elements(text, x=0.0, y=0.0, width=1.0, height=1.0,
1394
1372
  return PathPatch(tp, facecolor=color, edgecolor=edgecolor)
1395
1373
 
1396
1374
 
1397
- def plot_motif(ax: mpl.axes.Axes,
1375
+ def plot_motif(ax,
1398
1376
  obj, # list of weighted text
1399
1377
  graph_coords: Optional[Union[Dict, np.ndarray]] = None,
1400
1378
  width: float = 0.8,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trackplot
3
- Version: 0.5.5
3
+ Version: 0.5.6
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
@@ -23,7 +23,7 @@ Requires-Dist: pysam>=0.23.3
23
23
  Requires-Dist: requests>=2.32.4
24
24
  Requires-Dist: scipy>=1.15.3
25
25
  Requires-Dist: seaborn>=0.13.2
26
- Requires-Dist: xmltodict>=0.14.2
26
+ Requires-Dist: xmltodict>=0.15.0
27
27
  Dynamic: license-file
28
28
 
29
29
  # trackplot