Browse code

anno_mark(): labels can be duplicated

Zuguang Gu authored on 03/04/2023 12:34:13
Showing 1 changed files
... ...
@@ -3106,7 +3106,7 @@ anno_mark = function(at, labels, which = c("column", "row"),
3106 3106
 	link_gp = subset_gp(link_gp, od)
3107 3107
 	labels_gp = subset_gp(labels_gp, od)
3108 3108
 
3109
-	labels2index = structure(seq_along(at), names = as.character(labels))
3109
+	at2index = structure(seq_along(at), names = as.character(at))
3110 3110
 	at2labels = structure(labels, names = at)
3111 3111
 
3112 3112
 	if(length(extend) == 1) extend = rep(extend, 2)
... ...
@@ -3148,8 +3148,8 @@ anno_mark = function(at, labels, which = c("column", "row"),
3148 3148
 		}
3149 3149
 		labels = rev(at2labels[as.character(at)])
3150 3150
 
3151
-		labels_gp = subset_gp(labels_gp, labels2index[as.character(labels)])
3152
-		link_gp = subset_gp(link_gp, labels2index[as.character(labels)])
3151
+		labels_gp = subset_gp(labels_gp, rev(at2index[as.character(at)]))
3152
+		link_gp = subset_gp(link_gp, rev(at2index[as.character(at)]))
3153 3153
 
3154 3154
 		if(is.null(.scale)) {
3155 3155
 			.scale = c(0.5, n+0.5)
... ...
@@ -3225,8 +3225,8 @@ anno_mark = function(at, labels, which = c("column", "row"),
3225 3225
 		}
3226 3226
 		labels = at2labels[as.character(at)]
3227 3227
 		
3228
-		labels_gp = subset_gp(labels_gp, labels2index[as.character(labels)])
3229
-		link_gp = subset_gp(link_gp, labels2index[as.character(labels)])
3228
+		labels_gp = subset_gp(labels_gp, rev(at2index[as.character(at)]))
3229
+		link_gp = subset_gp(link_gp, rev(at2index[as.character(at)]))
3230 3230
 
3231 3231
 		if(is.null(.scale)) {
3232 3232
 			.scale = c(0.5, n+0.5)
... ...
@@ -3300,7 +3300,7 @@ anno_mark = function(at, labels, which = c("column", "row"),
3300 3300
 		width = width,
3301 3301
 		height = height,
3302 3302
 		n = -1,
3303
-		var_import = list(at, labels2index, at2labels, link_gp, labels_gp, labels_rot, padding, .pos, .scale,
3303
+		var_import = list(at, at2index, at2labels, link_gp, labels_gp, labels_rot, padding, .pos, .scale,
3304 3304
 			side, link_width, link_height, extend),
3305 3305
 		show_name = FALSE
3306 3306
 	)
Browse code

anno_numeric(): fill can be correctly set as a vector

Zuguang Gu authored on 08/02/2023 13:16:24
Showing 1 changed files
... ...
@@ -4414,7 +4414,6 @@ anno_numeric = function(x, rg = range(x), labels_gp = gpar(), x_convert = NULL,
4414 4414
     }
4415 4415
 
4416 4416
     cell_fun_pct = function(i) {
4417
-
4418 4417
     	min_x = rg[1]
4419 4418
     	max_x = rg[2]
4420 4419
         pushViewport(viewport(xscale = rg))
... ...
@@ -4445,24 +4444,24 @@ anno_numeric = function(x, rg = range(x), labels_gp = gpar(), x_convert = NULL,
4445 4444
         		if(round_corners) {
4446 4445
 		        	grid.roundrect(x = unit(0, "native"), 
4447 4446
 		                width = unit(-x[i], "native"), height = bar_width,  r = r,
4448
-		                just = "right", gp = subset_gp(bg_gp, 1))
4447
+		                just = "right", gp = subset_gp(bg_gp, i))
4449 4448
 		        } else {
4450 4449
 		        	grid.rect(x = unit(0, "native"), 
4451 4450
 		                width = unit(-x[i], "native"), height = bar_width, 
4452
-		                just = "right", gp = subset_gp(bg_gp, 1))
4451
+		                just = "right", gp = subset_gp(bg_gp, i))
4453 4452
 		        }
4454
-	            grid.text(labels[i], x = unit(0, "native") - labels_offset, just = "right", gp = subset_gp(labels_gp, 1))
4453
+	            grid.text(labels[i], x = unit(0, "native") - labels_offset, just = "right", gp = subset_gp(labels_gp, i))
4455 4454
 	        } else {
4456 4455
 	        	if(round_corners) {
4457 4456
 		        	grid.roundrect(x = unit(0, "native"), 
4458 4457
 		                width = unit(x[i], "native"), height = bar_width,  r = r,
4459
-		                just = "left", gp = subset_gp(bg_gp, 2))
4458
+		                just = "left", gp = subset_gp(bg_gp, i))
4460 4459
 		        } else {
4461 4460
 		        	grid.rect(x = unit(0, "native"), 
4462 4461
 		                width = unit(x[i], "native"), height = bar_width,
4463
-		                just = "left", gp = subset_gp(bg_gp, 2))
4462
+		                just = "left", gp = subset_gp(bg_gp, i))
4464 4463
 		        }
4465
-	            grid.text(labels[i], x = unit(0, "native") + labels_offset, just = "left", gp = subset_gp(labels_gp, 2))
4464
+	            grid.text(labels[i], x = unit(0, "native") + labels_offset, just = "left", gp = subset_gp(labels_gp, i))
4466 4465
 	        }
4467 4466
         }
4468 4467
         popViewport()
Browse code

add a new add_points argument in anno_boxplot()

Zuguang Gu authored on 27/10/2022 08:59:57
Showing 1 changed files
... ...
@@ -1561,8 +1561,10 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1561 1561
 # -extend The extension to both side of ``ylim``. The value is a percent value corresponding to ``ylim[2] - ylim[1]``.
1562 1562
 # -outline Whether draw outline of boxplots?
1563 1563
 # -box_width Relative width of boxes. The value should be smaller than one.
1564
+# -add_points Whether add points on top of the boxes?
1564 1565
 # -pch Point style.
1565 1566
 # -size Point size.
1567
+# -pt_gp Graphics parameters for points.
1566 1568
 # -axis Whether to add axis?
1567 1569
 # -axis_param parameters for controlling axis. See `default_axis_param` for all possible settings and default parameters.
1568 1570
 # -width Width of the annotation. The value should be an absolute unit. Width is not allowed to be set for column annotation.
... ...
@@ -1584,8 +1586,8 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1584 1586
 # draw(anno, test = "anno_boxplot with gp")
1585 1587
 anno_boxplot = function(x, which = c("column", "row"), border = TRUE,
1586 1588
 	gp = gpar(fill = "#CCCCCC"), ylim = NULL, extend = 0.05, outline = TRUE, box_width = 0.6,
1587
-	pch = 1, size = unit(2, "mm"), axis = TRUE, axis_param = default_axis_param(which),
1588
-	width = NULL, height = NULL, ...) {
1589
+	add_points = FALSE, pch = 16, size = unit(4, "pt"), pt_gp = gpar(), axis = TRUE, 
1590
+	axis_param = default_axis_param(which), width = NULL, height = NULL, ...) {
1589 1591
 
1590 1592
 	other_args = list(...)
1591 1593
 	if(length(other_args)) {
... ...
@@ -1639,6 +1641,7 @@ anno_boxplot = function(x, which = c("column", "row"), border = TRUE,
1639 1641
 
1640 1642
 	n = length(value)
1641 1643
 	gp = recycle_gp(gp, n)
1644
+	pt_gp = recycle_gp(pt_gp, n)
1642 1645
 	if(length(pch) == 1) pch = rep(pch, n)
1643 1646
 	if(length(size) == 1) size = rep(size, n)
1644 1647
 
... ...
@@ -1657,6 +1660,7 @@ anno_boxplot = function(x, which = c("column", "row"), border = TRUE,
1657 1660
 		
1658 1661
 		n = length(index)
1659 1662
 		gp = subset_gp(gp, index)
1663
+		pt_gp = subset_gp(pt_gp, index)
1660 1664
 		pch = pch[index]
1661 1665
 		size = size[index]
1662 1666
 		pushViewport(viewport(xscale = data_scale, yscale = c(0.5, n+0.5)))
... ...
@@ -1680,18 +1684,25 @@ anno_boxplot = function(x, which = c("column", "row"), border = TRUE,
1680 1684
 		grid.segments(boxplot_stats[3, ], n - seq_along(index) + 1 - 0.5*box_width, 
1681 1685
 			          boxplot_stats[3, ], n - seq_along(index) + 1 + 0.5*box_width, 
1682 1686
 			          default.units = "native", gp = gp)
1683
-		if(outline) {
1687
+		if(!add_points && outline) {
1684 1688
 			for(i in seq_along(value)) {
1685 1689
 				l1 = value[[i]] > boxplot_stats[5,i]
1686 1690
 				l1[is.na(l1)] = FALSE
1687 1691
 				if(sum(l1)) grid.points(y = rep(n - i + 1, sum(l1)), x = value[[i]][l1], 
1688
-					default.units = "native", gp = subset_gp(gp, i), pch = pch[i], size = size[i])
1692
+					default.units = "native", gp = subset_gp(pt_gp, i), pch = pch[i], size = size[i])
1689 1693
 				l2 = value[[i]] < boxplot_stats[1,i]
1690 1694
 				l2[is.na(l2)] = FALSE
1691 1695
 				if(sum(l2)) grid.points(y = rep(n - i + 1, sum(l2)), x = value[[i]][l2], 
1692
-					default.units = "native", gp = subset_gp(gp, i), pch = pch[i], size = size[i])
1696
+					default.units = "native", gp = subset_gp(pt_gp, i), pch = pch[i], size = size[i])
1697
+			}
1698
+		}
1699
+		if(add_points && outline) {
1700
+			for(i in seq_along(value)) {
1701
+				grid.points(y = n - runif(length(value[[i]]), min = i - 0.5*0.5*box_width, max = i + 0.5*0.5*box_width) + 1,
1702
+					        x = value[[i]], default.units = "native", gp = subset_gp(pt_gp, i), pch = pch[i], size = size[i])
1693 1703
 			}
1694 1704
 		}
1705
+
1695 1706
 		if(axis_param$side == "top") {
1696 1707
 			if(k > 1) axis = FALSE
1697 1708
 		} else if(axis_param$side == "bottom") {
... ...
@@ -1712,6 +1723,7 @@ anno_boxplot = function(x, which = c("column", "row"), border = TRUE,
1712 1723
 
1713 1724
 		n = length(index)
1714 1725
 		gp = subset_gp(gp, index)
1726
+		pt_gp = subset_gp(pt_gp, index)
1715 1727
 		pch = pch[index]
1716 1728
 		size = size[index]
1717 1729
 		pushViewport(viewport(xscale = c(0.5, n+0.5), yscale = data_scale))
... ...
@@ -1734,16 +1746,24 @@ anno_boxplot = function(x, which = c("column", "row"), border = TRUE,
1734 1746
 		grid.segments(seq_along(index) - 0.5*box_width, boxplot_stats[3, ],
1735 1747
 			          seq_along(index) + 0.5*box_width, boxplot_stats[3, ], 
1736 1748
 			          default.units = "native", gp = gp)
1737
-		if(outline) {	
1749
+		
1750
+		if(!add_points && outline) {	
1738 1751
 			for(i in seq_along(value)) {
1739 1752
 				l1 = value[[i]] > boxplot_stats[5,i]
1740 1753
 				l1[is.na(l1)] = FALSE
1741 1754
 				if(sum(l1)) grid.points(x = rep(i, sum(l1)), y = value[[i]][l1], 
1742
-					default.units = "native", gp = subset_gp(gp, i), pch = pch[i], size = size[i])
1755
+					default.units = "native", gp = subset_gp(pt_gp, i), pch = pch[i], size = size[i])
1743 1756
 				l2 = value[[i]] < boxplot_stats[1,i]
1744 1757
 				l2[is.na(l2)] = FALSE
1745 1758
 				if(sum(l2)) grid.points(x = rep(i, sum(l2)), y = value[[i]][l2], 
1746
-					default.units = "native", gp = subset_gp(gp, i), pch = pch[i], size = size[i])
1759
+					default.units = "native", gp = subset_gp(pt_gp, i), pch = pch[i], size = size[i])
1760
+			}
1761
+		}
1762
+
1763
+		if(add_points && outline) {
1764
+			for(i in seq_along(value)) {
1765
+				grid.points(x = runif(length(value[[i]]), min = i - 0.5*0.5*box_width, max = i + 0.5*0.5*box_width),
1766
+					        y = value[[i]], default.units = "native", gp = subset_gp(pt_gp, i), pch = pch[i], size = size[i])
1747 1767
 			}
1748 1768
 		}
1749 1769
 		if(axis_param$side == "left") {
... ...
@@ -1770,11 +1790,12 @@ anno_boxplot = function(x, which = c("column", "row"), border = TRUE,
1770 1790
 		width = anno_size$width,
1771 1791
 		height = anno_size$height,
1772 1792
 		data_scale = data_scale,
1773
-		var_import = list(value, gp, border, box_width, axis, axis_param, axis_grob, data_scale, pch, size, outline)
1793
+		var_import = list(value, gp, border, box_width, axis, axis_param, axis_grob, data_scale, add_points, pch, pt_gp, size, outline)
1774 1794
 	)
1775 1795
 
1776 1796
 	anno@subset_rule$value = subset_vector
1777 1797
 	anno@subset_rule$gp = subset_gp
1798
+	anno@subset_rule$pt_gp = subset_gp
1778 1799
 	anno@subset_rule$pch = subset_vector
1779 1800
 	anno@subset_rule$size = subset_vector
1780 1801
 	
Browse code

anno_barplot(): fixed a bug when besides = TRUE

Zuguang Gu authored on 27/10/2022 08:33:37
Showing 1 changed files
... ...
@@ -1396,7 +1396,7 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1396 1396
 		} else {
1397 1397
 			if(beside) {
1398 1398
 				nbar = ncol(value)
1399
-				nr = nrow(value)
1399
+				nr = length(index)
1400 1400
 				for(i in seq_along(index)) {
1401 1401
 			        for(j in 1:nbar) {
1402 1402
 			        	if(attach) {
... ...
@@ -1471,7 +1471,7 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1471 1471
 		} else {
1472 1472
 			if(beside) {
1473 1473
 				nbar = ncol(value)
1474
-				nr = nrow(value)
1474
+				nr = length(index)
1475 1475
 				for(i in seq_along(index)) {
1476 1476
 			        for(j in 1:nbar) {
1477 1477
 			        	if(attach) {
Browse code

anno_density(): fixed a bug in heatmap density

Zuguang Gu authored on 06/10/2022 08:26:08
Showing 1 changed files
... ...
@@ -2112,17 +2112,17 @@ anno_density = function(x, which = c("column", "row"),
2112 2112
 					width = density_x[[i]][-1] - density_x[[i]][-n_breaks], height = 1, 
2113 2113
 					just = c("right", "bottom"), default.units = "native", 
2114 2114
 					gp = gpar(fill = col_fun((density_y[[i]][-1] + density_y[[i]][-n_breaks])/2), 
2115
-						col = NA))
2115
+						col = col_fun((density_y[[i]][-1] + density_y[[i]][-n_breaks])/2)))
2116 2116
 				if(density_x[[i]][1] - min_density_x > 0) {
2117 2117
 					grid.rect(x = density_x[[i]][1], y = 0, width = density_x[[i]][1] - min_density_x, 
2118 2118
 						height = 1, just = c("right", "bottom"), default.units = "native", 
2119
-						gp = gpar(fill = col_fun(0), col = NA))
2119
+						gp = gpar(fill = col_fun(0), col = col_fun(0)))
2120 2120
 				}
2121 2121
 				if(max_density_x - density_x[[i]][n_breaks] > 0) {
2122 2122
 					grid.rect(x = density_x[[i]][n_breaks], y = 0, 
2123 2123
 						width = max_density_x - density_x[[i]][n_breaks], height = 1, 
2124 2124
 						just = c("left", "bottom"), default.units = "native", 
2125
-						gp = gpar(fill = col_fun(0), col = NA))
2125
+						gp = gpar(fill = col_fun(0), col = col_fun(0)))
2126 2126
 				}
2127 2127
 			}
2128 2128
 			popViewport()
... ...
@@ -2149,8 +2149,6 @@ anno_density = function(x, which = c("column", "row"),
2149 2149
 		density_x = density_x[index]
2150 2150
 		density_y = density_y[index]
2151 2151
 		
2152
-		yscale = range(unlist(density_x), na.rm = TRUE)
2153
-		yscale = yscale + c(0, 0.05)*(yscale[2] - yscale[1])
2154 2152
 		if(type == "lines") {
2155 2153
 			xscale = c(0, max(unlist(density_y)))
2156 2154
 			xscale[2] = xscale[2]*1.05
... ...
@@ -2158,7 +2156,6 @@ anno_density = function(x, which = c("column", "row"),
2158 2156
 			xscale = max(unlist(density_y))
2159 2157
 			xscale = c(-xscale*1.05, xscale*1.05)
2160 2158
 		} else if(type == "heatmap") {
2161
-			yscale = range(unlist(density_x), na.rm = TRUE)
2162 2159
 			xscale = c(0, 1)
2163 2160
 			min_y = min(unlist(density_y))
2164 2161
 			max_y = max(unlist(density_y))
... ...
@@ -2192,17 +2189,17 @@ anno_density = function(x, which = c("column", "row"),
2192 2189
 					height = density_x[[i]][-1] - density_x[[i]][-n_breaks], width = 1, 
2193 2190
 					just = c("left", "top"), default.units = "native", 
2194 2191
 					gp = gpar(fill = col_fun((density_y[[i]][-1] + density_y[[i]][-n_breaks])/2), 
2195
-						col = NA))
2192
+						col = col_fun((density_y[[i]][-1] + density_y[[i]][-n_breaks])/2)))
2196 2193
 				if(density_x[[i]][1] - min_density_x > 0) {
2197 2194
 					grid.rect(y = density_x[[i]][1], x = 0, height = density_x[[i]][1] - min_density_x, 
2198 2195
 						width = 1, just = c("left", "top"), default.units = "native", 
2199
-						gp = gpar(fill = col_fun(0), col = NA))
2196
+						gp = gpar(fill = col_fun(0), col = col_fun(0)))
2200 2197
 				}
2201 2198
 				if(max_density_x - density_x[[i]][n_breaks] > 0) {
2202 2199
 					grid.rect(y = density_x[[i]][n_breaks], x = 0, 
2203 2200
 						height = max_density_x - density_x[[i]][n_breaks], width = 1, 
2204 2201
 						just = c("left", "bottom"), default.units = "native", 
2205
-						gp = gpar(fill = col_fun(0), col = NA))
2202
+						gp = gpar(fill = col_fun(0), col = col_fun(0)))
2206 2203
 				}
2207 2204
 			}
2208 2205
 			popViewport()
Browse code

anno_density(): fixed a bug where 'xlim' is ignored for 'heatmap'

Zuguang Gu authored on 28/09/2022 13:59:00
Showing 1 changed files
... ...
@@ -2042,6 +2042,8 @@ anno_density = function(x, which = c("column", "row"),
2042 2042
 			density_x[[i]] = c(density_x[[i]][ 1 ], density_x[[i]], density_x[[i]][ length(density_x[[i]]) ])
2043 2043
 			density_y[[i]] = c(0, density_y[[i]], 0)
2044 2044
 		}
2045
+		min_density_x = xlim[1]
2046
+		max_density_x = xlim[2]
2045 2047
 	}
2046 2048
 	
2047 2049
 	if(type == "lines") {
... ...
@@ -2111,13 +2113,17 @@ anno_density = function(x, which = c("column", "row"),
2111 2113
 					just = c("right", "bottom"), default.units = "native", 
2112 2114
 					gp = gpar(fill = col_fun((density_y[[i]][-1] + density_y[[i]][-n_breaks])/2), 
2113 2115
 						col = NA))
2114
-				grid.rect(x = density_x[[i]][1], y = 0, width = density_x[[i]][1] - min_density_x, 
2115
-					height = 1, just = c("right", "bottom"), default.units = "native", 
2116
-					gp = gpar(fill = col_fun(0), col = NA))
2117
-				grid.rect(x = density_x[[i]][n_breaks], y = 0, 
2118
-					width = max_density_x - density_x[[i]][n_breaks], height = 1, 
2119
-					just = c("left", "bottom"), default.units = "native", 
2120
-					gp = gpar(fill = col_fun(0), col = NA))
2116
+				if(density_x[[i]][1] - min_density_x > 0) {
2117
+					grid.rect(x = density_x[[i]][1], y = 0, width = density_x[[i]][1] - min_density_x, 
2118
+						height = 1, just = c("right", "bottom"), default.units = "native", 
2119
+						gp = gpar(fill = col_fun(0), col = NA))
2120
+				}
2121
+				if(max_density_x - density_x[[i]][n_breaks] > 0) {
2122
+					grid.rect(x = density_x[[i]][n_breaks], y = 0, 
2123
+						width = max_density_x - density_x[[i]][n_breaks], height = 1, 
2124
+						just = c("left", "bottom"), default.units = "native", 
2125
+						gp = gpar(fill = col_fun(0), col = NA))
2126
+				}
2121 2127
 			}
2122 2128
 			popViewport()
2123 2129
 		}
... ...
@@ -2187,13 +2193,17 @@ anno_density = function(x, which = c("column", "row"),
2187 2193
 					just = c("left", "top"), default.units = "native", 
2188 2194
 					gp = gpar(fill = col_fun((density_y[[i]][-1] + density_y[[i]][-n_breaks])/2), 
2189 2195
 						col = NA))
2190
-				grid.rect(y = density_x[[i]][1], x = 0, height = density_x[[i]][1] - min_density_x, 
2191
-					width = 1, just = c("left", "top"), default.units = "native", 
2192
-					gp = gpar(fill = col_fun(0), col = NA))
2193
-				grid.rect(y = density_x[[i]][n_breaks], x = 0, 
2194
-					height = max_density_x - density_x[[i]][n_breaks], width = 1, 
2195
-					just = c("left", "bottom"), default.units = "native", 
2196
-					gp = gpar(fill = col_fun(0), col = NA))
2196
+				if(density_x[[i]][1] - min_density_x > 0) {
2197
+					grid.rect(y = density_x[[i]][1], x = 0, height = density_x[[i]][1] - min_density_x, 
2198
+						width = 1, just = c("left", "top"), default.units = "native", 
2199
+						gp = gpar(fill = col_fun(0), col = NA))
2200
+				}
2201
+				if(max_density_x - density_x[[i]][n_breaks] > 0) {
2202
+					grid.rect(y = density_x[[i]][n_breaks], x = 0, 
2203
+						height = max_density_x - density_x[[i]][n_breaks], width = 1, 
2204
+						just = c("left", "bottom"), default.units = "native", 
2205
+						gp = gpar(fill = col_fun(0), col = NA))
2206
+				}
2197 2207
 			}
2198 2208
 			popViewport()
2199 2209
 		}
Browse code

add max_density argument

Zuguang Gu authored on 15/06/2022 10:42:56
Showing 1 changed files
... ...
@@ -1958,6 +1958,8 @@ anno_histogram = function(x, which = c("column", "row"), n_breaks = 11,
1958 1958
 # -type Type of graphics to represent density distribution. "lines" for normal density plot; "violine" for violin plot
1959 1959
 #       and "heatmap" for heatmap visualization of density distribution.
1960 1960
 # -xlim Range on x-axis.
1961
+# -max_density Maximal density values in the plot. Normally you don't need to manually set it, but when you have multiple density annotations
1962
+#   and you want to compare between them, you should manually set this argument to make density distributions are in a same scale.
1961 1963
 # -heatmap_colors A vector of colors for interpolating density values.
1962 1964
 # -joyplot_scale Relative height of density distribution. A value higher than 1 increases the height of the density
1963 1965
 #               distribution and the plot will represented as so-called "joyplot".
... ...
@@ -1986,7 +1988,7 @@ anno_histogram = function(x, which = c("column", "row"), n_breaks = 11,
1986 1988
 #     heatmap_colors = c("white", "orange"))
1987 1989
 # draw(anno, test = "heatmap, colors")
1988 1990
 anno_density = function(x, which = c("column", "row"),
1989
-	type = c("lines", "violin", "heatmap"), xlim = NULL,
1991
+	type = c("lines", "violin", "heatmap"), xlim = NULL, max_density = NULL,
1990 1992
 	heatmap_colors = rev(brewer.pal(name = "RdYlBu", n = 11)), 
1991 1993
 	joyplot_scale = 1, border = TRUE, gp = gpar(fill = "#CCCCCC"),
1992 1994
 	axis = TRUE, axis_param = default_axis_param(which),
... ...
@@ -2044,16 +2046,29 @@ anno_density = function(x, which = c("column", "row"),
2044 2046
 	
2045 2047
 	if(type == "lines") {
2046 2048
 		xscale = xscale + c(-0.025, 0.025)*(xscale[2] - xscale[1])
2047
-		yscale = c(0, max(unlist(density_y)))
2049
+		if(is.null(max_density)) {
2050
+			yscale = c(0, max(unlist(density_y)))
2051
+		} else {
2052
+			yscale = c(0, max_density)
2053
+		}
2048 2054
 		yscale[2] = yscale[2]*1.05
2049 2055
 	} else if(type == "violin") {
2050 2056
 		xscale = xscale + c(-0.025, 0.025)*(xscale[2] - xscale[1])
2051
-		yscale = max(unlist(density_y))
2057
+		if(is.null(max_density)) {
2058
+			yscale = max(unlist(density_y))
2059
+		} else {
2060
+			yscale = max_density
2061
+		}
2052 2062
 		yscale = c(-yscale*1.05, yscale*1.05)
2053 2063
 	} else if(type == "heatmap") {
2054 2064
 		yscale = c(0, 1)
2055
-		min_y = min(unlist(density_y))
2056
-		max_y = max(unlist(density_y))
2065
+		if(is.null(max_density)) {
2066
+			min_y = min(unlist(density_y))
2067
+			max_y = max(unlist(density_y))
2068
+		} else {
2069
+			min_y = 0
2070
+			max_y = max_density
2071
+		}
2057 2072
 		col_fun = colorRamp2(seq(min_y, max_y, 
2058 2073
 			length.out = length(heatmap_colors)), heatmap_colors)
2059 2074
 	}
Browse code

add more annotation functions

Zuguang Gu authored on 18/02/2022 19:51:49
Showing 1 changed files
... ...
@@ -1300,18 +1300,18 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1300 1300
 		data_scale = range(rowSums(x, na.rm = TRUE), na.rm = TRUE)
1301 1301
 	}
1302 1302
 
1303
-	if(data_scale[1] == data_scale[2]) data_scale[2] = data_scale[1] + 1
1303
+	if(data_scale[1] == data_scale[2]) data_scale[2] = data_scale[1] + .Machine$double.eps*1.1
1304 1304
 
1305 1305
 	if(!is.null(ylim)) data_scale = ylim
1306 1306
 	if(baseline == "min") {
1307 1307
 		data_scale = data_scale + c(0, extend)*(data_scale[2] - data_scale[1])
1308
-		baseline = min(x)
1308
+		baseline = min(x, na.rm = TRUE)
1309 1309
 	} else if(baseline == "max") {
1310 1310
 		data_scale = data_scale + c(-extend, 0)*(data_scale[2] - data_scale[1])
1311
-		baseline = max(x)
1311
+		baseline = max(x, na.rm = TRUE)
1312 1312
 	} else {
1313 1313
 		if(is.numeric(baseline)) {
1314
-			if(baseline == 0 && all(abs(rowSums(x) - 1) < 1e-6) && !beside) {
1314
+			if(baseline == 0 && all(abs(rowSums(x, na.rm = TRUE) - 1) < 1e-6) && !beside) {
1315 1315
 				data_scale = c(0, 1)
1316 1316
 			} else if(baseline <= data_scale[1]) {
1317 1317
 				data_scale = c(baseline, extend*(data_scale[2] - baseline) + data_scale[2])
... ...
@@ -4314,8 +4314,8 @@ anno_customize = function(x, graphics = list(), which = c("column", "row"),
4314 4314
 # == param
4315 4315
 # -x A vector of numeric values.
4316 4316
 # -rg Range. A numeric vector of length two.
4317
-# -labels_gp. Graphics parameters for labels.
4318
-# -x_convert. A function applied on ``x``. E.g. when ``x`` contains p-values, to map ``x`` to the heights of bars, a transformation of ``-log10(x)`` 
4317
+# -labels_gp Graphics parameters for labels.
4318
+# -x_convert A function applied on ``x``. E.g. when ``x`` contains p-values, to map ``x`` to the heights of bars, a transformation of ``-log10(x)`` 
4319 4319
 #      is normally applied.
4320 4320
 # -labels_format A function applied on ``x``. E.g., when ``x`` is a numeric, ``labels_format`` can be set to ``function(x) sprintf("\%.2f", x)``.
4321 4321
 # -labels_offset Offset of labels to the left or right of bars.
... ...
@@ -4330,7 +4330,7 @@ anno_customize = function(x, graphics = list(), which = c("column", "row"),
4330 4330
 #
4331 4331
 # == example
4332 4332
 # m = matrix(rnorm(100), 10)
4333
-# x = numeric(10)
4333
+# x = rnorm(10)
4334 4334
 # Heatmap(m, right_annotation = rowAnnotation(numeric = anno_numeric(x)))
4335 4335
 anno_numeric = function(x, rg = range(x), labels_gp = gpar(), x_convert = NULL, 
4336 4336
 	labels_format = NULL, labels_offset = unit(4, "pt"),
... ...
@@ -4359,6 +4359,10 @@ anno_numeric = function(x, rg = range(x), labels_gp = gpar(), x_convert = NULL,
4359 4359
 		rg = range(x_convert(rg))
4360 4360
 	}
4361 4361
 
4362
+	if(rg[1] == rg[2]) {
4363
+		rg[2] = rg[2] + .Machine$double.eps*1.1
4364
+	}
4365
+
4362 4366
     x[x < rg[1]] = rg[1]
4363 4367
     x[x > rg[2]] = rg[2]
4364 4368
 
Browse code

add show_name in anno_empty()

Zuguang Gu authored on 03/02/2022 09:53:48
Showing 1 changed files
... ...
@@ -10,6 +10,7 @@
10 10
 #       and the original heatmap slices.
11 11
 # -width Width of the annotation. The value should be an absolute unit. Width is not allowed to be set for column annotation.
12 12
 # -height Height of the annotation. The value should be an absolute unit. Height is not allowed to be set for row annotation.
13
+# -show_name Whether to show annotation name.
13 14
 #
14 15
 # == details
15 16
 # It creates an empty annotation and holds space, later users can add graphics
... ...
@@ -46,7 +47,7 @@
46 47
 # anno = anno_empty(border = FALSE)
47 48
 # draw(anno, test = "anno_empty without border")
48 49
 anno_empty = function(which = c("column", "row"), border = TRUE, zoom = FALSE,
49
-	width = NULL, height = NULL) {
50
+	width = NULL, height = NULL, show_name = FALSE) {
50 51
 	
51 52
 	if(is.null(.ENV$current_annotation_which)) {
52 53
 		which = match.arg(which)[1]
... ...
@@ -68,10 +69,10 @@ anno_empty = function(which = c("column", "row"), border = TRUE, zoom = FALSE,
68 69
 		which = which,
69 70
 		var_import = list(border, zoom),
70 71
 		subset_rule = list(),
71
-		subsetable = TRUE,
72
+		subsettable = TRUE,
72 73
 		height = anno_size$height,
73 74
 		width = anno_size$width,
74
-		show_name = FALSE
75
+		show_name = show_name
75 76
 	)
76 77
 	
77 78
 	return(anno) 
... ...
@@ -242,10 +243,15 @@ anno_simple = function(x, col, na_col = "grey",
242 243
 			pch = pch[index, , drop = FALSE]
243 244
 
244 245
 			for(i in seq_len(nc)) {
245
-				if(color_mapping@type == "continuous") {
246
+				if(color_mapping@type == "continuous" || !is.null(gp$col)) {
246 247
 				    fill = map_to_colors(color_mapping, value[index, i])
247
-				    if(is.null(gp$col)) gp$col = fill
248
+				    flag = 0
249
+	                if(is.null(gp$col)) {
250
+	                	gp$col = fill
251
+	                	flag = 1
252
+	                }
248 253
 				    grid.rect(x = (i-0.5)/nc, y, height = 1/n, width = 1/nc, gp = do.call("gpar", c(list(fill = fill), gp)))
254
+				    if(flag) gp$col = NULL
249 255
 				} else {
250 256
 					r = rle(value[index, i])
251 257
 					fill = map_to_colors(color_mapping, r$values)
... ...
@@ -269,7 +275,7 @@ anno_simple = function(x, col, na_col = "grey",
269 275
 			    }
270 276
 			}
271 277
 	    } else {
272
-	    	if(color_mapping@type == "continuous") {
278
+	    	if(color_mapping@type == "continuous" || !is.null(gp$col)) {
273 279
 				fill = map_to_colors(color_mapping, value[index])
274 280
 				if(is.null(gp$col)) gp$col = fill
275 281
 				grid.rect(x = 0.5, y, height = 1/n, width = 1, gp = do.call("gpar", c(list(fill = fill), gp)))
... ...
@@ -308,12 +314,16 @@ anno_simple = function(x, col, na_col = "grey",
308 314
 
309 315
             nc = ncol(value)
310 316
 		    pch = pch[index, , drop = FALSE]
311
-				  
312 317
 	        for(i in seq_len(nc)) {
313
-	        	if(color_mapping@type == "continuous") {
318
+	        	if(color_mapping@type == "continuous" || !is.null(gp$col)) {
314 319
 	                fill = map_to_colors(color_mapping, value[index, i])
315
-	                if(is.null(gp$col)) gp$col = fill
320
+	                flag = 0
321
+	                if(is.null(gp$col)) {
322
+	                	gp$col = fill
323
+	                	flag = 1
324
+	                }
316 325
 	                grid.rect(x, y = (nc-i +0.5)/nc, width = 1/n, height = 1/nc, gp = do.call("gpar", c(list(fill = fill), gp)))
326
+	                if(flag) gp$col = NULL
317 327
 	            } else {
318 328
 	            	r = rle(value[index, i])
319 329
 					fill = map_to_colors(color_mapping, r$values)
... ...
@@ -337,7 +347,7 @@ anno_simple = function(x, col, na_col = "grey",
337 347
 				}
338 348
 		    }
339 349
         } else {
340
-        	if(color_mapping@type == "continuous") {
350
+        	if(color_mapping@type == "continuous" || !is.null(gp$col)) {
341 351
 				fill = map_to_colors(color_mapping, value[index])
342 352
 				if(is.null(gp$col)) gp$col = fill
343 353
 				grid.rect(x, y = 0.5, width = 1/n, height = 1, gp = do.call("gpar", c(list(fill = fill), gp)))
... ...
@@ -400,7 +410,7 @@ anno_simple = function(x, col, na_col = "grey",
400 410
 		}
401 411
 	}
402 412
 
403
-	anno@subsetable = TRUE
413
+	anno@subsettable = TRUE
404 414
 
405 415
 	return(anno)      
406 416
 }
... ...
@@ -563,7 +573,13 @@ anno_image = function(image, which = c("column", "row"), border = TRUE,
563 573
 				grid.picture(image_list[[ index[i] ]], x = (i-0.5)/n, width = width, height = height)
564 574
 			}
565 575
 		}
566
-		if(border) grid.rect(gp = gpar(fill = "transparent"))
576
+		if(is.logical(border)) {
577
+			if(border) {
578
+				grid.rect(gp = gpar(fill = "transparent"))
579
+			}
580
+		} else {
581
+			grid.rect(gp = gpar(fill = "transparent", col = border))
582
+		}
567 583
 		popViewport()
568 584
 	}
569 585
 
... ...
@@ -592,7 +608,13 @@ anno_image = function(image, which = c("column", "row"), border = TRUE,
592 608
 				grid.picture(image_list[[ index[i] ]], y = (n - i + 0.5)/n, width = width, height = height)
593 609
 			}
594 610
 		}
595
-		if(border) grid.rect(gp = gpar(fill = "transparent"))
611
+		if(is.logical(border)) {
612
+			if(border) {
613
+				grid.rect(gp = gpar(fill = "transparent"))
614
+			}
615
+		} else {
616
+			grid.rect(gp = gpar(fill = "transparent", col = border))
617
+		}
596 618
 		popViewport()
597 619
 	}
598 620
 	
... ...
@@ -617,7 +639,7 @@ anno_image = function(image, which = c("column", "row"), border = TRUE,
617 639
 	anno@subset_rule$image_list = subset_vector
618 640
 	anno@subset_rule$image_class = subset_vector
619 641
 
620
-	anno@subsetable = TRUE
642
+	anno@subsettable = TRUE
621 643
 
622 644
 	return(anno)   
623 645
 }
... ...
@@ -914,7 +936,7 @@ anno_points = function(x, which = c("column", "row"), border = TRUE, gp = gpar()
914 936
 		anno@subset_rule$pch = subset_vector
915 937
 	}
916 938
 
917
-	anno@subsetable = TRUE
939
+	anno@subsettable = TRUE
918 940
 
919 941
 	anno@extended = update_anno_extend(anno, axis_grob, axis_param)
920 942
 		
... ...
@@ -1185,7 +1207,7 @@ anno_lines = function(x, which = c("column", "row"), border = TRUE, gp = gpar(),
1185 1207
 		anno@subset_rule$pch = subset_vector
1186 1208
 	}
1187 1209
 
1188
-	anno@subsetable = TRUE
1210
+	anno@subsettable = TRUE
1189 1211
 
1190 1212
 	anno@extended = update_anno_extend(anno, axis_grob, axis_param)
1191 1213
 		
... ...
@@ -1205,6 +1227,7 @@ anno_lines = function(x, which = c("column", "row"), border = TRUE, gp = gpar(),
1205 1227
 # -border Wether draw borders of the annotation region?
1206 1228
 # -bar_width Relative width of the bars. The value should be smaller than one.
1207 1229
 # -beside When ``x`` is a matrix, will bars be positioned beside each other or as stacked bars?
1230
+# -attach When ``beside`` is ``TRUE``, it controls whether bars should be attached.
1208 1231
 # -gp Graphic parameters for bars. The length of each graphic parameter can be 1, length of ``x`` if ``x``
1209 1232
 #     is a vector, or number of columns of ``x`` is ``x`` is a matrix.
1210 1233
 # -ylim Data ranges. By default it is ``range(x)`` if ``x`` is a vector, or ``range(rowSums(x))`` if ``x`` is a matrix.
... ...
@@ -1233,7 +1256,8 @@ anno_lines = function(x, which = c("column", "row"), border = TRUE, gp = gpar(),
1233 1256
 # m = t(apply(m, 1, function(x) x/sum(x)))
1234 1257
 # anno = anno_barplot(m, gp = gpar(fill = 2:5), bar_width = 1, height = unit(6, "cm"))
1235 1258
 # draw(anno, test = "proportion matrix")
1236
-anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TRUE, bar_width = 0.6, beside = FALSE,
1259
+anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TRUE, bar_width = 0.6, 
1260
+	beside = FALSE, attach = FALSE,
1237 1261
 	gp = gpar(fill = "#CCCCCC"), ylim = NULL, extend = 0.05, axis = TRUE, 
1238 1262
 	axis_param = default_axis_param(which), 
1239 1263
 	add_numbers = FALSE, numbers_gp = gpar(fontsize = 8), 
... ...
@@ -1375,13 +1399,23 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1375 1399
 				nr = nrow(value)
1376 1400
 				for(i in seq_along(index)) {
1377 1401
 			        for(j in 1:nbar) {
1378
-			        	if(axis_param$direction == "normal") {
1379
-				        	grid.rect(x = baseline, y = nr-i+0.5 + (j-0.5)/nbar, width = value[index[i], j], height = 1/nbar*bar_width, just = c("left"),
1380
-				        		default.units = "native", gp = subset_gp(gp, j))
1381
-				        } else {
1382
-				        	grid.rect(x = baseline, y = nr-i+0.5 + (j-0.5)/nbar, width = value[index[i], j], height = 1/nbar*bar_width, just = c("right"),
1383
-				        		default.units = "native", gp = subset_gp(gp, j))
1384
-				        }
1402
+			        	if(attach) {
1403
+			        		if(axis_param$direction == "normal") {
1404
+					        	grid.rect(x = baseline, y = nr-i+0.5 + (1-bar_width)/2 + (nbar - j + 0.5)/nbar*bar_width, width = value[index[i], j], height = 1/nbar*bar_width, just = c("left"),
1405
+					        		default.units = "native", gp = subset_gp(gp, j))
1406
+					        } else {
1407
+					        	grid.rect(x = baseline, y = nr-i+0.5 + (1-bar_width)/2 + (nbar - j + 0.5)/nbar*bar_width, width = value[index[i], j], height = 1/nbar*bar_width, just = c("right"),
1408
+					        		default.units = "native", gp = subset_gp(gp, j))
1409
+					        }
1410
+			        	} else {
1411
+				        	if(axis_param$direction == "normal") {
1412
+					        	grid.rect(x = baseline, y = nr-i+0.5 + (nbar - j + 0.5)/nbar, width = value[index[i], j], height = 1/nbar*bar_width, just = c("left"),
1413
+					        		default.units = "native", gp = subset_gp(gp, j))
1414
+					        } else {
1415
+					        	grid.rect(x = baseline, y = nr-i+0.5 + (nbar - j + 0.5)/nbar, width = value[index[i], j], height = 1/nbar*bar_width, just = c("right"),
1416
+					        		default.units = "native", gp = subset_gp(gp, j))
1417
+					        }
1418
+					    }
1385 1419
 			        }
1386 1420
 			    }
1387 1421
 			} else {
... ...
@@ -1440,13 +1474,23 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1440 1474
 				nr = nrow(value)
1441 1475
 				for(i in seq_along(index)) {
1442 1476
 			        for(j in 1:nbar) {
1443
-			        	if(axis_param$direction == "normal") {
1444
-				        	grid.rect(y = baseline, x = nr-i+0.5 + (j-0.5)/nbar, height = value[index[i], j], width = 1/nbar*bar_width, just = c("bottom"),
1445
-				        		default.units = "native", gp = subset_gp(gp, j))
1446
-				        } else {
1447
-				        	grid.rect(y = baseline, x = nr-i+0.5 + (j-0.5)/nbar, height = value[index[i], j], width = 1/nbar*bar_width, just = c("top"),
1448
-				        		default.units = "native", gp = subset_gp(gp, j))
1449
-				        }
1477
+			        	if(attach) {
1478
+				        	if(axis_param$direction == "normal") {
1479
+					        	grid.rect(y = baseline, x = i-0.5 + (1-bar_width)/2 + (j-0.5)/nbar*bar_width, height = value[index[i], j], width = 1/nbar*bar_width, just = c("bottom"),
1480
+					        		default.units = "native", gp = subset_gp(gp, j))
1481
+					        } else {
1482
+					        	grid.rect(y = baseline, x = i-0.5 + (1-bar_width)/2 + (j-0.5)/nbar*bar_width, height = value[index[i], j], width = 1/nbar*bar_width, just = c("top"),
1483
+					        		default.units = "native", gp = subset_gp(gp, j))
1484
+					        }
1485
+					    } else {
1486
+					    	if(axis_param$direction == "normal") {
1487
+					        	grid.rect(y = baseline, x = i-0.5 + (j-0.5)/nbar, height = value[index[i], j], width = 1/nbar*bar_width, just = c("bottom"),
1488
+					        		default.units = "native", gp = subset_gp(gp, j))
1489
+					        } else {
1490
+					        	grid.rect(y = baseline, x = i-0.5 + (j-0.5)/nbar, height = value[index[i], j], width = 1/nbar*bar_width, just = c("top"),
1491
+					        		default.units = "native", gp = subset_gp(gp, j))
1492
+					        }
1493
+					    }
1450 1494
 			        }
1451 1495
 			    }
1452 1496
 			} else {
... ...
@@ -1489,7 +1533,7 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1489 1533
 		height = anno_size$height,
1490 1534
 		n = n,
1491 1535
 		data_scale = data_scale,
1492
-		var_import = list(value, gp, border, bar_width, baseline, beside, axis, axis_param, axis_grob, data_scale, add_numbers, numbers_gp, numbers_offset, numbers_rot)
1536
+		var_import = list(value, gp, border, bar_width, baseline, beside, attach, axis, axis_param, axis_grob, data_scale, add_numbers, numbers_gp, numbers_offset, numbers_rot)
1493 1537
 	)
1494 1538
 
1495 1539
 	anno@subset_rule$value = subset_matrix_by_row
... ...
@@ -1497,7 +1541,7 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1497 1541
 		anno@subset_rule$gp = subset_gp
1498 1542
 	}
1499 1543
 		
1500
-	anno@subsetable = TRUE
1544
+	anno@subsettable = TRUE
1501 1545
 
1502 1546
 	anno@extended = update_anno_extend(anno, axis_grob, axis_param)
1503 1547
 
... ...
@@ -1734,7 +1778,7 @@ anno_boxplot = function(x, which = c("column", "row"), border = TRUE,
1734 1778
 	anno@subset_rule$pch = subset_vector
1735 1779
 	anno@subset_rule$size = subset_vector
1736 1780
 	
1737
-	anno@subsetable = TRUE
1781
+	anno@subsettable = TRUE
1738 1782
 
1739 1783
 	anno@extended = update_anno_extend(anno, axis_grob, axis_param)
1740 1784
 
... ...
@@ -1897,7 +1941,7 @@ anno_histogram = function(x, which = c("column", "row"), n_breaks = 11,
1897 1941
 	anno@subset_rule$histogram_breaks = subset_vector
1898 1942
 	anno@subset_rule$histogram_counts = subset_vector
1899 1943
 	
1900
-	anno@subsetable = TRUE
1944
+	anno@subsettable = TRUE
1901 1945
 
1902 1946
 	anno@extended = update_anno_extend(anno, axis_grob, axis_param)
1903 1947
 
... ...
@@ -2176,7 +2220,7 @@ anno_density = function(x, which = c("column", "row"),
2176 2220
 	anno@subset_rule$density_x = subset_vector
2177 2221
 	anno@subset_rule$density_y = subset_vector
2178 2222
 	
2179
-	anno@subsetable = TRUE
2223
+	anno@subsettable = TRUE
2180 2224
 
2181 2225
 	anno@extended = update_anno_extend(anno, axis_grob, axis_param)
2182 2226
 
... ...
@@ -2360,7 +2404,7 @@ anno_text = function(x, which = c("column", "row"), gp = gpar(),
2360 2404
 	anno@subset_rule$value = subset_vector
2361 2405
 	anno@subset_rule$gp = subset_gp
2362 2406
 
2363
-	anno@subsetable = TRUE
2407
+	anno@subsettable = TRUE
2364 2408
 
2365 2409
 	return(anno)
2366 2410
 }
... ...
@@ -2549,7 +2593,7 @@ anno_joyplot = function(x, which = c("column", "row"), gp = gpar(fill = "#000000
2549 2593
 	anno@subset_rule$value = subset_vector
2550 2594
 	anno@subset_rule$gp = subset_gp
2551 2595
 
2552
-	anno@subsetable = TRUE
2596
+	anno@subsettable = TRUE
2553 2597
 
2554 2598
 	anno@extended = update_anno_extend(anno, axis_grob, axis_param)
2555 2599
 
... ...
@@ -2733,7 +2777,7 @@ anno_horizon = function(x, which = c("column", "row"),
2733 2777
 	anno@subset_rule$value = subset_vector
2734 2778
 	anno@subset_rule$gp = subset_gp
2735 2779
 
2736
-	anno@subsetable = TRUE
2780
+	anno@subsettable = TRUE
2737 2781
 
2738 2782
 	anno@extended = update_anno_extend(anno, axis_grob, axis_param)
2739 2783
 
... ...
@@ -3220,7 +3264,7 @@ anno_mark = function(at, labels, which = c("column", "row"),
3220 3264
 
3221 3265
 	anno@subset_rule$at = subset_by_intersect
3222 3266
 
3223
-	anno@subsetable = TRUE
3267
+	anno@subsettable = TRUE
3224 3268
 
3225 3269
 	attr(anno, "called_args") = list(
3226 3270
 		at = at, 
... ...
@@ -3427,7 +3471,7 @@ anno_summary = function(which = c("column", "row"), border = TRUE, bar_width = 0
3427 3471
 		show_name = FALSE
3428 3472
 	)
3429 3473
 
3430
-	anno@subsetable = FALSE
3474
+	anno@subsettable = FALSE
3431 3475
 	anno@extended = update_anno_extend(anno, axis_grob, axis_param)
3432 3476
 
3433 3477
 	return(anno)
... ...
@@ -3437,6 +3481,8 @@ anno_summary = function(which = c("column", "row"), border = TRUE, bar_width = 0
3437 3481
 # Block annotation
3438 3482
 #
3439 3483
 # == param
3484
+# -align_to If you don't want to create block annotation for all slices, you can specify a list of indices that cover continuously adjacent
3485
+#        rows or columns.
3440 3486
 # -gp Graphic parameters.
3441 3487
 # -labels Labels put on blocks.
3442 3488
 # -labels_gp Graphic parameters for labels.
... ...
@@ -3447,7 +3493,7 @@ anno_summary = function(which = c("column", "row"), border = TRUE, bar_width = 0
3447 3493
 # -width Width of the annotation. The value should be an absolute unit. Width is not allowed to be set for column annotation.
3448 3494
 # -height Height of the annotation. The value should be an absolute unit. Height is not allowed to be set for row annotation.
3449 3495
 # -show_name Whether show annotatio name.
3450
-# -graphics A self-defined function that draws graphics in each slice. It must have two arguments: 1. row/column indices for the 
3496
+# -panel_fun A self-defined function that draws graphics in each slice. It must have two arguments: 1. row/column indices for the 
3451 3497
 #      current slice and 2. a vector of levels from the split variable that correspond to current slice. When ``graphics`` is set,
3452 3498
 #      all other graphics parameters in `anno_block` are ignored.
3453 3499
 #
... ...
@@ -3470,11 +3516,11 @@ anno_summary = function(which = c("column", "row"), border = TRUE, bar_width = 0
3470 3516
 #     row_km = 3)
3471 3517
 #
3472 3518
 #
3473
-# # =============  set the graphics argument ==============
3519
+# # =============  set the panel_fun argument ==============
3474 3520
 # col = c("1" = "red", "2" = "blue", "A" = "green", "B" = "orange")
3475 3521
 # Heatmap(matrix(rnorm(100), 10), row_km = 2, row_split = sample(c("A", "B"), 10, replace = TRUE)) + 
3476 3522
 # rowAnnotation(foo = anno_block(
3477
-# 	graphics = function(index, levels) {
3523
+# 	panel_fun = function(index, levels) {
3478 3524
 # 		grid.rect(gp = gpar(fill = col[levels[2]], col = "black"))
3479 3525
 # 		grid.text(paste(levels, collapse = ","), 0.5, 0.5, rot = 90,
3480 3526
 # 			gp = gpar(col = col[levels[1]]))
... ...
@@ -3483,7 +3529,7 @@ anno_summary = function(which = c("column", "row"), border = TRUE, bar_width = 0
3483 3529
 #
3484 3530
 # labels = c("1" = "one", "2" = "two", "A" = "Group_A", "B" = "Group_B")
3485 3531
 # Heatmap(matrix(rnorm(100), 10), row_km = 2, row_split = sample(c("A", "B"), 10, replace = TRUE)) + 
3486
-# rowAnnotation(foo = anno_block(graphics = function(index, levels) {
3532
+# rowAnnotation(foo = anno_block(panel_fun = function(index, levels) {
3487 3533
 # 	grid.rect(gp = gpar(fill = col[levels[2]], col = "black"))
3488 3534
 # 	grid.text(paste(labels[levels], collapse = ","), 0.5, 0.5, rot = 90,
3489 3535
 # 		gp = gpar(col = col[levels[1]]))
... ...
@@ -3491,7 +3537,7 @@ anno_summary = function(which = c("column", "row"), border = TRUE, bar_width = 0
3491 3537
 #
3492 3538
 # Heatmap(matrix(rnorm(100), 10), row_km = 2, row_split = sample(c("A", "B"), 10, replace = TRUE)) + 
3493 3539
 # rowAnnotation(foo = anno_block(
3494
-# 	graphics = function(index, levels) {
3540
+# 	panel_fun = function(index, levels) {
3495 3541
 # 		grid.rect(gp = gpar(fill = col[levels[2]], col = "black"))
3496 3542
 # 		txt = paste(levels, collapse = ",")
3497 3543
 # 		txt = paste0(txt, "\n", length(index), " rows")
... ...
@@ -3501,17 +3547,40 @@ anno_summary = function(which = c("column", "row"), border = TRUE, bar_width = 0
3501 3547
 # 	width = unit(3, "cm")
3502 3548
 # ))
3503 3549
 #
3504
-anno_block = function(gp = gpar(), labels = NULL, labels_gp = gpar(), 
3550
+# # =========== set align_to ################
3551
+# col = c("foo" = "red", "bar" = "blue")
3552
+# Heatmap(matrix(rnorm(100), 10), cluster_rows = FALSE) +
3553
+# rowAnnotation(foo = anno_block(
3554
+# 	align_to = list(foo = 1:4, bar = 6:10),
3555
+# 	panel_fun = function(index, nm) {
3556
+# 		grid.rect(gp = gpar(fill = col[nm]))
3557
+# 		grid.text(nm, 0.5, 0.5)
3558
+# 	},
3559
+# 	width = unit(2, "cm"))
3560
+# )
3561
+anno_block = function(align_to = NULL, gp = gpar(), labels = NULL, labels_gp = gpar(), 
3505 3562
 	labels_rot = ifelse(which == "row", 90, 0),
3506 3563
 	labels_offset = unit(0.5, "npc"), labels_just = "center",
3507 3564
 	which = c("column", "row"), width = NULL, height = NULL, show_name = FALSE,
3508
-	graphics = NULL) {
3565
+	panel_fun = NULL) {
3509 3566
 
3510 3567
 	if(is.null(.ENV$current_annotation_which)) {
3511 3568
 		which = match.arg(which)[1]
3512 3569
 	} else {
3513 3570
 		which = .ENV$current_annotation_which
3514 3571
 	}
3572
+	if(!is.null(align_to)) {
3573
+		if(is.numeric(align_to)) {
3574
+			align_to = list(v = align_to)
3575
+		}
3576
+		if(!is.list(align_to)) {
3577
+			stop_wrap("`align_to` should be a list.")
3578
+		}
3579
+		if(is.null(names(align_to))) {
3580
+			stop_wrap("`align_to` should be a named list.")
3581
+		}
3582
+	}
3583
+
3515 3584
 	if(length(labels)) {
3516 3585
 		if(which == "column") {
3517 3586
 			if(missing(height)) {
... ...
@@ -3534,10 +3603,40 @@ anno_block = function(gp = gpar(), labels = NULL, labels_gp = gpar(),
3534 3603
 		}
3535 3604
 	}
3536 3605
 
3606
+	if(!is.null(panel_fun)) {
3607
+		if(length(as.list(formals(panel_fun))) == 1) {
3608
+	 		formals(panel_fun) = alist(index = , nm = NULL)
3609
+		}
3610
+	}
3611
+
3537 3612
 	anno_size = anno_width_and_height(which, width, height, unit(5, "mm"))
3538 3613
 	
3539 3614
 	fun = function(index, k, n) {
3540
-		if(is.null(graphics)) {
3615
+		if(!is.null(align_to)) {
3616
+			is_in = sapply(align_to, function(x) any(x %in% index))
3617
+			
3618
+			ind_aln = which(is_in)
3619
+
3620
+			for(ai in ind_aln) {
3621
+				ind = which(index %in% align_to[[ai]])
3622
+				if(any(diff(ind) > 1)) {
3623
+					stop_wrap("Indices in `align_to` should be continuously adjacent in the heatmap.")
3624
+				}
3625
+
3626
+				ni = length(index)
3627
+
3628
+				if(which == "row") {
3629
+					pushViewport(viewport(y = (ni - ind[length(ind)])/ni, height = length(ind)/ni, default.units = "npc", just = "bottom"))
3630
+					panel_fun(index[ind], names(align_to)[ai])
3631
+					popViewport()
3632
+				} else {
3633
+					pushViewport(viewport(x = (ind[length(ind)])/ni, width = length(ind)/ni, default.units = "npc", just = "right"))
3634
+					panel_fun(index[ind], names(align_to)[ai])
3635
+					popViewport()
3636
+				}
3637
+			}
3638
+
3639
+		} else if(is.null(panel_fun)) {
3541 3640
 			gp = subset_gp(recycle_gp(gp, n), k)
3542 3641
 			grid.rect(gp = gp)
3543 3642
 			if(length(labels)) {
... ...
@@ -3551,7 +3650,7 @@ anno_block = function(gp = gpar(), labels = NULL, labels_gp = gpar(),
3551 3650
 				if(which == "row") x = labels_offset
3552 3651
 				grid.text(label, x = x, y = y, gp = labels_gp, rot = labels_rot, just = labels_just)
3553 3652
 			}
3554
-		} else {
3653
+		} else  {
3555 3654