[英]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
,但更复杂。
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))
只是将标签稍微远离线的末端移动。
mapply
and directlabels
mapply
和directlabels
放置标签 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.