2017-03-04 106 views
1

我想根据另一个字段放置每个x轴文本/标签。 ggplot2是否有本地的方式来实现这一目标?目前我正在通过geom_text来完成。这里是我的数据和plot.I有这种方法的两个问题 -使用ggplot根据数据中的另一个字段沿x轴定位x轴文本/标签

  1. 标签在绘图区
  2. 内落下一个面的标签应该只出现在最底层的次要情节如下alt text

不是所有的小区都如下面的情况(我的情节)。 (上面的影像是从here采取)

library(ggplot2) 
library(magrittr)  

mydata = data.frame(expand.grid(Tag = c('A','B','C'), 
    Year = 2010:2011,PNo = paste0("X-",1:4)),Value = round(runif(24,1,20))) 
mydata$dist = ifelse(mydata$Tag == 'A',0,ifelse(mydata$Tag=='B',2,7)) 

mydata %>% ggplot(aes(x = dist,y = Value,fill = factor(Year))) + 
    geom_bar(stat='summary',position = 'dodge',fun.y='mean',width=1) + 
    facet_wrap(~PNo,ncol=2) + 
    theme(axis.text.x = element_blank(),axis.ticks.x = element_blank()) + 
    geom_text(aes(x = dist,label = Tag),color = 'black',size=4,angle = 0,show.legend = F) 

我想向基于distTag标签。 enter image description here

+0

这不是很清楚,我的问题是什么。 _“它看起来并不那么整洁” - 太模糊,无法直接回答。 – Axeman

+0

我现在把问题弄清楚了 –

回答

1

我注意到你已经在其他地方接受了答案,并且你在这里回答了你自己的问题。但他们不完全回答你原来的问题。特别是,标签仍在绘图面板内。我提供了两种可能性,但既不简单。

第一次使用版本annotation_custom。默认annotation_custom在所有面板中绘制注释。但只要稍作修改(取自here),可以在选定的面板中绘制注释 - 对于您的情节,下面两个面板。

library(ggplot2) 
library(magrittr)  
mydata = data.frame(expand.grid(Tag = c('A', 'B', 'C'), 
      Year = 2010:2011, PNo = paste0("X-", 1:4)), Value = round(runif(24,1,20))) 
mydata$dist = ifelse(mydata$Tag == 'A', 0, ifelse(mydata$Tag == 'B', 2, 7)) 

# The bar plot. Note extra margin above x-axis title. 
# This gives space for the annotations between the panel and the title. 
p1 = mydata %>% ggplot() + 
    geom_bar(aes(x = dist, y = Value, fill = factor(Year)), 
      width = 1, stat = 'identity', position = "dodge") + 
    facet_wrap(~PNo, ncol = 2) + 
    theme(axis.text.x = element_blank(), 
     axis.ticks.x = element_blank(), 
     axis.title.x = element_text(margin = margin(t = 2, unit = "lines"))) 

# Baptiste's modification to annotation_custom 
annotation_custom2 = 
function (grob, xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf, data) { 
    layer(data = data, stat = StatIdentity, position = PositionIdentity, 
     geom = ggplot2:::GeomCustomAnn, 
     inherit.aes = TRUE, params = list(grob = grob, 
              xmin = xmin, xmax = xmax, 
              ymin = ymin, ymax = ymax)) 
} 

# The plot with annotations. (ymin and ymax set to -Inf 
# draws the annotation at the bottom of the panel. 
# vjust = 1.5 drops them below the panel). 
for (i in 1:length(unique(mydata$Tag))) { 
    p1 = p1 + annotation_custom2(
     grob = textGrob(label = unique(mydata$Tag)[i], vjust = 1.5, 
         gp = gpar(col = 'red', cex = 1)), 
     xmin = unique(mydata$dist)[i], 
     xmax = unique(mydata$dist)[i], 
     ymin = -Inf, 
     ymax = -Inf, 
     data=data.frame(PNo=c("X-3", "X-4"))) # The two bottom panels 
} 

# The annotations are placed outside the panels. 
# Therefore, have to turn off clipping to the panels. 
g1 = ggplotGrob(p1) 
g1$layout$clip[grepl("panel", g1$layout$name)] = "off" 

# Draw the chart 
grid.newpage() 
grid.draw(g1) 

enter image description here

第二绘制了两个图表:P1是你的柱状图中,与P2仅包含标签。诀窍是让两个图表中的x轴相同。然后,绘图面板从p2中提取出来,并放置到p1中,但进入p1绘图面板下方的新行中。

library(ggplot2) 
library(magrittr)  
mydata = data.frame(expand.grid(Tag = c('A', 'B', 'C'), 
     Year = 2010:2011,PNo = paste0("X-", 1:4)),Value = round(runif(24, 1, 20))) 
mydata$dist = ifelse(mydata$Tag == 'A', 0, ifelse(mydata$Tag == 'B', 2, 7)) 

# The bar plot 
p1 = mydata %>% ggplot(aes(x = dist, y = Value, fill = factor(Year))) + 
    geom_bar(stat = 'summary', position = 'dodge',fun.y = 'mean', width = 1) + 
    facet_wrap(~PNo, ncol = 2) + 
    theme(axis.text.x = element_blank(), axis.ticks.x = element_blank()) 

# To get the range of x values - 
# so that the extent of the x-axis in p1 and in the following p2 are the same 
gd = ggplot_build(p1) 
xrange = gd$layout$panel_ranges[[1]]$x.range # xrange used in p2 (see below) 

# Plot with labels (A, B, and C) only 
p2 = mydata %>% ggplot(aes(x = dist, y = Value)) + 
    facet_wrap(~PNo, ncol = 2) + 
    geom_label(aes(x = dist, y = 0, label = Tag), size = 6, inherit.aes = F, color = 'red') + 
    ### geom_text(aes(x = dist, y = 0, label = Tag), size=6, color = 'red') + ### Alternative style for labels 
    scale_x_continuous(lim = xrange, expand = c(0,0)) + 
    theme_bw() + 
    theme(panel.grid = element_blank(), 
      panel.border = element_rect(colour = NA)) 


# Grab a plot panel from p2 
g2 = ggplotGrob(p2) 
panels = subset(g2$layout, grepl("panel", g2$layout$name), t:r) 
panels = subset(panels, t == min(t)) 

g2 = g2[unique(panels$t), min(panels$l):max(panels$r)] 

# Add a row to p1 to take the plot panels 
library(gtable) 
library(grid) 
g1 <- ggplotGrob(p1) 
pos = max(subset(g1$layout, grepl("panel", g1$layout$name), t)) 
g1 = gtable_add_rows(g1, height = unit(2, "lines"), pos = pos) 

# Add the panel (g2) to the new row 
g1 = gtable_add_grob(g1,g2, t = pos + 1, l = min(panels$l), r = max(panels$r)) 

# Draw the chart 
grid.newpage() 
grid.draw(g1) 

enter image description here

0

我试图自己解决问题,但遇到了一些问题。我在SO here上发布了另一个问题。答案和问题一起在一定程度上解决了这个问题。这是一个可能的解决方案。

p <- mydata %>% ggplot(aes(x = dist,y = Value,fill = factor(Year))) +geom_bar(stat='summary',position = 'dodge',fun.y='mean',width = 1) + 
    facet_wrap(~PNo,ncol=2) + 
    theme(axis.text.x = element_blank(),axis.ticks.x = element_blank()) + 
    geom_label(data = mydata %>% dplyr::filter(PNo %in% c('X-3','X-4')),aes(x = dist,y=0,label = Tag),size=6,inherit.aes=F,color = 'red') 
library(grid) 
gt <- ggplot_gtable(ggplot_build(p)) 
gt$layout$clip[grep("panel-2-\\d+", gt$layout$name)] <- "off" 
grid.draw(gt)