tidyverse / ggplot2

An implementation of the Grammar of Graphics in R
https://ggplot2.tidyverse.org
Other
6.5k stars 2.02k forks source link

tag position inside plot borders #4297

Closed Aariq closed 1 year ago

Aariq commented 3 years ago

Some peer-reviewed journals (e.g. Oecologia) require figure panel labels to be inside of plot borders (although they seem to enforce these requirements inconsistently). It would be nice if there were an option like theme(plot.tag.position = "topleftinner") to place a label at the upper left corner of the inside of plot borders. Currently, I think I have to kludge this by tweaking theme(plot.tag = element_text(vjust = , hjust = ), but it's inconsistent, so I have to do this tweaking for every panel individually. Maybe there's an easier way that I don't know about?

Related to: https://github.com/thomasp85/patchwork/issues/222

library(ggplot2)
p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp)) + labs(tag = "a)")
p1 + theme(plot.tag.position = c(0,1),
           plot.tag = element_text(vjust = 1.5, hjust = -2.85))

# left of "a" just touching plot border

p3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec)) + labs(tag = "b)")
p3 + theme(plot.tag.position = c(0,1),
           plot.tag = element_text(vjust = 1.5, hjust = -2.85))
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'

# "b)" is slightly further in with same theme()

Created on 2020-12-15 by the reprex package (v0.3.0)

teunbrand commented 3 years ago

If you wrap a text annotation, it's not that cumbersome to achieve similar effects. The -Inf and Inf positions place it in the corner.

library(ggplot2)

place_label <- function(label, size = 5, ...) {
  annotate("text", label = label, x = -Inf, y = Inf, 
           hjust = 0, vjust = 1, size = size, ...)
}

p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
p1 + place_label("a)")

Created on 2021-01-09 by the reprex package (v0.3.0)

Aariq commented 3 years ago

Wow, thank you! I had no clue you could pass Inf as a position like that.

eliocamp commented 3 years ago

I also came into this issue and made a package: tagger. It's not perfect, but it might be useful!

library(tagger)
library(ggplot2)

ggplot(mtcars, aes(hp, mpg)) +
   geom_point() +
   facet_grid(cyl ~ vs) +
   tag_facets()

image

thomasp85 commented 3 years ago

I think the main benefit of having it as a proper part of the tag element is that it will allow patchwork to use the position for auto tagging

thomasp85 commented 3 years ago

I think adding a setting such as plot.tag.position would be nicely aligned with how positioning of titles currently work