cmirian
cmirian

Reputation: 2253

ggplot: how to add an outline around each fill in a stacked barchart but only partly

I have the following stacked barchart produced with geom_bar.

Question: how to add an outline around each fill corresponding to the matched color in cols. The tricky part is, that the outline should not be in between each fill but around the "borders" and the top, exclusively (expected output below)

I have

enter image description here

Written with

library(ggplot)
cols = c("#E1B930", "#2C77BF","#E38072","#6DBCC3", "grey40","black")

ggplot(i, aes(fill=uicc, x=n)) + theme_bw() +

  geom_bar(position="stack", stat="count") +

  scale_fill_manual(values=alpha(cols,0.5)) 

Expected output

enter image description here

My data i

i <- structure(list(uicc = structure(c(4L, 4L, 4L, 4L, 3L, 4L, 4L, 
4L, 4L, 3L, 4L, 3L, 4L, 2L, 4L, 4L, 4L, 1L, 4L, 4L, 2L, 4L, 4L, 
3L, 4L, 4L, 4L, 4L, 3L, 2L, 4L, 4L, 3L, 3L, 3L, 3L, 1L, 3L, 4L, 
4L, 2L, 4L, 4L, 4L, 4L, 4L, 4L, 1L, 4L, 4L, 4L, 4L, 4L, 4L, 3L, 
4L, 1L, 3L, 1L, 4L, 4L, 3L, 1L, 2L, 1L, 3L, 3L, 3L, 4L, 3L, 4L, 
4L, 3L, 4L, 3L, 3L, 3L, 2L, 2L, 4L, 3L, 4L, 2L, 1L, 1L, 4L, 4L, 
4L, 4L, 1L, 4L, 4L, 4L, 4L, 4L, 4L, 2L, 3L, 3L, 4L), .Label = c("1", 
"2", "3", "4"), class = "factor"), n = structure(c(4L, 4L, 4L, 
4L, 2L, 1L, 4L, 1L, 4L, 2L, 4L, 2L, 4L, 1L, 4L, 5L, 2L, 1L, 1L, 
5L, 1L, 1L, 2L, 2L, 1L, 4L, 3L, 4L, 2L, 1L, 5L, 2L, 2L, 2L, 2L, 
2L, 1L, 2L, 3L, 2L, 1L, 4L, 2L, 1L, 4L, 1L, 4L, 1L, 2L, 2L, 2L, 
4L, 1L, 4L, 2L, 4L, 1L, 1L, 1L, 4L, 1L, 2L, 1L, 1L, 1L, 2L, 2L, 
1L, 1L, 2L, 4L, 1L, 1L, 4L, 2L, 2L, 2L, 1L, 1L, 3L, 2L, 5L, 1L, 
1L, 1L, 4L, 4L, 4L, 5L, 1L, 4L, 4L, 1L, 4L, 2L, 1L, 1L, 2L, 2L, 
4L), .Label = c("0", "1", "2", "3", "4", "5"), class = "factor")), row.names = c(NA, 
100L), class = "data.frame")

Upvotes: 1

Views: 1156

Answers (1)

chemdork123
chemdork123

Reputation: 13903

Well, I found a way.

There's no easy way to draw just the "outside" lines, so the approach I used was to go ahead and draw them with the geom_bar call. The inner lines are "erased" by drawing white rectangles over top the initial geom_bar call, and then the fill is drawn back in with a colorless color= aesthetic.

In order to draw the rectangles over the initial geom_bar call, I created a summary dataframe of i which sets the y values.

i.sum <- i %>% group_by(n) %>% tally()

ggplot(i, aes(x=n)) + theme_bw() +

  # draw lines
  geom_bar(position='stack', stat='count',
      aes(color=uicc), fill=NA, size=1.5) +

  # cover over those inner lines
  geom_col(data=i.sum, aes(y=nn), fill='white') +

  # put back in the fill
  geom_bar(position='stack', stat='count',
      aes(fill=uicc), color=NA) +

  scale_fill_manual(values=alpha(cols,0.5)) +
  scale_color_manual(values=cols)

Note that the size= of the color= aesthetic needs to be much higher than normal, since the white rectangle ends up covering about half the line.

enter image description here

Upvotes: 3

Related Questions