comparison plot_facets_enhanced-v22.R @ 3:d1914f4d9daf draft

planemo upload for repository https://github.com/ARTbio/tools-artbio/tree/main/tools/facets commit 64ac36125f04497dd51028f307e059fca9ec0503
author artbio
date Sun, 05 Oct 2025 00:55:34 +0000
parents
children
comparison
equal deleted inserted replaced
2:66a56502199d 3:d1914f4d9daf
1 plot_facets_enhanced <- function(x, emfit = NULL, clustered = FALSE,
2 plot.type = c("em", "naive", "both", "none"),
3 sname = NULL, add.legend = TRUE) {
4 def.par <- par(no.readonly = TRUE)
5 plot.type <- match.arg(plot.type)
6
7 # Setup layout
8 if (plot.type == "none") {
9 layout(matrix(1:2, ncol = 1))
10 }
11 if (plot.type == "em") {
12 layout(matrix(rep(1:4, c(9, 9, 6, 1)), ncol = 1))
13 }
14 if (plot.type == "naive") {
15 layout(matrix(rep(1:4, c(9, 9, 6, 1)), ncol = 1))
16 }
17 if (plot.type == "both") {
18 layout(matrix(rep(1:6, c(9, 9, 6, 1, 6, 1)), ncol = 1))
19 }
20
21 par(
22 mar = c(0.25, 3, 0.25, 1), mgp = c(1.75, 0.6, 0),
23 oma = c(3, 0, 1.25, 0)
24 )
25
26 # Prepare data
27 jseg <- x$jointseg
28 chrbdry <- which(diff(jseg$chrom) != 0)
29
30 if (missing(emfit)) {
31 out <- x$out
32 if (plot.type == "em" | plot.type == "both") {
33 warning("emfit is missing; plot.type set to naive")
34 plot.type <- "naive"
35 }
36 } else {
37 out <- emfit$cncf
38 out$tcn <- x$out$tcn
39 out$lcn <- x$out$lcn
40 out$cf <- x$out$cf
41 }
42
43 if (clustered) {
44 cnlr.median <- out$cnlr.median.clust
45 mafR <- out$mafR.clust
46 mafR[is.na(mafR)] <- out$mafR[is.na(mafR)]
47 } else {
48 cnlr.median <- out$cnlr.median
49 mafR <- out$mafR
50 }
51
52 mafR <- abs(mafR)
53 chrcol <- 1 + rep(out$chrom - 2 * floor(out$chrom / 2), out$num.mark)
54 nn <- cumsum(table(jseg$chrom[is.finite(jseg$cnlr)]))
55 segbdry <- cumsum(c(0, out$num.mark))
56 segstart <- segbdry[-length(segbdry)]
57 segend <- segbdry[-1]
58
59 # Plot 1: log-ratio
60 plot(jseg$cnlr[is.finite(jseg$cnlr)],
61 pch = ".", cex = 2,
62 col = c("grey", "lightblue", "azure4", "slateblue")[chrcol],
63 ylab = "log-ratio", xaxt = "n"
64 )
65 abline(v = chrbdry, lwd = 0.25)
66
67 # Calculate reference lines
68 global_median <- median(jseg$cnlr, na.rm = TRUE)
69 diploid_logr <- x$dipLogR
70 lines_diff <- abs(global_median - diploid_logr)
71
72 # Only show reference lines if they are sufficiently different (> 0.1)
73 legend_items <- c("Segments")
74 legend_cols <- c(2)
75 legend_lwd <- c(1.75)
76 legend_lty <- c(1)
77
78 if (lines_diff > 0.1) {
79 # Lines are different enough to show both
80 abline(h = global_median, col = "green2", lwd = 2.5)
81 abline(h = diploid_logr, col = "magenta4", lwd = 2.5, lty = 2)
82 legend_items <- c(
83 legend_items,
84 sprintf("Global median (%.3f)", global_median),
85 sprintf("Diploid LogR (%.3f)", diploid_logr)
86 )
87 legend_cols <- c(legend_cols, "green2", "magenta4")
88 legend_lwd <- c(legend_lwd, 2.5, 2.5)
89 legend_lty <- c(legend_lty, 1, 2)
90 } else {
91 # Lines are too close, show only one with combined label
92 abline(h = global_median, col = "green2", lwd = 2.5)
93 legend_items <- c(
94 legend_items,
95 sprintf("Median/Diploid (%.3f)", global_median)
96 )
97 legend_cols <- c(legend_cols, "green2")
98 legend_lwd <- c(legend_lwd, 2.5)
99 legend_lty <- c(legend_lty, 1)
100 }
101
102 segments(segstart, cnlr.median, segend, cnlr.median, lwd = 1.75, col = 2)
103
104 # Add legend for log-ratio plot
105 if (add.legend) {
106 legend("topright",
107 legend = legend_items,
108 col = legend_cols,
109 lwd = legend_lwd,
110 lty = legend_lty,
111 bty = "n",
112 cex = 0.7
113 )
114 }
115
116 # Plot 2: log-odds-ratio
117 plot(jseg$valor[is.finite(jseg$cnlr)],
118 pch = ".", cex = 2.5,
119 col = c("grey", "lightblue", "azure4", "slateblue")[chrcol],
120 ylab = "log-odds-ratio", ylim = c(-4, 4), xaxt = "n"
121 )
122 abline(v = chrbdry, lwd = 0.25)
123 segments(segstart, sqrt(mafR), segend, sqrt(mafR), lwd = 1.75, col = 2)
124 segments(segstart, -sqrt(mafR), segend, -sqrt(mafR), lwd = 1.75, col = 2)
125
126 # Add legend for log-odds-ratio plot
127 if (add.legend) {
128 legend("topright",
129 legend = c("BAF segments"),
130 col = c(2),
131 lwd = c(1.75),
132 bty = "n",
133 cex = 0.7
134 )
135 }
136
137 cfpalette <- c(colorRampPalette(c("white", "steelblue"))(10), "bisque2")
138
139 # Plot 3: copy number (naive)
140 if (plot.type == "naive" | plot.type == "both") {
141 out$tcn[out$tcn > 10] <- 9 + log10(out$tcn[out$tcn > 10])
142 ii <- which(out$lcn > 5)
143 if (length(ii) > 0) {
144 out$lcn[ii] <- 5 + log10(out$lcn[ii])
145 }
146
147 plot(c(0, length(jseg$cnlr)), c(0, max(out$tcn)),
148 type = "n",
149 ylab = "copy number (nv)", xaxt = "n"
150 )
151 abline(v = chrbdry, lwd = 0.25)
152 segments(segstart, out$lcn, segend, out$lcn, lwd = 1.75, col = 2)
153 segments(segstart, out$tcn, segend, out$tcn, lwd = 1.75, col = 1)
154
155 # Add legends for copy number plot (including CF legend)
156 if (add.legend) {
157 # CN legend on top left
158 legend("topleft",
159 legend = c("Total CN (TCN)", "Minor CN (LCN)"),
160 col = c(1, 2),
161 lwd = 1.75,
162 bty = "n",
163 cex = 0.7
164 )
165
166 # CF legend on top right
167 legend("topright",
168 legend = c(
169 "CF = 0 (normal)", "CF = 0.2 (low tumor)",
170 "CF = 0.8 (high tumor)", "CF = 1.0 (pure tumor)"
171 ),
172 fill = c("white", "lightblue", "steelblue", "tan"),
173 border = "black",
174 bty = "o",
175 box.col = "black",
176 box.lwd = 1.5,
177 cex = 0.65,
178 title = "Cellular Fraction (CF)",
179 bg = "white"
180 )
181 }
182
183 # CF bar (naive)
184 plot(c(0, length(jseg$cnlr)), 0:1,
185 type = "n", ylab = "",
186 xaxt = "n", yaxt = "n"
187 )
188 mtext("cf-nv", side = 2, at = 0.5, line = 0.3, las = 2, cex = 0.75)
189 cfcol <- cfpalette[round(10 * out$cf + 0.501)]
190 rect(segstart, 0, segend, 1, col = cfcol, border = NA)
191 }
192
193 # Plot 4: copy number (EM)
194 if (plot.type == "em" | plot.type == "both") {
195 out$tcn.em[out$tcn.em > 10] <- 9 + log10(out$tcn.em[out$tcn.em > 10])
196 ii <- which(out$lcn.em > 5)
197 if (length(ii) > 0) {
198 out$lcn.em[ii] <- 5 + log10(out$lcn.em[ii])
199 }
200
201 plot(c(0, length(jseg$cnlr)), c(0, max(out$tcn.em)),
202 type = "n", ylab = "copy number (em)", xaxt = "n"
203 )
204 abline(v = chrbdry, lwd = 0.25)
205 segments(segstart, out$lcn.em, segend, out$lcn.em, lwd = 1.75, col = 2)
206 segments(segstart, out$tcn.em, segend, out$tcn.em, lwd = 1.75, col = 1)
207
208 # Add legends for EM copy number plot (including CF legend)
209 if (add.legend) {
210 # CN legend on top left
211 legend("topleft",
212 legend = c("Total CN (TCN)", "Minor CN (LCN)"),
213 col = c(1, 2),
214 lwd = 1.75,
215 bty = "n",
216 cex = 0.7
217 )
218
219 # CF legend on top right
220 legend("topright",
221 legend = c(
222 "CF = 0 (normal)", "CF = 0.2 (low tumor)",
223 "CF = 0.8 (high tumor)", "CF = 1.0 (pure tumor)"
224 ),
225 fill = c("white", "lightblue", "steelblue", "tan"),
226 border = "black",
227 bty = "o",
228 box.col = "black",
229 box.lwd = 1.5,
230 cex = 0.65,
231 title = "Cellular Fraction (CF)",
232 bg = "white"
233 )
234 }
235
236 # CF bar (EM)
237 plot(c(0, length(jseg$cnlr)), 0:1,
238 type = "n", ylab = "",
239 xaxt = "n", yaxt = "n"
240 )
241 mtext("cf-em", side = 2, at = 0.5, line = 0.2, las = 2, cex = 0.75)
242 cfcol <- cfpalette[round(10 * out$cf.em + 0.501)]
243 rect(segstart, 0, segend, 1, col = cfcol, border = NA)
244 }
245
246 # X-axis with chromosome labels
247 chromlevels <- x$chromlevels
248 if (is.null(chromlevels)) {
249 chromlevels <- 1:length(nn)
250 }
251 axis(
252 labels = chromlevels, side = 1,
253 at = (nn + c(0, nn[-length(nn)])) / 2, cex = 0.65
254 )
255 mtext(side = 1, line = 1.75, "Chromosome", cex = 0.8)
256
257 # Sample name title
258 if (!missing(sname)) {
259 mtext(sname, side = 3, line = 0, outer = TRUE, cex = 0.8)
260 }
261
262 par(def.par)
263 }