简体   繁体   English

在R中包括格子图例图中的线和点

[英]Include lines and points in lattice legend plot in R

Hi everybody I am working in a lattice graph and all works fine but I have some trouble with legend. 大家好,我正在格子图中工作,一切正常但我对传奇有些麻烦。 I am using xyplot() and it works awesome. 我正在使用xyplot() ,它工作得很棒。 My dataframe is NM (I add dput() version in the final part): 我的数据帧是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

I used the next code to produce the next plot: 我使用下一个代码来生成下一个图:

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

The result is the next graph: 结果是下一个图: 在此输入图像描述

I would like to get in the legend of this plot points in the middle of the lines, but not separated as yiu can see. 我想在线条中间的这个情节点的传说,但没有分开,因为yiu可以看到。 Also I would like to get the same style that I used in the graph for lines and points in the legend. 另外,我想获得我在图表中用于图例中的线条和点的相同样式。 Also I don't know if it is possible to remove top x axis and right y axis or at least remove the breaks in this axis. 另外我不知道是否可以移除顶部x轴和右y轴或至少移除此轴上的断点。 The dput() version of my dataframe is the next: 我的数据帧的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")

Many thanks for your help. 非常感谢您的帮助。

EDIT 编辑

I don't know if it is possible to get in lattice a legend with this style, where points are inside lines in the legend: 我不知道是否有可能使用这种样式进入格子传奇,其中点是图例中的线条内部:

在此输入图像描述

To put the legend in the middle, you need to set the x= and y= elements of the auto.key list rather than using space= . 要将图例放在中间,您需要设置auto.key列表的x=y=元素,而不是使用space= The coordinates you pass are on the 0-1 scale with 0,0 being the lower left. 您传递的坐标为0-1刻度,0,0为左下角。 You kind of have to try out numbers till you get it in the right place. 你有必要尝试数字,直到你得到它在正确的地方。

And if you want the legend to match the plot (which is really the point after all), you should be changing the properties in the par.settings parameter and not using lwd= and pch= directly in the call to xyplot 如果你想让图例与图表匹配(毕竟这是真正的点),你应该改变par.settings参数中的属性,而不是在调用xyplot直接使用lwd=pch=

I believe this should do the trick 我相信这应该可以解决问题

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;

更新的情节

Alternatively you can just adjust some setting in key. 或者,您可以在键中调整一些设置。

Basically by setting type="b" in the lines argument in key, you can easily add points inside the lines 基本上通过在键的lines参数中设置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])))

I haven't tried to figure out how to only get a single point on the lines in the key instead of 3, but it does the job. 我没有试图找出如何只在键中的行上获得单个点而不是3,但它完成了这项工作。 The annoying part is specifying the colours manually, but I'm sure there is a way to import the number of levels for your colours directly from the trellis settings. 恼人的部分是手动指定颜色,但我确信有一种方法可以直接从格子设置导入颜色的级别数。

Hope this Helps. 希望这可以帮助。

具有叠加线和点的网格键的示例

I've been thinking about this problem for a while but i've been very busy so I didn't have much time to work on it till now. 我一直在考虑这个问题,但我一直很忙,所以到目前为止我没有太多时间去研究它。 I understand better what your original question was. 我更清楚你原来的问题是什么。 By default Lattice does not like to stack the points on top of the lines in the legend. 默认情况下,莱迪思不喜欢将点堆叠在图例中的线条顶部。 That's simply not an easily accessible option. 这根本不是一个容易获得的选择。 However, If you're willing do dig into grid (the package Lattice is built on) you can pretty much do anything. 但是,如果你愿意深入研究gridLattice包是建立的),你几乎可以做任何事情。 So i've hacked together a solution I think may work for you. 所以我已经破解了一个我觉得可能适合你的解决方案。 This should work when 这应该适用于

  • You only have one column of values in the legend 图例中只有一列值
  • You set auto.key=(..., points=T, lines=T) 你设置auto.key=(..., points=T, lines=T)

The strategy here is to supply a customized legend drawing function to the plot. 这里的策略是为绘图提供定制的图例绘制功能。 I try to reuse as much of the calculations as I can from Lattice. 我尝试尽可能多地重复使用莱迪思的计算。 I intercept the grid viewport and make a few changes to merge the lines and points. 我拦截网格视口并进行一些更改以合并线和点。 Here's the customized legend drawing function: 这是自定义的图例绘制功能:

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
}

To use this function, you must intercept the trellis object and set this as the drawing function for the legend. 要使用此功能,必须截取格子对象并将其设置为图例的绘图功能。 So, starting with the code from last time 所以,从上次的代码开始

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;

So you can see in the second to the last line I specified our new drawing function. 所以你可以在第二行到最后一行看到我指定的新绘图函数。 And that's pretty much it. 这就是它。 This function is quite fragile and basically a hack. 这个功能非常脆弱,基本上都是黑客攻击。 I cannot guarantee that it will always work if Lattice decides to change how it builds legends or anything like that so use at your own risk. 我不能保证,如果莱迪思决定改变它构建传说或其他任何类似的东西,它将永远有效,所以使用风险自负。 Nevertheless, it's a pretty good example of the kinds of things you can do with trellis objects to customize them. 尽管如此,这是一个很好的例子,你可以用格子对象来定制它们。

And here's the result: 这是结果:

带有过分点和线的图例

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

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