0

I want to add some custom labels to my plot in R. Code below to create the original plot (found example on the internet).

library(ggplot2)
theme_set(theme_bw())  
data("mtcars")  # load data
mtcars$`car name` <- rownames(mtcars)  # create new column for car names
mtcars$mpg_z <- round((mtcars$mpg - mean(mtcars$mpg))/sd(mtcars$mpg), 2)  # compute normalized mpg
mtcars$mpg_type <- ifelse(mtcars$mpg_z < 0, "below", "above")  # above / below avg flag
mtcars <- mtcars[order(mtcars$mpg_z), ]  # sort
mtcars$`car name` <- factor(mtcars$`car name`, levels = mtcars$`car name`)  # convert to factor to retain sorted order in plot.

ggplot(mtcars, aes(x=`car name`, y=mpg_z, label=mpg_z)) + 
  geom_bar(stat='identity', aes(fill=mpg_type), width=.5)  +
  scale_fill_manual(name="Mileage", 
                labels = c("Above Average", "Below Average"), 
                values = c("above"="#00ba38", "below"="#f8766d")) + 
  labs(subtitle="Normalised mileage from 'mtcars'", 
   title= "Diverging Bars") + 
  coord_flip()

Plot looks like this (text in red on x-axis is what I want to add)...

enter image description here

AyeTown
  • 831
  • 1
  • 5
  • 20

1 Answers1

0

You can use annotation_custom if you set clip = off:

library(ggplot2)
ggplot(mtcars, aes(x=`car name`, y=mpg_z, label=mpg_z)) + 
  geom_bar(stat='identity', aes(fill=mpg_type), width=.5)  +
  scale_fill_manual(name="Mileage", 
                labels = c("Above Average", "Below Average"), 
                values = c("above"="#00ba38", "below"="#f8766d")) + 
  labs(subtitle="Normalised mileage from 'mtcars'", 
   title= "Diverging Bars") + ylab("") +
  coord_flip(clip = "off") + 
  annotation_custom(textGrob("Below", 
                             gp=gpar(fontsize=13,
                                     col = "red", 
                                     fontface="bold")),
                    xmin=-2, xmax=-2, ymin=-0.5, ymax=-0.5) +
  annotation_custom(textGrob("Above",
                             gp=gpar(fontsize=13,
                                     col = "red",
                                     fontface="bold")),
                    xmin=-2, xmax=-2, ymin=1.5, ymax=1.5) +
      theme(plot.margin = unit(c(1,3,1,1), "lines"))

enter image description here

Just remember that x and y are switched when you set coord_flip.

Community
  • 1
  • 1
Ian Campbell
  • 23,484
  • 14
  • 36
  • 57
  • This is great, however, I am trying to get the same result in plotly. But when I assign the ggplot2 to variable "plot" and code ggplotly(plot)... the textGrob function is not supported :( – AyeTown May 13 '20 at 21:47
  • @AyeTown add grid:: as a prefix to specify the library. Also for gpar. Example: annotation_custom(grid::textGrob("Above", gp=grid::gpar(fontsize=13, col = "red", fontface="bold")), xmin=-2, xmax=-2, ymin=1.5, ymax=1.5) – Peurke Jul 28 '21 at 09:24