How to make a ggplot2 sequence coverage map

Hello all,

I am trying to make this graph in R:
image

However, I am not sure how to make the heights of each rectangle reset when their is no overlap.

The data frame that I am using is as follows:

data = data.frame("x"=c(1,1,1,5,5,7,7,10),
"y"=c(15,12,8,15,10,10,13,15),
"d"=c(1,2,3,4,5,6,7,8))
And a simplified version of the code is below:

ggplot() +
geom_rect(data=data,mapping=aes(xmin=x,xmax=y,ymin=d-0.4,ymax=d+0.4))

However, this is not quite right...
Any help would be appreciated!

library(ggplot2)
dat = data.frame(x = c(1,1,1,5,5,7,7,10),
                 y = c(15,12,8,15,10,10,13,15),
                 d = c(1,2,3,4,5,6,7,8))

dat |> ggplot(aes(x,y)) + 
  geom_rect(dat,
            mapping=aes(xmin=x,xmax=y,
            ymin=d-0.4,ymax=d+0.4)) +
  coord_fixed(0.5) +
  theme_void()

Created on 2023-03-08 with reprex v2.0.2

1 Like

Hi thank you for your suggestion,

Do you know of a way to reset the height of the bar if there is no overlap? For instance, if we look at the top most bar, it should be placed on the third row from the bottom.

Help me out, so I don’t have to parse closely. What is now controlling the placement of bars along the y-axis?

The position along the y-axis is the thing that needs to be determined, and is shown here in the repex only as example.
The idea is to do a optimised stacking of the bars with given ranges to prevent overlap but decrease the total height.
E.g. we have ranges of 1:10, 1:5, 6:11 then in the non-optimal case they would be stacked on top of each other (total height = 3), in the optimal case 1:5 & 6:11 do not overlap with each other (but with 1:10) so they could be located in the same row (next to each other) and stacked on the other one (total height = 2)
In the given example the last bar can/should be moved down to row 3 as there is no overlap (+ some additional space so they can better separated)

I tried it once for myself but didn't come to a solution (or found something on the web) and stopped wasting time on that...

1 Like

I think I may understand what you want as output . Does this give you something like it?

library(tidyverse)

dat2 <-  data.frame(
  aa = as.factor(c(1L, 1L, 2L)),
  xx = c(1L, 5L, 2L),
  xend = c(3L, 9L, 6L),
  labs <- c("A", "B", "C")
)

p1   <- ggplot(dat2, aes(x = xx , xend = xend, y= aa, yend = aa, colour = as.factor(labs))) +
  geom_segment(linewidth = 6) 

Hey thank you for your suggestion, but I would hope to not have to manually adjust all the segments. These plots can be 300+ rectangles. As previously suggested, I need a way to optimize the placements of each bar. So far the best, I have come up with is :
for(i in 1:nrow(pepmap)){
if(i==1){x=pepmap[i,]}else{
if((pepmap[i,1]>=x[,1])&&(pepmap[i,1] < x[,2])){
pepmap[i,3]=pepmap[i-1,3]+1
}else{x=pepmap[i,]}
}}
Simply starting the height at 1 and with each overlapping bar, I increase the height by 1.

In that case., I just do not understand what you want. Sorry not to be of more help.

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.