Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add vertical lines to ggplot boxplots in R

I am plotting boxplots from this data:

MY_LABEL     MY_REAL     MY_CATEGORY
1 [POS]       .56            POS
1 [POS]       .57            POS
1 [POS]       .37            POS
2 [POS]       .51            POS
1 [sim v]     .65            sim v
...

I'm using ggplot2:

ggplot( data=myDF, aes( x=MY_LABEL, y=MY_REAL, fill=MY_CATEGORY ) ) +
    scale_colour_manual( values=palette ) +
    coord_flip() + 
    geom_boxplot( outlier.size = 0 )

This works fine, and groups the boxplots by the field MY_CATEGORY: enter image description here

I'd like to do 2 things:

1) To improve the clarity of this plot, I'd like to add separators between the various blocks, i.e. between POS and sim v, between sim v and C, etc (see the ugly red lines in the plot). I've been struggling with geom_vline with no luck. Alternatively, I'd like to add blank space between the blocks.

2) If I print this plot in grayscale, I can't distinguish the different blocks. I'm trying to force a different palette with:

scale_colour_manual( values=c("black","darkgray","gray","white") )

Again, no luck, the plot doesn't change at all.

What would you suggest to do?

like image 272
Mulone Avatar asked Jun 26 '12 20:06

Mulone


People also ask

How do I add a vertical line in ggplot2?

To create a vertical line using ggplot2, we can use geom_vline function of ggplot2 package and if we want to have a wide vertical line with different color then lwd and colour argument will be used. The lwd argument will increase the width of the line and obviously colour argument will change the color.

How do I graph a vertical line in R?

The R function abline() can be used to add vertical, horizontal or regression lines to a graph. A simplified format of the abline() function is : abline(a=NULL, b=NULL, h=NULL, v=NULL, ...)


3 Answers

Would this work for you?

require(ggplot2)
mtcars$cyl2<- ifelse(mtcars$cyl > 4, c('A'), c('B')) 
p <- ggplot(mtcars, aes(factor(cyl), mpg))
p + geom_boxplot() + facet_grid(. ~ cyl2, scales = "free", space = "free")

would give something like this, bbb

like image 93
Eric Fail Avatar answered Nov 03 '22 00:11

Eric Fail


To change the fill colors, you need a named vector of values. The names need exactly match the y-axis category names.

scale_fill_manual(values=c("POS"="black", "sim v"="gray50",
                           "C"="gray80", "sim t"="white"))

To separate the y-axis categories, try facet_grid().

facet_grid(factor(MY_CATEGORY) ~ ., drop=TRUE)

I'm not sure that this will work because I don't have your data to test it.

like image 24
bdemarest Avatar answered Nov 03 '22 01:11

bdemarest


No one covered the horizontal line route, so I thought I'd add it. Not sure why geom_vline() wasn't working for you. Here's what I did (chose to play off of Eric Fail's approach):

require(ggplot2)
p <- ggplot(mtcars, aes(factor(cyl), mpg))
p <- p + geom_boxplot(aes(fill=factor(cyl))) + coord_flip()
p <- p + geom_vline(xintercept=c(1.5,2.5))
p

There's only three boxplots here, but in playing around, ggplot appears to place them at integer locations. Just figure out which box you want a line after (nth) and put the xintercept argument at n+0.5 for the line. You can obviously change the thickness and color to your liking: just add a size=width and colour="name" after the xintercept bit.

By the way, geom_vline() seems to work for me regardless of whether it's before or after coord_flip(). I find that counter-intuitive.


I'm not sure bdemarest is correct that you need the names to match the category names. I think the issue is that you used scale_colour_manual(), which applies if you used aes(..., colour=var) whereas you used fill=var. Thus, you need scale_fill_manual. Building on the above, we can add:

p <- p + scale_fill_manual(values=c("black","gray","white"))
p

Note that I've not defined any factor names for the colors to match. I think the colors are simply applied to your factor levels according to their order, but I could be wrong.


The end result of all of the above:

cyl boxplot

like image 42
Hendy Avatar answered Nov 03 '22 01:11

Hendy