在R中的格点图例绘制中,包括线条和点。

7
大家好,我正在使用一个格点图进行工作,一切都很顺利,但是在图例方面遇到了一些问题。我正在使用xyplot()函数,效果非常棒。我的数据框是NM(我在最后部分添加了dput()版本)。
        AMes     A2009     A2010   A2011   A2012   A2013   A2014
1       enero  710004.3 1458624.4 6229245 4407423 3006568 1749746
2     febrero  889398.1  942099.6 5553163 4248144 2615730 1902865
3       marzo 1114883.1 1210951.2 6372920 3537103 2833299 1605746
4       abril 1419242.1 1151423.9 6755055 3500596 3438797 2116088
5        mayo 1585857.2 1598355.1 7119008 4049074 3224926      NA
6       junio 1010455.6 1370856.8 7585412 3279869 2794030      NA
7       julio 1292333.4 1420547.4 7258676 3420974 3003458      NA
8      agosto 1032443.3 2048291.1 7250944 2602310 2486932      NA
9  septiembre 1133260.1 3043637.6 6227707 2225635 2515076      NA
10    octubre 1229593.8 3669634.1 5795989 2853467 2674568      NA
11  noviembre 1074569.6 3641665.2 4015226 2830482 1731063      NA
12  diciembre 1370905.6 6780879.4 5391953 2823591 2054560      NA

我使用了下面的代码来生成下面的图表:
library(lattice)
library(latticeExtra)
parSettings <- list(layout.widths=list(left.padding=8,rigth.padding=20))
comma_formatter <- function (lim, logsc = FALSE, at = NULL, ...)  {
  ans <- yscale.components.default(lim = lim, logsc = logsc, at = at, ...)
  xxPrime <- as.numeric(ans$left$labels$labels)
  ans$left$labels$labels <- formatC(xxPrime, format = "fg", big.mark = ",")
  ans
}

D <- xyplot(A2009 + A2010 + A2011 + A2012 + A2013 + A2014 ~ factor(NM$AMes, unique(NM$AMes)),
            NM, type=c("p", "l"),
            yscale.components=comma_formatter,
            auto.key=list(space="right", lines=TRUE, points=T),
            par.settings=parSettings,
            layout=c(1, 1), aspect=0.6, main="Delta Index",
            lwd=2, pch=16, cex.axis=4,
            scales=list(x=list(rot=90, font=2, cex=0.8), y=list(font=2), tick.number=9))

结果是下一个图表: enter image description here

我希望在图例中将点放在线的中间,而不是分开显示。同时,我希望图例中的线和点使用与图表相同的样式。另外,我不知道是否可以移除顶部的 x 轴和右侧的 y 轴,或者至少移除这些轴上的刻度线。我的数据框的 dput() 版本如下:

structure(list(AMes = c("enero", "febrero", "marzo", "abril", 
"mayo", "junio", "julio", "agosto", "septiembre", "octubre", 
"noviembre", "diciembre"), A2009 = c(710004.35, 889398.08, 1114883.11, 
1419242.11, 1585857.22, 1010455.56, 1292333.35, 1032443.35, 1133260.11, 
1229593.84, 1074569.64, 1370905.58), A2010 = c(1458624.41, 942099.6, 
1210951.2, 1151423.89, 1598355.1, 1370856.78, 1420547.36, 2048291.06, 
3043637.6, 3669634.09, 3641665.16, 6780879.37), A2011 = c(6229245.09, 
5553163.01, 6372919.9, 6755054.64, 7119008.27, 7585411.87, 7258675.63, 
7250944.21, 6227706.73, 5795989.01, 4015226.43, 5391952.87), 
    A2012 = c(4407422.89, 4248144.11, 3537103.4, 3500595.75, 
    4049074.18, 3279868.96, 3420974.23, 2602310.3, 2225635.25, 
    2853467.41, 2830482.27, 2823590.65), A2013 = c(3006568.05, 
    2615730, 2833299.1, 3438797.32, 3224926.48, 2794029.57, 3003458.16, 
    2486931.57, 2515076.46, 2674568.38, 1731063.04, 2054559.54
    ), A2014 = c(1749745.71, 1902865, 1605746.41, 2116087.84, 
    NA, NA, NA, NA, NA, NA, NA, NA)), .Names = c("AMes", "A2009", 
"A2010", "A2011", "A2012", "A2013", "A2014"), row.names = c(NA, 
-12L), class = "data.frame")

非常感谢您的帮助。
编辑:
我不知道在格子图中是否可能使用这种样式来显示图例,其中点位于图例中的线条内部。

enter image description here

3个回答

4
要将图例放在中间,您需要设置auto.key列表的x=y=元素,而不是使用space=。您传递的坐标在0-1比例尺上,其中0,0是左下角。您需要尝试一些数字,直到将其放置在正确位置。
如果您希望图例与图形匹配(这毕竟是重点),则应更改par.settings参数中的属性,而不是直接在调用xyplot时使用lwd=pch=
我相信这样就可以解决问题了。
library(lattice)
library(latticeExtra)
parSettings <- list(
    layout.widths=list(left.padding=8,rigth.padding=20),
    superpose.line=list(lwd=2),
    superpose.symbol=list(pch=16)
)
comma_formatter <- function (lim, logsc = FALSE, at = NULL, ...)  {
  ans <- yscale.components.default(lim = lim, logsc = logsc, at = at, ...)
  xxPrime <- as.numeric(ans$left$labels$labels)
  ans$left$labels$labels <- formatC(xxPrime, format = "fg", big.mark = ",")
  ans
}

D <- xyplot(A2009+A2010+A2011+A2012+A2013+A2014 ~ factor(NM$AMes,unique(NM$AMes)), NM, 
    type = c("p","l"), 
    yscale.components = comma_formatter,
    auto.key=list(x=.35,y=.82, lines=TRUE,points=T), 
    par.settings = parSettings,layout=c(1,1),aspect=0.6,
    main = "Delta Index",
    cex.axis=4,
    scales=list(x=list(rot=90,font=2,cex=0.8),y=list(font=2),tick.number=9))
D;

updated plot


1
如果可以的话,我会给您另一个+1,因为superpose.symbol = list(pch=16)非常好用。 - Matthew Lundberg
谢谢您的帮助,亲爱的@MrFlick,但我想把点放在图例的线中间而不是绘图区域的中间。也许这是可能的。 - Duck
在图例中同时显示点和线,而不是这两个元素分开显示,这将非常棒。 - Duck

3

或者,您可以在“键”中调整一些设置。

基本上,通过在键的行参数中设置 type="b",您可以轻松地在行内添加点。

# Your code from above
parSettings <- list(layout.widths=list(left.padding=8,rigth.padding=20))
comma_formatter <- function (lim, logsc = FALSE, at = NULL, ...)  {
ans <- yscale.components.default(lim = lim, logsc = logsc, at = at, ...)
xxPrime <- as.numeric(ans$left$labels$labels)
ans$left$labels$labels <- formatC(xxPrime, format = "fg", big.mark = ",")
ans
}


# create your lattice plot
xyplot(A2009+A2010+A2011+A2012+A2013+A2014 ~ factor(NM$AMes,unique(NM$AMes)), NM, 
   type = "b",par.settings = parSettings,layout=c(1,1),
   aspect=0.6,main = "Delta Index",lwd=2,
   pch=16,cex.axis=4,
   scales=list(x=list(rot=90,font=2,cex=0.8),
               y=list(font=2),tick.number=9,tck=c(1,0)),

   # add a legend using key

   key=list(space="right",
            text=list(paste("A",2009:2014,sep="")),
            lines=list(pch=19,type="b",
                       col=trellis.par.get()$superpose.symbol$col[1:6])))

我还没有尝试过如何仅在关键线上获取单个点而不是3个,但它可以完成任务。让人烦恼的是手动指定颜色,但我相信有一种方法可以直接从格子设置中导入您的颜色级别数量。

希望这可以帮助到您。

lattice key with superposed lines and points示例


3

我已经思考这个问题有一段时间了,但由于很忙,所以直到现在才有时间来处理它。我更好地理解了你最初的问题。默认情况下,Lattice不喜欢将点堆叠在图例中的线上。这不是一个容易访问的选项。然而,如果你愿意深入研究gridLattice包的基础),你几乎可以做任何事情。所以我想出了一个解决方案,我认为这可能适合你。当:

  • 你只有一个值列在图例中
  • 你设置了auto.key=(..., points=T, lines=T)

这里的策略是向绘图提供一个定制的图例绘制函数。我尽量重用Lattice的计算结果。我拦截网格视口并对其进行了一些更改,以合并线条和点。这是定制的图例绘制函数:

drawComboKey <- function(...) {
    key = simpleKey(...)
    key = draw.key(key, draw = FALSE)

    ngroups <- (length(key$children)-1)/3
    #remove points column
    key$framevp$layout$ncol <- 
        key$framevp$layout$ncol-3L
    key$framevp$layout$respect.mat <- 
        key$framevp$layout$respect.mat[,-(3:5)]
    key$framevp$layout$widths <- 
        key$framevp$layout$widths[-(3:5)]

    #adjust background
    key$children[[1]]$col[2] <- 
        key$children[[1]]$col[2]-3L
    key$children[[1]]$cellvp$layout.pos.col[2] <-
        key$children[[1]]$cellvp$layout.pos.col[2]-3L
    key$children[[1]]$cellvp$valid.pos.col[2] <- 
        key$children[[1]]$cellvp$valid.pos.col[2]-3L

    #combine lines/points
    mylines<-(2+ngroups*2):(1+ngroups*3)
    for(i in mylines) {
        key$children[[i]]$children <- 
            gList(key$children[[i-ngroups]]$children, key$children[[i]]$children)
        key$children[[i]]$childrenOrder <- 
            names(key$children[[i]]$children)
        key$children[[i]]$col <- key$children[[i]]$col-3L
        key$children[[i]]$cellvp$layout.pos.col <- 
            key$children[[i]]$cellvp$layout.pos.col-3L
        key$children[[i]]$cellvp$valid.pos.col <- 
            key$children[[i]]$cellvp$valid.pos.col-3L
    }

    key$childrenOrder<-names(key$children)
    key
}

要使用此功能,您必须拦截trellis对象并将其设置为图例的绘图函数。因此,从上次的代码开始。
library(lattice)
library(latticeExtra)
parSettings <- list(
    layout.widths=list(left.padding=8,rigth.padding=20),
    superpose.line=list(lwd=2),
    superpose.symbol=list(pch=16)
)
comma_formatter <- function (lim, logsc = FALSE, at = NULL, ...)  {
  ans <- yscale.components.default(lim = lim, logsc = logsc, at = at, ...)
  xxPrime <- as.numeric(ans$left$labels$labels)
  ans$left$labels$labels <- formatC(xxPrime, format = "fg", big.mark = ",")
  ans
}

D <- xyplot(A2009+A2010+A2011+A2012+A2013+A2014 ~ factor(NM$AMes,unique(NM$AMes)), NM, 
    type = c("p","l"), 
    yscale.components = comma_formatter,
    auto.key=list(space="right", lines=TRUE,points=TRUE), 
    par.settings = parSettings,layout=c(1,1),aspect=0.6,
    main = "Delta Index",
    cex.axis=4,
    scales=list(x=list(rot=90,font=2,cex=0.8),y=list(font=2),tick.number=9))
D$legend$right$fun = "drawComboKey"
D;

所以您可以在倒数第二行中看到,我指定了我们的新绘图函数。基本上就是这样。这个函数非常脆弱,基本上是一个hack。如果Lattice决定改变如何构建图例或其他任何事情,我不能保证它总是有效,因此请自行承担风险。尽管如此,这是使用trellis对象自定义它们的示例。
以下是结果: legend with overplotted points and lines

太棒了,我需要更多了解关于 trellis 和 Lattice 的知识。谢谢大师 @MrFlick。 - Duck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接