trackplot 0.5.2__tar.gz → 0.5.3__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 (80) hide show
  1. {trackplot-0.5.2 → trackplot-0.5.3}/PKG-INFO +1 -1
  2. {trackplot-0.5.2 → trackplot-0.5.3}/pyproject.toml +1 -1
  3. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/base/Junction.py +13 -0
  4. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/Annotation.py +23 -7
  5. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/Bam.py +22 -4
  6. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/ReadSegments.py +3 -1
  7. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/plot.py +2 -2
  8. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/plot_func.py +124 -63
  9. trackplot-0.5.3/ui/assets/Home-7GzAh8lS.js +1 -0
  10. trackplot-0.5.3/ui/assets/Home-CDW3Zwoa.js +1 -0
  11. trackplot-0.5.3/ui/assets/Home-zRV7yePL.css +1 -0
  12. trackplot-0.5.3/ui/assets/Plot-BrjU8Kwg.js +17 -0
  13. trackplot-0.5.3/ui/assets/Plot-COvGnprQ.css +1 -0
  14. trackplot-0.5.3/ui/assets/Plot-Cyj_LlDt.js +17 -0
  15. trackplot-0.5.3/ui/assets/Plot-DpL7z7tp.css +1 -0
  16. trackplot-0.5.3/ui/assets/el-divider-BVZhQIwQ.js +1 -0
  17. trackplot-0.5.3/ui/assets/el-divider-Brt4-Qvr.js +1 -0
  18. trackplot-0.5.3/ui/assets/el-divider-Cwxg0Ado.css +1 -0
  19. trackplot-0.5.3/ui/assets/el-divider-i9JMIXVR.css +1 -0
  20. trackplot-0.5.3/ui/assets/index-4hxJ_zbq.js +26 -0
  21. trackplot-0.5.3/ui/assets/index-CWfdj0DH.js +26 -0
  22. trackplot-0.5.3/ui/assets/index-O8P0XkxB.css +1 -0
  23. trackplot-0.5.3/ui/assets/index-ns9n7-F7.css +1 -0
  24. {trackplot-0.5.2 → trackplot-0.5.3}/ui/index.html +2 -2
  25. {trackplot-0.5.2 → trackplot-0.5.3}/LICENSE +0 -0
  26. {trackplot-0.5.2 → trackplot-0.5.3}/README.md +0 -0
  27. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/__init__.py +0 -0
  28. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/anno/AxLabel.py +0 -0
  29. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/anno/__init__.py +0 -0
  30. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/anno/theme.py +0 -0
  31. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/base/CoordinateMap.py +0 -0
  32. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/base/GenomicLoci.py +0 -0
  33. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/base/Protein.py +0 -0
  34. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/base/ReadDepth.py +0 -0
  35. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/base/Readder.py +0 -0
  36. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/base/Stroke.py +0 -0
  37. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/base/Transcript.py +0 -0
  38. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/base/__init__.py +0 -0
  39. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/base/pyUniprot.py +0 -0
  40. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/cli.py +0 -0
  41. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/conf/DomainSetting.py +0 -0
  42. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/conf/__init__.py +0 -0
  43. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/conf/config.py +0 -0
  44. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/conf/drawing.py +0 -0
  45. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/conf/ui.py +0 -0
  46. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/ATAC.py +0 -0
  47. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/BedGraph.py +0 -0
  48. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/Bigwig.py +0 -0
  49. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/Depth.py +0 -0
  50. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/Fasta.py +0 -0
  51. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/File.py +0 -0
  52. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/HiCMatrixTrack.py +0 -0
  53. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/Junction.py +0 -0
  54. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/Motif.py +0 -0
  55. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/file/__init__.py +0 -0
  56. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/plot_tests.py +0 -0
  57. {trackplot-0.5.2 → trackplot-0.5.3}/trackplot/server.py +0 -0
  58. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/Home-DOO13BH7.js +0 -0
  59. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/Home-QmeAKOl4.js +0 -0
  60. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/Home-RdVPWns6.js +0 -0
  61. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/Home-jSR0MsHI.css +0 -0
  62. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/Plot-BmqHZ4QE.css +0 -0
  63. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/Plot-Bvyo6ju9.css +0 -0
  64. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/Plot-CTM-EDrj.js +0 -0
  65. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/Plot-DiuFnwNK.js +0 -0
  66. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/Plot-hvkDteAn.js +0 -0
  67. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/Plot-rbQz1TOM.css +0 -0
  68. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/el-divider-BHm65SRq.css +0 -0
  69. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/el-divider-BuEUMHwE.css +0 -0
  70. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/el-divider-SYT5K-ds.css +0 -0
  71. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/el-divider-VYjL3C7L.js +0 -0
  72. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/el-divider-eEJXnQD5.js +0 -0
  73. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/el-divider-u9f0bZWY.js +0 -0
  74. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/index-CETGMNio.css +0 -0
  75. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/index-Cexhr_fn.css +0 -0
  76. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/index-CrzyEb9s.js +0 -0
  77. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/index-D_Cw0sbX.js +0 -0
  78. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/index-Dd6Bavnk.js +0 -0
  79. {trackplot-0.5.2 → trackplot-0.5.3}/ui/assets/index-Sq2gI4sE.css +0 -0
  80. {trackplot-0.5.2 → trackplot-0.5.3}/ui/vite.svg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: trackplot
3
- Version: 0.5.2
3
+ Version: 0.5.3
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
  License: BSD-3
6
6
  Author: ygidtu
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "trackplot"
3
- version = "0.5.2"
3
+ version = "0.5.3"
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 = ["ygidtu <ygidtu@gmail.com>"]
6
6
  license = "BSD-3"
@@ -134,6 +134,19 @@ class Junction(object):
134
134
 
135
135
  return self.start > other.end
136
136
 
137
+ def str(self, with_strand: bool = True) -> str:
138
+ u"""convert junctions to string, with or without strand
139
+
140
+ Keyword arguments:
141
+ :param with_strand: as name says
142
+ Return: chr:strat-end:strand or chr:start-end
143
+ """
144
+ if with_strand:
145
+ return str(self)
146
+ return f"{self.chromosome}:{self.start}-{self.end}"
147
+
148
+
149
+
137
150
 
138
151
  if __name__ == '__main__':
139
152
  pass
@@ -2,8 +2,10 @@
2
2
  # -*- coding:utf-8 -*-
3
3
  u"""
4
4
  Created by ygidtu@gmail.com at 2020.05.07
5
-
6
5
  This scripts contains the class handle the reference file
6
+
7
+ Modified by AD 2025/01/12 to include only specified transcripts, otherwise their exon coordinates still occupy the alignments.
8
+
7
9
  """
8
10
  import glob
9
11
  import gzip
@@ -349,16 +351,15 @@ class Annotation(File):
349
351
 
350
352
  return output_gtf
351
353
 
352
- def __load_gtf__(self):
353
-
354
+ def __load_gtf__(self, transcripts_to_show: list[str]|None = None):
354
355
  u"""
355
356
  Load transcripts inside of region from gtf file
356
357
  :param region: target region
357
358
  :return: list of Transcript
358
- """
359
+ """
360
+ # AD - passing transcripts_to_show
359
361
  transcripts = {}
360
362
  exons = {}
361
-
362
363
  for rec in Reader.read_gtf(self.path, self.region):
363
364
  start = max(rec.start, self.region.start)
364
365
  end = min(rec.end, self.region.end)
@@ -369,6 +370,13 @@ class Annotation(File):
369
370
  break
370
371
 
371
372
  if re.search(r"(rna|transcript|cds)", rec.feature, re.I):
373
+
374
+ if transcripts_to_show:
375
+ _name = rec.transcript_name if "transcript_name" in rec.attributes else rec.transcript_id
376
+ if _name not in transcripts_to_show:
377
+ logger.info(f"Skipping transcript {_name}")
378
+ continue
379
+
372
380
  if rec.transcript_id not in transcripts.keys():
373
381
  transcripts[rec.transcript_id] = Transcript(
374
382
  chromosome=rec.contig,
@@ -380,7 +388,8 @@ class Annotation(File):
380
388
  gene=rec.gene_name if "gene_name" in rec.attributes else "",
381
389
  transcript=rec.transcript_name if "transcript_name" in rec.attributes else "",
382
390
  exons=[]
383
- )
391
+ )
392
+
384
393
  elif re.search(r"(exon)", rec.feature, re.I):
385
394
  if rec.transcript_id not in exons.keys():
386
395
  exons[rec.transcript_id] = []
@@ -581,9 +590,16 @@ class Annotation(File):
581
590
  assert isinstance(region, GenomicLoci), "region should be a GenomicLoci object"
582
591
  if transcripts is None:
583
592
  transcripts = []
593
+ elif isinstance(transcripts, str):
594
+ # AD when no transcripts are specified, transcripts is an empty string, not None
595
+ if transcripts == "":
596
+ transcripts = []
597
+ else:
598
+ transcripts = transcripts.split(",")
584
599
  self.region = region
600
+ # AD - pass specified transcripts early
585
601
  if self.category == "gtf":
586
- self.__load_gtf__()
602
+ self.__load_gtf__(transcripts)
587
603
  if self.add_local_domain:
588
604
  self.__load_local_domain__(region)
589
605
 
@@ -20,7 +20,7 @@ from trackplot.base.Junction import Junction
20
20
  from trackplot.base.ReadDepth import ReadDepth
21
21
  from trackplot.base.Readder import Reader
22
22
  from trackplot.conf.config import NORMALIZATION
23
- from trackplot.file.File import SingleCell
23
+ from trackplot.file.File import SingleCell
24
24
 
25
25
 
26
26
  class Bam(SingleCell):
@@ -275,14 +275,32 @@ class Bam(SingleCell):
275
275
  site_minus[start - region.start] += 1
276
276
 
277
277
  for k, v in spanned_junctions.items():
278
- if included_junctions and str(k) not in included_junctions:
278
+ kept = v >= threshold
279
+
280
+ # if the number of junctiosn is lower than threshold, then skip
281
+ if not kept:
279
282
  continue
280
-
281
- if v >= threshold:
283
+
284
+ # if included_junctions is provided, then skip all junctions by default
285
+ if included_junctions:
286
+ kept = False
287
+
288
+ # check whether junctions should be kept
289
+ if k.str(with_strand = True) in included_junctions:
290
+ logger.debug(f"{str(k)} is included")
291
+ kept = True
292
+ elif k.str(with_strand = False) in included_junctions:
293
+ logger.debug(f"{str(k)} is included, but strand is ignored")
294
+ kept = True
295
+
296
+ if not kept:
297
+ logger.debug(f"{str(k)} is not included")
298
+ else:
282
299
  if k.strand == "+":
283
300
  spanned_junctions_plus[k] = 1 + spanned_junctions_plus.get(k, v)
284
301
  elif k.strand == "-":
285
302
  spanned_junctions_minus[k] = -1 + spanned_junctions_minus.get(k, v)
303
+
286
304
  except IOError as err:
287
305
  logger.error('There is no .bam file at {0}'.format(self.path))
288
306
  logger.error(err)
@@ -382,7 +382,9 @@ class ReadSegment(File):
382
382
  current_ignore_num = min(
383
383
  [self.deletion_ignore, read.query_alignment_length * self.del_ratio_ignore])
384
384
  else:
385
- current_ignore_num = np.Inf
385
+ current_ignore_num = np.inf
386
+ # AD - AttributeError: `np.Inf` was removed in the NumPy 2.0 release. Use `np.inf` instead.
387
+
386
388
 
387
389
  exon_bound = []
388
390
  intron_bound = []
@@ -30,7 +30,7 @@ logging.getLogger('matplotlib.font_manager').setLevel(logging.ERROR)
30
30
  faulthandler.enable()
31
31
 
32
32
 
33
- __version__ = "0.5.2"
33
+ __version__ = "0.5.3"
34
34
  __author__ = "ygidtu & Ran Zhou"
35
35
  __email__ = "ygidtu@gmail.com"
36
36
 
@@ -1437,7 +1437,7 @@ class Plot(object):
1437
1437
 
1438
1438
  if output:
1439
1439
  logger.info(f"saving fig into {output}")
1440
- fig.savefig(output, transparent=True, bbox_inches='tight')
1440
+ fig.savefig(output, transparent=False, bbox_inches='tight') # AD
1441
1441
  elif return_image:
1442
1442
  output = io.BytesIO()
1443
1443
  if return_image == "png":
@@ -2,11 +2,13 @@
2
2
  # -*- coding:utf-8 -*-
3
3
  u"""
4
4
  This script contains the functions to draw different images
5
+ Modified by AD 2025/01/13
5
6
  """
6
- import gzip
7
+ import itertools # AD - for cumulative sum of graph_coords
8
+ #import gzip
7
9
  import math
8
10
  from copy import deepcopy
9
- from decimal import Decimal
11
+ #from decimal import Decimal
10
12
  from typing import Dict, List, Optional, Union, Tuple, Set
11
13
 
12
14
  import matplotlib as mpl
@@ -25,6 +27,7 @@ from matplotlib.textpath import TextPath
25
27
  from matplotlib.transforms import Affine2D
26
28
  from scipy.cluster.hierarchy import dendrogram, linkage
27
29
  from scipy.stats import gaussian_kde, zscore
30
+ from scipy.stats import beta # AD
28
31
 
29
32
  from trackplot.anno.theme import Theme
30
33
  from trackplot.base.GenomicLoci import GenomicLoci
@@ -100,7 +103,6 @@ def cubic_bezier(pts, t):
100
103
  p3 = np.array(p3)
101
104
  return p0 * (1 - t) ** 3 + 3 * t * p1 * (1 - t) ** 2 + 3 * t ** 2 * (1 - t) * p2 + t ** 3 * p3
102
105
 
103
-
104
106
  def __merge_exons__(exons: List[List[int]]):
105
107
  u"""
106
108
  merge the overlap exons into one
@@ -124,7 +126,7 @@ def __merge_exons__(exons: List[List[int]]):
124
126
 
125
127
 
126
128
  def init_graph_coords(region: GenomicLoci, exons: Optional[List[List[int]]] = None, exon_scale=1,
127
- intron_scale=.5) -> np.array:
129
+ intron_scale=0.5) -> np.array:
128
130
  u"""
129
131
  init the default
130
132
  :param region: the plot region
@@ -135,33 +137,62 @@ def init_graph_coords(region: GenomicLoci, exons: Optional[List[List[int]]] = No
135
137
  graph_coords = np.zeros(len(region), dtype=int)
136
138
 
137
139
  if exons:
138
- # if there have exons, init graph_coords by exon and intron scales
139
- for i in range(0, exons[0][0] - region.start):
140
- graph_coords[i] = (i - 0) * intron_scale
141
-
142
- exons = __merge_exons__(exons)
143
- for i in range(0, len(exons)):
144
- exon = exons[i]
145
-
146
- if i > 0:
147
- intron = [exons[i - 1][1], exons[i][0]]
148
-
149
- for j in range(intron[0], intron[1]):
140
+ # AD - if user specifies an intron scale in line with Trackplot, addition is transparent
141
+ if intron_scale <= 1:
142
+ # if there have exons, init graph_coords by exon and intron scales
143
+ for i in range(0, exons[0][0] - region.start):
144
+ graph_coords[i] = (i - 0) * intron_scale
145
+ exons = __merge_exons__(exons)
146
+ for i in range(0, len(exons)):
147
+ exon = exons[i]
148
+ if i > 0:
149
+ intron = [exons[i - 1][1], exons[i][0]]
150
+
151
+ for j in range(intron[0], intron[1]):
152
+ if j >= region.start:
153
+ graph_coords[j - region.start] = graph_coords[intron[0] - region.start - 1] + (
154
+ j - intron[0] + 1) * intron_scale
155
+ for j in range(exon[0], exon[1] + 1):
150
156
  if j >= region.start:
151
- graph_coords[j - region.start] = graph_coords[intron[0] - region.start - 1] + (
152
- j - intron[0] + 1) * intron_scale
153
-
154
- for j in range(exon[0], exon[1] + 1):
155
- if j >= region.start:
156
- graph_coords[j - region.start] = graph_coords[exon[0] - region.start - 1] + (
157
- j - exon[0] + 1) * exon_scale
158
-
159
- intron = [exons[-1][-1], region.end]
160
- for i in range(intron[0], intron[1]):
161
- if i >= region.start:
162
- graph_coords[i - region.start] = graph_coords[intron[0] - region.start - 1] + (
163
- i - intron[0] + 1) * intron_scale
164
-
157
+ graph_coords[j - region.start] = graph_coords[exon[0] - region.start - 1] + (
158
+ j - exon[0] + 1) * exon_scale
159
+ intron = [exons[-1][-1], region.end]
160
+ for i in range(intron[0], intron[1]):
161
+ if i >= region.start:
162
+ graph_coords[i - region.start] = graph_coords[intron[0] - region.start - 1] + (
163
+ i - intron[0] + 1) * intron_scale
164
+ else:
165
+ exons = __merge_exons__(exons)
166
+ while exons[0][1] < region.start:
167
+ exons = exons[1:]
168
+ while exons[-1][0] > region.end:
169
+ exons = exons[:-1]
170
+ exons[0][0] = max(exons[0][0], region.start)
171
+ exons[-1][1] = min(exons[-1][1], region.end)
172
+ last_interval = region.end - exons[-1][1]
173
+ for i, e in enumerate(exons):
174
+ exons[i][0] -= region.start
175
+ exons[i][1] -= region.start
176
+
177
+ steps = [float(exon_scale)] * len(region)
178
+ if exons[0][0] > 0:
179
+ step = intron_scale / exons[0][0]
180
+ for i in range(exons[0][0]):
181
+ steps[i] = step
182
+ for e in range(1, len(exons)):
183
+ interval = exons[e][0] - exons[e-1][1] - 2
184
+ step = intron_scale / interval
185
+ for i in range(exons[e-1][1], exons[e][0]):
186
+ steps[i] = step
187
+ interval = exons[e][0] - exons[e-1][1] - 2
188
+ if last_interval := len(region) - exons[-1][1] - 1:
189
+ step = intron_scale / last_interval
190
+ for i in range(exons[1][1] +1, len(region)):
191
+ steps[i] = step
192
+ graph_coords = list(map(int, itertools.accumulate(steps)))
193
+ #increments match exactly with original code
194
+ #for i, e in enumerate(graph_objects):
195
+ # print(f"{i}\t{e}")
165
196
  else:
166
197
  # if there is not any exons, just init graph_coords by region
167
198
  for i, j in enumerate(range(region.start, region.end + 1)):
@@ -175,7 +206,6 @@ def init_graph_coords(region: GenomicLoci, exons: Optional[List[List[int]]] = No
175
206
  graph_coords[i] = max(graph_coords) + 1
176
207
  return graph_coords
177
208
 
178
-
179
209
  def set_x_ticks(
180
210
  ax: mpl.axes.Axes,
181
211
  region: GenomicLoci,
@@ -284,6 +314,8 @@ def set_y_ticks(
284
314
  universal_y_ticks = sorted(universal_y_ticks)
285
315
 
286
316
  for lab in universal_y_ticks:
317
+ curr_y_tick_labels.append(f"{int(lab)}")
318
+ """
287
319
  if y_axis_skip_zero and lab == 0:
288
320
  # Exclude label for 0
289
321
  curr_y_tick_labels.append("")
@@ -291,6 +323,7 @@ def set_y_ticks(
291
323
  curr_y_tick_labels.append(f"{Decimal(lab):.2E}")
292
324
  else:
293
325
  curr_y_tick_labels.append(f"{lab:.1f}" if lab % 1 != 0 else f"{int(lab)}")
326
+ """
294
327
  u"""
295
328
  @2019.01.04
296
329
  If there is no bam file, draw a blank y-axis
@@ -306,6 +339,7 @@ def set_y_ticks(
306
339
  """
307
340
 
308
341
  if show_y_label:
342
+
309
343
  def __dynamic_distance__(distance_between_label_axis: float, label: str, scale: int = 100) -> float:
310
344
  if distance_between_label_axis != 0:
311
345
  return -distance_between_label_axis
@@ -314,9 +348,7 @@ def set_y_ticks(
314
348
 
315
349
  curr_y_tick_labels = sorted(curr_y_tick_labels, key=lambda x: len(x), reverse=True)
316
350
  ax.text(
317
- x=__dynamic_distance__(
318
- distance_between_label_axis, curr_y_tick_labels[0] if curr_y_tick_labels else ""
319
- ) * max(graph_coords),
351
+ x=__dynamic_distance__(distance_between_label_axis, curr_y_tick_labels[0] if curr_y_tick_labels else "") * max(graph_coords),
320
352
  y=(max_used_y_val + min_used_y_val) / 2,
321
353
  s=label, fontsize=font_size, ha="right"
322
354
  )
@@ -629,7 +661,7 @@ def plot_density(
629
661
  color="blue",
630
662
  font_size: int = 8,
631
663
  show_junction_number: bool = True,
632
- junction_number_font_size: int = 5,
664
+ junction_number_font_size: int = 12,
633
665
  n_y_ticks: int = 4,
634
666
  distance_between_label_axis: float = .1,
635
667
  show_y_label: bool = True,
@@ -664,6 +696,8 @@ def plot_density(
664
696
  :param kwargs:
665
697
  :return:
666
698
  """
699
+ # max_used_y_val is None
700
+ # distance_between_label_axis: 0
667
701
  if obj:
668
702
  assert obj.region is not None, "please load data first"
669
703
  region = obj.region
@@ -684,7 +718,17 @@ def plot_density(
684
718
  except AttributeError:
685
719
  # depth do not have junctions
686
720
  jxns = {}
721
+
722
+ # AD - convert junction counts to log scale early if requested
723
+ if obj.log_trans and obj.log_trans.isdigit() and int(obj.log_trans) > 0: # in ["2", "10"]:
724
+
725
+ y_label += f" (log{obj.log_trans})"
726
+ denominator = np.log(int(obj.log_trans))
727
+ for k, v in jxns.items():
728
+ jxns[k] = np.log1p(v) / denominator
687
729
 
730
+ min_used_y_val = 0 # AD
731
+ fixed_min_used_y = True # AD
688
732
  fixed_max_used_y, fixed_min_used_y = max_used_y_val is not None, min_used_y_val is not None
689
733
  if max_used_y_val is None:
690
734
  if isinstance(data, dict):
@@ -720,7 +764,6 @@ def plot_density(
720
764
  if data.strand_aware:
721
765
  max_used_y_val = max(abs(min_used_y_val), max_used_y_val)
722
766
  min_used_y_val = -max(abs(min_used_y_val), max_used_y_val) if data.minus is not None else 0
723
-
724
767
  if jxns:
725
768
  # sort the junctions by intron length for better plotting look
726
769
  jxns_sorted_list = sorted(jxns.keys(), key=lambda x: (x.end - x.start, x.start, x.end), reverse=True)
@@ -732,10 +775,11 @@ def plot_density(
732
775
  min_junction_count = min(jxns.values())
733
776
  junction_count_gap = max_junction_count - min_junction_count
734
777
 
735
- recorded_pts = set()
778
+ #recorded_pts = set()
736
779
  jxn_numbers = []
780
+
737
781
  for jxn_idx, jxn in enumerate(jxns_sorted_list):
738
- logger.debug(f"junctions of {y_label}: {jxn} - {round(jxns[jxn], 2)}")
782
+ #logger.info(f"junctions of {y_label}: {jxn} - {round(jxns[jxn], 2)}")
739
783
  leftss, rightss = jxn.start, jxn.end
740
784
 
741
785
  # junction must at least have one anchor located in plotted region
@@ -748,20 +792,26 @@ def plot_density(
748
792
  # the junction out of boundaries, set the boundaries as coordinate
749
793
  ss1_idx, ss1_modified = get_limited_index(leftss - region.start, len(graph_coords))
750
794
  ss2_idx, ss2_modified = get_limited_index(rightss - region.start, len(graph_coords))
795
+ #logger.info(f"{y_label} ss1_idx {ss1_idx} ss1_modified {ss1_modified} ss2_idx {ss2_idx} ss2_modified {ss2_modified}")
751
796
  u"""
752
797
  @2019.01.14
753
798
  add two new variables to make it clear which one is index, which one is genomic site
754
799
  """
755
800
  ss1, ss2 = graph_coords[ss1_idx], graph_coords[ss2_idx]
756
-
801
+ # AD = keep junction arcs on top
802
+ #min_used_y_val = 1
803
+ jxn_on_top = True
804
+ min_used_y_val = 0
757
805
  # draw junction on bottom
806
+ """
758
807
  if kwargs.get("density_by_strand"):
759
808
  jxn_on_top = jxn.strand == "+"
760
809
  else:
761
810
  jxn_on_top = jxn_idx % 2 == 0
811
+ #jxn_on_top = True # AD - keep all junctions on same strand
762
812
  if abs(min_used_y_val) < max_used_y_val:
763
813
  min_used_y_val = -max_used_y_val
764
-
814
+ """
765
815
  if fill_step == "post":
766
816
  ss1_idx = max(0, ss1_idx - 1)
767
817
  elif fill_step == "pre":
@@ -785,46 +835,57 @@ def plot_density(
785
835
  -right_dens - current_height,
786
836
  -right_dens if not ss2_modified else -right_dens - current_height
787
837
  ]
788
-
838
+ """
789
839
  if sum(pts) > 0:
790
840
  pts_ = "_".join([str(x) for x in pts])
791
841
  while pts_ in recorded_pts:
792
842
  pts[1], pts[2] = pts[1] * 1.1, pts[2] * 1.1
793
843
  pts_ = "_".join([str(x) for x in pts])
794
844
  recorded_pts.add(pts_)
795
-
845
+ """
796
846
  """
797
847
  @2018.12.26
798
848
  scale the junctions line width
799
849
  """
800
850
  if junction_count_gap > 0:
801
- line_width = (jxns[jxn] - min_junction_count) / junction_count_gap
851
+ #line_width = (jxns[jxn] - min_junction_count) / junction_count_gap
852
+ line_width = .5 + 1.5 * (jxns[jxn] - min_junction_count) / junction_count_gap
802
853
  else:
803
854
  line_width = 0
855
+ #line_width = max(.5,np.log())
856
+ #pts = [(ss1, pts[0]), (ss1, pts[1]), (ss2, pts[2]), (ss2, pts[3])]
857
+
804
858
 
805
- pts = [(ss1, pts[0]), (ss1, pts[1]), (ss2, pts[2]), (ss2, pts[3])]
859
+ temp = np.linspace(0, 1.0, 100)
860
+ bdist = beta.pdf(temp, 3, 3) # or 2, 2
861
+ bdist /= np.max(bdist) # max = 1
862
+ bdist *= jxns[jxn]
863
+ pts_x = np.linspace(ss1, ss2, 100)
864
+
865
+ #pts = [(ss1, 0), (ss1+5, jxns[jxn]), (ss2-5, jxns[jxn]), (ss2, 0)]
866
+ path = Path(np.array([pts_x, bdist]).T)
867
+ patch = PathPatch(path, facecolor='none', edgecolor="#BA55D3", linewidth=line_width)
868
+ ax.add_patch(patch)
869
+ """
870
+ # pts = [(ss1, 0), (midpt-5, jxns[jxn]), (midpt+5, jxns[jxn]), (ss2, 0)]
806
871
  ax.add_patch(PathPatch(Path(pts, [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]),
807
- ec=color, lw=line_width + 0.2, fc='none'))
808
-
872
+ ec="#BA55D3", lw=line_width, fc='none'))
873
+ #ec=color, lw=line_width + 0.2, fc='none'))
874
+ """
809
875
  if show_junction_number:
810
- midpt = cubic_bezier(pts, .5)
811
-
812
- t = ax.text(
813
- midpt[0], midpt[1],
814
- '{0}'.format(round(jxns[jxn], 2)),
815
- fontsize=junction_number_font_size,
816
- ha='center', va='center',
817
- backgroundcolor='w'
818
- )
819
-
876
+ t = ax.text( (ss1+ss2)/2, jxns[jxn] * 1.1,
877
+ '{0}'.format(round(jxns[jxn], 2)),
878
+ fontsize=junction_number_font_size, ha='center', va='center')
879
+ #, backgroundcolor='w' ) AD - white here overrides transparency below
820
880
  # @2018.12.19 transparent background
821
881
  t.set_bbox(dict(alpha=0))
822
882
  jxn_numbers.append(t)
823
883
 
824
- try:
825
- adjust_text(jxn_numbers, force_text=(0.2, 0.2), arrowprops=dict(arrowstyle="-", color='black', lw=1))
826
- except IndexError as err:
827
- logger.debug(err)
884
+ # AD - this adds a dot next to the counts
885
+ #try:
886
+ # adjust_text(jxn_numbers, force_text=(0.2, 0.2), arrowprops=dict(arrowstyle="-", color='black', lw=1))
887
+ #except IndexError as err:
888
+ # logger.debug(err)
828
889
 
829
890
  if obj and obj.title:
830
891
  ax.text(max(graph_coords) - len(obj.title), max_used_y_val, obj.title, color=color, fontsize=font_size)
@@ -849,13 +910,13 @@ def plot_density(
849
910
  set_y_ticks(
850
911
  ax, label=y_label, theme=theme,
851
912
  graph_coords=graph_coords,
852
- max_used_y_val=max_used_y_val * 1.1, # keep a buffer at top and bottom of junctions
853
- min_used_y_val=min_used_y_val * 1.1,
913
+ max_used_y_val=max_used_y_val, # * 1.1, # keep a buffer at top and bottom of junctions
914
+ min_used_y_val=min_used_y_val, # * 1.1, # AD
854
915
  n_y_ticks=n_y_ticks,
855
916
  distance_between_label_axis=distance_between_label_axis,
856
917
  font_size=font_size,
857
918
  show_y_label=show_y_label,
858
- y_axis_skip_zero=False if not isinstance(data, dict) and data.strand_aware else True
919
+ y_axis_skip_zero=False #if not isinstance(data, dict) and data.strand_aware else True
859
920
  )
860
921
 
861
922
 
@@ -0,0 +1 @@
1
+ import{d as _,o as m,c as u,a as c,t as f,b as e,w as t,E as g,e as n,u as i,f as h,_ as y}from"./index-CWfdj0DH.js";import{E as k,a as w,b as E,m as v,v as b}from"./el-divider-BVZhQIwQ.js";const x={name:"Home",data(){return{msg:"Welcome to trackplot App",example:"https://trackplot.readthedocs.io/en/latest/imgs/diagram.png"}}},C=_({...x,setup(B){return(r,a)=>{const s=k,l=w,o=h,p=g,d=E;return m(),u("div",null,[c("h1",null,f(r.msg),1),e(s),e(p,null,{default:t(()=>[e(o,{span:12,offset:3},{default:t(()=>[e(l,{type:"primary",href:"/#/plot"},{default:t(()=>a[0]||(a[0]=[n("Create your own plot")])),_:1})]),_:1}),e(o,{span:6},{default:t(()=>[e(l,{type:"primary",href:"https://github.com/ygidtu/trackplot/issues",icon:i(v)},{default:t(()=>a[1]||(a[1]=[n("Report bug at Github")])),_:1},8,["icon"]),e(s,{direction:"vertical"}),e(l,{type:"primary",icon:i(b),href:"https://trackplot.readthedocs.io/en/latest/web/"},{default:t(()=>a[2]||(a[2]=[n("Read the tutorial")])),_:1},8,["icon"])]),_:1}),e(o,{span:6})]),_:1}),e(s),e(p,null,{default:t(()=>[e(o,{span:20,offset:2},{default:t(()=>[e(d,{src:r.example,width:"100%"},null,8,["src"])]),_:1})]),_:1})])}}}),V=y(C,[["__scopeId","data-v-3d7de397"]]);export{V as default};
@@ -0,0 +1 @@
1
+ import{d as _,c as m,a as u,b as e,t as c,w as t,E as f,o as g,e as h,f as n,u as i,_ as y}from"./index-4hxJ_zbq.js";import{E as k,a as w,m as E,v,b}from"./el-divider-Brt4-Qvr.js";const x={name:"Home",data(){return{msg:"Welcome to trackplot App",example:"https://trackplot.readthedocs.io/en/latest/imgs/diagram.png"}}},C=_({...x,setup(B){return(r,a)=>{const s=k,l=w,o=h,p=f,d=b;return g(),m("div",null,[u("h1",null,c(r.msg),1),e(s),e(p,null,{default:t(()=>[e(o,{span:12,offset:3},{default:t(()=>[e(l,{type:"primary",href:"/#/plot"},{default:t(()=>a[0]||(a[0]=[n("Create your own plot")])),_:1})]),_:1}),e(o,{span:6},{default:t(()=>[e(l,{type:"primary",href:"https://github.com/ygidtu/trackplot/issues",icon:i(E)},{default:t(()=>a[1]||(a[1]=[n("Report bug at Github")])),_:1},8,["icon"]),e(s,{direction:"vertical"}),e(l,{type:"primary",icon:i(v),href:"https://trackplot.readthedocs.io/en/latest/web/"},{default:t(()=>a[2]||(a[2]=[n("Read the tutorial")])),_:1},8,["icon"])]),_:1}),e(o,{span:6})]),_:1}),e(s),e(p,null,{default:t(()=>[e(o,{span:20,offset:2},{default:t(()=>[e(d,{src:r.example,width:"100%"},null,8,["src"])]),_:1})]),_:1})])}}}),V=y(C,[["__scopeId","data-v-3d7de397"]]);export{V as default};
@@ -0,0 +1 @@
1
+ h3[data-v-3d7de397]{margin:40px 0 0}ul[data-v-3d7de397]{list-style-type:none;padding:0}li[data-v-3d7de397]{display:inline-block;margin:0 10px}a[data-v-3d7de397]{color:#42b983}