Browse code

axis labels are automatical formatted for genomic coordinates

Zuguang Gu authored on 03/08/2021 21:05:45
Showing3 changed files

... ...
@@ -8,6 +8,7 @@ CHANGES in VERSION 2.9.3
8 8
 * discrete annotations: neighbour grids are merged into one single grid if they have the 
9 9
   same values.
10 10
 * `anno_barplot()`: allows to add numbers on top of bars.
11
+* `UpSet()`: axis labels are automatically formated for genomic coordinates.
11 12
 
12 13
 =========================
13 14
 
... ...
@@ -665,7 +665,7 @@ validate_axis_param = function(axis_param, which) {
665 665
 	return(dft)
666 666
 }
667 667
 
668
-construct_axis_grob = function(axis_param, which, data_scale) {
668
+construct_axis_grob = function(axis_param, which, data_scale, format = NULL) {
669 669
 	axis_param_default = default_axis_param(which)
670 670
 
671 671
 	for(nm in setdiff(names(axis_param_default), names(axis_param))) {
... ...
@@ -675,13 +675,20 @@ construct_axis_grob = function(axis_param, which, data_scale) {
675 675
 	if(is.null(axis_param$at)) {
676 676
 		at = pretty_breaks(data_scale)
677 677
 		axis_param$at = at
678
-		axis_param$labels = at
678
+		if(is.null(format)) {
679
+			axis_param$labels = at
680
+		} else {
681
+			axis_param$labels = format(at)
682
+		}
679 683
 	}
680 684
 
681 685
 	if(is.null(axis_param$labels)) {
682
-		axis_param$labels = axis_param$at
686
+		if(is.null(format)) {
687
+			axis_param$labels = axis_param$at
688
+		} else {
689
+			axis_param$labels = format(axis_param$at)
690
+		}
683 691
 	}
684
-
685 692
 	axis_param$scale = data_scale
686 693
 	axis_grob = do.call(annotation_axis_grob, axis_param)
687 694
 	return(axis_grob)
... ...
@@ -1239,6 +1246,8 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1239 1246
 			stop_wrap("Since `x` is a matrix, the sign of each row should be either all positive or all negative.")
1240 1247
 		}
1241 1248
 	}
1249
+
1250
+	labels_format = attr(x, "labels_format")
1242 1251
 	# convert everything to matrix
1243 1252
 	if(is.null(dim(x))) x = matrix(x, ncol = 1)
1244 1253
 	nc = ncol(x)
... ...
@@ -1288,6 +1297,7 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1288 1297
 	}
1289 1298
 
1290 1299
 	value = x
1300
+	attr(value, "labels_format") = labels_format
1291 1301
 
1292 1302
 	if(ncol(value) == 1) {
1293 1303
 		if(add_numbers) {
... ...
@@ -1302,7 +1312,7 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1302 1312
 	}
1303 1313
 
1304 1314
 	axis_param = validate_axis_param(axis_param, which)
1305
-	axis_grob = if(axis) construct_axis_grob(axis_param, which, data_scale) else NULL
1315
+	axis_grob = if(axis) construct_axis_grob(axis_param, which, data_scale, format = labels_format) else NULL
1306 1316
 
1307 1317
 	row_fun = function(index, k = 1, N = 1) {
1308 1318
 		n = length(index)
... ...
@@ -1320,9 +1330,17 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1320 1330
 			grid.rect(x = x_coor, y = n - seq_along(index) + 1, width = abs(width), height = 1*bar_width, default.units = "native", gp = subset_gp(gp, index))
1321 1331
 			if(add_numbers) {
1322 1332
 				if(axis_param$direction == "normal") {
1323
-					grid.text(value[index], x = unit(baseline + width, "native") + numbers_offset, y = n - seq_along(index) + 1, default.units = "native", gp = subset_gp(numbers_gp, index), just = c("left"), rot = numbers_rot)
1333
+					txt = value[index]
1334
+					if(!is.null(attr(value, "labels_format"))) {
1335
+						txt = attr(value, "labels_format")(value[index])
1336
+					}
1337
+					grid.text(txt, x = unit(baseline + width, "native") + numbers_offset, y = n - seq_along(index) + 1, default.units = "native", gp = subset_gp(numbers_gp, index), just = c("left"), rot = numbers_rot)
1324 1338
 				} else {
1325
-					grid.text(value_origin[index], x = unit(baseline + width, "native") - numbers_offset, y = n - seq_along(index) + 1, default.units = "native", gp = subset_gp(numbers_gp, index), just = c("right"), rot = numbers_rot)
1339
+					txt = value_origin[index]
1340
+					if(!is.null(attr(value, "labels_format"))) {
1341
+						txt = attr(value, "labels_format")(value[index])
1342
+					}
1343
+					grid.text(txt, x = unit(baseline + width, "native") - numbers_offset, y = n - seq_along(index) + 1, default.units = "native", gp = subset_gp(numbers_gp, index), just = c("right"), rot = numbers_rot)
1326 1344
 				}
1327 1345
 			}
1328 1346
 		} else {
... ...
@@ -1363,7 +1381,11 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR
1363 1381
 			y_coor = height/2+baseline
1364 1382
 			grid.rect(y = y_coor, x = seq_along(index), height = abs(height), width = 1*bar_width, default.units = "native", gp = subset_gp(gp, index))
1365 1383
 			if(add_numbers) {
1366
-				grid.text(value[index], x = seq_along(index), y = unit(baseline + height, "native") + numbers_offset, default.units = "native", gp = subset_gp(numbers_gp, index), just = c("left"), rot = numbers_rot)
1384
+				txt = value[index]
1385
+				if(!is.null(attr(value, "labels_format"))) {
1386
+					txt = attr(value, "labels_format")(value[index])
1387
+				}
1388
+				grid.text(txt, x = seq_along(index), y = unit(baseline + height, "native") + numbers_offset, default.units = "native", gp = subset_gp(numbers_gp, index), just = c("left"), rot = numbers_rot)
1367 1389
 			}
1368 1390
 		} else {
1369 1391
 			for(i in seq_len(ncol(value))) {
... ...
@@ -1484,6 +1484,24 @@ UpSet = function(m,
1484 1484
 	ht
1485 1485
 }
1486 1486
 
1487
+format_genomic_coor = function(x) {
1488
+	x2 = character(length(x))
1489
+	l1 = x >= 1e6
1490
+	x2[l1] = paste(x[l1]/1000000, "MB", sep = " ")
1491
+	l2 = x >= 1e3 & !l1
1492
+	x2[l2] = paste(x[l2]/1000, "KB", sep = " ")
1493
+	
1494
+	l3 = !(l1 | l2)
1495
+	last_unit = "bp"
1496
+	if(all(l1 | x == 0)) {
1497
+		last_unit = "MB"
1498
+	} else if(all(l1 | l2 | x == 0)) {
1499
+		last_unit = "KB"
1500
+	}
1501
+	x2[l3] = paste(x[l3], last_unit, sep = " ")
1502
+	gsub("\\.(\\d\\d)\\d*", "\\.\\1", x2)
1503
+}
1504
+
1487 1505
 # == title
1488 1506
 # Order of the Combination Sets
1489 1507
 #
... ...
@@ -1552,9 +1570,12 @@ upset_top_annotation = function(m,
1552 1570
 	...) {
1553 1571
 
1554 1572
 	set_on_rows = attr(m, "param")$set_on_rows
1555
-	
1556 1573
 	if(set_on_rows) {
1557
-		ha = HeatmapAnnotation("intersection_size" = anno_barplot(comb_size(m), 
1574
+		x = comb_size(m)
1575
+		if(inherits(attr(m, "data")[[1]], "GRanges")) {
1576
+			attr(x, "labels_format") = format_genomic_coor
1577
+		}
1578
+		ha = HeatmapAnnotation("intersection_size" = anno_barplot(x, 
1558 1579
 					border = FALSE, gp = gp, height = height, ...), 
1559 1580
 				show_annotation_name = show_annotation_name,
1560 1581
 				annotation_name_gp = annotation_name_gp,
... ...
@@ -1563,7 +1584,11 @@ upset_top_annotation = function(m,
1563 1584
 				annotation_name_rot = annotation_name_rot,
1564 1585
 				annotation_label = "Intersection\nsize")
1565 1586
 	} else {
1566
-		ha = HeatmapAnnotation("set_size" = anno_barplot(set_size(m), border = FALSE, 
1587
+		x = set_size(m)
1588
+		if(inherits(attr(m, "data")[[1]], "GRanges")) {
1589
+			attr(x, "labels_format") = format_genomic_coor
1590
+		}
1591
+		ha = HeatmapAnnotation("set_size" = anno_barplot(x, border = FALSE, 
1567 1592
 					gp = gp, height = height, ...),
1568 1593
 				show_annotation_name = show_annotation_name,
1569 1594
 				annotation_name_gp = annotation_name_gp,
... ...
@@ -1620,7 +1645,11 @@ upset_right_annotation = function(m,
1620 1645
 	set_on_rows = attr(m, "param")$set_on_rows
1621 1646
 
1622 1647
 	if(set_on_rows) {
1623
-		ha = rowAnnotation("set_size" = anno_barplot(set_size(m), border = FALSE, 
1648
+		x = set_size(m)
1649
+		if(inherits(attr(m, "data")[[1]], "GRanges")) {
1650
+			attr(x, "labels_format") = format_genomic_coor
1651
+		}
1652
+		ha = rowAnnotation("set_size" = anno_barplot(x, border = FALSE, 
1624 1653
 					gp = gp, width = width, ...),
1625 1654
 				show_annotation_name = show_annotation_name,
1626 1655
 				annotation_name_gp = annotation_name_gp,
... ...
@@ -1629,7 +1658,11 @@ upset_right_annotation = function(m,
1629 1658
 				annotation_name_rot = annotation_name_rot,
1630 1659
 				annotation_label = "Set size")
1631 1660
 	} else {
1632
-		ha = rowAnnotation("intersection_size" = anno_barplot(comb_size(m), 
1661
+		x = comb_size(m)
1662
+		if(inherits(attr(m, "data")[[1]], "GRanges")) {
1663
+			attr(x, "labels_format") = format_genomic_coor
1664
+		}
1665
+		ha = rowAnnotation("intersection_size" = anno_barplot(x, 
1633 1666
 					border = FALSE, gp = gp, width = width, ...),
1634 1667
 				show_annotation_name = show_annotation_name,
1635 1668
 				annotation_name_gp = annotation_name_gp,
... ...
@@ -1684,7 +1717,11 @@ upset_left_annotation = function(m,
1684 1717
 	}
1685 1718
 
1686 1719
 	if(set_on_rows) {
1687
-		ha = rowAnnotation("set_size" = anno_barplot(set_size(m), border = FALSE, 
1720
+		x = set_size(m)
1721
+		if(inherits(attr(m, "data")[[1]], "GRanges")) {
1722
+			attr(x, "labels_format") = format_genomic_coor
1723
+		}
1724
+		ha = rowAnnotation("set_size" = anno_barplot(x, border = FALSE, 
1688 1725
 					gp = gp, width = width, axis_param = axis_param, ...),
1689 1726
 				show_annotation_name = show_annotation_name,
1690 1727
 				annotation_name_gp = annotation_name_gp,
... ...
@@ -1693,7 +1730,11 @@ upset_left_annotation = function(m,
1693 1730
 				annotation_name_rot = annotation_name_rot,
1694 1731
 				annotation_label = "Set size")
1695 1732
 	} else {
1696
-		ha = rowAnnotation("intersection_size" = anno_barplot(comb_size(m), 
1733
+		x = comb_size(m)
1734
+		if(inherits(attr(m, "data")[[1]], "GRanges")) {
1735
+			attr(x, "labels_format") = format_genomic_coor
1736
+		}
1737
+		ha = rowAnnotation("intersection_size" = anno_barplot(x, 
1697 1738
 					border = FALSE, gp = gp, width = width, axis_param = axis_param, ...),
1698 1739
 				show_annotation_name = show_annotation_name,
1699 1740
 				annotation_name_gp = annotation_name_gp,