@@ -268,11 +268,6 @@ ggplot_gtable.ggplot_built <- function(data) {
268268 subtitle <- element_render(theme , " plot.subtitle" , plot $ labels $ subtitle , margin_y = TRUE )
269269 subtitle_height <- grobHeight(subtitle )
270270
271- # Tag
272- tag <- element_render(theme , " plot.tag" , plot $ labels $ tag , margin_y = TRUE , margin_x = TRUE )
273- tag_height <- grobHeight(tag )
274- tag_width <- grobWidth(tag )
275-
276271 # whole plot annotation
277272 caption <- element_render(theme , " plot.caption" , plot $ labels $ caption , margin_y = TRUE )
278273 caption_height <- grobHeight(caption )
@@ -318,75 +313,7 @@ ggplot_gtable.ggplot_built <- function(data) {
318313 plot_table <- gtable_add_grob(plot_table , caption , name = " caption" ,
319314 t = - 1 , b = - 1 , l = caption_l , r = caption_r , clip = " off" )
320315
321- plot_table <- gtable_add_rows(plot_table , unit(0 , ' pt' ), pos = 0 )
322- plot_table <- gtable_add_cols(plot_table , unit(0 , ' pt' ), pos = 0 )
323- plot_table <- gtable_add_rows(plot_table , unit(0 , ' pt' ), pos = - 1 )
324- plot_table <- gtable_add_cols(plot_table , unit(0 , ' pt' ), pos = - 1 )
325-
326- tag_pos <- theme $ plot.tag.position %|| % " topleft"
327- if (length(tag_pos ) == 2 ) tag_pos <- " manual"
328- valid_pos <- c(" topleft" , " top" , " topright" , " left" , " right" , " bottomleft" ,
329- " bottom" , " bottomright" )
330-
331- if (! (tag_pos == " manual" || tag_pos %in% valid_pos )) {
332- cli :: cli_abort(" {.arg plot.tag.position} should be a coordinate or one of {.or {.val {valid_pos}}}" )
333- }
334-
335- if (tag_pos == " manual" ) {
336- xpos <- theme $ plot.tag.position [1 ]
337- ypos <- theme $ plot.tag.position [2 ]
338- tag_parent <- justify_grobs(tag , x = xpos , y = ypos ,
339- hjust = theme $ plot.tag $ hjust ,
340- vjust = theme $ plot.tag $ vjust ,
341- int_angle = theme $ plot.tag $ angle ,
342- debug = theme $ plot.tag $ debug )
343- plot_table <- gtable_add_grob(plot_table , tag_parent , name = " tag" , t = 1 ,
344- b = nrow(plot_table ), l = 1 ,
345- r = ncol(plot_table ), clip = " off" )
346- } else {
347- # Widths and heights are reassembled below instead of assigning into them
348- # in order to avoid bug in grid 3.2 and below.
349- if (tag_pos == " topleft" ) {
350- plot_table $ widths <- unit.c(tag_width , plot_table $ widths [- 1 ])
351- plot_table $ heights <- unit.c(tag_height , plot_table $ heights [- 1 ])
352- plot_table <- gtable_add_grob(plot_table , tag , name = " tag" ,
353- t = 1 , l = 1 , clip = " off" )
354- } else if (tag_pos == " top" ) {
355- plot_table $ heights <- unit.c(tag_height , plot_table $ heights [- 1 ])
356- plot_table <- gtable_add_grob(plot_table , tag , name = " tag" ,
357- t = 1 , l = 1 , r = ncol(plot_table ),
358- clip = " off" )
359- } else if (tag_pos == " topright" ) {
360- plot_table $ widths <- unit.c(plot_table $ widths [- ncol(plot_table )], tag_width )
361- plot_table $ heights <- unit.c(tag_height , plot_table $ heights [- 1 ])
362- plot_table <- gtable_add_grob(plot_table , tag , name = " tag" ,
363- t = 1 , l = ncol(plot_table ), clip = " off" )
364- } else if (tag_pos == " left" ) {
365- plot_table $ widths <- unit.c(tag_width , plot_table $ widths [- 1 ])
366- plot_table <- gtable_add_grob(plot_table , tag , name = " tag" ,
367- t = 1 , b = nrow(plot_table ), l = 1 ,
368- clip = " off" )
369- } else if (tag_pos == " right" ) {
370- plot_table $ widths <- unit.c(plot_table $ widths [- ncol(plot_table )], tag_width )
371- plot_table <- gtable_add_grob(plot_table , tag , name = " tag" ,
372- t = 1 , b = nrow(plot_table ), l = ncol(plot_table ),
373- clip = " off" )
374- } else if (tag_pos == " bottomleft" ) {
375- plot_table $ widths <- unit.c(tag_width , plot_table $ widths [- 1 ])
376- plot_table $ heights <- unit.c(plot_table $ heights [- nrow(plot_table )], tag_height )
377- plot_table <- gtable_add_grob(plot_table , tag , name = " tag" ,
378- t = nrow(plot_table ), l = 1 , clip = " off" )
379- } else if (tag_pos == " bottom" ) {
380- plot_table $ heights <- unit.c(plot_table $ heights [- nrow(plot_table )], tag_height )
381- plot_table <- gtable_add_grob(plot_table , tag , name = " tag" ,
382- t = nrow(plot_table ), l = 1 , r = ncol(plot_table ), clip = " off" )
383- } else if (tag_pos == " bottomright" ) {
384- plot_table $ widths <- unit.c(plot_table $ widths [- ncol(plot_table )], tag_width )
385- plot_table $ heights <- unit.c(plot_table $ heights [- nrow(plot_table )], tag_height )
386- plot_table <- gtable_add_grob(plot_table , tag , name = " tag" ,
387- t = nrow(plot_table ), l = ncol(plot_table ), clip = " off" )
388- }
389- }
316+ plot_table <- table_add_tag(plot_table , plot $ labels $ tag , theme )
390317
391318 # Margins
392319 plot_table <- gtable_add_rows(plot_table , theme $ plot.margin [1 ], pos = 0 )
@@ -431,3 +358,117 @@ by_layer <- function(f, layers, data, step = NULL) {
431358 )
432359 out
433360}
361+
362+ # Add the tag element to the gtable
363+ table_add_tag <- function (table , label , theme ) {
364+ # Initialise the tag margins
365+ table <- gtable_add_padding(table , unit(0 , " pt" ))
366+
367+ # Early exit when label is absent or element is blank
368+ if (length(label ) < 1 ) {
369+ return (table )
370+ }
371+ element <- calc_element(" plot.tag" , theme )
372+ if (inherits(element , " element_blank" )) {
373+ return (table )
374+ }
375+
376+ # Resolve position
377+ position <- calc_element(" plot.tag.position" , theme ) %|| % " topleft"
378+ location <- calc_element(" plot.tag.location" , theme ) %|| %
379+ (if (is.numeric(position )) " plot" else " margin" )
380+
381+ if (is.numeric(position )) {
382+ if (location == " margin" ) {
383+ cli :: cli_abort(paste0(
384+ " A {.cls numeric} {.arg plot.tag.position} cannot be used with " ,
385+ " {.code \" margin\" } as {.arg plot.tag.location}."
386+ ))
387+ }
388+ if (length(position ) != 2 ) {
389+ cli :: cli_abort(paste0(
390+ " A {.cls numeric} {.arg plot.tag.position} " ,
391+ " theme setting must have length 2."
392+ ))
393+ }
394+ top <- left <- right <- bottom <- FALSE
395+ } else {
396+ # Break position into top/left/right/bottom
397+ position <- arg_match0(
398+ position [1 ],
399+ c(" topleft" , " top" , " topright" , " left" ,
400+ " right" , " bottomleft" , " bottom" , " bottomright" ),
401+ arg_nm = " plot.tag.position"
402+ )
403+ top <- position %in% c(" topleft" , " top" , " topright" )
404+ left <- position %in% c(" topleft" , " left" , " bottomleft" )
405+ right <- position %in% c(" topright" , " right" , " bottomright" )
406+ bottom <- position %in% c(" bottomleft" , " bottom" , " bottomright" )
407+ }
408+
409+ # Resolve tag and sizes
410+ tag <- element_grob(element , label = label , margin_y = TRUE , margin_x = TRUE )
411+ height <- grobHeight(tag )
412+ width <- grobWidth(tag )
413+
414+ if (location %in% c(" plot" , " panel" )) {
415+ if (! is.numeric(position )) {
416+ if (right || left ) {
417+ x <- (1 - element $ hjust ) * width
418+ if (right ) {
419+ x <- unit(1 , " npc" ) - x
420+ }
421+ } else {
422+ x <- unit(element $ hjust , " npc" )
423+ }
424+ if (top || bottom ) {
425+ y <- (1 - element $ vjust ) * height
426+ if (top ) {
427+ y <- unit(1 , " npc" ) - y
428+ }
429+ } else {
430+ y <- unit(element $ vjust , " npc" )
431+ }
432+ } else {
433+ x <- unit(position [1 ], " npc" )
434+ y <- unit(position [2 ], " npc" )
435+ }
436+ # Do manual placement of tag
437+ tag <- justify_grobs(
438+ tag , x = x , y = y ,
439+ hjust = element $ hjust , vjust = element $ vjust ,
440+ int_angle = element $ angle , debug = element $ debug
441+ )
442+ if (location == " plot" ) {
443+ table <- gtable_add_grob(
444+ table , tag , name = " tag" , clip = " off" ,
445+ t = 1 , b = nrow(table ), l = 1 , r = ncol(table )
446+ )
447+ return (table )
448+ }
449+ }
450+
451+ if (location == " panel" ) {
452+ place <- find_panel(table )
453+ } else {
454+ n_col <- ncol(table )
455+ n_row <- nrow(table )
456+ # Actually fill margin with relevant units
457+ if (top ) table $ heights <- unit.c(height , table $ heights [- 1 ])
458+ if (left ) table $ widths <- unit.c(width , table $ widths [- 1 ])
459+ if (right ) table $ widths <- unit.c(table $ widths [- n_col ], width )
460+ if (bottom ) table $ heights <- unit.c(table $ heights [- n_row ], height )
461+ place <- data_frame0(t = 1L , r = n_col , b = n_row , l = 1L )
462+ }
463+
464+ # Shrink placement to position
465+ if (top ) place $ b <- place $ t
466+ if (left ) place $ r <- place $ l
467+ if (right ) place $ l <- place $ r
468+ if (bottom ) place $ t <- place $ b
469+
470+ gtable_add_grob(
471+ table , tag , name = " tag" , clip = " off" ,
472+ t = place $ t , l = place $ l , b = place $ b , r = place $ r
473+ )
474+ }
0 commit comments