Skip to content

Commit 0a69e9f

Browse files
committed
multiple inside guide box with different position
1 parent 4193a50 commit 0a69e9f

File tree

4 files changed

+90
-48
lines changed

4 files changed

+90
-48
lines changed

R/guide-colorbar.R

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -212,19 +212,21 @@ GuideColourbar <- ggproto(
212212
hashables = exprs(title, key$.label, decor, name),
213213

214214
elements = list(
215-
background = "legend.background",
216-
margin = "legend.margin",
217-
key = "legend.key",
218-
key_height = "legend.key.height",
219-
key_width = "legend.key.width",
220-
text = "legend.text",
221-
theme.title = "legend.title",
222-
text_position = "legend.text.position",
223-
title_position = "legend.title.position",
224-
axis_line = "legend.axis.line",
225-
ticks = "legend.ticks",
226-
ticks_length = "legend.ticks.length",
227-
frame = "legend.frame"
215+
background = "legend.background",
216+
margin = "legend.margin",
217+
key = "legend.key",
218+
key_height = "legend.key.height",
219+
key_width = "legend.key.width",
220+
text = "legend.text",
221+
theme.title = "legend.title",
222+
text_position = "legend.text.position",
223+
title_position = "legend.title.position",
224+
axis_line = "legend.axis.line",
225+
ticks = "legend.ticks",
226+
ticks_length = "legend.ticks.length",
227+
frame = "legend.frame",
228+
inside_position = "legend.position.inside",
229+
inside_justification = "legend.justification.inside"
228230
),
229231

230232
extract_key = function(scale, aesthetic, ...) {

R/guide-legend.R

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -169,18 +169,20 @@ GuideLegend <- ggproto(
169169
hashables = exprs(title, key$.label, name),
170170

171171
elements = list(
172-
background = "legend.background",
173-
margin = "legend.margin",
174-
key = "legend.key",
175-
key_height = "legend.key.height",
176-
key_width = "legend.key.width",
177-
text = "legend.text",
178-
theme.title = "legend.title",
179-
spacing_x = "legend.key.spacing.x",
180-
spacing_y = "legend.key.spacing.y",
181-
text_position = "legend.text.position",
182-
title_position = "legend.title.position",
183-
byrow = "legend.byrow"
172+
background = "legend.background",
173+
margin = "legend.margin",
174+
key = "legend.key",
175+
key_height = "legend.key.height",
176+
key_width = "legend.key.width",
177+
text = "legend.text",
178+
theme.title = "legend.title",
179+
spacing_x = "legend.key.spacing.x",
180+
spacing_y = "legend.key.spacing.y",
181+
text_position = "legend.text.position",
182+
title_position = "legend.title.position",
183+
byrow = "legend.byrow",
184+
inside_position = "legend.position.inside",
185+
inside_justification = "legend.justification.inside"
184186
),
185187

186188
extract_params = function(scale, params,
@@ -342,7 +344,14 @@ GuideLegend <- ggproto(
342344
)
343345
)
344346
elements$text <- calc_element("legend.text", add_theme(theme, text))
345-
Guide$setup_elements(params, elements, theme)
347+
ans <- Guide$setup_elements(params, elements, theme)
348+
ans$inside_justification <- .subset2(
349+
theme, "legend.justification.inside"
350+
) %||% .subset2(ans, "inside_position")
351+
ans$inside_justification <- valid.just(.subset2(
352+
ans, "inside_justification"
353+
))
354+
ans
346355
},
347356

348357
override_elements = function(params, elements, theme) {
@@ -559,7 +568,14 @@ GuideLegend <- ggproto(
559568
gt <- gtable_add_grob(
560569
gt, elements$background,
561570
name = "background", clip = "off",
562-
t = 1, r = -1, b = -1, l =1, z = -Inf
571+
t = 1, r = -1, b = -1, l = 1, z = -Inf
572+
)
573+
}
574+
# attach the `position` and `justification` for the inside legends
575+
if (identical(.subset2(params, "position"), "inside")) {
576+
attr(gt, "inside_position") <- .subset2(elements, "inside_position")
577+
attr(gt, "inside_justification") <- .subset2(
578+
elements, "inside_justification"
563579
)
564580
}
565581
gt

R/guides-.R

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -517,9 +517,8 @@ Guides <- ggproto(
517517
positions <- vapply(
518518
params,
519519
function(p) p$position[1] %||% default_position,
520-
character(1)
520+
character(1), USE.NAMES = FALSE
521521
)
522-
positions <- factor(positions, levels = c(.trbl, "inside"))
523522

524523
directions <- rep(direction %||% "vertical", length(positions))
525524
if (is.null(direction)) {
@@ -529,11 +528,26 @@ Guides <- ggproto(
529528
grobs <- vector("list", length(guides))
530529
for (i in seq_along(grobs)) {
531530
grobs[[i]] <- guides[[i]]$draw(
532-
theme = theme, position = as.character(positions[i]),
531+
theme = theme, position = positions[i],
533532
direction = directions[i], params = params[[i]]
534533
)
534+
if (identical(positions[i], "inside")) {
535+
positions[i] <- paste(
536+
"inside",
537+
paste(attr(.subset2(grobs, i), "inside_position"), collapse = "_"),
538+
paste(attr(.subset2(grobs, i), "inside_justification"),
539+
collapse = "_"
540+
),
541+
sep = "_"
542+
)
543+
}
535544
}
536-
keep <- !vapply(grobs, is.zero, logical(1))
545+
546+
# move inside legends to the last
547+
positions <- factor(positions,
548+
levels = c(.trbl, unique(positions[startsWith(positions, "inside")]))
549+
)
550+
keep <- !vapply(grobs, is.zero, logical(1), USE.NAMES = FALSE)
537551
split(grobs[keep], positions[keep])
538552
},
539553

@@ -546,8 +560,10 @@ Guides <- ggproto(
546560
# Determine default direction
547561
direction <- switch(
548562
position,
549-
inside = , left = , right = "vertical",
550-
top = , bottom = "horizontal"
563+
left = , right = "vertical",
564+
top = , bottom = "horizontal",
565+
# for all inside guide legends
566+
"vertical"
551567
)
552568

553569
# Populate missing theme arguments
@@ -569,16 +585,22 @@ Guides <- ggproto(
569585
# Global justification of the complete legend box
570586
global_just <- paste0("legend.justification.", position)
571587
global_just <- valid.just(calc_element(global_just, theme))
572-
573-
if (position == "inside") {
588+
if (startsWith(position, "inside")) {
574589
# The position of inside legends are set by their justification
575-
inside_position <- theme$legend.position.inside %||% global_just
576-
global_xjust <- inside_position[1]
577-
global_yjust <- inside_position[2]
578-
global_margin <- margin()
579-
} else {
590+
global_just <- attr(.subset2(grobs, 1L), "inside_justification") %||%
591+
# fallback to original method of ggplot2 <=3.3.5
592+
global_just
593+
inside_position <- attr(.subset2(grobs, 1L), "inside_position") %||%
594+
# fallback to original method of ggplot2 <=3.3.5
595+
.subset2(theme, "legend.position.inside") %||% global_just
580596
global_xjust <- global_just[1]
581597
global_yjust <- global_just[2]
598+
x <- inside_position[1]
599+
y <- inside_position[2]
600+
global_margin <- margin()
601+
} else {
602+
x <- global_xjust <- global_just[1]
603+
y <- global_yjust <- global_just[2]
582604
# Legends to the side of the plot need a margin for justification
583605
# relative to the plot panel
584606
global_margin <- margin(
@@ -620,7 +642,7 @@ Guides <- ggproto(
620642

621643
# Set global justification
622644
vp <- viewport(
623-
x = global_xjust, y = global_yjust, just = global_just,
645+
x = x, y = y, just = global_just,
624646
height = max(heights),
625647
width = vp_width
626648
)
@@ -658,7 +680,7 @@ Guides <- ggproto(
658680

659681
# Set global justification
660682
vp <- viewport(
661-
x = global_xjust, y = global_yjust, just = global_just,
683+
x = x, y = y, just = global_just,
662684
height = vp_height,
663685
width = max(widths)
664686
)

R/plot-build.R

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -515,12 +515,14 @@ table_add_legends <- function(table, legends, theme) {
515515

516516
# Add manual legend
517517
place <- find_panel(table)
518-
table <- gtable_add_grob(
519-
table, legends$inside, clip = "off",
520-
t = place$t, b = place$b, l = place$l, r = place$r,
521-
name = "guide-box-inside"
522-
)
523-
518+
inside_legends <- .subset(legends, startsWith(names(legends), "inside"))
519+
for (i in seq_along(inside_legends)) {
520+
table <- gtable_add_grob(
521+
table, .subset2(inside_legends, i), clip = "off",
522+
t = place$t, b = place$b, l = place$l, r = place$r,
523+
name = paste("guide-box-inside", i, sep = "-")
524+
)
525+
}
524526
table
525527
}
526528

0 commit comments

Comments
 (0)