From 2bc989ef6464ab7d0291173ac43b2ae7a8458032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arion=20F=C3=B6rtsch?= <68943888+foertsch@users.noreply.github.com> Date: Mon, 23 Mar 2026 15:16:57 +0100 Subject: [PATCH 1/2] Respect explicit ylim in anno_barplot with add_numbers Fixes #1248 --- R/AnnotationFunction-function.R | 35 +++++++++++++++---- ...AnnotationFunction-barplot-explicit-ylim.R | 33 +++++++++++++++++ 2 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 tests/testthat/testthat-AnnotationFunction-barplot-explicit-ylim.R diff --git a/R/AnnotationFunction-function.R b/R/AnnotationFunction-function.R index 3158e51..6a8f15f 100644 --- a/R/AnnotationFunction-function.R +++ b/R/AnnotationFunction-function.R @@ -1370,18 +1370,25 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR value = x attr(value, "labels_format") = labels_format + number_extension = unit(0, "mm") if(ncol(value) == 1) { if(add_numbers) { if(which == "column") { if(numbers_rot == 0) { - extend = convertHeight(max_text_height(value, gp = numbers_gp) + numbers_offset + unit(2, "mm"), "mm", valueOnly = TRUE)/convertHeight(anno_size$height, "mm", valueOnly = TRUE)*(data_scale[2] - data_scale[1]) + number_extension = max_text_height(value, gp = numbers_gp) + numbers_offset + unit(2, "mm") } else { - extend = convertHeight(sin(numbers_rot/180*pi)*max_text_width(value, gp = numbers_gp) + numbers_offset + unit(4, "mm"), "mm", valueOnly = TRUE)/convertHeight(anno_size$height, "mm", valueOnly = TRUE)*(data_scale[2] - data_scale[1]) + number_extension = sin(numbers_rot/180*pi)*max_text_width(value, gp = numbers_gp) + numbers_offset + unit(4, "mm") } - data_scale[2] = data_scale[2] + extend } else if(which == "row") { - extend = convertWidth(cos(numbers_rot/180*pi)*max_text_width(value, gp = numbers_gp) + numbers_offset + unit(4, "mm"), "mm", valueOnly = TRUE)/convertWidth(anno_size$width, "mm", valueOnly = TRUE)*(data_scale[2] - data_scale[1]) + number_extension = cos(numbers_rot/180*pi)*max_text_width(value, gp = numbers_gp) + numbers_offset + unit(4, "mm") + } + if(is.null(ylim)) { + if(which == "column") { + extend = convertHeight(number_extension, "mm", valueOnly = TRUE)/convertHeight(anno_size$height, "mm", valueOnly = TRUE)*(data_scale[2] - data_scale[1]) + } else if(which == "row") { + extend = convertWidth(number_extension, "mm", valueOnly = TRUE)/convertWidth(anno_size$width, "mm", valueOnly = TRUE)*(data_scale[2] - data_scale[1]) + } data_scale[2] = data_scale[2] + extend } } @@ -1588,10 +1595,27 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR if(ncol(value) == 1) { anno@subset_rule$gp = subset_gp } - + anno@subsettable = TRUE anno@extended = update_anno_extend(anno, axis_grob, axis_param) + if(!is.null(ylim) && add_numbers && ncol(value) == 1) { + if(which == "column") { + number_extension = convertHeight(number_extension, "mm") + if(axis_param$direction == "normal") { + anno@extended[3] = anno@extended[3] + number_extension + } else { + anno@extended[1] = anno@extended[1] + number_extension + } + } else { + number_extension = convertWidth(number_extension, "mm") + if(axis_param$direction == "normal") { + anno@extended[4] = anno@extended[4] + number_extension + } else { + anno@extended[2] = anno@extended[2] + number_extension + } + } + } return(anno) } @@ -4548,4 +4572,3 @@ anno_numeric = function(x, rg = range(x), labels_gp = gpar(), x_convert = NULL, width = width ) } - diff --git a/tests/testthat/testthat-AnnotationFunction-barplot-explicit-ylim.R b/tests/testthat/testthat-AnnotationFunction-barplot-explicit-ylim.R new file mode 100644 index 0000000..7aec6df --- /dev/null +++ b/tests/testthat/testthat-AnnotationFunction-barplot-explicit-ylim.R @@ -0,0 +1,33 @@ +test_that("anno_barplot keeps explicit ylim when numbers are added", { + anno_normal_without_numbers = anno_barplot(1:10, + add_numbers = FALSE, + ylim = c(0, 8), + height = unit(2, "cm")) + anno_normal_with_numbers = anno_barplot(1:10, + add_numbers = TRUE, + ylim = c(0, 8), + height = unit(2, "cm")) + + expect_equal(anno_normal_with_numbers@data_scale, anno_normal_without_numbers@data_scale) + expect_gt( + convertHeight(anno_normal_with_numbers@extended[3], "mm", valueOnly = TRUE), + convertHeight(anno_normal_without_numbers@extended[3], "mm", valueOnly = TRUE) + ) + + anno_reverse_without_numbers = anno_barplot(1:10, + add_numbers = FALSE, + ylim = c(0, 8), + height = unit(2, "cm"), + axis_param = list(direction = "reverse")) + anno_reverse_with_numbers = anno_barplot(1:10, + add_numbers = TRUE, + ylim = c(0, 8), + height = unit(2, "cm"), + axis_param = list(direction = "reverse")) + + expect_equal(anno_reverse_with_numbers@data_scale, anno_reverse_without_numbers@data_scale) + expect_gt( + convertHeight(anno_reverse_with_numbers@extended[1], "mm", valueOnly = TRUE), + convertHeight(anno_reverse_without_numbers@extended[1], "mm", valueOnly = TRUE) + ) +}) From f74fdda15f1711a14db121321ded4b3f8b3b02b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arion=20F=C3=B6rtsch?= <68943888+foertsch@users.noreply.github.com> Date: Mon, 23 Mar 2026 15:18:28 +0100 Subject: [PATCH 2/2] Fix reverse anno_barplot number spacing and labels Fixes #1247 --- R/AnnotationFunction-function.R | 12 ++++++++---- ...testthat-AnnotationFunction-barplot-reverse.R | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 tests/testthat/testthat-AnnotationFunction-barplot-reverse.R diff --git a/R/AnnotationFunction-function.R b/R/AnnotationFunction-function.R index 6a8f15f..30536b0 100644 --- a/R/AnnotationFunction-function.R +++ b/R/AnnotationFunction-function.R @@ -1371,6 +1371,7 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR value = x attr(value, "labels_format") = labels_format number_extension = unit(0, "mm") + axis_param = validate_axis_param(axis_param, which) if(ncol(value) == 1) { if(add_numbers) { @@ -1383,7 +1384,7 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR } else if(which == "row") { number_extension = cos(numbers_rot/180*pi)*max_text_width(value, gp = numbers_gp) + numbers_offset + unit(4, "mm") } - if(is.null(ylim)) { + if(is.null(ylim) && axis_param$direction == "normal") { if(which == "column") { extend = convertHeight(number_extension, "mm", valueOnly = TRUE)/convertHeight(anno_size$height, "mm", valueOnly = TRUE)*(data_scale[2] - data_scale[1]) } else if(which == "row") { @@ -1394,7 +1395,6 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR } } - axis_param = validate_axis_param(axis_param, which) axis_grob = if(axis) construct_axis_grob(axis_param, which, data_scale, format = labels_format) else NULL row_fun = function(index, k = 1, N = 1) { @@ -1506,7 +1506,11 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR if(add_numbers) { txt = value_origin[index] if(!is.null(attr(value, "labels_format"))) { - txt = attr(value, "labels_format")(value[index]) + if(axis_param$direction == "normal") { + txt = attr(value, "labels_format")(value[index]) + } else { + txt = attr(value, "labels_format")(value_origin[index]) + } } numbers_rot = numbers_rot %% 360 if(axis_param$direction == "normal") { @@ -1599,7 +1603,7 @@ anno_barplot = function(x, baseline = 0, which = c("column", "row"), border = TR anno@subsettable = TRUE anno@extended = update_anno_extend(anno, axis_grob, axis_param) - if(!is.null(ylim) && add_numbers && ncol(value) == 1) { + if(add_numbers && ncol(value) == 1 && (!is.null(ylim) || axis_param$direction == "reverse")) { if(which == "column") { number_extension = convertHeight(number_extension, "mm") if(axis_param$direction == "normal") { diff --git a/tests/testthat/testthat-AnnotationFunction-barplot-reverse.R b/tests/testthat/testthat-AnnotationFunction-barplot-reverse.R new file mode 100644 index 0000000..2065ca5 --- /dev/null +++ b/tests/testthat/testthat-AnnotationFunction-barplot-reverse.R @@ -0,0 +1,16 @@ +test_that("anno_barplot reverse numbers do not expand scale", { + anno_reverse_without_numbers = anno_barplot(1:10, + add_numbers = FALSE, + height = unit(2, "cm"), + axis_param = list(direction = "reverse")) + anno_reverse_with_numbers = anno_barplot(1:10, + add_numbers = TRUE, + height = unit(2, "cm"), + axis_param = list(direction = "reverse")) + + expect_equal(anno_reverse_with_numbers@data_scale, anno_reverse_without_numbers@data_scale) + expect_gt( + convertHeight(anno_reverse_with_numbers@extended[1], "mm", valueOnly = TRUE), + convertHeight(anno_reverse_without_numbers@extended[1], "mm", valueOnly = TRUE) + ) +})