如何在情节图例中的线条顶部居中?

时间:2018-06-21 04:55:53

标签: r plot legend

我想在图例中的行上方叠加透明框。

一个小例子:

xdata <- 1:7
y1 <- c(1,4,9,16,25,36,49)
y2 <- c(1, 5, 12, 21, 34, 51, 72)
y3 <- c(1, 6, 14, 28, 47, 73, 106 )
y4 <- c(1, 7, 17, 35, 60, 95, 140 )

plot(xdata, y1, type = 'l', col = "red")
lines(xdata, y2, type = 'l', col = "red", lty = 3)
lines(xdata, y3, type = 'l', col = "blue") 
lines(xdata, y4, type = 'l', col = "blue",  lty = 3)

# add legend with lines
legend("topleft", legend = c("Plot 1", "Plot 2", "Plot 3", "Plot 4"),
      lty = c(1,3,1,3), lwd = rep(1.3 ,4),
      col = c("blue", "blue", "red", "red") ,
      pch = rep(NA, 4), cex = 0.8, 
      x.intersp = 0.7, y.intersp = 1.2, bty = 'n')

# add boxes
legend("topleft", legend = c("", "", "", ""), lty = rep(0, 4), 
       col = c(adjustcolor(blues9[3], alpha.f = 0.6), 
               adjustcolor(blues9[3], alpha.f = 0.6), 
               adjustcolor("red", alpha.f = 0.1), 
               adjustcolor("red", alpha.f = 0.1)),
        pch = rep(15, 4), cex = 0.8, pt.cex = rep(2, 4),
        x.intersp = 0.7, y.intersp = 1.2, bty = 'n')

产生:

enter image description here

如您所见,方框沿图例中的行向左移动。

如何设置框的对齐方式,以使它们在图例中的线符号上方水平居中?谢谢!

3 个答案:

答案 0 :(得分:8)

由于您明确欢迎其他解决方案,因此可以使用ggplot2

library(tidyverse);
data.frame(xdata, y1, y2, y3, y4) %>%
    gather(key, y, -xdata) %>%
    mutate(key = sub("y", "Plot ", key)) %>%
    ggplot(aes(xdata, y, colour = key, linetype = key)) +
    geom_line() +
    geom_ribbon(aes(ymin = y, ymax = y, fill = key), alpha = 0.2, colour = NA) +
    scale_colour_manual(
        values = c("Plot 1" = "red", "Plot 2" = "red", "Plot 3" = "blue", "Plot 4" = "blue"),
        name = "Legend") +
    scale_linetype_manual(
        values = c("Plot 1" = "solid", "Plot 2" = "dashed", "Plot 3" = "solid", "Plot 4" = "dashed"),
        name = "Legend") +
    scale_fill_manual(
        values = c("Plot 1" = "red", "Plot 2" = "red", "Plot 3" = "blue", "Plot 4" = "blue"),
        name = "Legend") +
    theme_bw() +
    theme(
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        legend.justification = c(0, 1),
        legend.position = c(0.02, 0.98),
        legend.spacing.x = unit(0.5, 'cm'),
        legend.title = element_blank())

enter image description here

以下是主要调整的摘要:

  1. 通过零宽度fill添加geom_ribbon美感。这将为我们提供图例中的彩色框。我们使用alpha = 0.2来确保透明度。
  2. 我们手动为所有美学标尺赋予相同的名称。这样可以防止出现三个不同的图例,并将colourlinetypefill合并到一个图例中。
  3. 我们通过调整图例位置
    • legend.positionlegend.justification,以确保图例位于左上角的绘图区域内。这些参数需要根据图例文本进行一些微调,
    • 使用legend.title = element_blank()删除图例标题,
    • 使用legend.spacing.x增加图例符号和文本之间的距离;同样,根据您的个人喜好,此参数可能需要一些手动微调。

最后,我们进行了一些小的调整,以通过删除网格线(theme_bwpanel.grid.major = element_blank()panel.grid.minor = element_blank()的组合来增加与基本R图的美学相似度。

答案 1 :(得分:8)

这里的提示是在两个lwd调用中,即在legend框的调用中指定相同的lty = 0

这是一个简单的示例,仅包含与您的实际问题相关的参数:

plot(1)

# lines
legend(x = "topleft",
       legend = c("Plot 1", "Plot 2", "Plot 3", "Plot 4"), bty = 'n',
       lty = c(1, 3), lwd = 1,
       pch = NA,
       col = rep(c("blue", "red"), each = 2))

# boxes
legend(x = "topleft", 
       legend = rep("", 4), bty = "n",
       lty = 0, lwd = 1, # <- lwd = 1  
       pch = 15, pt.cex = 2,
       col = c(rep(adjustcolor(blues9[3], alpha.f = 0.6), 2),
               rep(adjustcolor("red", alpha.f = 0.1), 2)))

enter image description here


如果您对方框的颜色轮廓满意,那么一个legend调用就足够了。只需使用接受pch(此处为22)的pt.bg

plot(1)
legend(x = "topleft",
       legend = c("Plot 1", "Plot 2", "Plot 3", "Plot 4"), bty = 'n',
       lty = c(1, 3), col = rep(c("blue", "red"), each = 2),
       pch = 22, pt.cex = 2, 
       pt.bg = c(rep(adjustcolor(blues9[3], alpha.f = 0.6), 2),
                 rep(adjustcolor("red", alpha.f = 0.1), 2)))

enter image description here

答案 2 :(得分:4)

这是我使用 base R:

完成的操作

下面是您可以最终获得所需结果的一些设置。

seg.len:它基本上与基准R图形中图例行的长度一起使用,我将该值设为1.25

pt.cex:rep(4.4,4),所以我们将box作为正方形,我使用4.4调整了这些正方形的值。

x.intersp:在图例文本和图例形状之间的空间内处理

text.col:如果您对其进行注释,这是图例文本颜色的可选设置,您将获得图例文本为黑色(如您的答案)

xjust:对于0值,图例左对齐,对于0.5则居中对齐,对于1则右对齐

我反复更改了这些设置,以使它们成为最终结果。希望对您有所帮助。我已经在机器上运行了很多次以提出这个问题。

在我玩过的所有设置中,并给出以下图表:

plot(xdata, y1, type = 'l', col = "red")
lines(xdata, y2, type = 'l', col = "red", lty = 3)
lines(xdata, y3, type = 'l', col = "blue") 
lines(xdata, y4, type = 'l', col = "blue",  lty = 3)
legend("topleft", legend = c("Plot 1", "Plot 2", "Plot 3", "Plot 4"), 
       lty = c(1,3,1,3), lwd = rep(1.3 ,4), 
       col = c("blue", "blue", "red", "red") , 
       pch = rep(NA,4), cex = 0.8, 
       text.col = c("blue", "blue", "red","red"),
       y.intersp=1.2, bty = 'n', x.intersp = .5,
       seg.len = 1.265, xjust =1)
legend("topleft", legend = c("", "", "", ""), lty = rep(0, 4),
       col = c(adjustcolor(blues9[3],alpha.f=0.6),
               adjustcolor(blues9[3],alpha.f=0.6),
               adjustcolor("red",alpha.f=0.1),
               adjustcolor("red",alpha.f=0.1)),
       pch = rep(15,4), bty ='n', cex = 0.8,
       pt.cex = rep(4.3, 4), y.intersp = 1.2, x.intersp =  0.1,
       xjust = 0)

enter image description here

注意: 您已缩放图形以查看R Studio中的正确效果。