-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Axes at interior panels #4064 #4467
Changes from 28 commits
59850ac
8d98452
b486e7f
f4b3ece
a0984fe
16995f7
a7def9a
465596b
5ee44e9
5006c53
c97778e
de88a18
2b25dcd
24b7be0
f00d02d
72d5508
ce77b7a
574785c
432c603
7aa2d16
d6119b1
3e9a0a2
4d0c896
3970cad
3cc697d
925edf7
313bd89
1f19415
c629845
214dda5
441190c
7d950f7
ed56066
1a05cf2
5d2b39c
63c4368
2501629
74993a8
33a1d6b
657356d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,6 +59,16 @@ NULL | |
#' variables for which margins are to be created. | ||
#' @param facets `r lifecycle::badge("deprecated")` Please use `rows` | ||
#' and `cols` instead. | ||
#' @param axes Determines which axes will be drawn. When `"margins"` | ||
#' (default), axes will be drawn at the exterior margins. `"all_x"` and | ||
#' `"all_y"` will draw the respective axes at the interior panels too, whereas | ||
#' `"all"` will draw all axes at all panels. | ||
#' @param axis_labels Determines whether to draw labels for interior axes when | ||
#' the `axes` argument is not `"margins"`. When `"all"` (default), all | ||
#' interior axes get labels. When `"margins"`, only the exterior axes get | ||
#' labels and the interior axes get none. When `"all_x"` or `"all_y"`, only | ||
#' draws the labels at the interior axes in the x- or y-direction | ||
#' respectively. | ||
#' @export | ||
#' @examples | ||
#' p <- ggplot(mpg, aes(displ, cty)) + geom_point() | ||
|
@@ -112,7 +122,8 @@ facet_grid <- function(rows = NULL, cols = NULL, scales = "fixed", | |
space = "fixed", shrink = TRUE, | ||
labeller = "label_value", as.table = TRUE, | ||
switch = NULL, drop = TRUE, margins = FALSE, | ||
facets = deprecated()) { | ||
facets = deprecated(), axes = "margins", | ||
axis_labels = "all") { | ||
teunbrand marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# `facets` is deprecated and renamed to `rows` | ||
if (lifecycle::is_present(facets)) { | ||
deprecate_warn0("2.2.0", "facet_grid(facets)", "facet_grid(rows)") | ||
|
@@ -137,6 +148,20 @@ facet_grid <- function(rows = NULL, cols = NULL, scales = "fixed", | |
y = any(space %in% c("free_y", "free")) | ||
) | ||
|
||
draw_axes <- arg_match0(axes, c("margins", "all_x", "all_y", "all")) | ||
draw_axes <- list( | ||
x = any(draw_axes %in% c("all_x", "all")), | ||
y = any(draw_axes %in% c("all_y", "all")) | ||
) | ||
|
||
# Omitting labels is special-cased internally, so even when no internal axes | ||
# are to be drawn, register as labelled. | ||
axis_labels <- arg_match0(axis_labels, c("margins", "all_x", "all_y", "all")) | ||
axis_labels <- list( | ||
x = !draw_axes$x || any(axis_labels %in% c("all_x", "all")), | ||
y = !draw_axes$y || any(axis_labels %in% c("all_y", "all")) | ||
) | ||
|
||
if (!is.null(switch)) { | ||
arg_match0(switch, c("both", "x", "y")) | ||
} | ||
|
@@ -150,7 +175,8 @@ facet_grid <- function(rows = NULL, cols = NULL, scales = "fixed", | |
shrink = shrink, | ||
params = list(rows = facets_list$rows, cols = facets_list$cols, margins = margins, | ||
free = free, space_free = space_free, labeller = labeller, | ||
as.table = as.table, switch = switch, drop = drop) | ||
as.table = as.table, switch = switch, drop = drop, | ||
draw_axes = draw_axes, axis_labels = axis_labels) | ||
) | ||
} | ||
|
||
|
@@ -306,8 +332,22 @@ FacetGrid <- ggproto("FacetGrid", Facet, | |
cli::cli_abort("{.fn {snake_class(coord)}} doesn't support free scales.") | ||
} | ||
|
||
cols <- which(layout$ROW == 1) | ||
rows <- which(layout$COL == 1) | ||
if (!params$axis_labels$x) { | ||
cols <- seq_len(nrow(layout)) | ||
x_axis_order <- as.integer(layout$PANEL[order(layout$ROW, layout$COL)]) | ||
} else { | ||
cols <- which(layout$ROW == 1) | ||
x_axis_order <- layout$COL | ||
} | ||
if (!params$axis_labels$y) { | ||
rows <- seq_len(nrow(layout)) | ||
y_axis_order <- as.integer(layout$PANEL[order(layout$ROW, layout$COL)]) | ||
} else { | ||
rows <- which(layout$COL == 1) | ||
y_axis_order <- layout$ROW | ||
} | ||
|
||
ranges <- censor_labels(ranges, layout, params$axis_labels) | ||
axes <- render_axes(ranges[cols], ranges[rows], coord, theme, transpose = TRUE) | ||
|
||
col_vars <- unique0(layout[names(params$cols)]) | ||
|
@@ -367,17 +407,53 @@ FacetGrid <- ggproto("FacetGrid", Facet, | |
theme$panel.spacing.y %||% theme$panel.spacing) | ||
|
||
# Add axes | ||
panel_table <- gtable_add_rows(panel_table, max_height(axes$x$top), 0) | ||
panel_table <- gtable_add_rows(panel_table, max_height(axes$x$bottom), -1) | ||
panel_table <- gtable_add_cols(panel_table, max_width(axes$y$left), 0) | ||
panel_table <- gtable_add_cols(panel_table, max_width(axes$y$right), -1) | ||
panel_pos_col <- panel_cols(panel_table) | ||
panel_pos_rows <- panel_rows(panel_table) | ||
if (params$draw_axes$x) { | ||
# Take facet_wrap approach to axis placement | ||
axes$x$top <- matrix(axes$x$top[x_axis_order], | ||
nrow = nrow, ncol = ncol, byrow = TRUE) | ||
panel_table <- weave_tables_row( | ||
panel_table, axes$x$top, -1, | ||
unit(apply(axes$x$top, 1, max_height, value_only = TRUE), "cm"), | ||
name = "axis-t", z = 3 | ||
) | ||
axes$x$bottom <- matrix(axes$x$bottom[x_axis_order], | ||
nrow = nrow, ncol = ncol, byrow = TRUE) | ||
panel_table <- weave_tables_row( | ||
panel_table, axes$x$bottom, 0, | ||
unit(apply(axes$x$bottom, 1, max_height, value_only = TRUE), "cm"), | ||
name = "axis-b", z = 3 | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be abstracted away if we are using it multiple places in the code base (both for x and y and in facet_grid and facet_wrap? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like this too, but the actual facet_wrap code has very involved code dealing with empty panels (restoring axes for non-empty panels and getting the correct axis sizes). This is right between the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could we at least abstract it away for x and y? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll see what I can do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I figured that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see... I knew you could do it |
||
} else { | ||
panel_table <- gtable_add_rows(panel_table, max_height(axes$x$top), 0) | ||
panel_table <- gtable_add_rows(panel_table, max_height(axes$x$bottom), -1) | ||
panel_pos_col <- panel_cols(panel_table) | ||
panel_table <- gtable_add_grob(panel_table, axes$x$top, 1, panel_pos_col$l, clip = "off", name = paste0("axis-t-", seq_along(axes$x$top)), z = 3) | ||
panel_table <- gtable_add_grob(panel_table, axes$x$bottom, -1, panel_pos_col$l, clip = "off", name = paste0("axis-b-", seq_along(axes$x$bottom)), z = 3) | ||
} | ||
|
||
panel_table <- gtable_add_grob(panel_table, axes$x$top, 1, panel_pos_col$l, clip = "off", name = paste0("axis-t-", seq_along(axes$x$top)), z = 3) | ||
panel_table <- gtable_add_grob(panel_table, axes$x$bottom, -1, panel_pos_col$l, clip = "off", name = paste0("axis-b-", seq_along(axes$x$bottom)), z = 3) | ||
panel_table <- gtable_add_grob(panel_table, axes$y$left, panel_pos_rows$t, 1, clip = "off", name = paste0("axis-l-", seq_along(axes$y$left)), z = 3) | ||
panel_table <- gtable_add_grob(panel_table, axes$y$right, panel_pos_rows$t, -1, clip = "off", name = paste0("axis-r-", seq_along(axes$y$right)), z= 3) | ||
if (params$draw_axes$y) { | ||
# Take facet_wrap approach to axis placement | ||
axes$y$left <- matrix(axes$y$left[y_axis_order], | ||
nrow = nrow, ncol = ncol, byrow = TRUE) | ||
panel_table <- weave_tables_col( | ||
panel_table, axes$y$left, -1, | ||
unit(apply(axes$y$left, 2, max_width, value_only = TRUE), "cm"), | ||
name = "axis-l", z = 3 | ||
) | ||
axes$y$right <- matrix(axes$y$right[y_axis_order], | ||
nrow = nrow, ncol = ncol, byrow = TRUE) | ||
panel_table <- weave_tables_col( | ||
panel_table, axes$y$right, 0, | ||
unit(apply(axes$y$right, 2, max_width, value_only = TRUE), "cm"), | ||
name = "axis-r", z = 3 | ||
) | ||
} else { | ||
panel_table <- gtable_add_cols(panel_table, max_width(axes$y$left), 0) | ||
panel_table <- gtable_add_cols(panel_table, max_width(axes$y$right), -1) | ||
panel_pos_rows <- panel_rows(panel_table) | ||
panel_table <- gtable_add_grob(panel_table, axes$y$left, panel_pos_rows$t, 1, clip = "off", name = paste0("axis-l-", seq_along(axes$y$left)), z = 3) | ||
panel_table <- gtable_add_grob(panel_table, axes$y$right, panel_pos_rows$t, -1, clip = "off", name = paste0("axis-r-", seq_along(axes$y$right)), z= 3) | ||
} | ||
|
||
# Add strips | ||
switch_x <- !is.null(params$switch) && params$switch %in% c("both", "x") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps add an example showing the new functionality