13

So this is very relevant to this question and this answer is an excellent solution.

The problem is that when I try to export the plot using ggsave the curly braces aren't present.

example:

library(ggplot2)
library(grid)
library(pBrackets) 

x <- c(runif(10),runif(10)+2)
y <- c(runif(10),runif(10)+2)

the_plot <- qplot(x=x,y=y) +
  scale_x_continuous("",breaks=c(.5,2.5),labels=c("Low types","High types") ) +
  theme(axis.ticks = element_blank(),
        axis.ticks.length = unit(.85, "cm"))
the_plot

grid.locator(unit="native") 
bottom_y <- 284 

grid.brackets(220, bottom_y,   80, bottom_y, lwd=2, col="red")
grid.brackets(600, bottom_y,  440, bottom_y, lwd=2, col="red")

ggsave("test.png",width = 4, height = 2.5)

I'm not open to using the RStudio export button as it doesn't properly export my theme font sizes etc. I also need higher resolution than 76 dpi. I need a solution to add curly braces to a ggplot2 graphic and be able to save it using ggsave.

zx8754
  • 52,746
  • 12
  • 114
  • 209
SamanthaDS
  • 1,123
  • 1
  • 10
  • 18

4 Answers4

18

I don't understand the logic used in grid.brackets but it would help if there was a bracketsGrob function that would simply return a grob without drawing it. Perhaps contact the maintainer with a feature request?

Anyway, assuming such a function was available, it can be fed to annotation_custom making it compatible with ggsave.

bracketsGrob <- function(...){
l <- list(...)
e <- new.env()
e$l <- l
  grid:::recordGrob(  {
    do.call(grid.brackets, l)
  }, e)
}

# note that units here are "npc", the only unit (besides physical units) that makes sense
# when annotating the plot panel in ggplot2 (since we have no access to 
# native units)

b1 <- bracketsGrob(0.33, 0.05, 0, 0.05, h=0.05, lwd=2, col="red")
b2 <- bracketsGrob(1, 0.05, 0.66, 0.05, h=0.05,  lwd=2, col="red")

p <- the_plot + 
  annotation_custom(b1)+ 
  annotation_custom(b2) +
  scale_y_continuous(expand=c(0.11,0))
p

ggsave("test.png", p, width = 4, height = 2.5)

enter image description here

baptiste
  • 75,767
  • 19
  • 198
  • 294
  • 1
    Yes, that is a better answer. – Mike Wise Mar 04 '16 at 22:29
  • This is amazing. One of these days I have to learn grid/grob manipulation. One simplification: you don’t need to create a new environment in `bracketsGrob`, you can pass `environment()`. It only contains the `l` variable anyway. – Konrad Rudolph Nov 29 '16 at 11:33
  • Great answer, one comment on the "npc" units as it took me a while to get my head around it (thanks for making it clear in your answer!). If you want to go from your x,y values you will need to scale them by the axes (so 1 = end of axis and 0 = beginning of axis). – Gooze Nov 26 '19 at 16:06
3

Well I figured you could do something with devices, as an alternative to ggsave, and I finally got this to work. It was more effort than it should have been because R-Studio somehow gets confused about which devices are actually open or closed (off). So you have to reset your R session sometimes. Checking dev.list() a lot helps. Sort of...

But after a bit of testing this sequence works fairly reliably.

I tested it with jpeg too because I can look at the resolution with the file property command in windows to see that the resolution I specified (200 ppi) is getting through:

library(ggplot2)
library(grid)
library(pBrackets) 


x <- c(runif(10),runif(10)+2)
y <- c(runif(10),runif(10)+2)
the_plot <- qplot(x=x,y=y) +
  scale_x_continuous("",breaks=c(.5,2.5),labels=c("Low types","High types") ) +
  theme(axis.ticks = element_blank(),
        axis.ticks.length = unit(.85, "cm"))

the_plot

# User has to click here to specify where the brackets go
grid.locator(unit="native") 
bottom_y <- 284 
grid.brackets(220, bottom_y,   80, bottom_y, lwd=2, col="red")
grid.brackets(600, bottom_y,  440, bottom_y, lwd=2, col="red")

#dev.copy(png,"mypng.png",height=1000,width=1000,res=200)
dev.copy(jpeg,"myjpg.jpg",height=1000,width=1000,res=200) 
dev.off()

The image: enter image description here

The properties:

enter image description here

Mike Wise
  • 22,131
  • 8
  • 81
  • 104
2

A very, very late answer, my package lemon does this, albeit not curly braces, but square braces.

Here's an example from the vignette - they can be directed both outwards and inwards, see more at https://cran.r-project.org/package=lemon.

enter image description here

MrGumble
  • 5,631
  • 1
  • 18
  • 33
0

You can check out this this answer to the same question. Those braces have no issues for exporting as they is based on normal geom_path.

NicolasH2
  • 774
  • 5
  • 20