Skip to content

Commit bd50a55

Browse files
authored
Make sure axes are added correctly to facet_wrap in all circumstances (#4673)
1 parent 391a164 commit bd50a55

File tree

4 files changed

+577
-22
lines changed

4 files changed

+577
-22
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# ggplot2 (development version)
22

3+
* Axes are now added correctly in `facet_wrap()` when `as.table = FALSE`
4+
(@thomasp85, #4553)
5+
36
* Better compatibility of custom device functions in `ggsave()`
47
(@thomasp85, #4539)
58

R/facet-wrap.r

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -313,30 +313,70 @@ FacetWrap <- ggproto("FacetWrap", Facet,
313313
)
314314
# Add back missing axes
315315
if (any(empties)) {
316-
first_row <- which(apply(empties, 1, any))[1] - 1
317-
first_col <- which(apply(empties, 2, any))[1] - 1
318-
row_panels <- which(layout$ROW == first_row & layout$COL > first_col)
319-
row_pos <- convertInd(layout$ROW[row_panels], layout$COL[row_panels], nrow)
320-
row_axes <- axes$x$bottom[layout$SCALE_X[row_panels]]
321-
col_panels <- which(layout$ROW > first_row & layout$COL == first_col)
322-
col_pos <- convertInd(layout$ROW[col_panels], layout$COL[col_panels], nrow)
323-
col_axes <- axes$y$right[layout$SCALE_Y[col_panels]]
316+
row_ind <- row(empties)
317+
col_ind <- col(empties)
324318
inside <- (theme$strip.placement %||% "inside") == "inside"
325-
if (params$strip.position == "bottom" &&
326-
!inside &&
327-
any(!vapply(row_axes, is.zero, logical(1))) &&
328-
!params$free$x) {
329-
warn("Suppressing axis rendering when strip.position = 'bottom' and strip.placement == 'outside'")
330-
} else {
331-
axis_mat_x_bottom[row_pos] <- row_axes
319+
empty_bottom <- apply(empties, 2, function(x) c(diff(x) == 1, FALSE))
320+
if (any(empty_bottom)) {
321+
pos <- which(empty_bottom)
322+
panel_loc <- data_frame(ROW = row_ind[pos], COL = col_ind[pos])
323+
# Substitute with vctrs::vec_match(panel_loc, layout[, c("ROW", "COL")])
324+
# Once we switch to vctrs wholesale
325+
panels <- merge(panel_loc, cbind(layout, .index = seq_len(nrow(layout))))$.index
326+
x_axes <- axes$x$bottom[layout$SCALE_X[panels]]
327+
if (params$strip.position == "bottom" &&
328+
!inside &&
329+
any(!vapply(x_axes, is.zero, logical(1))) &&
330+
!params$free$x) {
331+
warn("Suppressing axis rendering when strip.position = 'bottom' and strip.placement == 'outside'")
332+
} else {
333+
axis_mat_x_bottom[pos] <- x_axes
334+
}
332335
}
333-
if (params$strip.position == "right" &&
334-
!inside &&
335-
any(!vapply(col_axes, is.zero, logical(1))) &&
336-
!params$free$y) {
337-
warn("Suppressing axis rendering when strip.position = 'right' and strip.placement == 'outside'")
338-
} else {
339-
axis_mat_y_right[col_pos] <- col_axes
336+
empty_top <- apply(empties, 2, function(x) c(FALSE, diff(x) == -1))
337+
if (any(empty_top)) {
338+
pos <- which(empty_top)
339+
panel_loc <- data_frame(ROW = row_ind[pos], COL = col_ind[pos])
340+
panels <- merge(panel_loc, cbind(layout, .index = seq_len(nrow(layout))))$.index
341+
x_axes <- axes$x$top[layout$SCALE_X[panels]]
342+
if (params$strip.position == "top" &&
343+
!inside &&
344+
any(!vapply(x_axes, is.zero, logical(1))) &&
345+
!params$free$x) {
346+
warn("Suppressing axis rendering when strip.position = 'top' and strip.placement == 'outside'")
347+
} else {
348+
axis_mat_x_top[pos] <- x_axes
349+
}
350+
}
351+
empty_right <- t(apply(empties, 1, function(x) c(diff(x) == 1, FALSE)))
352+
if (any(empty_right)) {
353+
pos <- which(empty_right)
354+
panel_loc <- data_frame(ROW = row_ind[pos], COL = col_ind[pos])
355+
panels <- merge(panel_loc, cbind(layout, .index = seq_len(nrow(layout))))$.index
356+
y_axes <- axes$y$right[layout$SCALE_Y[panels]]
357+
if (params$strip.position == "right" &&
358+
!inside &&
359+
any(!vapply(y_axes, is.zero, logical(1))) &&
360+
!params$free$y) {
361+
warn("Suppressing axis rendering when strip.position = 'right' and strip.placement == 'outside'")
362+
} else {
363+
axis_mat_y_right[pos] <- y_axes
364+
}
365+
}
366+
empty_left <- t(apply(empties, 1, function(x) c(FALSE, diff(x) == -1)))
367+
if (any(empty_left)) {
368+
pos <- which(empty_left)
369+
panel_loc <- data_frame(ROW = row_ind[pos], COL = col_ind[pos])
370+
panels <- merge(panel_loc, cbind(layout, .index = seq_len(nrow(layout))))$.index
371+
y_axes <- axes$y$left[layout$SCALE_Y[panels]]
372+
if (params$strip.position == "left" &&
373+
!inside &&
374+
any(!vapply(y_axes, is.zero, logical(1))) &&
375+
!params$free$y) {
376+
warn("Suppressing axis rendering when strip.position = 'left' and strip.placement == 'outside'")
377+
} else {
378+
axis_mat_y_left[pos] <- y_axes
379+
}
340380
}
341381
}
342382
panel_table <- weave_tables_row(panel_table, axis_mat_x_top, -1, axis_height_top, "axis-t", 3)

0 commit comments

Comments
 (0)