Add vertical separator and labels to R barplot

2019-07-14 19:13发布

I have the following data frame from which I make a bar plot. Then, I am trying to add Group separators with vertical lines and to place labels in between these lines by creating a new x-axis:

Group = c("1_1", "1_2", "1_3", "2_1", "2_2", "3_1", "3_2", "3_3", "3_4")
Value = as.numeric(c("-1.23", "2.34", "0.56", "1.87", "-2.40", "5.54", "-0.98", "-2.31", "6"))
data = data.frame(Group, Value)
data
Group   Value
1_1   -1.23
1_2   2.34
1_3   0.56
2_1   1.87
2_2   -2.40
3_1   5.54
3_2   -0.98
3_3   -2.31
3_4   6.0

barplot(data$Value, xaxs="i",xaxt="n")

I am trying to add vertical lines as Group separators:

. between "1_3" and "2_1"

. between "2_2" and "3_1"

And place labels:

. "1" between origin and first separator

. "2" between first and second separator

. "3" between second separator and end of axis

It works fine with a continuous axis when making a scatter plot for instance, but it does not work with a categorical axis. Is there any way to sort of converting the Group categories to number depending on their position on the plot?

2条回答
Root(大扎)
2楼-- · 2019-07-14 19:30

I think this is what you are describing:

barplot(data$Value, xaxs="i",xaxt="n")
abline(v = 3.7)
abline(v = 6.1)
text(3.7/2, 5.9, label = '1')
text(4.85, 5.9, label = '2')
text(8.5, 5.9, label = '3')
查看更多
我只想做你的唯一
3楼-- · 2019-07-14 19:37

You can use ggplot2 package for this purpose:

library(ggplot2)

ggplot(data=df, aes(x=Group, y=Value)) +
  geom_bar(stat="identity") + 
  scale_x_discrete(breaks = df$Group, labels = substring(df$Group, 3, 3),
                                                                      expand=c(0.1,0.1)) +
  facet_grid(~ substring(Group, 1, 1), space="free_x", scales="free_x", switch="x") + 
  theme_bw() +
  theme(strip.placement = "outside",
        strip.background = element_rect(fill=NA,colour="grey50"),
        panel.spacing=unit(0,"cm"))

This will plot:

enter image description here

If you don't want subgroup x-axis labels, simply put labels = NULL instead of labels = substring(Group, 3, 3).

Data:

  df <- structure(list(Group = structure(1:9, .Label = c("1_1", "1_2",  
  "1_3", "2_1", "2_2", "3_1", "3_2", "3_3", "3_4"), class = "factor"),  
      Value = c(-1.23, 2.34, 0.56, 1.87, -2.4, 5.54, -0.98, -2.31,  
      6)), .Names = c("Group", "Value"), row.names = c(NA, -9L), class = "data.frame")
查看更多
登录 后发表回答