如何在ggplot2的绘图区域之外绘制线条? [英] How to draw lines outside of plot area in ggplot2?

查看:152
本文介绍了如何在ggplot2的绘图区域之外绘制线条?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 ggplot2 创建了此图:



外线需要对应于Y刻度,(即Text1的行的Y位置应该是100和85)。唯一的方法是,我可以通过在图的右侧绘制一个空白图,并使用与条形图相同的比例,然后使用注释功能绘制线条。另一种方法是用 grid.lines 简单地手动绘制线条,但是 grid.lines 的坐标将会不对应于情节的Y尺度。



是否有可能以某种方式使用不同的方法绘制这些线条?我假设它必须用 grid.lines 来完成。我怎样才能将条形图的Y坐标传递给 grid.lines



以下是用于创建这个数字:

  library(ggplot2)
test = data.frame(
group = c(rep (1,6),代表(2,6)),
子组= c(1,1,1,2,2,2,1,1,1,2,2,2),
类别= c(代表(1:3,4)),
计数= c(10,80,10,5,90,5,10,80,10,5,90,5)


qplot(小组,
计数,
数据=测试,
几何=bar,
stat =身份,
fill = category,
facets =。〜group,width = 0.9)+
opts(legend.position =none,
plot.margin = unit(c(0,9 ,2,0),lines))



如何绘制线条右侧的线条?



我最近在 ggplot2 中提出了一个关于在绘图区域之外绘制文本的问题,而解决方案n是使用 gt $ layout grid.draw



显示由ggplot2生成的图下面的文本



这里可以使用类似的方法吗?我的理解是,annotation_custom仅适用于文本,不适用于其他图形元素。
Thanks $ / $>

解决方案

更新

原始解决方案使用 annotation_custom ,但是 annotation_custom 的问题在于它在所有面板中绘制了注释。但是,通过一个简单的修改,可以使 annotation_custom 仅在一个面板中绘制(摘自Baptiste的回答 $ b $ 32807665 /移除一个tablegrob-when-a-to-a-box-plot-with-a-facet-wrap / 32832732#32832732>

  annotation_custom2 < -  
函数(grob,xmin = -Inf,xmax = Inf,ymin = -Inf,ymax = Inf,data)
{
图层(data = data,stat = StatIdentity,position = PositionIdentity,
geom = ggplot2 ::: GeomCustomAnn,
inherit.aes = TRUE,params = list(grob = grob,
xmin = xmin,xmax = xmax,
ymin = ymin,ymax = ymax))
}

library(ggplot2)
library(grid)
$ b $#一些数据
test = data.frame(
group = c(rep(1,6),rep(2,6)),
subgroup = c 1,1,1,2,2,2,1,1,1,2,2,2),
category = c(rep(1:3,4)),
count = c (10,80,10,5, 90,5,10,80,10,5,90,5)


#基点
p < - ggplot(test)+
geom_bar( aes(subgroup,count,fill = category),stat =identity)+
facet_grid(。 〜group)+
theme(legend.position =none,
plot.margin = unit(c(1,5,1,1),lines))

$创建文本Grobs
Text1 = textGrob(Text 1)
Text2 = textGrob(Text 2)
Text4 = textGrob(Text 4)

##添加注释
#将哪个面板附加注释
data = data.frame(group = 2)

#文本1
p1 = p + annotation_custom2(text1,xmin = 3.,xmax = 3,ymin = 85,ymax = 100,data = data)+
annotation_custom2(linesGrob(),xmin = 2.6,xmax = 2.75,ymin = 100,ymax = 100,data = data)+
annotation_custom2(linesGrob(),xmin = 2.6,xmax = 2.75,ymin = 85,ymax = 85,data = data)+
annotation_custom2(linesGrob ),xmin = 2.75,xmax = 2.75,ymin = 85,ymax = 100,data = data)

#Text 2
p1 = p1 + annotation_custom2(Text2,xmin = 3,xmax = 3,ymin = 20,ymax = 80,data = data)+
annotation_custom2(linesGrob(),xmin = 2.6,xmax = 2.75,ymin = 80,ymax = 80,data = data) +
annotation_custom2(linesGrob(),xmin = 2.6,xmax = 2.75,ymin = 20,ymax = 20,data = data)+
annotation_custom2(linesGrob(),xmin = 2.75,xmax = 2.75, ymin = 20,ymax = 80,data = data)

#Text 4
p1 = p1 + annotation_custom2(Text4,xmin = 3,xmax = 3,ymin = 0,ymax = 15 ,data = data)+
annotation_custom2(linesGrob(),xmin = 2.6,xmax = 2.75,ymin = 15,ymax = 15,data = data)+
annotation_custom2(linesGrob(),xmin = 2.6 ,xmax = 2.75,ymin = 0,ymax = 0,data = data)+
annotation_custom2(linesGrob(),xmin = 2.75,xmax = 2.75,ymin = 0,ymax = 15,data = data)


#代码覆盖剪辑
gt< - ggplotGrob(p1)
gt $ layout [grepl(panel,gt $ layout $ name),] $ clip< - off

#绘制绘图
grid.newpage()
grid.draw(gt)

原始解决方案



c $ c> grid()可以在<$ c $中使用C> annotation_custom()。
可能有更简单的方法来做到这一点,但这里有一个使用 grid , annotation_custom 和@ baptiste's代码从这里覆盖剪辑(如在之前的文章中) 。

  library(ggplot2)
library(grid)

test = data.frame (
group = c(rep(1,6),rep(2,6)),
subgroup = c(1,1,1,2,2,2,1,1,1, 2,2,2),
category = c(rep(1:3,4)),
count = c(10,80,10,5,9,0,5,10,80,10 ,5,90,5)


##编辑:更新的qplot()命令
p < - qplot(小组,计数,
data = test, geom =bar,stat =identity,
fill = category,
facets =。〜group,width = 0.9)+
theme(legend.position =none,plot .margin = unit(c(0,9,2,0),lines))



#创建文本Grobs
Text1 = textGrob( Text 1)
Text2 = textGrob(Text 2)
Text4 = textGrob(Text 4)

#绘制绘图
#Text 1
p1 = p + annotation_custom(grob = Text1,xmin = 3.,xmax = 3.,ymin = 85,ymax = 100)+
annotation_custom( grob = linesGrob(),xmin = 2.6,xmax = 2.75,ymin = 85,ymax = 85),其中grob = linesGrob(),xmin = 2.6,xmax = 2.75,ymin = 100,ymax = 100)+
annotation_custom )+
annotation_custom(grob = linesGrob(),xmin = 2.75,xmax = 2.75,ymin = 85,ymax = 100)

#Text 2
p1 = p1 + annotation_custom (grob = linesGrob(),xmin = 2.6,xmax = 2.75,ymin = 80,ymax = 80)(grob = Text2,xmin = 3,xmax = 3,ymin = 20,ymax = 80)+
annotation_custom +
annotation_custom(grob = linesGrob(),xmin = 2.6,xmax = 2.75,ymin = 20,ymax = 20)+
annotation_custom(grob = linesGrob(),xmin = 2.75,xmax = 2.75, ymin = 20,ymax = 80)

#文本4
p1 = p1 + annotation_custom(grob = Text4,xmin = 3,xmax = 3,ymin = 0,ymax = 15)+
annotation_custom(grob = linesGrob(),xmin = 2.6,xmax = 2.75,ymi (grob = linesGrob(),xmin = 2.6,xmax = 2.75,ymin = 0,ymax = 0)+
annotation_custom(grob = linesGrob(), xmin = 2.75,xmax = 2.75,ymin = 0,ymax = 15)

p1

#覆盖剪辑的代码
gt< - ggplot_gtable(ggplot_build p1))
gt $ layout $ clip [gt $ layout $ name ==panel]< - off
grid.draw(gt)


I created this plot with ggplot2:

The outside lines need to correspond to the Y scale, (i.e the Y position of the lines for Text1 should be 100 and 85). The only way I can do it by drawing a blank plot to the right of the figure with the same scale as the barchart and then using annotate function to draw the lines. Another approach is to simply "manually" draw the lines with grid.lines, however the coordinates of grid.lines will not correspond to the Y scale of the plot.

Is it possible to somehow draw these lines using a different approach? I assume it would have to be done with grid.lines. How could I pass Y coordindates of the barchart to grid.lines?

Below is the minimal code used to create this figure:

library (ggplot2)
test= data.frame(
  group=c(rep(1,6), rep(2,6)),
  subgroup=c( 1,1,1,2,2,2,1,1,1,2,2,2),
  category=c( rep(1:3, 4)),
  count=c( 10,80,10,5,90,5,  10,80,10,5,90,5   )
  )

qplot(subgroup, 
      count, 
      data=test, 
      geom="bar", 
      stat="identity",
      fill =category,  
      facets =  .~ group,  width=0.9)+
      opts(legend.position="none",
           plot.margin = unit(c(0,9,2,0), "lines"))

How can I draw the lines to the right of the bars?

I recently asked a question about drawing text outside of plot area in ggplot2 and the solution was to use gt$layout and grid.draw.

Displaying text below the plot generated by ggplot2

Could the similar approach be used here? It is my understanding that annotation_custom is for text only and won't work with other graphical elements. Thanks

解决方案

Update

The original solution used annotation_custom, but a problem with annotation_custom is that it draws the annotation in all panels. However, with a simple modification, annotation_custom can be made to draw in one panel only (taken from Baptiste's answer here)

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))
}

library(ggplot2)
library(grid)

 #Some data
test = data.frame(
  group=c(rep(1,6), rep(2,6)),
  subgroup=c( 1,1,1,2,2,2,1,1,1,2,2,2),
  category=c( rep(1:3, 4)),
  count=c( 10,80,10,5,90,5,  10,80,10,5,90,5   )
  )

# base plot
p <- ggplot(test) +
   geom_bar(aes(subgroup, count, fill = category), stat = "identity") +
   facet_grid(. ~ group) +
  theme(legend.position = "none",  
        plot.margin = unit(c(1,5,1,1), "lines"))

# Create the text Grobs
Text1 = textGrob("Text 1")
Text2 = textGrob("Text 2")
Text4 = textGrob("Text 4")

## Add the annotations
# Which panel to attach the annotations
data = data.frame(group=2)

# Text 1
p1 = p + annotation_custom2(Text1,  xmin = 3., xmax = 3., ymin = 85, ymax = 100, data = data) +
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 100, ymax = 100, data = data) +
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 85, ymax = 85, data = data) +
    annotation_custom2(linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 85, ymax = 100, data = data)

# Text 2
p1 = p1 + annotation_custom2(Text2,  xmin = 3, xmax = 3, ymin = 20, ymax = 80, data = data) +
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 80, ymax = 80, data = data) +
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 20, ymax = 20, data = data) +
    annotation_custom2(linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 20, ymax = 80, data = data)

# Text 4
p1 = p1 + annotation_custom2(Text4,  xmin = 3, xmax = 3, ymin = 0, ymax = 15, data = data) +
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 15, ymax = 15, data = data) +
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 0, ymax = 0, data = data) +
    annotation_custom2(linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 0, ymax = 15, data = data)


# Code to override clipping
gt <- ggplotGrob(p1)
gt$layout[grepl("panel", gt$layout$name), ]$clip <- "off"

# Draw the plot
grid.newpage()
grid.draw(gt)

Original Solution

I think almost any Grob created using grid() can be used in annotation_custom(). There might be neater ways to do this, but here's a way using grid, annotation_custom and @baptiste's code from here to override the clipping (as in the earlier post).

library (ggplot2)
library(grid)

test= data.frame(
  group=c(rep(1,6), rep(2,6)),
  subgroup=c( 1,1,1,2,2,2,1,1,1,2,2,2),
  category=c( rep(1:3, 4)),
  count=c( 10,80,10,5,90,5,  10,80,10,5,90,5   )
  )

## EDIT:  Updated qplot() command
p <- qplot(subgroup, count, 
  data = test, geom = "bar",  stat = "identity",
  fill = category,  
  facets = .~ group,  width = 0.9)+
  theme(legend.position="none",  plot.margin = unit(c(0,9,2,0), "lines"))



# Create the text Grobs
Text1 = textGrob("Text 1")
Text2 = textGrob("Text 2")
Text4 = textGrob("Text 4")

# Draw the plot
# Text 1
p1 = p + annotation_custom(grob = Text1,  xmin = 3., xmax = 3., ymin = 85, ymax = 100) +
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 100, ymax = 100) +
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 85, ymax = 85) +
    annotation_custom(grob = linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 85, ymax = 100)

# Text 2
p1 = p1 + annotation_custom(grob = Text2,  xmin = 3, xmax = 3, ymin = 20, ymax = 80) +
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 80, ymax = 80) +
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 20, ymax = 20) +
    annotation_custom(grob = linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 20, ymax = 80)

# Text 4
p1 = p1 + annotation_custom(grob = Text4,  xmin = 3, xmax = 3, ymin = 0, ymax = 15) +
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 15, ymax = 15) +
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 0, ymax = 0) +
    annotation_custom(grob = linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 0, ymax = 15)

p1

# Code to override clipping
gt <- ggplot_gtable(ggplot_build(p1))
gt$layout$clip[gt$layout$name=="panel"] <- "off"
grid.draw(gt)

这篇关于如何在ggplot2的绘图区域之外绘制线条?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆