ggplot2-在情节之外进行注释


73

我想将样本大小值与绘图上的点相关联。我可以geom_text用来将数字定位在点附近,但这很混乱。将它们沿着地块的外部边缘对齐会更清洁。

例如,我有:

df=data.frame(y=c("cat1","cat2","cat3"),x=c(12,10,14),n=c(5,15,20))

ggplot(df,aes(x=x,y=y,label=n))+geom_point()+geom_text(size=8,hjust=-0.5)

产生此图: 在此处输入图片说明

我更喜欢这样的东西: 在此处输入图片说明

我知道我可以创建第二个图并使用grid.arrange(la la post),但是确定textGrobs的间距与y轴对齐将很繁琐。有没有更简单的方法可以做到这一点?谢谢!


1
这可以通过我认为正在开发的辅助轴来完成。但是,如果您想尝试一下,请点击此链接groups.google.com/forum/?fromgroups=#!topic/ggplot2/_3Pm-JEoCqE
Luciano Selzer 2012年

嗯,很有趣...我想知道哈德利是否要实现这一目标。但是,尝试加载时出现了一些奇怪的错误devtoolscall: if (!version_match) { error: argument is of length zero
jslefche 2012年

我只能说devtools对我有用。如果无法解决问题,则应尝试发布问题。
Luciano Selzer 2012年

我通过从CRAN上的.zip安装ggp​​lot2 0.9.2.1来解决此问题。现在,@ LucianoSelzer链接中提供的代码无法运行(guide_axis的多个参数)。今晚也许太多了?我会认真考虑的,看看我能不能弄明白早晨
jslefche

Answers:


62

您无需绘制第二个图。您可以使用annotation_custom将grob放置在绘图区域内或外的任何位置。齿轮的定位是根据数据坐标进行的。假设“ 5”,“ 10”,“ 15”与“ cat1”,“ cat2”,“ cat3”对齐,则考虑了textGrobs的垂直位置-三个textGrobs的y坐标由三个数据点的y坐标。默认情况下,ggplot2剪辑会切换到绘图区域,但是可以覆盖剪辑。需要扩大相关的余量,以便为grob腾出空间。以下内容(使用ggplot2 0.9.2)给出了类似于第二个图的图:

library (ggplot2)
library(grid)

df=data.frame(y=c("cat1","cat2","cat3"),x=c(12,10,14),n=c(5,15,20))

p <- ggplot(df, aes(x,y)) + geom_point() +            # Base plot
     theme(plot.margin = unit(c(1,3,1,1), "lines"))   # Make room for the grob

for (i in 1:length(df$n))  {
p <- p + annotation_custom(
      grob = textGrob(label = df$n[i], hjust = 0, gp = gpar(cex = 1.5)),
      ymin = df$y[i],      # Vertical position of the textGrob
      ymax = df$y[i],
      xmin = 14.3,         # Note: The grobs are positioned outside the plot area
      xmax = 14.3)
 }    

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

在此处输入图片说明


9
在x = Inf处有一个geom_text层,正好大于等于1,然后关闭剪辑会更容易吗?
baptiste 2012年

14
@jslefche,您应该注意,@ baptiste提供的解决方案要简单得多。p = p + geom_text(aes(label = n, x = Inf, y = y), hjust = -1)。然后关闭剪辑。虽然对齐可能会略有偏离。
桑迪·穆斯普拉特

2
以及如何关闭剪辑?
Thomas Browne

1
@ThomasBrowne要关闭剪辑,请参见上面的最后三行代码。
桑迪·穆斯普拉特

2
不幸的是,您需要放置文本的x位置随x轴的范围而变化。因此,您需要使用相对于轴范围的x值。这是我的解决方案。我得到x ggplot计算轴范围 xlim.range <- ggplot_build(plot)$panel$ranges[[1]]$x.range。然后,我将其用作x位置:x = xlim.range[1] - diff(xlim.range)/10 它起作用了!
巴卡堡2015年

62

ggplot2 3.0.0现在很简单,因为现在可以通过使用clip = 'off'坐标函数(例如coord_cartesian(clip = 'off')或)中的参数在绘图中禁用裁剪coord_fixed(clip = 'off')。这是下面的例子。

    # Generate data
    df <- data.frame(y=c("cat1","cat2","cat3"),
                     x=c(12,10,14),
                     n=c(5,15,20))

    # Create the plot
    ggplot(df,aes(x=x,y=y,label=n)) +
      geom_point()+
      geom_text(x = 14.25, # Set the position of the text to always be at '14.25'
                hjust = 0,
                size = 8) +
      coord_cartesian(xlim = c(10, 14), # This focuses the x-axis on the range of interest
                      clip = 'off') +   # This keeps the labels from disappearing
      theme(plot.margin = unit(c(1,3,1,1), "lines")) # This widens the right margin

在此处输入图片说明


如何为箱形图的x轴执行此操作?
ktyagi

1
这绝对是最简单的选择,谢谢!@ktyagi也许您现在已经对此进行了排序,但是您将使用完全相同的参数,但指定ylim相反的位置或xlim
EcologyTom

2
为了完整起见,clip = off也可以称为@ coord_flip(并且我也假定为coord_ x)。coord_cartesian(clip = 'off')对我来说,添加不是解决方案coord_flip
Leroy Tyrone

很好,谢谢@LeroyTyrone。我只是更新了答案以反映这一点。
bschneidr

值得注意的是,这似乎不适用于coord_polar
MokeEire '20

5

Simplier解决方案基于 grid

require(grid)

df = data.frame(y = c("cat1", "cat2", "cat3"), x = c(12, 10, 14), n = c(5, 15, 20))

p <- ggplot(df, aes(x, y)) + geom_point() + # Base plot
theme(plot.margin = unit(c(1, 3, 1, 1), "lines"))

p

grid.text("20", x = unit(0.91, "npc"), y = unit(0.80, "npc"))
grid.text("15", x = unit(0.91, "npc"), y = unit(0.56, "npc"))
grid.text("5", x = unit(0.91, "npc"), y = unit(0.31, "npc"))

5
乍看之下要简单得多,但是...字体与ggplot2的默认设置不匹配,因此您必须摆弄这些设置,并且由于使用npc单位而更难放置文本。可能最终变得同样复杂。
Mooks
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.