Skip to content

Commit b4887eb

Browse files
committed
remove the requirement of ggplot2 >=3.5.0
1 parent a0aba70 commit b4887eb

File tree

6 files changed

+403
-27
lines changed

6 files changed

+403
-27
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Description: The 'ggplot2' package provides a strong API for sequentially
1919
License: MIT + file LICENSE
2020
Encoding: UTF-8
2121
Imports:
22-
ggplot2 (>= 3.5.0),
22+
ggplot2 (>= 3.0.0),
2323
gtable,
2424
grid,
2525
stats,

NAMESPACE

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,10 @@ importFrom(farver,get_channel)
9292
importFrom(farver,set_channel)
9393
importFrom(ggplot2,aes)
9494
importFrom(ggplot2,calc_element)
95+
importFrom(ggplot2,element_blank)
96+
importFrom(ggplot2,element_grob)
9597
importFrom(ggplot2,element_line)
98+
importFrom(ggplot2,element_render)
9699
importFrom(ggplot2,element_text)
97100
importFrom(ggplot2,find_panel)
98101
importFrom(ggplot2,geom_blank)
@@ -123,12 +126,14 @@ importFrom(grDevices,is.raster)
123126
importFrom(grid,absolute.size)
124127
importFrom(grid,convertHeight)
125128
importFrom(grid,convertWidth)
129+
importFrom(grid,editGrob)
126130
importFrom(grid,gTree)
127131
importFrom(grid,grid.draw)
128132
importFrom(grid,grid.newpage)
129133
importFrom(grid,grobHeight)
130134
importFrom(grid,grobTree)
131135
importFrom(grid,grobWidth)
136+
importFrom(grid,heightDetails)
132137
importFrom(grid,is.grob)
133138
importFrom(grid,is.unit)
134139
importFrom(grid,pushViewport)
@@ -138,7 +143,9 @@ importFrom(grid,unit)
138143
importFrom(grid,unit.c)
139144
importFrom(grid,unit.pmax)
140145
importFrom(grid,upViewport)
146+
importFrom(grid,valid.just)
141147
importFrom(grid,viewport)
148+
importFrom(grid,widthDetails)
142149
importFrom(gtable,gtable)
143150
importFrom(gtable,gtable_add_cols)
144151
importFrom(gtable,gtable_add_grob)
@@ -149,6 +156,7 @@ importFrom(gtable,is.gtable)
149156
importFrom(stats,ave)
150157
importFrom(stats,na.omit)
151158
importFrom(utils,as.roman)
159+
importFrom(utils,getFromNamespace)
152160
importFrom(utils,modifyList)
153161
importFrom(utils,str)
154162
importFrom(utils,tail)

R/guides.R

Lines changed: 107 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,28 +60,123 @@ collapse_guides <- function(guides) {
6060
guides
6161
}
6262

63+
#' @importFrom utils getFromNamespace
6364
#' @importFrom ggplot2 calc_element
64-
assemble_guides <- function(guides, theme) {
65-
position <- theme$legend.position %||% "right"
66-
if (length(position) == 2) {
67-
warning("Manual legend position not possible for collected guides. Defaulting to 'right'", call. = FALSE)
68-
position <- "right"
69-
}
65+
assemble_guides <- function(guides, position, theme) {
7066
# https://github.com/tidyverse/ggplot2/blob/57ba97fa04dadc6fd73db1904e39a09d57a4fcbe/R/guides-.R#L512
7167
theme$legend.spacing <- theme$legend.spacing %||% unit(0.5, "lines")
7268
theme$legend.spacing.y <- calc_element("legend.spacing.y", theme)
7369
theme$legend.spacing.x <- calc_element("legend.spacing.x", theme)
70+
7471
# for every position, collect all individual guides and arrange them
7572
# into a guide box which will be inserted into the main gtable
76-
Guides <- utils::getFromNamespace("Guides", "ggplot2")
77-
Guides$package_box(guides, position, theme)
73+
Guides <- getFromNamespace("Guides", "ggplot2")
74+
package_box <- .subset2(Guides, "package_box") %||% package_box
75+
package_box(guides, position, theme)
76+
}
77+
78+
#' @importFrom grid valid.just editGrob
79+
package_box <- function(guides, guide_pos, theme) {
80+
theme <- complete_guide_theme(guide_pos, theme)
81+
guides <- guides_build(guides, theme)
82+
83+
# Set the justification of the legend box
84+
# First value is xjust, second value is yjust
85+
just <- valid.just(calc_element("legend.justification", theme))
86+
xjust <- just[1]
87+
yjust <- just[2]
88+
guides <- editGrob(guides,
89+
vp = viewport(x = xjust, y = yjust, just = c(xjust, yjust))
90+
)
91+
guides <- gtable_add_rows(guides, unit(yjust, "null"))
92+
guides <- gtable_add_rows(guides, unit(1 - yjust, "null"), 0)
93+
guides <- gtable_add_cols(guides, unit(xjust, "null"), 0)
94+
guides <- gtable_add_cols(guides, unit(1 - xjust, "null"))
95+
guides
96+
}
97+
98+
#' @importFrom ggplot2 calc_element
99+
complete_guide_theme <- function(guide_pos, theme) {
100+
if (guide_pos %in% c("top", "bottom")) {
101+
theme$legend.box <- calc_element("legend.box", theme) %||% "horizontal"
102+
theme$legend.direction <- calc_element("legend.direction", theme) %||%
103+
"horizontal"
104+
theme$legend.box.just <- calc_element("legend.box.just", theme) %||%
105+
c("center", "top")
106+
} else {
107+
theme$legend.box <- calc_element("legend.box", theme) %||% "vertical"
108+
theme$legend.direction <- calc_element("legend.direction", theme) %||%
109+
"vertical"
110+
theme$legend.box.just <- calc_element("legend.box.just", theme) %||%
111+
c("left", "top")
112+
}
113+
theme
114+
}
115+
116+
#' @importFrom gtable gtable_width gtable_height gtable gtable_add_grob
117+
#' @importFrom grid editGrob heightDetails widthDetails valid.just unit.c unit
118+
#' @importFrom ggplot2 margin element_grob element_blank calc_element element_render
119+
guides_build <- function(guides, theme) {
120+
legend.spacing.y <- .subset2(theme, "legend.spacing.y")
121+
legend.spacing.x <- .subset2(theme, "legend.spacing.x")
122+
legend.box.margin <- calc_element("legend.box.margin", theme) %||% margin()
123+
124+
widths <- exec(unit.c, !!!lapply(guides, gtable_width))
125+
heights <- exec(unit.c, !!!lapply(guides, gtable_height))
126+
127+
just <- valid.just(calc_element("legend.box.just", theme))
128+
xjust <- just[1]
129+
yjust <- just[2]
130+
vert <- identical(calc_element("legend.box", theme), "horizontal")
131+
guides <- lapply(guides, function(g) {
132+
editGrob(g, vp = viewport(
133+
x = xjust, y = yjust, just = c(xjust, yjust),
134+
height = if (vert) heightDetails(g) else 1,
135+
width = if (!vert) widthDetails(g) else 1
136+
))
137+
})
138+
guide_ind <- seq(by = 2, length.out = length(guides))
139+
sep_ind <- seq(2, by = 2, length.out = length(guides) - 1)
140+
if (vert) {
141+
heights <- max(heights)
142+
if (length(widths) != 1) {
143+
w <- unit(rep_len(0, length(widths) * 2 - 1), "mm")
144+
w[guide_ind] <- widths
145+
w[sep_ind] <- legend.spacing.x
146+
widths <- w
147+
}
148+
} else {
149+
widths <- max(widths)
150+
if (length(heights) != 1) {
151+
h <- unit(rep_len(0, length(heights) * 2 - 1), "mm")
152+
h[guide_ind] <- heights
153+
h[sep_ind] <- legend.spacing.y
154+
heights <- h
155+
}
156+
}
157+
widths <- unit.c(legend.box.margin[4], widths, legend.box.margin[2])
158+
heights <- unit.c(legend.box.margin[1], heights, legend.box.margin[3])
159+
guides <- gtable_add_grob(
160+
gtable(widths, heights, name = "guide-box"),
161+
guides,
162+
t = 1 + if (!vert) guide_ind else 1,
163+
l = 1 + if (vert) guide_ind else 1,
164+
name = "guides"
165+
)
166+
167+
gtable_add_grob(
168+
guides,
169+
element_render(theme, "legend.box.background"),
170+
t = 1, l = 1, b = -1, r = -1,
171+
z = -Inf, clip = "off", name = "legend.box.background"
172+
)
78173
}
79174

80175
#' @importFrom ggplot2 calc_element find_panel
81176
#' @importFrom gtable gtable_width gtable_height
82177
#' @importFrom grid unit.c
83-
attach_guides <- function(table, guides, theme) {
84-
guide_areas <- grepl('panel-guide_area', table$layout$name)
178+
attach_guides <- function(table, guides, position, theme) {
179+
guide_areas <- grepl("panel-guide_area", table$layout$name)
85180
if (any(guide_areas)) {
86181
area_ind <- which(guide_areas)
87182
if (length(area_ind) != 1) {
@@ -91,14 +186,8 @@ attach_guides <- function(table, guides, theme) {
91186
return(table)
92187
}
93188
p_loc <- find_panel(table)
94-
position <- theme$legend.position %||% "right"
95-
if (length(position) == 2) {
96-
warning('Manual position of collected guides not supported', call. = FALSE)
97-
position <- "right"
98-
}
99-
100-
spacing <- calc_element("legend.box.spacing", theme) %||% unit(0.2, 'cm')
101-
legend_width <- gtable_width(guides)
189+
spacing <- calc_element("legend.box.spacing", theme) %||% unit(0.2, "cm")
190+
legend_width <- gtable_width(guides)
102191
legend_height <- gtable_height(guides)
103192
if (position == "left") {
104193
table <- gtable_add_grob(table, guides, clip = "off", t = p_loc$t,

R/plot_patchwork.R

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,13 @@ build_patchwork <- function(x, guides = 'auto') {
222222
if (!attr(theme, 'complete')) {
223223
theme <- theme_get() + theme
224224
}
225-
guide_grobs <- assemble_guides(guide_grobs, theme)
226-
gt_new <- attach_guides(gt_new, guide_grobs, theme)
225+
position <- theme$legend.position %||% "right"
226+
if (length(position) == 2) {
227+
warning("Manual legend position not possible for collected guides. Defaulting to 'right'", call. = FALSE)
228+
position <- "right"
229+
}
230+
guide_grobs <- assemble_guides(guide_grobs, position, theme)
231+
gt_new <- attach_guides(gt_new, guide_grobs, position, theme)
227232
}
228233
} else {
229234
gt_new$collected_guides <- guide_grobs

0 commit comments

Comments
 (0)