trackplot 0.6.6__tar.gz → 0.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {trackplot-0.6.6/trackplot.egg-info → trackplot-0.7.0}/PKG-INFO +62 -27
  2. {trackplot-0.6.6 → trackplot-0.7.0}/README.md +61 -26
  3. {trackplot-0.6.6 → trackplot-0.7.0}/pyproject.toml +1 -1
  4. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/base/Transcript.py +4 -0
  5. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/cli.py +20 -0
  6. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/conf/ui.py +24 -0
  7. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/Annotation.py +17 -0
  8. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/plot/core.py +10 -0
  9. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/plot/render.py +94 -19
  10. {trackplot-0.6.6 → trackplot-0.7.0/trackplot.egg-info}/PKG-INFO +62 -27
  11. {trackplot-0.6.6 → trackplot-0.7.0}/LICENSE +0 -0
  12. {trackplot-0.6.6 → trackplot-0.7.0}/setup.cfg +0 -0
  13. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/__init__.py +0 -0
  14. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/anno/AxLabel.py +0 -0
  15. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/anno/__init__.py +0 -0
  16. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/anno/theme.py +0 -0
  17. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/base/CoordinateMap.py +0 -0
  18. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/base/GenomicLoci.py +0 -0
  19. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/base/Junction.py +0 -0
  20. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/base/Protein.py +0 -0
  21. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/base/ReadDepth.py +0 -0
  22. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/base/Readder.py +0 -0
  23. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/base/Stroke.py +0 -0
  24. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/base/__init__.py +0 -0
  25. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/base/pyUniprot.py +0 -0
  26. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/conf/DomainSetting.py +0 -0
  27. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/conf/__init__.py +0 -0
  28. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/conf/config.py +0 -0
  29. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/conf/drawing.py +0 -0
  30. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/ATAC.py +0 -0
  31. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/Bam.py +0 -0
  32. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/BedGraph.py +0 -0
  33. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/Bigwig.py +0 -0
  34. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/Depth.py +0 -0
  35. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/Fasta.py +0 -0
  36. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/File.py +0 -0
  37. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/HiCMatrixTrack.py +0 -0
  38. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/Junction.py +0 -0
  39. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/Motif.py +0 -0
  40. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/ReadSegments.py +0 -0
  41. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/file/__init__.py +0 -0
  42. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/plot/__init__.py +0 -0
  43. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/plot/coord.py +0 -0
  44. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/plot/info.py +0 -0
  45. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/plot/limits.py +0 -0
  46. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/plot/utils.py +0 -0
  47. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/plot_func.py +0 -0
  48. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot/server.py +0 -0
  49. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot.egg-info/SOURCES.txt +0 -0
  50. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot.egg-info/dependency_links.txt +0 -0
  51. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot.egg-info/entry_points.txt +0 -0
  52. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot.egg-info/requires.txt +0 -0
  53. {trackplot-0.6.6 → trackplot-0.7.0}/trackplot.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trackplot
3
- Version: 0.6.6
3
+ Version: 0.7.0
4
4
  Summary: The trackplot is a tool for visualizing various next-generation sequencing (NGS) data, including DNA-seq, RNA-seq, single-cell RNA-seq and full-length sequencing datasets. https://sashimi.readthedocs.io/
5
5
  Author-email: ygidtu <ygidtu@gmail.com>
6
6
  License-Expression: BSD-3-Clause
@@ -30,9 +30,9 @@ Dynamic: license-file
30
30
 
31
31
  [![PyPI version](https://badge.fury.io/py/trackplot.svg)](https://pypi.org/project/trackplot/)
32
32
  [![PyPI download](https://img.shields.io/pypi/dm/trackplot.svg)](https://pypi.org/project/trackplot/)
33
- [![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg?style=flat)](http://bioconda.github.io/recipes/trackplot/README.html)
33
+ [![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg?style=flat)](https://bioconda.github.io/recipes/trackplot/README.html)
34
34
  [![Documentation Status](https://readthedocs.org/projects/trackplot/badge/?version=latest)](https://trackplot.readthedocs.io/en/latest/)
35
- [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%20v3-clause.svg)](https://www.gnu.org/licenses/agpl-3.0)
35
+ [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
36
36
  [![DOI](https://img.shields.io/badge/DOI-10.1101%2F2022.11.02.514803%20-blue)](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1011477)
37
37
 
38
38
  ---
@@ -41,11 +41,11 @@ Dynamic: license-file
41
41
 
42
42
  [Tutorials](https://trackplot.readthedocs.io/en/latest/)
43
43
 
44
- ## what is trackplot
44
+ ## What is trackplot
45
45
 
46
- 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.
46
+ 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.
47
47
 
48
- ### Features of trackplot
48
+ ### Features
49
49
 
50
50
  1. Support various file formats as input
51
51
  2. Support strand-aware coverage plot
@@ -78,7 +78,7 @@ Trackplot is based on **Python3** `(python_requires='>=3.8')`,
78
78
  and we have simplified the installation process on the main page.
79
79
  For a more comprehensive installation guide, please refer to [this link](./docs/installation.md).
80
80
 
81
- ### For impatient
81
+ ### Quick start
82
82
 
83
83
  ```shell
84
84
  pip install trackplot
@@ -123,15 +123,23 @@ pip install trackplot
123
123
 
124
124
  ---
125
125
 
126
- 2. [AppImage](https://github.com/ygidtu/trackplot/releases) (Linux/WSL x86_64 platform only)
126
+ 2. [AppBundle](https://github.com/xplshn/pelf) (Linux/WSL x86_64 platform only)
127
127
 
128
128
  For a binary version of the tool and more comprehensive information, please visit [this link](./docs/installation.md).
129
129
 
130
130
  ```bash
131
- # example with version v0.3.5, please using your interested version according to your needs
132
- export VERSION=0.3.5
133
- chmod +x trackplot-${VERSION}-x86_64.AppImage
134
- ./trackplot-${VERSION}-x86_64.AppImage --help
131
+ # build the AppBundle from source (version auto-detected from pyproject.toml)
132
+ sh build-appbundle.sh
133
+
134
+ # the output filename and appbundle ID are printed at the end of the script
135
+ # package with pelf (see https://github.com/xplshn/pelf)
136
+ pelf \
137
+ --add-appdir "./trackplot.AppDir" \
138
+ --appbundle-id "$APPBUNDLE_ID" \
139
+ --output-to "$OUTPUT_FILE"
140
+
141
+ chmod +x "$OUTPUT_FILE"
142
+ ./"$OUTPUT_FILE" --help
135
143
  ```
136
144
 
137
145
  ---
@@ -170,20 +178,20 @@ trackplot --help
170
178
  <p>
171
179
 
172
180
 
173
- 1. [AppImage](https://github.com/ygidtu/trackplot/releases) (Linux/WSL x86_64 only)
181
+ 1. AppBundle (Linux/WSL x86_64 only)
182
+
183
+ Build the AppBundle following the [instructions above](#using-trackplot-by-a-command-line), then:
174
184
 
175
185
  ```bash
176
- # example with version v0.3.3, please using your interested version according to your needs
177
- export VERSION=0.3.3
178
- gunzip trackplot-${VERSION}-x86_64.AppImage
179
- chmod +x trackplot-${VERSION}-x86_64.AppImage
180
- ./trackplot-${VERSION}-x86_64.AppImage --help
186
+ # OUTPUT_FILE is printed by build-appbundle.sh
187
+ chmod +x "$OUTPUT_FILE"
188
+ ./"$OUTPUT_FILE" --help
181
189
 
182
190
  # startup webserver
183
- ./trackplot-${VERSION}-x86_64.AppImage --start-server --host 0.0.0.0 --port 5000 --plots ./plots
191
+ ./"$OUTPUT_FILE" --start-server --host 0.0.0.0 --port 5000 --plots ./plots
184
192
  ```
185
-
186
- **Note:** the `--plots` were required while using appimages
193
+
194
+ **Note:** the `--plots` were required while using appbundles
187
195
 
188
196
  ---
189
197
 
@@ -246,7 +254,7 @@ trackplot \
246
254
  -p 4
247
255
  ```
248
256
 
249
- if trackplot was installed by docker, here is the cmd
257
+ If trackplot was installed via docker, here is the cmd:
250
258
 
251
259
  ```bash
252
260
  ## The absolute path is required in Docker env.
@@ -280,17 +288,44 @@ docker run -v $PWD:$PWD -w $PWD --rm ygidtu/trackplot \
280
288
 
281
289
  ```
282
290
 
283
- here is the [output file](https://raw.githubusercontent.com/ygidtu/trackplot/main/example/example.png).
291
+ Here is the [output file](https://raw.githubusercontent.com/ygidtu/trackplot/main/example/example.png).
292
+
293
+
294
+ ## For AI agents (auto-install the trackplot skill)
295
+
296
+ This repo ships a ready-to-use **skill** that teaches an AI coding agent how to
297
+ invoke trackplot. When an agent is asked to create a trackplot/sashimi figure,
298
+ it should install this skill once (path relative to this file):
299
+
300
+ ```bash
301
+ # opencode / Claude Code style: point the skill manager at the bundled skill
302
+ cp -r skills/trackplot ~/.config/opencode/skills/trackplot # or ~/.claude/skills/trackplot
303
+ ```
304
+
305
+ Then the agent reads `skills/trackplot/SKILL.md` (plus
306
+ `skills/trackplot/references/config_files.md` and
307
+ `skills/trackplot/references/python_api.md`) and follows it to:
308
+
309
+ 1. Confirm the input region in `chr:start-end:strand` form and the annotation GTF.
310
+ 2. Build the matching config TSV(s) for the requested track type(s) (see the
311
+ `# filepath category label color` conventions).
312
+ 3. Run `trackplot -e <region> -r <gtf> --density <list.tsv> -o <out>.pdf` (or the
313
+ equivalent Python `Plot(...).set_region(...).add_density(...).plot(...)` chain).
314
+ 4. Verify the output exists; if `pybigwig`/`hicmatrix` are needed for bigWig/HiC,
315
+ install them first.
316
+
317
+ The skill is the single source of truth for trackplot usage; keep it in sync with
318
+ `docs/command.md` and `docs/interactive.md`.
284
319
 
285
320
 
286
321
  ## Questions
287
322
 
288
- Visit [issues](https://github.com/ygidtu/trackplot/issues) or
289
- contact [Yiming Zhang](https://github.com/ygidtu) or
323
+ Visit [issues](https://github.com/ygidtu/trackplot/issues) or
324
+ contact [Yiming Zhang](https://github.com/ygidtu) or
290
325
  [Ran Zhou](https://github.com/zhou-ran)
291
326
 
292
327
  ## Citation
293
328
 
294
- If you use the tool in your publication, please cite by
329
+ If you use trackplot in your publication, please cite:
295
330
 
296
- [Zhang Y, Zhou R, Liu L, et al. Trackplot: A flexible toolkit for combinatorial analysis of genomic data[J]. PLoS computational biology, 2023, 19(9): e1011477.](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1011477)
331
+ Zhang Y, Zhou R, Liu L, et al. Trackplot: A flexible toolkit for combinatorial analysis of genomic data. *PLoS Computational Biology*, 2023, 19(9): e1011477.
@@ -2,9 +2,9 @@
2
2
 
3
3
  [![PyPI version](https://badge.fury.io/py/trackplot.svg)](https://pypi.org/project/trackplot/)
4
4
  [![PyPI download](https://img.shields.io/pypi/dm/trackplot.svg)](https://pypi.org/project/trackplot/)
5
- [![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg?style=flat)](http://bioconda.github.io/recipes/trackplot/README.html)
5
+ [![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg?style=flat)](https://bioconda.github.io/recipes/trackplot/README.html)
6
6
  [![Documentation Status](https://readthedocs.org/projects/trackplot/badge/?version=latest)](https://trackplot.readthedocs.io/en/latest/)
7
- [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%20v3-clause.svg)](https://www.gnu.org/licenses/agpl-3.0)
7
+ [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
8
8
  [![DOI](https://img.shields.io/badge/DOI-10.1101%2F2022.11.02.514803%20-blue)](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1011477)
9
9
 
10
10
  ---
@@ -13,11 +13,11 @@
13
13
 
14
14
  [Tutorials](https://trackplot.readthedocs.io/en/latest/)
15
15
 
16
- ## what is trackplot
16
+ ## What is trackplot
17
17
 
18
- 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.
18
+ 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.
19
19
 
20
- ### Features of trackplot
20
+ ### Features
21
21
 
22
22
  1. Support various file formats as input
23
23
  2. Support strand-aware coverage plot
@@ -50,7 +50,7 @@ Trackplot is based on **Python3** `(python_requires='>=3.8')`,
50
50
  and we have simplified the installation process on the main page.
51
51
  For a more comprehensive installation guide, please refer to [this link](./docs/installation.md).
52
52
 
53
- ### For impatient
53
+ ### Quick start
54
54
 
55
55
  ```shell
56
56
  pip install trackplot
@@ -95,15 +95,23 @@ pip install trackplot
95
95
 
96
96
  ---
97
97
 
98
- 2. [AppImage](https://github.com/ygidtu/trackplot/releases) (Linux/WSL x86_64 platform only)
98
+ 2. [AppBundle](https://github.com/xplshn/pelf) (Linux/WSL x86_64 platform only)
99
99
 
100
100
  For a binary version of the tool and more comprehensive information, please visit [this link](./docs/installation.md).
101
101
 
102
102
  ```bash
103
- # example with version v0.3.5, please using your interested version according to your needs
104
- export VERSION=0.3.5
105
- chmod +x trackplot-${VERSION}-x86_64.AppImage
106
- ./trackplot-${VERSION}-x86_64.AppImage --help
103
+ # build the AppBundle from source (version auto-detected from pyproject.toml)
104
+ sh build-appbundle.sh
105
+
106
+ # the output filename and appbundle ID are printed at the end of the script
107
+ # package with pelf (see https://github.com/xplshn/pelf)
108
+ pelf \
109
+ --add-appdir "./trackplot.AppDir" \
110
+ --appbundle-id "$APPBUNDLE_ID" \
111
+ --output-to "$OUTPUT_FILE"
112
+
113
+ chmod +x "$OUTPUT_FILE"
114
+ ./"$OUTPUT_FILE" --help
107
115
  ```
108
116
 
109
117
  ---
@@ -142,20 +150,20 @@ trackplot --help
142
150
  <p>
143
151
 
144
152
 
145
- 1. [AppImage](https://github.com/ygidtu/trackplot/releases) (Linux/WSL x86_64 only)
153
+ 1. AppBundle (Linux/WSL x86_64 only)
154
+
155
+ Build the AppBundle following the [instructions above](#using-trackplot-by-a-command-line), then:
146
156
 
147
157
  ```bash
148
- # example with version v0.3.3, please using your interested version according to your needs
149
- export VERSION=0.3.3
150
- gunzip trackplot-${VERSION}-x86_64.AppImage
151
- chmod +x trackplot-${VERSION}-x86_64.AppImage
152
- ./trackplot-${VERSION}-x86_64.AppImage --help
158
+ # OUTPUT_FILE is printed by build-appbundle.sh
159
+ chmod +x "$OUTPUT_FILE"
160
+ ./"$OUTPUT_FILE" --help
153
161
 
154
162
  # startup webserver
155
- ./trackplot-${VERSION}-x86_64.AppImage --start-server --host 0.0.0.0 --port 5000 --plots ./plots
163
+ ./"$OUTPUT_FILE" --start-server --host 0.0.0.0 --port 5000 --plots ./plots
156
164
  ```
157
-
158
- **Note:** the `--plots` were required while using appimages
165
+
166
+ **Note:** the `--plots` were required while using appbundles
159
167
 
160
168
  ---
161
169
 
@@ -218,7 +226,7 @@ trackplot \
218
226
  -p 4
219
227
  ```
220
228
 
221
- if trackplot was installed by docker, here is the cmd
229
+ If trackplot was installed via docker, here is the cmd:
222
230
 
223
231
  ```bash
224
232
  ## The absolute path is required in Docker env.
@@ -252,17 +260,44 @@ docker run -v $PWD:$PWD -w $PWD --rm ygidtu/trackplot \
252
260
 
253
261
  ```
254
262
 
255
- here is the [output file](https://raw.githubusercontent.com/ygidtu/trackplot/main/example/example.png).
263
+ Here is the [output file](https://raw.githubusercontent.com/ygidtu/trackplot/main/example/example.png).
264
+
265
+
266
+ ## For AI agents (auto-install the trackplot skill)
267
+
268
+ This repo ships a ready-to-use **skill** that teaches an AI coding agent how to
269
+ invoke trackplot. When an agent is asked to create a trackplot/sashimi figure,
270
+ it should install this skill once (path relative to this file):
271
+
272
+ ```bash
273
+ # opencode / Claude Code style: point the skill manager at the bundled skill
274
+ cp -r skills/trackplot ~/.config/opencode/skills/trackplot # or ~/.claude/skills/trackplot
275
+ ```
276
+
277
+ Then the agent reads `skills/trackplot/SKILL.md` (plus
278
+ `skills/trackplot/references/config_files.md` and
279
+ `skills/trackplot/references/python_api.md`) and follows it to:
280
+
281
+ 1. Confirm the input region in `chr:start-end:strand` form and the annotation GTF.
282
+ 2. Build the matching config TSV(s) for the requested track type(s) (see the
283
+ `# filepath category label color` conventions).
284
+ 3. Run `trackplot -e <region> -r <gtf> --density <list.tsv> -o <out>.pdf` (or the
285
+ equivalent Python `Plot(...).set_region(...).add_density(...).plot(...)` chain).
286
+ 4. Verify the output exists; if `pybigwig`/`hicmatrix` are needed for bigWig/HiC,
287
+ install them first.
288
+
289
+ The skill is the single source of truth for trackplot usage; keep it in sync with
290
+ `docs/command.md` and `docs/interactive.md`.
256
291
 
257
292
 
258
293
  ## Questions
259
294
 
260
- Visit [issues](https://github.com/ygidtu/trackplot/issues) or
261
- contact [Yiming Zhang](https://github.com/ygidtu) or
295
+ Visit [issues](https://github.com/ygidtu/trackplot/issues) or
296
+ contact [Yiming Zhang](https://github.com/ygidtu) or
262
297
  [Ran Zhou](https://github.com/zhou-ran)
263
298
 
264
299
  ## Citation
265
300
 
266
- If you use the tool in your publication, please cite by
301
+ If you use trackplot in your publication, please cite:
267
302
 
268
- [Zhang Y, Zhou R, Liu L, et al. Trackplot: A flexible toolkit for combinatorial analysis of genomic data[J]. PLoS computational biology, 2023, 19(9): e1011477.](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1011477)
303
+ Zhang Y, Zhou R, Liu L, et al. Trackplot: A flexible toolkit for combinatorial analysis of genomic data. *PLoS Computational Biology*, 2023, 19(9): e1011477.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "trackplot"
3
- version = "0.6.6"
3
+ version = "0.7.0"
4
4
  description = "The trackplot is a tool for visualizing various next-generation sequencing (NGS) data, including DNA-seq, RNA-seq, single-cell RNA-seq and full-length sequencing datasets. https://sashimi.readthedocs.io/"
5
5
  authors = [
6
6
  { name = "ygidtu", email = "ygidtu@gmail.com" }
@@ -30,6 +30,7 @@ class Transcript(GenomicLoci):
30
30
  "domain_type",
31
31
  "domain_description",
32
32
  "plot_intron",
33
+ "coding_intervals",
33
34
  ]
34
35
 
35
36
  def __init__(
@@ -47,6 +48,7 @@ class Transcript(GenomicLoci):
47
48
  domain_category: str = "",
48
49
  domain_type: str = "",
49
50
  domain_description: str = "",
51
+ coding_intervals: Optional[List] = None,
50
52
  ):
51
53
  """
52
54
  :param chromosome:
@@ -62,6 +64,7 @@ class Transcript(GenomicLoci):
62
64
  :param domain_category: category of domain
63
65
  :param domain_description: description of domain
64
66
  :param domain_type: if category is protein, the type information of the given domain
67
+ :param coding_intervals: list of (start, end) absolute genomic coordinates of the coding region (CDS), used to distinguish UTR from CDS in the annotation plot
65
68
  """
66
69
 
67
70
  super().__init__(chromosome=chromosome, start=start, end=end, strand=strand)
@@ -74,6 +77,7 @@ class Transcript(GenomicLoci):
74
77
  self.domain_category = domain_category
75
78
  self.domain_type = domain_type
76
79
  self.domain_description = domain_description
80
+ self.coding_intervals = coding_intervals if coding_intervals is not None else []
77
81
 
78
82
  @property
79
83
  def exon_list(self):
@@ -489,6 +489,8 @@ def _handle_igv(p, path, kwargs):
489
489
  label=f.label,
490
490
  exon_color=f.color,
491
491
  intron_color=f.color,
492
+ show_utr=kwargs["show_utr"],
493
+ utr_color=kwargs["utr_color"],
492
494
  features=igv_features or None,
493
495
  font_size=kwargs["font_size"],
494
496
  n_y_ticks=kwargs["n_y_ticks"],
@@ -787,6 +789,22 @@ def _add_interval(p, f):
787
789
  help="The scale of exon",
788
790
  show_default=True,
789
791
  )
792
+ @optgroup.option(
793
+ "--show-utr",
794
+ is_flag=True,
795
+ type=click.BOOL,
796
+ show_default=True,
797
+ help="Whether to distinguish untranslated regions (UTR) from coding regions (CDS) "
798
+ "inside exons. Requires a GTF/GFF with CDS features. UTR parts are drawn in "
799
+ "--utr-color while CDS parts keep --ref-color.",
800
+ )
801
+ @optgroup.option(
802
+ "--utr-color",
803
+ type=click.STRING,
804
+ default="#0099CC",
805
+ show_default=True,
806
+ help="The fill color of untranslated regions (UTR) in the annotation and IGV-like tracks.",
807
+ )
790
808
  @optgroup.group("Density plot settings")
791
809
  @optgroup.option(
792
810
  "--density",
@@ -1342,6 +1360,8 @@ def main(**kwargs):
1342
1360
  local_domain=kwargs["local_domain"],
1343
1361
  domain_include=kwargs["domain_include"],
1344
1362
  domain_exclude=kwargs["domain_exclude"],
1363
+ show_utr=kwargs["show_utr"],
1364
+ utr_color=kwargs["utr_color"],
1345
1365
  )
1346
1366
  elif key in _CATEGORY_HANDLERS:
1347
1367
  _CATEGORY_HANDLERS[key](
@@ -305,6 +305,18 @@ __PARAMS__ = {
305
305
  "default": "0.3",
306
306
  "note": "The exon width of current track",
307
307
  },
308
+ {
309
+ "key": "show_utr",
310
+ "annotation": "bool",
311
+ "default": "false",
312
+ "note": "Whether to distinguish untranslated regions (UTR) from coding regions (CDS) inside exons. Requires an annotation with CDS features loaded in the same plot.",
313
+ },
314
+ {
315
+ "key": "utr_color",
316
+ "annotation": "color",
317
+ "default": "#0099CC",
318
+ "note": "The fill color of untranslated regions (UTR) in the IGV-like track.",
319
+ },
308
320
  ],
309
321
  "add_interval": [
310
322
  {
@@ -542,6 +554,18 @@ __PARAMS__ = {
542
554
  "default": "#000000",
543
555
  "note": "The color of exons",
544
556
  },
557
+ {
558
+ "key": "show_utr",
559
+ "annotation": "bool",
560
+ "default": "false",
561
+ "note": "Whether to distinguish untranslated regions (UTR) from coding regions (CDS) inside exons. Requires a GTF/GFF with CDS features; UTR parts are drawn in --utr-color while CDS parts keep the exon color.",
562
+ },
563
+ {
564
+ "key": "utr_color",
565
+ "annotation": "color",
566
+ "default": "#0099CC",
567
+ "note": "The fill color of untranslated regions (UTR) in the annotation track.",
568
+ },
545
569
  {
546
570
  "key": "font_size",
547
571
  "annotation": "int",
@@ -119,6 +119,17 @@ class Annotation(File):
119
119
  res.append([exon.start, exon.end])
120
120
  return sorted(res, key=lambda x: [x[0], x[1]])
121
121
 
122
+ @property
123
+ def coding_intervals(self) -> List[tuple]:
124
+ """
125
+ Merge coding (CDS) intervals across all loaded transcripts for the region,
126
+ used to distinguish UTR from CDS in the IGV-like plot.
127
+ """
128
+ merged = []
129
+ for transcript in self.data:
130
+ merged.extend(transcript.coding_intervals)
131
+ return merged
132
+
122
133
  @classmethod
123
134
  def create(
124
135
  cls,
@@ -393,6 +404,7 @@ class Annotation(File):
393
404
  # AD - passing transcripts_to_show
394
405
  transcripts = {}
395
406
  exons = {}
407
+ coding = {}
396
408
  for rec in Reader.read_gtf(self.path, self.region):
397
409
  start = max(rec.start, self.region.start)
398
410
  end = min(rec.end, self.region.end)
@@ -428,6 +440,9 @@ class Annotation(File):
428
440
  exons=[],
429
441
  )
430
442
 
443
+ if re.search(r"(cds)", rec.feature, re.I):
444
+ coding.setdefault(rec.transcript_id, []).append((start, end))
445
+
431
446
  elif re.search(r"(exon)", rec.feature, re.I):
432
447
  if rec.transcript_id not in exons.keys():
433
448
  exons[rec.transcript_id] = []
@@ -456,6 +471,8 @@ class Annotation(File):
456
471
  for key, trans in transcripts.items():
457
472
  if key in exons.keys():
458
473
  trans.exons += exons[key]
474
+ if key in coding.keys():
475
+ trans.coding_intervals = coding[key]
459
476
 
460
477
  self.data += sorted(transcripts.values())
461
478
 
@@ -284,6 +284,8 @@ class Plot(object):
284
284
  "show_id": kwargs.get("show_id", False),
285
285
  "exon_width": kwargs.get("exon_width", 0.3),
286
286
  "show_exon_id": kwargs.get("show_exon_id", False),
287
+ "show_utr": kwargs.get("show_utr", False),
288
+ "utr_color": kwargs.get("utr_color", None),
287
289
  "theme": kwargs.get("theme", "blank"),
288
290
  }
289
291
  return self
@@ -592,6 +594,8 @@ class Plot(object):
592
594
  intron_color=None,
593
595
  feature_color=None,
594
596
  exon_width=0.3,
597
+ show_utr=False,
598
+ utr_color=None,
595
599
  height_scale=None,
596
600
  font_size=8,
597
601
  n_y_ticks=1,
@@ -621,6 +625,8 @@ class Plot(object):
621
625
  "font_size": font_size,
622
626
  "n_y_ticks": n_y_ticks,
623
627
  "show_y_label": show_y_label,
628
+ "show_utr": show_utr,
629
+ "utr_color": utr_color,
624
630
  "theme": theme,
625
631
  }
626
632
  return self
@@ -1189,12 +1195,16 @@ class Plot(object):
1189
1195
  **self.params.get(p, {}),
1190
1196
  )
1191
1197
  elif p.type == "igv":
1198
+ coding_intervals = []
1199
+ if self.params.get(p, {}).get("show_utr") and self.annotation is not None:
1200
+ coding_intervals = self.annotation.coding_intervals
1192
1201
  plot_igv_like(
1193
1202
  ax=ax_var,
1194
1203
  obj=p.data,
1195
1204
  graph_coords=self.graph_coords,
1196
1205
  raster=raster,
1197
1206
  distance_between_label_axis=distance_between_label_axis,
1207
+ coding_intervals=coding_intervals,
1198
1208
  **self.params.get(p, {}),
1199
1209
  )
1200
1210
  elif p.type == "motif":
@@ -81,6 +81,49 @@ def plot_stroke(
81
81
  # ============================================================================
82
82
 
83
83
 
84
+ def _merge_intervals(intervals: List[tuple]) -> List[tuple]:
85
+ """Merge overlapping or adjacent (start, end) intervals into sorted non-overlapping ones."""
86
+ cleaned = sorted((s, e) for s, e in intervals if e >= s)
87
+ merged = []
88
+ for start, end in cleaned:
89
+ if merged and start <= merged[-1][1] + 1:
90
+ merged[-1] = (merged[-1][0], max(merged[-1][1], end))
91
+ else:
92
+ merged.append((start, end))
93
+ return merged
94
+
95
+
96
+ def _split_exon_into_cds_utr(
97
+ seg_start: int,
98
+ seg_end: int,
99
+ coding_intervals: List[tuple],
100
+ ) -> List[tuple]:
101
+ """
102
+ Split an exon segment [seg_start, seg_end] into alternating CDS/UTR sub-segments.
103
+
104
+ :param seg_start: start of the segment (inclusive), in the same coordinate system as coding_intervals
105
+ :param seg_end: end of the segment (inclusive), in the same coordinate system as coding_intervals
106
+ :param coding_intervals: list of (start, end) coding (CDS) intervals
107
+ :return: list of (start, end, is_coding) tuples covering [seg_start, seg_end]
108
+ """
109
+ merged = _merge_intervals(coding_intervals)
110
+ result: List[tuple] = []
111
+ cursor = seg_start
112
+ for coding_start, coding_end in merged:
113
+ coding_start = max(coding_start, seg_start)
114
+ coding_end = min(coding_end, seg_end)
115
+ if coding_start > coding_end:
116
+ continue
117
+ if cursor < coding_start:
118
+ result.append((cursor, coding_start - 1, False))
119
+ if cursor <= coding_end:
120
+ result.append((max(cursor, coding_start), coding_end, True))
121
+ cursor = max(cursor, coding_end + 1)
122
+ if cursor <= seg_end:
123
+ result.append((cursor, seg_end, False))
124
+ return result
125
+
126
+
84
127
  def plot_annotation(
85
128
  ax,
86
129
  obj: Annotation,
@@ -94,6 +137,8 @@ def plot_annotation(
94
137
  exon_width: float = 0.3,
95
138
  plot_domain: bool = False,
96
139
  show_exon_id: bool = False,
140
+ show_utr: bool = False,
141
+ utr_color: Optional[str] = None,
97
142
  raster: bool = True,
98
143
  **kwargs,
99
144
  ):
@@ -109,6 +154,7 @@ def plot_annotation(
109
154
  graph_coords = init_graph_coords(region)
110
155
 
111
156
  color = "k" if not color else color
157
+ utr_color = utr_color if utr_color else "#0099CC"
112
158
 
113
159
  patches, arrows = [], {}
114
160
  for transcript in data:
@@ -161,17 +207,28 @@ def plot_annotation(
161
207
  if s < 0 or e < 0:
162
208
  continue
163
209
 
164
- patches.append(
165
- plt.Rectangle(
166
- (graph_coords[s], y_loc - exon_width / 2),
167
- width=graph_coords[e] - graph_coords[s],
168
- height=exon_width,
169
- lw=0.5,
170
- zorder=20,
171
- rasterized=raster,
172
- color=color,
173
- )
210
+ exon_coding = [
211
+ (region.relative(cs), region.relative(ce))
212
+ for cs, ce in transcript.coding_intervals
213
+ ]
214
+ segments = (
215
+ _split_exon_into_cds_utr(s, e, exon_coding)
216
+ if show_utr and exon_coding
217
+ else [(s, e, True)]
174
218
  )
219
+ for seg_s, seg_e, is_cds in segments:
220
+ seg_color = color if is_cds else utr_color
221
+ patches.append(
222
+ plt.Rectangle(
223
+ (graph_coords[seg_s], y_loc - exon_width / 2),
224
+ width=graph_coords[seg_e] - graph_coords[seg_s],
225
+ height=exon_width,
226
+ lw=0.5,
227
+ zorder=20,
228
+ rasterized=raster,
229
+ color=seg_color,
230
+ )
231
+ )
175
232
  if show_exon_id and exon.name:
176
233
  y_loc_offset = 0.1 if ind % 2 == 0 else -0.2
177
234
  ax.text(
@@ -1109,6 +1166,9 @@ def plot_igv_like(
1109
1166
  distance_between_label_axis: float = 0.1,
1110
1167
  show_y_label: bool = True,
1111
1168
  theme: str = "ticks_blank",
1169
+ show_utr: bool = False,
1170
+ utr_color: Optional[str] = None,
1171
+ coding_intervals: Optional[List[tuple]] = None,
1112
1172
  raster: bool = False,
1113
1173
  **kwargs,
1114
1174
  ):
@@ -1123,6 +1183,7 @@ def plot_igv_like(
1123
1183
  if not y_label:
1124
1184
  y_label = obj.label
1125
1185
  y_loc = 0.5
1186
+ utr_color = utr_color if utr_color else "#0099CC"
1126
1187
 
1127
1188
  patches, scatters_x, scatters_y = [], [], []
1128
1189
  if obj.meta is not None:
@@ -1139,16 +1200,30 @@ def plot_igv_like(
1139
1200
  continue
1140
1201
  s = 0 if s < 0 else s
1141
1202
  e = len(region) - 1 if e >= len(region) else e
1142
- patches.append(
1143
- plt.Rectangle(
1144
- (graph_coords[s], y_loc - exon_width),
1145
- width=graph_coords[e] - graph_coords[s],
1146
- height=exon_width * 2,
1147
- facecolor="k" if not exon_color else exon_color,
1148
- lw=0.5,
1149
- zorder=20,
1150
- )
1203
+
1204
+ exon_coding = [
1205
+ (region.relative(cs), region.relative(ce))
1206
+ for cs, ce in (coding_intervals or [])
1207
+ ]
1208
+ segments = (
1209
+ _split_exon_into_cds_utr(s, e, exon_coding)
1210
+ if show_utr and exon_coding
1211
+ else [(s, e, True)]
1151
1212
  )
1213
+ for seg_s, seg_e, is_cds in segments:
1214
+ seg_color = (
1215
+ "k" if not exon_color else exon_color
1216
+ ) if is_cds else utr_color
1217
+ patches.append(
1218
+ plt.Rectangle(
1219
+ (graph_coords[seg_s], y_loc - exon_width),
1220
+ width=graph_coords[seg_e] - graph_coords[seg_s],
1221
+ height=exon_width * 2,
1222
+ facecolor=seg_color,
1223
+ lw=0.5,
1224
+ zorder=20,
1225
+ )
1226
+ )
1152
1227
  add_plot = add_plot | True
1153
1228
 
1154
1229
  for intron in c_data.introns:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trackplot
3
- Version: 0.6.6
3
+ Version: 0.7.0
4
4
  Summary: The trackplot is a tool for visualizing various next-generation sequencing (NGS) data, including DNA-seq, RNA-seq, single-cell RNA-seq and full-length sequencing datasets. https://sashimi.readthedocs.io/
5
5
  Author-email: ygidtu <ygidtu@gmail.com>
6
6
  License-Expression: BSD-3-Clause
@@ -30,9 +30,9 @@ Dynamic: license-file
30
30
 
31
31
  [![PyPI version](https://badge.fury.io/py/trackplot.svg)](https://pypi.org/project/trackplot/)
32
32
  [![PyPI download](https://img.shields.io/pypi/dm/trackplot.svg)](https://pypi.org/project/trackplot/)
33
- [![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg?style=flat)](http://bioconda.github.io/recipes/trackplot/README.html)
33
+ [![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg?style=flat)](https://bioconda.github.io/recipes/trackplot/README.html)
34
34
  [![Documentation Status](https://readthedocs.org/projects/trackplot/badge/?version=latest)](https://trackplot.readthedocs.io/en/latest/)
35
- [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%20v3-clause.svg)](https://www.gnu.org/licenses/agpl-3.0)
35
+ [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
36
36
  [![DOI](https://img.shields.io/badge/DOI-10.1101%2F2022.11.02.514803%20-blue)](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1011477)
37
37
 
38
38
  ---
@@ -41,11 +41,11 @@ Dynamic: license-file
41
41
 
42
42
  [Tutorials](https://trackplot.readthedocs.io/en/latest/)
43
43
 
44
- ## what is trackplot
44
+ ## What is trackplot
45
45
 
46
- 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.
46
+ 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.
47
47
 
48
- ### Features of trackplot
48
+ ### Features
49
49
 
50
50
  1. Support various file formats as input
51
51
  2. Support strand-aware coverage plot
@@ -78,7 +78,7 @@ Trackplot is based on **Python3** `(python_requires='>=3.8')`,
78
78
  and we have simplified the installation process on the main page.
79
79
  For a more comprehensive installation guide, please refer to [this link](./docs/installation.md).
80
80
 
81
- ### For impatient
81
+ ### Quick start
82
82
 
83
83
  ```shell
84
84
  pip install trackplot
@@ -123,15 +123,23 @@ pip install trackplot
123
123
 
124
124
  ---
125
125
 
126
- 2. [AppImage](https://github.com/ygidtu/trackplot/releases) (Linux/WSL x86_64 platform only)
126
+ 2. [AppBundle](https://github.com/xplshn/pelf) (Linux/WSL x86_64 platform only)
127
127
 
128
128
  For a binary version of the tool and more comprehensive information, please visit [this link](./docs/installation.md).
129
129
 
130
130
  ```bash
131
- # example with version v0.3.5, please using your interested version according to your needs
132
- export VERSION=0.3.5
133
- chmod +x trackplot-${VERSION}-x86_64.AppImage
134
- ./trackplot-${VERSION}-x86_64.AppImage --help
131
+ # build the AppBundle from source (version auto-detected from pyproject.toml)
132
+ sh build-appbundle.sh
133
+
134
+ # the output filename and appbundle ID are printed at the end of the script
135
+ # package with pelf (see https://github.com/xplshn/pelf)
136
+ pelf \
137
+ --add-appdir "./trackplot.AppDir" \
138
+ --appbundle-id "$APPBUNDLE_ID" \
139
+ --output-to "$OUTPUT_FILE"
140
+
141
+ chmod +x "$OUTPUT_FILE"
142
+ ./"$OUTPUT_FILE" --help
135
143
  ```
136
144
 
137
145
  ---
@@ -170,20 +178,20 @@ trackplot --help
170
178
  <p>
171
179
 
172
180
 
173
- 1. [AppImage](https://github.com/ygidtu/trackplot/releases) (Linux/WSL x86_64 only)
181
+ 1. AppBundle (Linux/WSL x86_64 only)
182
+
183
+ Build the AppBundle following the [instructions above](#using-trackplot-by-a-command-line), then:
174
184
 
175
185
  ```bash
176
- # example with version v0.3.3, please using your interested version according to your needs
177
- export VERSION=0.3.3
178
- gunzip trackplot-${VERSION}-x86_64.AppImage
179
- chmod +x trackplot-${VERSION}-x86_64.AppImage
180
- ./trackplot-${VERSION}-x86_64.AppImage --help
186
+ # OUTPUT_FILE is printed by build-appbundle.sh
187
+ chmod +x "$OUTPUT_FILE"
188
+ ./"$OUTPUT_FILE" --help
181
189
 
182
190
  # startup webserver
183
- ./trackplot-${VERSION}-x86_64.AppImage --start-server --host 0.0.0.0 --port 5000 --plots ./plots
191
+ ./"$OUTPUT_FILE" --start-server --host 0.0.0.0 --port 5000 --plots ./plots
184
192
  ```
185
-
186
- **Note:** the `--plots` were required while using appimages
193
+
194
+ **Note:** the `--plots` were required while using appbundles
187
195
 
188
196
  ---
189
197
 
@@ -246,7 +254,7 @@ trackplot \
246
254
  -p 4
247
255
  ```
248
256
 
249
- if trackplot was installed by docker, here is the cmd
257
+ If trackplot was installed via docker, here is the cmd:
250
258
 
251
259
  ```bash
252
260
  ## The absolute path is required in Docker env.
@@ -280,17 +288,44 @@ docker run -v $PWD:$PWD -w $PWD --rm ygidtu/trackplot \
280
288
 
281
289
  ```
282
290
 
283
- here is the [output file](https://raw.githubusercontent.com/ygidtu/trackplot/main/example/example.png).
291
+ Here is the [output file](https://raw.githubusercontent.com/ygidtu/trackplot/main/example/example.png).
292
+
293
+
294
+ ## For AI agents (auto-install the trackplot skill)
295
+
296
+ This repo ships a ready-to-use **skill** that teaches an AI coding agent how to
297
+ invoke trackplot. When an agent is asked to create a trackplot/sashimi figure,
298
+ it should install this skill once (path relative to this file):
299
+
300
+ ```bash
301
+ # opencode / Claude Code style: point the skill manager at the bundled skill
302
+ cp -r skills/trackplot ~/.config/opencode/skills/trackplot # or ~/.claude/skills/trackplot
303
+ ```
304
+
305
+ Then the agent reads `skills/trackplot/SKILL.md` (plus
306
+ `skills/trackplot/references/config_files.md` and
307
+ `skills/trackplot/references/python_api.md`) and follows it to:
308
+
309
+ 1. Confirm the input region in `chr:start-end:strand` form and the annotation GTF.
310
+ 2. Build the matching config TSV(s) for the requested track type(s) (see the
311
+ `# filepath category label color` conventions).
312
+ 3. Run `trackplot -e <region> -r <gtf> --density <list.tsv> -o <out>.pdf` (or the
313
+ equivalent Python `Plot(...).set_region(...).add_density(...).plot(...)` chain).
314
+ 4. Verify the output exists; if `pybigwig`/`hicmatrix` are needed for bigWig/HiC,
315
+ install them first.
316
+
317
+ The skill is the single source of truth for trackplot usage; keep it in sync with
318
+ `docs/command.md` and `docs/interactive.md`.
284
319
 
285
320
 
286
321
  ## Questions
287
322
 
288
- Visit [issues](https://github.com/ygidtu/trackplot/issues) or
289
- contact [Yiming Zhang](https://github.com/ygidtu) or
323
+ Visit [issues](https://github.com/ygidtu/trackplot/issues) or
324
+ contact [Yiming Zhang](https://github.com/ygidtu) or
290
325
  [Ran Zhou](https://github.com/zhou-ran)
291
326
 
292
327
  ## Citation
293
328
 
294
- If you use the tool in your publication, please cite by
329
+ If you use trackplot in your publication, please cite:
295
330
 
296
- [Zhang Y, Zhou R, Liu L, et al. Trackplot: A flexible toolkit for combinatorial analysis of genomic data[J]. PLoS computational biology, 2023, 19(9): e1011477.](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1011477)
331
+ Zhang Y, Zhou R, Liu L, et al. Trackplot: A flexible toolkit for combinatorial analysis of genomic data. *PLoS Computational Biology*, 2023, 19(9): e1011477.
File without changes
File without changes
File without changes