Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nudge ggplot text based on value [duplicate]

Tags:

r

ggplot2

How would I nudge text based on value:

E.g.,

library(ggplot2)
theme_set(theme_bw())  

# Data Prep
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.

# Diverging Barcharts
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")) + 
  geom_text(size=2, nudge_y = 0.1) +
  labs(subtitle="Normalised mileage from 'mtcars'", 
       title= "Diverging Bars") + 
  coord_flip()

Currently, text shows on top of negative bars: enter image description here

I'd like to nudge it to the left only for these bars, to the right for positive bars.

Example source

like image 876
dzeltzer Avatar asked Sep 04 '26 03:09

dzeltzer


2 Answers

We may use, e.g.,

geom_text(size = 2, nudge_y = -0.1 + 0.2 * (mtcars$mpg_z > 0))

or

geom_text(size = 2, nudge_y = ifelse(mtcars$mpg_z > 0, 0.1, -0.1))

to construct a vector of nudge_y values. This gives

enter image description here

like image 143
Julius Vainora Avatar answered Sep 06 '26 18:09

Julius Vainora


Here, instead of using nudge_y I just manually add (or subtract) a fixed value to y in geom_text depending on the sign of mpg_z, as determined by the aptly named function sign. The only line that differs from your example is geom_text(size=2, aes(y = mpg_z + 0.1 * sign(mpg_z)))

library(ggplot2)
theme_set(theme_bw())  

# Data Prep
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.

# Diverging Barcharts
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")) + 
  geom_text(size=2, aes(y = mpg_z + 0.1 * sign(mpg_z))) +
  labs(subtitle="Normalised mileage from 'mtcars'", 
       title= "Diverging Bars") + 
  coord_flip()

Created on 2019-02-05 by the reprex package (v0.2.1)

like image 44
Lyngbakr Avatar answered Sep 06 '26 20:09

Lyngbakr