@@ -30,98 +30,24 @@ S7::method(ggplot_gtable, class_ggplot_built) <- function(data) {
30
30
layout <- data @ layout
31
31
data <- data @ data
32
32
theme <- plot @ theme
33
+ labels <- plot @ labels
33
34
34
35
geom_grobs <- by_layer(function (l , d ) l $ draw_geom(d , layout ), plot @ layers , data , " converting geom to grob" )
35
36
36
- plot_table <- layout $ render(geom_grobs , data , theme , plot @ labels )
37
+ plot_table <- layout $ render(geom_grobs , data , theme , labels )
37
38
38
39
# Legends
39
40
legend_box <- plot @ guides $ assemble(theme )
40
41
plot_table <- table_add_legends(plot_table , legend_box , theme )
41
42
42
- # Title
43
- title <- element_render(
44
- theme , " plot.title" , plot @ labels $ title ,
45
- margin_y = TRUE , margin_x = TRUE
46
- )
47
- title_height <- grobHeight(title )
48
-
49
- # Subtitle
50
- subtitle <- element_render(
51
- theme , " plot.subtitle" , plot @ labels $ subtitle ,
52
- margin_y = TRUE , margin_x = TRUE
53
- )
54
- subtitle_height <- grobHeight(subtitle )
55
-
56
43
# whole plot annotation
57
- caption <- element_render(
58
- theme , " plot.caption" , plot @ labels $ caption ,
59
- margin_y = TRUE , margin_x = TRUE
60
- )
61
- caption_height <- grobHeight(caption )
62
-
63
- # positioning of title and subtitle is governed by plot.title.position
64
- # positioning of caption is governed by plot.caption.position
65
- # "panel" means align to the panel(s)
66
- # "plot" means align to the entire plot (except margins and tag)
67
- title_pos <- arg_match0(
68
- theme $ plot.title.position %|| % " panel" ,
69
- c(" panel" , " plot" ),
70
- arg_nm = " plot.title.position" ,
71
- error_call = expr(theme())
72
- )
73
-
74
- caption_pos <- arg_match0(
75
- theme $ plot.caption.position %|| % " panel" ,
76
- values = c(" panel" , " plot" ),
77
- arg_nm = " plot.caption.position" ,
78
- error_call = expr(theme())
79
- )
80
-
81
- pans <- plot_table $ layout [grepl(" ^panel" , plot_table $ layout $ name ), , drop = FALSE ]
82
- if (title_pos == " panel" ) {
83
- title_l <- min(pans $ l )
84
- title_r <- max(pans $ r )
85
- } else {
86
- title_l <- 1
87
- title_r <- ncol(plot_table )
88
- }
89
- if (caption_pos == " panel" ) {
90
- caption_l <- min(pans $ l )
91
- caption_r <- max(pans $ r )
92
- } else {
93
- caption_l <- 1
94
- caption_r <- ncol(plot_table )
95
- }
96
-
97
- plot_table <- gtable_add_rows(plot_table , subtitle_height , pos = 0 )
98
- plot_table <- gtable_add_grob(plot_table , subtitle , name = " subtitle" ,
99
- t = 1 , b = 1 , l = title_l , r = title_r , clip = " off" )
100
-
101
- plot_table <- gtable_add_rows(plot_table , title_height , pos = 0 )
102
- plot_table <- gtable_add_grob(plot_table , title , name = " title" ,
103
- t = 1 , b = 1 , l = title_l , r = title_r , clip = " off" )
104
-
105
- plot_table <- gtable_add_rows(plot_table , caption_height , pos = - 1 )
106
- plot_table <- gtable_add_grob(plot_table , caption , name = " caption" ,
107
- t = - 1 , b = - 1 , l = caption_l , r = caption_r , clip = " off" )
108
-
109
- plot_table <- table_add_tag(plot_table , plot @ labels $ tag , theme )
110
-
111
- # Margins
112
- plot_margin <- calc_element(" plot.margin" , theme ) %|| % margin()
113
- plot_table <- gtable_add_padding(plot_table , plot_margin )
114
-
115
- if (is_theme_element(theme $ plot.background )) {
116
- plot_table <- gtable_add_grob(plot_table ,
117
- element_render(theme , " plot.background" ),
118
- t = 1 , l = 1 , b = - 1 , r = - 1 , name = " background" , z = - Inf )
119
- # plot_table$layout <- plot_table$layout[c(nrow(plot_table$layout), 1:(nrow(plot_table$layout) - 1)),]
120
- # plot_table$grobs <- plot_table$grobs[c(nrow(plot_table$layout), 1:(nrow(plot_table$layout) - 1))]
121
- }
44
+ plot_table <- table_add_titles(plot_table , labels , theme )
45
+ plot_table <- table_add_caption(plot_table , labels $ caption , theme )
46
+ plot_table <- table_add_tag(plot_table , labels $ tag , theme )
47
+ plot_table <- table_add_background(plot_table , theme )
122
48
123
49
# add alt-text as attribute
124
- attr(plot_table , " alt-label" ) <- plot @ labels $ alt
50
+ attr(plot_table , " alt-label" ) <- labels $ alt
125
51
126
52
plot_table
127
53
}
@@ -158,6 +84,166 @@ by_layer <- function(f, layers, data, step = NULL) {
158
84
out
159
85
}
160
86
87
+ # Add the legends to the gtable
88
+ table_add_legends <- function (table , legends , theme ) {
89
+
90
+ if (is_zero(legends )) {
91
+ legends <- rep(list (zeroGrob()), 5 )
92
+ names(legends ) <- c(.trbl , " inside" )
93
+ }
94
+
95
+ # Extract sizes
96
+ widths <- heights <- set_names(
97
+ rep(list (unit(0 , " cm" )), length(legends )),
98
+ names(legends )
99
+ )
100
+
101
+ empty <- vapply(legends , is_zero , logical (1 ))
102
+ widths [! empty ] <- lapply(legends [! empty ], gtable_width )
103
+ heights [! empty ] <- lapply(legends [! empty ], gtable_height )
104
+ spacing <- calc_element(" legend.box.spacing" , theme ) %|| % unit(0.2 , " cm" )
105
+
106
+ # If legend is missing, set spacing to zero for that legend
107
+ zero <- unit(0 , " pt" )
108
+ spacing <- lapply(empty , function (is_empty ) if (is_empty ) zero else spacing )
109
+
110
+ location <- switch (
111
+ theme $ legend.location %|| % " panel" ,
112
+ " plot" = plot_extent ,
113
+ find_panel
114
+ )
115
+
116
+ place <- location(table )
117
+
118
+ # Add right legend
119
+ table <- gtable_add_cols(table , spacing $ right , pos = - 1 )
120
+ table <- gtable_add_cols(table , widths $ right , pos = - 1 )
121
+ table <- gtable_add_grob(
122
+ table , legends $ right , clip = " off" ,
123
+ t = place $ t , b = place $ b , l = - 1 , r = - 1 ,
124
+ name = " guide-box-right"
125
+ )
126
+
127
+ # Add left legend
128
+ table <- gtable_add_cols(table , spacing $ left , pos = 0 )
129
+ table <- gtable_add_cols(table , widths $ left , pos = 0 )
130
+ table <- gtable_add_grob(
131
+ table , legends $ left , clip = " off" ,
132
+ t = place $ t , b = place $ b , l = 1 , r = 1 ,
133
+ name = " guide-box-left"
134
+ )
135
+
136
+ place <- location(table )
137
+
138
+ # Add bottom legend
139
+ table <- gtable_add_rows(table , spacing $ bottom , pos = - 1 )
140
+ table <- gtable_add_rows(table , heights $ bottom , pos = - 1 )
141
+ table <- gtable_add_grob(
142
+ table , legends $ bottom , clip = " off" ,
143
+ t = - 1 , b = - 1 , l = place $ l , r = place $ r ,
144
+ name = " guide-box-bottom"
145
+ )
146
+
147
+ # Add top legend
148
+ table <- gtable_add_rows(table , spacing $ top , pos = 0 )
149
+ table <- gtable_add_rows(table , heights $ top , pos = 0 )
150
+ table <- gtable_add_grob(
151
+ table , legends $ top , clip = " off" ,
152
+ t = 1 , b = 1 , l = place $ l , r = place $ r ,
153
+ name = " guide-box-top"
154
+ )
155
+
156
+ # Add manual legend
157
+ place <- find_panel(table )
158
+ table <- gtable_add_grob(
159
+ table , legends $ inside , clip = " off" ,
160
+ t = place $ t , b = place $ b , l = place $ l , r = place $ r ,
161
+ name = " guide-box-inside"
162
+ )
163
+
164
+ table
165
+ }
166
+
167
+ table_add_titles <- function (table , labels , theme ) {
168
+
169
+ # Title
170
+ title <- element_render(
171
+ theme , " plot.title" , labels $ title ,
172
+ margin_y = TRUE , margin_x = TRUE
173
+ )
174
+ title_height <- grobHeight(title )
175
+
176
+ # Subtitle
177
+ subtitle <- element_render(
178
+ theme , " plot.subtitle" , labels $ subtitle ,
179
+ margin_y = TRUE , margin_x = TRUE
180
+ )
181
+ subtitle_height <- grobHeight(subtitle )
182
+
183
+ # positioning of title and subtitle is governed by plot.title.position
184
+ # "panel" means align to the panel(s)
185
+ # "plot" means align to the entire plot (except margins and tag)
186
+ title_pos <- arg_match0(
187
+ theme $ plot.title.position %|| % " panel" ,
188
+ c(" panel" , " plot" ),
189
+ arg_nm = " plot.title.position" ,
190
+ error_call = expr(theme())
191
+ )
192
+
193
+ panels <- table $ layout [grepl(" ^panel" , table $ layout $ name ), , drop = FALSE ]
194
+ if (title_pos == " panel" ) {
195
+ l <- min(panels $ l )
196
+ r <- max(panels $ r )
197
+ } else {
198
+ l <- 1
199
+ r <- ncol(table )
200
+ }
201
+
202
+ table <- gtable_add_rows(table , subtitle_height , pos = 0 )
203
+ table <- gtable_add_grob(table , subtitle , name = " subtitle" ,
204
+ t = 1 , b = 1 , l = l , r = r , clip = " off" )
205
+
206
+ table <- gtable_add_rows(table , title_height , pos = 0 )
207
+ table <- gtable_add_grob(table , title , name = " title" ,
208
+ t = 1 , b = 1 , l = l , r = r , clip = " off" )
209
+
210
+ table
211
+ }
212
+
213
+ table_add_caption <- function (table , label , theme ) {
214
+
215
+ caption <- element_render(
216
+ theme , " plot.caption" , label ,
217
+ margin_y = TRUE , margin_x = TRUE
218
+ )
219
+ caption_height <- grobHeight(caption )
220
+
221
+ # positioning of title and subtitle is governed by plot.title.position
222
+ # positioning of caption is governed by plot.caption.position
223
+ # "panel" means align to the panel(s)
224
+ # "plot" means align to the entire plot (except margins and tag)
225
+ position <- arg_match0(
226
+ theme $ plot.caption.position %|| % " panel" ,
227
+ values = c(" panel" , " plot" ),
228
+ arg_nm = " plot.caption.position" ,
229
+ error_call = expr(theme())
230
+ )
231
+
232
+ pans <- table $ layout [grepl(" ^panel" , table $ layout $ name ), , drop = FALSE ]
233
+ if (position == " panel" ) {
234
+ l <- min(pans $ l )
235
+ r <- max(pans $ r )
236
+ } else {
237
+ l <- 1
238
+ r <- ncol(table )
239
+ }
240
+
241
+ table <- gtable_add_rows(table , caption_height , pos = - 1 )
242
+ table <- gtable_add_grob(table , caption , name = " caption" ,
243
+ t = - 1 , b = - 1 , l = l , r = r , clip = " off" )
244
+ table
245
+ }
246
+
161
247
# Add the tag element to the gtable
162
248
table_add_tag <- function (table , label , theme ) {
163
249
# Initialise the tag margins
@@ -273,83 +359,20 @@ table_add_tag <- function(table, label, theme) {
273
359
)
274
360
}
275
361
276
- # Add the legends to the gtable
277
- table_add_legends <- function (table , legends , theme ) {
278
-
279
- if (is_zero(legends )) {
280
- legends <- rep(list (zeroGrob()), 5 )
281
- names(legends ) <- c(.trbl , " inside" )
362
+ table_add_background <- function (table , theme ) {
363
+ # Margins
364
+ margin <- calc_element(" plot.margin" , theme ) %|| % margin()
365
+ table <- gtable_add_padding(table , margin )
366
+
367
+ background <- calc_element(" plot.background" , theme )
368
+ if (is_theme_element(background )) {
369
+ table <- gtable_add_grob(
370
+ table , element_grob(background ),
371
+ t = 1 , l = 1 , b = - 1 , r = - 1 ,
372
+ name = " background" , z = - Inf
373
+ )
282
374
}
283
375
284
- # Extract sizes
285
- widths <- heights <- set_names(
286
- rep(list (unit(0 , " cm" )), length(legends )),
287
- names(legends )
288
- )
289
-
290
- empty <- vapply(legends , is_zero , logical (1 ))
291
- widths [! empty ] <- lapply(legends [! empty ], gtable_width )
292
- heights [! empty ] <- lapply(legends [! empty ], gtable_height )
293
- spacing <- calc_element(" legend.box.spacing" , theme ) %|| % unit(0.2 , " cm" )
294
-
295
- # If legend is missing, set spacing to zero for that legend
296
- zero <- unit(0 , " pt" )
297
- spacing <- lapply(empty , function (is_empty ) if (is_empty ) zero else spacing )
298
-
299
- location <- switch (
300
- theme $ legend.location %|| % " panel" ,
301
- " plot" = plot_extent ,
302
- find_panel
303
- )
304
-
305
- place <- location(table )
306
-
307
- # Add right legend
308
- table <- gtable_add_cols(table , spacing $ right , pos = - 1 )
309
- table <- gtable_add_cols(table , widths $ right , pos = - 1 )
310
- table <- gtable_add_grob(
311
- table , legends $ right , clip = " off" ,
312
- t = place $ t , b = place $ b , l = - 1 , r = - 1 ,
313
- name = " guide-box-right"
314
- )
315
-
316
- # Add left legend
317
- table <- gtable_add_cols(table , spacing $ left , pos = 0 )
318
- table <- gtable_add_cols(table , widths $ left , pos = 0 )
319
- table <- gtable_add_grob(
320
- table , legends $ left , clip = " off" ,
321
- t = place $ t , b = place $ b , l = 1 , r = 1 ,
322
- name = " guide-box-left"
323
- )
324
-
325
- place <- location(table )
326
-
327
- # Add bottom legend
328
- table <- gtable_add_rows(table , spacing $ bottom , pos = - 1 )
329
- table <- gtable_add_rows(table , heights $ bottom , pos = - 1 )
330
- table <- gtable_add_grob(
331
- table , legends $ bottom , clip = " off" ,
332
- t = - 1 , b = - 1 , l = place $ l , r = place $ r ,
333
- name = " guide-box-bottom"
334
- )
335
-
336
- # Add top legend
337
- table <- gtable_add_rows(table , spacing $ top , pos = 0 )
338
- table <- gtable_add_rows(table , heights $ top , pos = 0 )
339
- table <- gtable_add_grob(
340
- table , legends $ top , clip = " off" ,
341
- t = 1 , b = 1 , l = place $ l , r = place $ r ,
342
- name = " guide-box-top"
343
- )
344
-
345
- # Add manual legend
346
- place <- find_panel(table )
347
- table <- gtable_add_grob(
348
- table , legends $ inside , clip = " off" ,
349
- t = place $ t , b = place $ b , l = place $ l , r = place $ r ,
350
- name = " guide-box-inside"
351
- )
352
-
353
376
table
354
377
}
355
378
0 commit comments