directlabels:在同一个地块中为不同的面板使用不同的定位方法

时间:2016-12-06 23:09:22

标签: r graphics lattice direct-labels

我有一个双面板格子线图。我想使用directlabels包自动标记每个图中的线条。但我想为每个情节使用不同的定位方法。具体来说,我想对第一个面板使用first.bumpup方法,对第二个面板使用last.bumpup方法。这是一个最小的例子:

library(directlabels)
library(lattice)
myDF <- data.frame(
  y     = rep(1:4,         2),
  x     = rep(rep(1:2, 2), 2),
  group = rep(c('a', 'b'), each = 2),
  panel = rep(1:2,         each = 4))
myPlot <- xyplot(y ~ x | panel, groups = group, data = myDF, type = 'l')
direct.label(
  p      = myPlot,
  method = 'first.bumpup')

此代码生成一个图表,其中标签显示在每个面板的左侧:

figure produced by example code

我想在左侧面板的左侧(如本例所示)标签,但在右侧面板的右侧。产生这种形象的最简单方法是什么?

我已经检查了advanced examples in the directlabels documentation,他们让我觉得可以通过创建自定义定位方法或自定义面板,为不同的面板使用不同的方法。但我不太明白该怎么做。

2 个答案:

答案 0 :(得分:2)

我用ggplot2对此进行了解析(仅因为我知道ggplot2比我知道的lattice好得多)。让我知道你的想法。以下是两种方法。第一个实际上不使用directlabels。放置规则相对简单,因此我只使用geom_text进行标签展示。第二种方法确实使用directlabels,但更复杂。

使用geom_text

放置标签
library(dplyr)   # For chaining operator (%>%)
library(ggplot2)
library(cowplot) # For cowplot theme

ggplot(myDF, aes(x, y, colour=group)) + 
  geom_line() +
  geom_text(data=myDF %>% group_by(panel) %>%
              filter(ifelse(panel==1, x==min(x), x==max(x))),
            aes(x + 0.07*(panel-mean(panel)), y, label=group)) +
  facet_grid(~panel) +
  scale_x_continuous(breaks=seq(1,2,0.2)) +
  theme_cowplot() +
  guides(colour=FALSE)

在上面的代码中,在geom_text内,我们只保留第一个面板的最低x值和第二个面板中的最高x值,然后放置{{1} } group值处的标签与y值配对。 x只是将标签略微移动到线的末端。

enter image description here

使用x + 0.07*(panel-mean(panel))mapply

放置标签

这是使用directlabels的更复杂的方法。我的方法是使用directlabels分别绘制每个“facet”,这样我就可以为每个面板使用不同的mapply方法,但是然后将两个绘图放在一起就像它们是两个方面一样相同的整体情节。如果你喜欢这个结果,如果没有ggplot2版本满足你的需要,也许你可以将它改编为directlabels图。

lattice

因为我删除了面板2中的y轴标题,标签和刻度,所以该面板比面板1宽。library(directlabels) library(ggplot2) library(gridExtra) library(cowplot) pl = mapply(function(pnl, m) { # Create plot for each level of panel p = ggplot(myDF[myDF$panel==pnl, ], aes(x, y, colour=group)) + geom_line() + facet_grid(~panel) + scale_x_continuous(breaks=seq(1,2,0.2)) + theme_cowplot() # # Tweak margins of panel 1 # if(pnl==1) p = p + theme(plot.margin=unit(rep(0,4),"lines")) # Remove y-axis title, labels and ticks for panel 2 and tweak margins if(pnl==2) p = p + theme(axis.title.y=element_blank(), axis.text.y=element_blank(), axis.ticks.y=element_blank()) # Add directlabels with different method for each panel direct.label(p, method=m) }, pnl=unique(myDF$panel), m=c("first.bumpup", "last.bumpup"), SIMPLIFY=FALSE) 有一个plot_grid参数,允许我们对齐这两个图他们有相同的宽度,但我不知道如何摆脱情节之间的空间。 align也会列出这些图,但我们必须手动调整宽度(您也可以使用grid.arrange手动调整宽度)。

plot_grid

enter image description here

# Lay out each panel using plot_grid from cowplot package
plot_grid(plotlist=pl, ncol=2, align="v")

enter image description here

答案 1 :(得分:1)

以下是eipi10的第二种解决方案的改编,它在格子图中创造了所需的效果:

library(directlabels)
library(gridExtra)
library(lattice)

myDF <- data.frame(
  y     = rep(1:4,         2),
  x     = rep(rep(1:2, 2), 2),
  group = rep(c('a', 'b'), each = 2),
  panel = rep(1:2,         each = 4))

plotFunction <- function(panelNumber, labelMethod) {
  myPlot = xyplot(
    y ~ x, 
    groups = group, 
    data   = myDF[myDF$panel==panelNumber, ], 
    type   = 'l')
  direct.label(
    p      = myPlot,
    method = labelMethod)  
} 

panelList = mapply(
  FUN         = plotFunction, 
  panelNumber = unique(myDF$panel), 
  labelMethod = c('first.bumpup', 'last.bumpup'), 
  SIMPLIFY    = FALSE)

grid.arrange(grobs = panelList, ncol = 2)