Include lines and dots in the grid legend graph in R

Hi everyone, I work in the lattice graph, and everything works fine, but I have some problems with the legend. I use xyplot() and it works amazingly. My dataframe NM (I add the dput() version in the final part):

  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 following code to create the following graph:

 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 

As a result, the following graph appears: enter image description here

I would like to get a legend about these plot points in the middle of the lines, but not divided, as yiu can see. Also, I would like to get the same style that I used in the graphics for lines and dots in the legend. Also I do not know if it is possible to remove the top x axis and the right y axis, or at least remove the gaps of this axis. The dput() version of my data frame is as follows:

 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 a legend grid with this style, where the points are inside the lines in the legend:

enter image description here

+6
source share
3 answers

I thought about this problem for a while, but I was very busy, so I have not had much time to work on it so far. I better understand what was your original question. By default, Lattice does not like to lay dots on top of lines in a legend. This is simply not an easily accessible option. However, if you are ready to dig into the grid (based on the Lattice package), you can pretty much do something. So I hacked into a solution that I think might work for you. This should work when

  • There is only one value column in the legend
  • You set auto.key=(..., points=T, lines=T)

The strategy here is to provide an individual legend drawing function on the chart. I am trying to use as many calculations as I can from Lattice. I intercept the grid view of the grid and make a few changes to combine the lines and points. Here's the custom 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 lattice object and set this as the drawing function for the legend. So, starting with the last time code

 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 and last line, I indicated our new drawing function. And that is pretty much the case. This feature is pretty fragile and mostly hacked. I can’t guarantee that it will always work if Lattice decides to change how it creates legends or something like that, so use them at your own risk. However, this is a pretty good example of what you can do with lattice objects to customize them.

And here is the result:

legend with overplotted points and lines

+2
source

To put the legend in the middle, you need to set the x= and y= elements in the auto.key list instead of using space= . The coordinates that you go through are on the 0-1 scale, and 0.0 is in the lower left corner. You kind of have to try numbers until you get them in the right place.

And if you want the legend to fit the plot (this is really the point after all), you should change the properties in the par.settings parameter and not use lwd= and pch= directly in the xyplot call

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; 

updated plot

+3
source

Alternatively, you can simply adjust some settings in the key.

Basically, by setting type = "b" in the argument of the strings in the key, you can easily add dots inside the strings

 # 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 did not try to figure out how to get only one point in the lines in the key instead of 3, but this does the job. The annoying part indicates the colors manually, but I'm sure there is a way to import the number of levels for your colors directly from the grid settings.

Hope this helps.

Example of lattice key with superposed lines and points

+3
source

All Articles