trackplot 0.6.1__tar.gz → 0.6.4__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 (64) hide show
  1. {trackplot-0.6.1/trackplot.egg-info → trackplot-0.6.4}/PKG-INFO +1 -1
  2. {trackplot-0.6.1 → trackplot-0.6.4}/pyproject.toml +1 -1
  3. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/cli.py +28 -0
  4. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/plot/coord.py +11 -8
  5. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/plot/core.py +16 -2
  6. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/plot/limits.py +24 -3
  7. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/plot/render.py +13 -4
  8. {trackplot-0.6.1 → trackplot-0.6.4/trackplot.egg-info}/PKG-INFO +1 -1
  9. {trackplot-0.6.1 → trackplot-0.6.4}/LICENSE +0 -0
  10. {trackplot-0.6.1 → trackplot-0.6.4}/README.md +0 -0
  11. {trackplot-0.6.1 → trackplot-0.6.4}/setup.cfg +0 -0
  12. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/__init__.py +0 -0
  13. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/anno/AxLabel.py +0 -0
  14. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/anno/__init__.py +0 -0
  15. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/anno/theme.py +0 -0
  16. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/base/CoordinateMap.py +0 -0
  17. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/base/GenomicLoci.py +0 -0
  18. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/base/Junction.py +0 -0
  19. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/base/Protein.py +0 -0
  20. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/base/ReadDepth.py +0 -0
  21. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/base/Readder.py +0 -0
  22. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/base/Stroke.py +0 -0
  23. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/base/Transcript.py +0 -0
  24. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/base/__init__.py +0 -0
  25. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/base/pyUniprot.py +0 -0
  26. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/conf/DomainSetting.py +0 -0
  27. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/conf/__init__.py +0 -0
  28. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/conf/config.py +0 -0
  29. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/conf/drawing.py +0 -0
  30. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/conf/ui.py +0 -0
  31. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/ATAC.py +0 -0
  32. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/Annotation.py +0 -0
  33. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/Bam.py +0 -0
  34. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/BedGraph.py +0 -0
  35. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/Bigwig.py +0 -0
  36. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/Depth.py +0 -0
  37. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/Fasta.py +0 -0
  38. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/File.py +0 -0
  39. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/HiCMatrixTrack.py +0 -0
  40. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/Junction.py +0 -0
  41. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/Motif.py +0 -0
  42. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/ReadSegments.py +0 -0
  43. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/file/__init__.py +0 -0
  44. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/plot/__init__.py +0 -0
  45. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/plot/info.py +0 -0
  46. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/plot/utils.py +0 -0
  47. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/plot_func.py +0 -0
  48. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot/server.py +0 -0
  49. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot.egg-info/SOURCES.txt +0 -0
  50. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot.egg-info/dependency_links.txt +0 -0
  51. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot.egg-info/requires.txt +0 -0
  52. {trackplot-0.6.1 → trackplot-0.6.4}/trackplot.egg-info/top_level.txt +0 -0
  53. {trackplot-0.6.1 → trackplot-0.6.4}/ui/assets/Home-B1EPE6Lq.js +0 -0
  54. {trackplot-0.6.1 → trackplot-0.6.4}/ui/assets/Home-DuHqFHEh.css +0 -0
  55. {trackplot-0.6.1 → trackplot-0.6.4}/ui/assets/Plot-CkylK0fA.css +0 -0
  56. {trackplot-0.6.1 → trackplot-0.6.4}/ui/assets/Plot-jZAsK7Tq.js +0 -0
  57. {trackplot-0.6.1 → trackplot-0.6.4}/ui/assets/_plugin-vue_export-helper-DLf8tVwz.css +0 -0
  58. {trackplot-0.6.1 → trackplot-0.6.4}/ui/assets/_plugin-vue_export-helper-IgiCOkTJ.js +0 -0
  59. {trackplot-0.6.1 → trackplot-0.6.4}/ui/assets/css-BDwM7dEv.css +0 -0
  60. {trackplot-0.6.1 → trackplot-0.6.4}/ui/assets/css-CKLNJEB6.js +0 -0
  61. {trackplot-0.6.1 → trackplot-0.6.4}/ui/assets/index-De-rfTdP.js +0 -0
  62. {trackplot-0.6.1 → trackplot-0.6.4}/ui/assets/index-Dlq_kUQH.css +0 -0
  63. {trackplot-0.6.1 → trackplot-0.6.4}/ui/index.html +0 -0
  64. {trackplot-0.6.1 → trackplot-0.6.4}/ui/vite.svg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trackplot
3
- Version: 0.6.1
3
+ Version: 0.6.4
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.6.1"
3
+ version = "0.6.4"
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" }
@@ -1214,6 +1214,30 @@ def _add_interval(p, f):
1214
1214
  @optgroup.option(
1215
1215
  "--title", type=click.STRING, default=None, help="Title", show_default=True
1216
1216
  )
1217
+ @optgroup.option(
1218
+ "--no-title",
1219
+ type=click.BOOL,
1220
+ is_flag=True,
1221
+ default=False,
1222
+ help="Disable the plot title entirely",
1223
+ show_default=True,
1224
+ )
1225
+ @optgroup.option(
1226
+ "--no-region-text",
1227
+ type=click.BOOL,
1228
+ is_flag=True,
1229
+ default=False,
1230
+ help="Disable the --event region text on the x-axis ruler",
1231
+ show_default=True,
1232
+ )
1233
+ @optgroup.option(
1234
+ "--junctions-on-top",
1235
+ type=click.BOOL,
1236
+ is_flag=True,
1237
+ default=False,
1238
+ help="Force all junction arcs to be drawn above the density plot (only effective when --density-by-strand is not set)",
1239
+ show_default=True,
1240
+ )
1217
1241
  @optgroup.option(
1218
1242
  "--font", type=click.STRING, default=None, help="Fonts", show_default=True
1219
1243
  )
@@ -1362,6 +1386,10 @@ def main(**kwargs):
1362
1386
  normalize_format=kwargs.get("normalize_format"),
1363
1387
  fill_step=kwargs.get("fill_step", "post"),
1364
1388
  smooth_bin=kwargs["smooth_bin"],
1389
+ title=kwargs["title"],
1390
+ no_title=kwargs["no_title"],
1391
+ no_region_text=kwargs["no_region_text"],
1392
+ junctions_on_top=kwargs["junctions_on_top"],
1365
1393
  )
1366
1394
 
1367
1395
 
@@ -134,14 +134,17 @@ def set_x_ticks(
134
134
  x_label = f"{x_label}, y axis is {log_trans} transformed"
135
135
 
136
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
- )
137
+
138
+ no_region_text = kwargs.pop("no_region_text", False)
139
+ if not no_region_text:
140
+ ax.text(
141
+ x=graph_coords[len(graph_coords) // 2],
142
+ y=-2.8,
143
+ s=x_label,
144
+ fontsize=font_size,
145
+ ha="center",
146
+ va="top",
147
+ )
145
148
 
146
149
  bk = 1
147
150
  if not sequence and nx_ticks > 1:
@@ -986,6 +986,11 @@ class Plot(object):
986
986
 
987
987
  igv_height_scale = kwargs.get("igv_height_scale")
988
988
 
989
+ # Extract / pop custom params before they flow into downstream **kwargs
990
+ title = kwargs.pop("title", None)
991
+ no_title = kwargs.pop("no_title", False)
992
+ junctions_on_top = kwargs.pop("junctions_on_top", False)
993
+
989
994
  # ====== Phase 1: Load data ======
990
995
  self._load_plot_data(n_jobs, *args, **kwargs)
991
996
 
@@ -1048,8 +1053,8 @@ class Plot(object):
1048
1053
  else:
1049
1054
  ax_var = plt.subplot(gs[curr_idx, 0])
1050
1055
 
1051
- if curr_idx == 0:
1052
- ax_var.set_title(str(self.region), loc="left")
1056
+ if curr_idx == 0 and not no_title:
1057
+ ax_var.set_title(title or str(self.region), loc="left")
1053
1058
 
1054
1059
  max_y_val_, min_y_val_ = self._resolve_plot_y_limits(
1055
1060
  p,
@@ -1060,6 +1065,12 @@ class Plot(object):
1060
1065
  same_y_sc=kwargs.get("same_y_sc"),
1061
1066
  same_y=kwargs.get("same_y"),
1062
1067
  )
1068
+
1069
+ if max_y_val_ is not None:
1070
+ max_y_val_ *= 1.1
1071
+
1072
+ if min_y_val_ is not None:
1073
+ min_y_val_ *= 1.1
1063
1074
 
1064
1075
  logger.info(
1065
1076
  f"plotting {p.type} at idx: {curr_idx} with height_ratio: {height_ratio[curr_idx]}"
@@ -1082,6 +1093,7 @@ class Plot(object):
1082
1093
  distance_between_label_axis=distance_between_label_axis,
1083
1094
  raster=raster,
1084
1095
  fill_step=fill_step,
1096
+ junctions_on_top=junctions_on_top,
1085
1097
  **temp_params,
1086
1098
  )
1087
1099
  curr_idx += 1
@@ -1097,6 +1109,7 @@ class Plot(object):
1097
1109
  distance_between_label_axis=distance_between_label_axis,
1098
1110
  raster=raster,
1099
1111
  fill_step=fill_step,
1112
+ junctions_on_top=junctions_on_top,
1100
1113
  **self.params.get(p, {}),
1101
1114
  )
1102
1115
  elif p.type == "hic":
@@ -1117,6 +1130,7 @@ class Plot(object):
1117
1130
  min_used_y_val=min_y_val_,
1118
1131
  distance_between_label_axis=distance_between_label_axis,
1119
1132
  raster=raster,
1133
+ junctions_on_top=junctions_on_top,
1120
1134
  **self.params.get(p, {}),
1121
1135
  )
1122
1136
  curr_idx += 1
@@ -26,6 +26,7 @@ def _compute_y_limits(
26
26
  density_by_strand: bool = False,
27
27
  fill_step: str = "post",
28
28
  show_mean_jxn_number: bool = False,
29
+ junctions_on_top: bool = False,
29
30
  ) -> Tuple[float, float]:
30
31
  """
31
32
  Compute y-axis limits from ReadDepth data, including junction arc extents.
@@ -56,6 +57,13 @@ def _compute_y_limits(
56
57
  if base_max % 2 == 1:
57
58
  base_max += 1
58
59
 
60
+ # --- Track whether limits were explicitly provided (from precompute/user) ---
61
+ # When both are given, they already account for junction expansion, so we
62
+ # must NOT expand them again — doing so causes non-convergent arc growth
63
+ # (the arc height computed from the incoming limit is larger than the one
64
+ # used during precomputation, inflating the limit on every re-calculation).
65
+ _limits_explicitly_set = max_used_y_val is not None and min_used_y_val is not None
66
+
59
67
  # --- Set initial y-axis limits ---
60
68
  if max_used_y_val is None:
61
69
  max_used_y_val = base_max
@@ -112,6 +120,8 @@ def _compute_y_limits(
112
120
 
113
121
  if density_by_strand:
114
122
  jxn_on_top = jxn.strand == "+"
123
+ elif junctions_on_top:
124
+ jxn_on_top = True
115
125
  else:
116
126
  jxn_on_top = jxn_idx % 2 == 0
117
127
  if abs(min_used_y_val) < max_used_y_val:
@@ -143,17 +153,27 @@ def _compute_y_limits(
143
153
  -right_dens if not ss2_modified else -right_dens - current_height,
144
154
  ]
145
155
 
146
- max_used_y_val = max(max_used_y_val, max(pts_y))
147
- min_used_y_val = min(min_used_y_val, min(pts_y))
156
+ # Only expand y-limits for junctions when limits were NOT explicitly
157
+ # provided. Explicit limits (from precompute / --same-y) already
158
+ # account for junction arcs; re-expanding would cause non-convergent
159
+ # growth because arc heights are recomputed from the incoming limit.
160
+ if not _limits_explicitly_set:
161
+ max_used_y_val = max(max_used_y_val, max(pts_y))
162
+ min_used_y_val = min(min_used_y_val, min(pts_y))
148
163
 
149
164
  # Strand-aware adjustment
150
165
  if not isinstance(data, dict) and data.strand_aware:
151
166
  if density_by_strand:
152
167
  max_used_y_val = max(abs(min_used_y_val), max_used_y_val)
153
168
  min_used_y_val = -max_used_y_val
154
- elif not density_by_strand and not jxns:
169
+ elif not density_by_strand and (junctions_on_top or not jxns):
155
170
  min_used_y_val = 0
156
171
 
172
+ # Small expansion so the top / bottom arcs have visual breathing room
173
+ # and do not appear cramped against the axis edge.
174
+ max_used_y_val *= 1.1
175
+ min_used_y_val *= 1.1
176
+
157
177
  return max_used_y_val, min_used_y_val
158
178
 
159
179
 
@@ -190,4 +210,5 @@ def precompute_y_limits(
190
210
  density_by_strand=kwargs.get("density_by_strand", False),
191
211
  fill_step=fill_step,
192
212
  show_mean_jxn_number=False,
213
+ junctions_on_top=kwargs.get("junctions_on_top", False),
193
214
  )
@@ -474,7 +474,10 @@ def plot_density(
474
474
  _base_max += 1
475
475
 
476
476
  # Arc height reference: use the LARGER of (data baseline, incoming y-limit)
477
- # so arcs look proportional to the visible axis range (especially in --same-y mode).
477
+ # so arcs look proportional to the visible axis range (especially in
478
+ # --same-y / --same-y-sc mode). If we only used the data baseline, panels
479
+ # with small data would have tiny arcs hugging the x-axis when a large
480
+ # global y-limit is shared across panels.
478
481
  _arc_ref_max = (
479
482
  max(_base_max, max_used_y_val) if max_used_y_val is not None else _base_max
480
483
  )
@@ -490,6 +493,8 @@ def plot_density(
490
493
  # Compute y limits using shared logic
491
494
  fixed_max_used_y = max_used_y_val is not None
492
495
 
496
+ junctions_on_top = kwargs.get("junctions_on_top", False)
497
+
493
498
  max_used_y_val, min_used_y_val = _compute_y_limits(
494
499
  data=data,
495
500
  region=region,
@@ -499,8 +504,9 @@ def plot_density(
499
504
  density_by_strand=kwargs.get("density_by_strand", False),
500
505
  fill_step=fill_step,
501
506
  show_mean_jxn_number=show_mean_jxn_number,
507
+ junctions_on_top=junctions_on_top,
502
508
  )
503
-
509
+
504
510
  # Draw fill
505
511
  x, y1, y2 = [], [], []
506
512
  for i in range(len(graph_coords)):
@@ -543,7 +549,7 @@ def plot_density(
543
549
  f"junction {jxn} of {y_label} is out of plotting region, skip"
544
550
  )
545
551
  continue
546
-
552
+
547
553
  ss1_idx, ss1_modified = get_limited_index(
548
554
  leftss - region.start, len(graph_coords)
549
555
  )
@@ -554,6 +560,8 @@ def plot_density(
554
560
 
555
561
  if kwargs.get("density_by_strand"):
556
562
  jxn_on_top = jxn.strand == "+"
563
+ elif junctions_on_top:
564
+ jxn_on_top = True
557
565
  else:
558
566
  jxn_on_top = jxn_idx % 2 == 0
559
567
  if abs(min_used_y_val) < max_used_y_val:
@@ -573,6 +581,7 @@ def plot_density(
573
581
  right_dens + current_height,
574
582
  right_dens if not ss2_modified else right_dens + current_height,
575
583
  ]
584
+
576
585
  else:
577
586
  left_dens, right_dens = (
578
587
  abs(data.curr_min(ss1_idx)),
@@ -655,7 +664,7 @@ def plot_density(
655
664
  ):
656
665
  max_used_y_val = max(abs(min_used_y_val), max_used_y_val)
657
666
  min_used_y_val = -max_used_y_val
658
- elif not kwargs.get("density_by_strand") and not jxns:
667
+ elif not kwargs.get("density_by_strand") and (junctions_on_top or not jxns):
659
668
  min_used_y_val = 0
660
669
 
661
670
  set_y_ticks(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trackplot
3
- Version: 0.6.1
3
+ Version: 0.6.4
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes