Skip to content

Commit

Permalink
add .discrete_x and .discrete_y in the ggplot2 data
Browse files Browse the repository at this point in the history
  • Loading branch information
Yunuuuu committed Dec 11, 2024
1 parent cd234ea commit 8377a64
Show file tree
Hide file tree
Showing 14 changed files with 98 additions and 83 deletions.
50 changes: 27 additions & 23 deletions R/align-gg.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,20 @@
#' layout (including left and right annotation) and `aes(x = .data$.x)`
#' for vertical stack layout (including top and bottom annotation).
#'
#' `matrix` input will be automatically melted into a long foramted data frame.
#'
#' Atomic vector will be put in the `value` column of the data frame.
#'
#' In the case where the input data is already a data frame, 4 additional
#' columns (`.x`/`.y`, `.names`, `.index`, and `.panel`) are added to the data
#' frame.
#'
#' The data in the underlying `ggplot` object will contain following columns:
#'
#' - `.panel`: the panel for the aligned axis. It means `x-axis` for vertical
#' stack layout (including top and bottom annotation), `y-axis` for
#' horizontal stack layout (including left and right annotation).
#'
#' - `.x` or `.y`: the `x` or `y` coordinates
#' - `.x`/`y` and `.discrete_x`/`.discrete_y`: an integer index of `x`/`y`
#' coordinates and a factor of the data labels (only applicable when names
#' exists).
#'
#' - `.names` ([`vec_names()`][vctrs::vec_names]) and `.index`
#' ([`vec_size()`][vctrs::vec_size()]/[`NROW()`]): A factor of the names
#' (only applicable when names exists) and an integer of index of the
#' original data.
#' ([`vec_size()`][vctrs::vec_size()]/[`NROW()`]): a character names (only
#' applicable when names exists) and an integer of index of the original
#' data.
#'
#' - `.row_names` and `.row_index`: the row names and an integer of
#' row index of the original matrix (only applicable if `data` is a
Expand All @@ -65,7 +59,16 @@
#' - `value`: the actual value (only applicable if `data` is a `matrix` or
#' atomic vector).
#'
#' It is recommended to use `.x`/`.y`, or `.names` as the `x`/`y` mapping.
#' `matrix` input will be automatically melted into a long foramted data frame.
#'
#' Atomic vector will be put in the `value` column of the data frame.
#'
#' In the case where the input data is already a data frame, following columns
#' (`.panel`, `.index`, `.names`, `.x`/`.y`, `.discrete_x`/`.discrete_y`) are
#' added to the data frame.
#'
#' It is recommended to use `.x`/`.y`, or `.discrete_x`/`.discrete_y` as the
#' `x`/`y` mapping.
#'
#' If the data inherits from [`quad_layout()`]/[`ggheatmap()`], an additional
#' column will be added.
Expand All @@ -80,8 +83,8 @@
#' ggalign() +
#' geom_point(aes(y = value))
#'
#' # if data is `NULL`, a three column data frame will be created
#' # (`.panel`, `.index`, `.x`/`.y`)
#' # if data is `NULL`, a data frame with following column will be created
#' # (`.panel`, `.index`, `.names`, `.x`/`.y`, `.discrete_x`/`.discrete_y`)
#' ggheatmap(matrix(rnorm(81), nrow = 9)) +
#' anno_top(size = 0.5) +
#' align_dendro(k = 3L) +
Expand Down Expand Up @@ -180,11 +183,19 @@ AlignGG <- ggproto("AlignGG", Align,
axis <- to_coord_axis(direction)
coord_name <- paste0(".", axis)
ans <- data_frame0(
.panel = panel, .index = index,
.panel = panel,
.index = index,
# `data_frame0` will omit `NULL`
.names = .subset(self$labels, index)
)
ans[[coord_name]] <- seq_along(index)
if (!is.null(.subset2(ans, ".names"))) {
ans[[paste0(".discrete_", axis)]] <- reorder(
.subset2(ans, ".names"),
.subset2(ans, coord_name),
order = FALSE
)
}

# if inherit from the parent layout
if (is.waive(.subset2(self, "input_data")) && !is.null(extra_panel)) {
Expand All @@ -202,13 +213,6 @@ AlignGG <- ggproto("AlignGG", Align,
} else if (!is.null(data)) {
ans <- full_join(data, ans, by.x = ".index", by.y = ".index")
}
if (!is.null(.subset2(ans, ".names"))) {
ans$.names <- reorder(
.subset2(ans, ".names"),
.subset2(ans, coord_name),
order = FALSE
)
}
plot$data <- ggalign_attr_restore(ans, data)
plot
}
Expand Down
16 changes: 9 additions & 7 deletions R/layout-heatmap-.R
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,19 @@
#' @param guides `r lifecycle::badge("deprecated")` Please use
#' [`scheme_align()`] function instead.
#' @section ggplot2 specification:
#' The data input in `ggheatmap` will be converted into the long formated data
#' frame when drawing. The default mapping will use `aes(.data$.x, .data$.y)`,
#' you can use `mapping` argument to control it. The data in the underlying
#' `ggplot` object contains following columns:
#' The default mapping will use `aes(.data$.x, .data$.y)`, you can use `mapping`
#' argument to control it. The data in the underlying `ggplot` object contains
#' following columns:
#'
#' - `.xpanel` and `.ypanel`: the column and row panel
#'
#' - `.x` and `.y`: the `x` and `y` coordinates
#' - `.x` and `.y`: an integer index of `x` and `y` coordinates
#'
#' - `.row_names` and `.column_names`: A factor of the row and column names of
#' the original matrix (only applicable when names exist).
#' - `.discrete_x` and `.discrete_y`: a factor of the data labels (only
#' applicable when `.row_names`` and `.column_names` exists).
#'
#' - `.row_names` and `.column_names`: A character of the row and column names
#' of the original matrix (only applicable when names exist).
#'
#' - `.row_index` and `.column_index`: the row and column index of the original
#' matrix.
Expand Down
12 changes: 7 additions & 5 deletions R/layout-quad-.R
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,18 @@ quad_free.uneval <- function(data, ...) {

#########################################################################
#' @section ggplot2 specification:
#' For `quad_alignb`, `quad_alignh`, and `quad_alignv`, the data input will be
#' converted into the long formated data frame when drawing. The data in the
#' For `quad_alignb`, `quad_alignh`, and `quad_alignv`, the data in the
#' underlying `ggplot` object contains following columns:
#'
#' - `.xpanel` and `.ypanel`: the column and row panel
#'
#' - `.x` and `.y`: the `x` and `y` coordinates
#' - `.x` and `.y`: an integer index of `x` and `y` coordinates
#'
#' - `.row_names` and `.column_names`: A factor of the row and column names of
#' the original matrix (only applicable when names exist).
#' - `.discrete_x` and `.discrete_y`: a factor of the data labels (only
#' applicable when `.row_names`` and `.column_names` exists).
#'
#' - `.row_names` and `.column_names`: A character of the row and column names
#' of the original matrix (only applicable when names exist).
#'
#' - `.row_index` and `.column_index`: the row and column index of the original
#' matrix.
Expand Down
8 changes: 4 additions & 4 deletions R/layout-quad-build.R
Original file line number Diff line number Diff line change
Expand Up @@ -296,16 +296,16 @@ quad_build_data <- function(data, row_coords, column_coords) {
ans <- fortify_data_frame.matrix(data)
ans <- full_join(ans, coords, by.x = by.x, by.y = by.y)
if (!is.null(.subset2(ans, ".row_names")) &&
!is.null(.subset2(ans, ".y"))) {
ans$.row_names <- reorder(
!is.null(row_coords)) {
ans$.discrete_y <- reorder(
.subset2(ans, ".row_names"),
.subset2(ans, ".y"),
order = FALSE
)
}
if (!is.null(.subset2(ans, ".column_names")) &&
!is.null(.subset2(ans, ".x"))) {
ans$.column_names <- reorder(
!is.null(column_coords)) {
ans$.discrete_x <- reorder(
.subset2(ans, ".column_names"),
.subset2(ans, ".x"),
order = FALSE
Expand Down
2 changes: 2 additions & 0 deletions R/plot-align-cross.R
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#' horizontal stack layout (including left and right annotation).
#'
#' - `.index`: an integer of the data index.
#'
#' - `.names`: a character of data labels.
#'
#' - `.hand`: a factor indicates the index groups.
#'
Expand Down
33 changes: 18 additions & 15 deletions man/align_gg.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions man/cross_link.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 8 additions & 7 deletions man/heatmap_layout.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions man/quad_free.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 9 additions & 9 deletions tests/testthat/test-layout_heatmap.R
Original file line number Diff line number Diff line change
Expand Up @@ -141,29 +141,29 @@ testthat::test_that("`breaks` of `scale_*_()` works well", {
expect_doppelganger(
"discrete_no_breaks",
ggheatmap(small_mat, filling = FALSE) +
geom_tile(aes(.column_names, .row_names, fill = value)) +
geom_tile(aes(.discrete_x, .discrete_y, fill = value)) +
scale_x_discrete(breaks = NULL)
)
expect_doppelganger(
"discrete_character_breaks",
ggheatmap(small_mat, filling = FALSE) +
geom_tile(aes(.column_names, .row_names, fill = value)) +
geom_tile(aes(.discrete_x, .discrete_y, fill = value)) +
scale_x_discrete(breaks = c("column3", "column5")) +
anno_top() +
align_dendro(k = 3L)
)
expect_doppelganger(
"discrete_integer_breaks",
ggheatmap(small_mat, filling = FALSE) +
geom_tile(aes(.column_names, .row_names, fill = value)) +
geom_tile(aes(.discrete_x, .discrete_y, fill = value)) +
scale_x_discrete(breaks = c(3, 5)) +
anno_top() +
align_dendro(k = 3L)
)
expect_doppelganger(
"discrete_integer_as_is_breaks",
ggheatmap(small_mat, filling = FALSE) +
geom_tile(aes(.column_names, .row_names, fill = value)) +
geom_tile(aes(.discrete_x, .discrete_y, fill = value)) +
scale_x_discrete(breaks = I(3:4)) +
anno_top() +
align_dendro(k = 3L)
Expand Down Expand Up @@ -212,37 +212,37 @@ testthat::test_that("`labels` of `scale_*_()` works well", {
expect_doppelganger(
"discrete_no_labels",
ggheatmap(small_mat, filling = FALSE) +
geom_tile(aes(.column_names, .row_names, fill = value)) +
geom_tile(aes(.discrete_x, .discrete_y, fill = value)) +
scale_x_discrete(labels = NULL) +
anno_top() +
align_dendro(k = 3L)
)
expect_doppelganger(
"discrete_labels",
ggheatmap(small_mat, filling = FALSE) +
geom_tile(aes(.column_names, .row_names, fill = value)) +
geom_tile(aes(.discrete_x, .discrete_y, fill = value)) +
scale_x_discrete(labels = letters[seq_len(ncol(small_mat))]) +
anno_top() +
align_dendro(k = 3L)
)
expect_doppelganger(
"discrete_labels_as_is",
ggheatmap(small_mat, filling = FALSE) +
geom_tile(aes(.column_names, .row_names, fill = value)) +
geom_tile(aes(.discrete_x, .discrete_y, fill = value)) +
scale_x_discrete(labels = I(letters[seq_len(ncol(small_mat))])) +
anno_top() +
align_dendro(k = 3L)
)
expect_doppelganger(
"discrete_labels_match_breaks",
ggheatmap(small_mat, filling = FALSE) +
geom_tile(aes(.column_names, .row_names, fill = value)) +
geom_tile(aes(.discrete_x, .discrete_y, fill = value)) +
scale_x_discrete(breaks = c(5, 3), labels = c("a", "b"))
)
expect_doppelganger(
"discrete_labels_as_is_match_breaks",
ggheatmap(small_mat, filling = FALSE) +
geom_tile(aes(.column_names, .row_names, fill = value)) +
geom_tile(aes(.discrete_x, .discrete_y, fill = value)) +
scale_x_discrete(breaks = c(5, 3), labels = I(c("a", "b")))
)
})
Loading

0 comments on commit 8377a64

Please sign in to comment.