3

I have to plot the frequency data using a group variable As and subgroup variable ADs. What is the best way to visualize the frequency ie., pie chart or mosaic? Is there any function available in ggplot2?

df <- data.frame(As=c('GeA','GeA','GeA', 'GA'), 
             ADs=c('A44','A33','A37','A141'),
             freq=c(501,65,50,103))

#    As  ADs freq
# 1 GeA  A44  501
# 2 GeA  A33   65
# 3 GeA  A37   50
# 4  GA A141  103

Some thoughts are like below:

image1

However, is there any way to differentiate both group and subgroup in a single plot?

Out of the proposed solutions, below two charts looked promising.

Pie Chart & Tile Graph

piecharttileGraph

I have used the following code suggested by M--.

df.2 <- df
df.2$ymax <- with(df.2, ave(freq, As, FUN=cumsum))
df.2$ymin <- lag(df.2$ymax, default = 0)
df.2$ymin <- ifelse(lag(as.character(df.2$As), default = 0) != df.2$As, 0, df.2$ymin)

df.legend <- df.2[with(df.2, order(As)), ]

library(ggplot2)
# Pie Chart
ggplot(df.2) + 
  geom_rect(aes(fill=As, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) +
  geom_rect(aes(fill=ADs, ymax=ymax, ymin=ymin, xmax=3, xmin=0)) +
  xlim(c(0, 4)) + 
  theme(aspect.ratio=1) +
  coord_polar(theta="y") +
  scale_x_continuous(breaks=c(0,3), labels=c("ADs", "As")) + 
  annotate("text", x=rep(1.5,4), y=c(50, 350,530,590), 
           label= as.character(df.legend$ADs)) + 
  annotate("text", x=rep(3.5,2), y=c(50, 350), 
           label= as.character(unique(df.legend$As))) + 
  theme(legend.position="none", axis.title.x=element_blank(),
        axis.title.y=element_blank())

# Tile Graph
ggplot(df.2) + 
  geom_rect(aes(fill=As, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) +
  geom_rect(aes(fill=ADs, ymax=ymax, ymin=ymin, xmax=3, xmin=0)) +
  xlim(c(0, 4)) + theme(aspect.ratio=1) +
  scale_x_continuous(breaks=c(1.5,3.5), labels=c("ADs", "As")) + 
  annotate("text", x=rep(1.5,4), y=c(50, 350,530,590), 
           label= paste(as.character(df.legend$ADs), df.legend$freq,sep= " = ")) + 
  annotate("text", x=rep(3.5,2), y=c(50, 350), 
           label= as.character(unique(df.legend$As))) + 
  theme(legend.position="none", axis.title.x=element_blank(),
        axis.title.y=element_blank())

However, I didn't get the same output

Pie Chart & Tile Graph

piechart_err tileGraph_err

Message: Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.

Could you please advise what would be the issue? Is there any difference in the version of the package(s) used?

M--
  • 25,431
  • 8
  • 61
  • 93
Prradep
  • 5,506
  • 5
  • 43
  • 84

1 Answers1

3

Stacked Barplot:

You can use stacked barplots:

library(ggplot2)
ggplot(data = df, aes(x = As, y = freq, fill = ADs)) + 
       geom_bar(stat = "identity")

you can add this and get labels on the plot:

p +   geom_text(aes(label = paste(ADs, freq, sep=": ")), 
        position = position_stack(vjust = 0.5), size = 3) + #subgroups
       stat_summary(fun.y = sum, aes(label = ..y.., group = As), geom = "text") + #groups
        theme(legend.position="none")

enter image description here

Next two answers are in reference to this post.

Tile Graph:

For this we need to tweak the data:

  df.2 <- df
  df.2$ymax <- with(df.2, ave(freq, As, FUN=cumsum))
  df.2 <- df.2[with(df.2, order(As)), ]
  
  #for some reason lag function does not work properly in R 3.3.3
  library(data.table)
  setDT(df.2)[, ymin:=c(0,ymax[-.N])]  

  
  df.legend <- df.2[with(df.2, order(As)), ]

Then we can use ggplot again:

 ggplot(df.2) + 
   geom_rect(aes(fill=As, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) +
   geom_rect(aes(fill=ADs, ymax=ymax, ymin=ymin, xmax=3, xmin=0)) +
   xlim(c(0, 4)) + theme(aspect.ratio=1) +
   scale_x_continuous(breaks=c(1.5,3.5), labels=c("ADs", "As")) + 
   annotate("text", x=rep(1.5,4), y=c(50, 350,530,590), 
          label= paste(as.character(df.legend$ADs), df.legend$freq,sep= " = ")) + 
   annotate("text", x=rep(3.5,2), y=c(50, 350), 
        label= as.character(unique(df.legend$As))) + 
      theme(legend.position="none", axis.title.x=element_blank(),
     axis.title.y=element_blank())

enter image description here

Pie Chart:

ggplot(df.2) + 
 geom_rect(aes(fill=As, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) +
 geom_rect(aes(fill=ADs, ymax=ymax, ymin=ymin, xmax=3, xmin=0)) +
 xlim(c(0, 4)) + 
 theme(aspect.ratio=1) +
 coord_polar(theta="y") +
 scale_x_continuous(breaks=c(0,3), labels=c("ADs", "As")) + 
 annotate("text", x=rep(1.5,4), y=c(50, 350,530,590), 
        label= as.character(df.legend$ADs)) + 
 annotate("text", x=rep(3.5,2), y=c(50, 350), 
        label= as.character(unique(df.legend$As))) + 
 theme(legend.position="none", axis.title.x=element_blank(),
     axis.title.y=element_blank())

enter image description here

Community
  • 1
  • 1
M--
  • 25,431
  • 8
  • 61
  • 93
  • Thanks for the plot. It would be nice to see the share of each subgroup. – Prradep Jun 30 '17 at 15:54
  • Can you please post the package version of ggplot2 you are using? For some reason, I'm not getting colors for last two plots. – Prradep Jul 01 '17 at 11:50
  • @Prradep Edit your question. Add the result that you get, so it can be reopened. I will add my session info and package versions ASAP. – M-- Jul 01 '17 at 13:47
  • I have found the reason why I'm not getting the same output and it is due to the `ymin` values. After changing the values(`df.legend$ymin <- c(0,103,501,566)`), I have got the output. Please edit the answer so that I could accept it. – Prradep Jul 03 '17 at 12:15
  • otherwise using `lag` function on the `df.legend` would give the desired output! – Prradep Jul 03 '17 at 13:15
  • @Prradep I used `data.table` package. It does work on my other machine but not on my laptop either. Not sure what exactly has happened to `lag` function. But now this addresses your question. – M-- Jul 03 '17 at 18:56