Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot: Add geom_rect using categorical value for min and max values

Tags:

r

ggplot2

I have a very basic ggplot:

library(ggplot)

ggplot(mpg, aes(x=displ, y=manufacturer)) +
  geom_point() +
  geom_rect(aes(xmin=1.8, xmax=3.0, ymin='audi', ymax='audi', fill='red')) 

I'd like to add a bar from x axis values 1.8 to 3.0 only for the audi row on the y axis. Is there a way to achieve this in ggplot? Any help others can offer on this question would be greatly appreciated!

like image 265
duhaime Avatar asked Oct 21 '25 15:10

duhaime


2 Answers

Building on @Greg's answer, I believe it is is safer to recreate the factor levels in the aes call in geom_rect. This is because it is the factor levels rather than the character strings that are coerced to integer.

ggplot(mpg, aes(x=displ, y=manufacturer)) +
  geom_point() +
  geom_rect(aes(ymin = which(levels(as.factor(manufacturer))=="audi") -0.5,
                ymax = which(levels(as.factor(manufacturer))=="audi") +0.5,
                xmin=1.8,
                xmax=3,
                fill="red"))

enter image description here

This works even if the factor levels have been altered from default:

my.mpg <- mpg
my.mpg$manufacturer <-as.factor(my.mpg$manufacturer)
my.mpg$manufacturer <-factor(my.mpg$manufacturer,
                             levels = rev(levels(my.mpg$manufacturer)))
ggplot(my.mpg, aes(x=displ, y=manufacturer)) +
  geom_point() +
  geom_rect(aes(ymin = which(levels(as.factor(manufacturer))=="audi") -0.5,
                ymax = which(levels(as.factor(manufacturer))=="audi") +0.5,
                xmin=1.8,
                xmax=3,
                fill="red"))

enter image description here

In contrast, the which(unique(...)) method fails:

man_list <- unique(my.mpg$manufacturer)

ggplot(my.mpg, aes(x=displ, y=manufacturer)) +
  geom_point() +
  # geom_rect(aes(xmin=1.8, xmax=3.0, ymin= "audi", ymax=lead("audi"), fill='red')) 
  geom_rect(aes(ymin = which(man_list=="audi")-0.5,
                ymax = which(man_list=="audi")+0.5,
                xmin=1.8,
                xmax=3,
                fill="red"))

enter image description here

like image 127
Ian Campbell Avatar answered Oct 23 '25 05:10

Ian Campbell


It can be done. Categorical values are converted to integers for plotting, so you can either specify them as integers (audi is the first category, so integer is 1), or, as I've done below, make a list of the category names and specify by name.

library(ggplot)
data("mpg")
man_list <- unique(mpg$manufacturer)

ggplot(mpg, aes(x=displ, y=manufacturer)) +
  geom_point() +
  # geom_rect(aes(xmin=1.8, xmax=3.0, ymin= "audi", ymax=lead("audi"), fill='red')) 
  geom_rect(aes(ymin = which(man_list=="audi")-0.5,
                ymax = which(man_list=="audi")+0.5,
                xmin=1.8,
                xmax=3,
                fill="red"))

enter image description here

like image 24
Greg Avatar answered Oct 23 '25 06:10

Greg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!