Search code examples
rggplot2rectangles

Draw a series of rectangles with ggplot2, using different colors


I guess this questions has been asked already but I will try it anyways, as I couldn't find anything thich solved my problem.

I simply want to draw a series of rectangles, and then color them depending on a value, but not the x or y value.

So: I am reading from a file start and end positions for the rectangles I want to draw:

file <- read.table("positions.txt", header=FALSE)
names(file) <- c("start", "end")

char_start <- as.character(file$start)
first <- as.numeric(char_start)

char_end <- as.character(file$end)
last <- as.numeric(char_end)

mydata <- data.frame(first, last)

I make my plot then like this:

plot <- ggplot() + geom_rect(data = mydata, aes(xmin = mydata$first, xmax = mydata$last, ymin = 2, ymax = 5)) 

Now I was trying to fill the rectangles with two different colors, depending on some other value. Lets say for example that I have another file "positions_subset.txt" which contains a subset of the first file. If a rectangle is contained in both, I want it blue, otherwise red.

Idea:

So what I thought how I could do it, is to parse the to files, and every time I find the coordinate pair in both files, I add a "1" to a vector, otherwise "0". So at the end I get a vector like:

 in_both <- c(1,0,0,1,0...)

which has the same number of elements as rectangles I have. Then I simply did:

colors <- ifelse(in_both == 1, "blue", "red")

However if I then try to do it like

ggplot() + aes(xmin = mydata$first, xmax = mydata$last, ymin = 2, ymax = 5, fill=colors))

I get the error "Aesthetics must be either length 1 or the same as the data (30): xmin, xmax, ymin, ymax, fill"

I understand what the error is saying but I don't know how I could do it otherwise. Do I really need for each point on the x axis to have a color information?


Solution

  • Add a column to you data containing the variable used to color

     data$color<-colors
    

    Then use

     aes(xmin=first, xmax=last,...,fill=color)
    

    you should pass the name of the variable to aes, not a vector