简体   繁体   English

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

[英]directlabels: using different positioning methods for different panels in the same plot

I have a two-panel lattice lineplot. 我有一个双面板格子线图。 I want to use the directlabels package to automatically label the lines in each plot. 我想使用directlabels包自动标记每个图中的线条。 But I want to use a different positioning method for each plot. 但我想为每个情节使用不同的定位方法。 Specifically, I want to use the first.bumpup method for the first panel, and the last.bumpup method for the second panel. 具体而言,我想使用first.bumpup对于第一面板的方法,并且last.bumpup对于所述第二面板的方法。 Here is a minimal example: 这是一个最小的例子:

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

This code produces a plot in which labels appear on the left-hand side of each panel: 此代码生成一个图表,其中标签显示在每个面板的左侧:

由示例代码生成的图

I want labels on the left-hand side of the left-hand panel (as in this example), but on the right-hand side of the right-hand panel. 我想在左侧面板的左侧(如本例所示)标签,但在右侧面板的右侧。 What is the simplest way to produce that sort of figure? 制作这种形象的最简单方法是什么?

I've checked the advanced examples in the directlabels documentation , and they make me think that it may be possible to use different methods for different panels by creating a custom positioning method or a custom panel. 我已经检查了directlabels文档中高级示例 ,它们让我认为通过创建自定义定位方法或自定义面板可以为不同的面板使用不同的方法。 But I cannot quite see how to do it. 但我不太明白该怎么做。

I took a crack at this with ggplot2 (only because I know ggplot2 much better than I know lattice ). 我用ggplot2对此进行了一次破解(仅仅因为我知道ggplot2比我知道lattice好得多)。 Let me know what you think. 让我知道你的想法。 Below are two approaches. 以下是两种方法。 The first actually doesn't use directlabels . 第一个实际上不使用directlabels The placement rule is relatively simple, so I just used geom_text for label placement. 放置规则相对简单,所以我只使用geom_text进行标签放置。 The second method does use directlabels , but is more complicated. 第二种方法确实使用directlabels ,但更复杂。

Place labels using geom_text 使用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)

In the code above, inside geom_text we keep only the lowest x value for the first panel and the highest x value in the second panel and then place the group labels at the y values that pair with the x values. 在上面的代码中,在geom_text我们只保留第一个面板的最低x值和第二个面板中的最高x值,然后将group标签放在与y值配对的x值上。 The x + 0.07*(panel-mean(panel)) is just to move the labels slightly away from the ends of the lines. x + 0.07*(panel-mean(panel))只是将标签稍微远离线的末端移动。

在此输入图像描述

Place labels using mapply and directlabels 使用mapplydirectlabels放置标签

Here's a more complicated method using directlabels . 这是使用directlabels的更复杂的方法。 My approach was to plot each "facet" separately using mapply , so that I could use a different directlabels method for each panel, but then lay the two plots out together as if they were two facets of the same overall plot. 我的方法是使用mapply分别绘制每个“facet”,这样我就可以为每个面板使用不同的directlabels方法,但是然后将两个绘图放在一起就好像它们是同一整体图的两个面。 If you like the result, maybe you can adapt it to a lattice plot if none of the ggplot2 versions meet your needs. 如果你喜欢这个结果,如果没有ggplot2版本符合你的需要,也许你可以将它调整到lattice图。

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)

Because I removed the y-axis title, labels, and ticks in panel 2, that panel is wider than panel 1. plot_grid has an align argument that allows us to align the two plots so that they have the same width, but I don't know of a way to get rid of the space between the plots. 因为我删除了面板2中的y轴标题,标签和刻度,所以该面板比面板1 plot_grid有一个align参数,允许我们对齐这两个图,使它们具有相同的宽度,但我不知道知道如何摆脱地块之间的空间。 grid.arrange will also lay out that plots, but we have to adjust the widths manually (you can adjust the widths manually with plot_grid as well). grid.arrange也将列出该图,但我们必须手动调整宽度(您也可以使用plot_grid手动调整宽度)。

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

在此输入图像描述

# Lay out each panel using grid.arrange from gridExtra package
grid.arrange(grobs=pl, ncol=2, widths=c(10,9))

在此输入图像描述

Here is an adaptation of eipi10's second solution that creates the desired effect in a lattice plot: 以下是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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM