2014-05-11 11 views
6

Witam wszystkich, pracuję na grafie sieci i wszystko działa dobrze, ale mam problem z legendą. Używam xyplot() i działa świetnie. Moja dataframe jest NM (dodam dput() wersję w końcowej części):Dołącz linie i punkty na wykresie legendy kraty w R

 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 

użyłem następny kod do produkcji kolejnej działki:

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 

wynik jest kolejnym wykresie: enter image description here

Chciałbym dostać się do legendy o tych punktach fabuły w środku linii, ale nie można ich oddzielić tak, jak widać. Chciałbym również uzyskać ten sam styl, którego użyłem na wykresie dla linii i punktów w legendzie. Nie wiem też, czy możliwe jest usunięcie górnej osi x i prawej osi y lub przynajmniej usunięcie przerw w tej osi. dput() wersja mojego dataframe jest następny:

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

Wielkie dzięki za pomoc.

EDIT

ja nie wiem, czy to jest możliwe, aby uzyskać w kratę legendę z tego stylu, w którym punkty są linie wewnątrz w legendzie:

enter image description here

Odpowiedz

2

Myślałam o tym problemie na chwilę, ale i” Byłem bardzo zajęty, więc nie miałem zbyt wiele czasu, aby nad tym pracować. Rozumiem lepiej, jakie było twoje pierwotne pytanie. Domyślnie Lattice nie lubi układać punktów na górze linii w legendzie. To po prostu nie jest łatwo dostępna opcja. Jeśli jednak chcesz zagłębić się w grid (pakiet jest zbudowany pod numerem Lattice), możesz zrobić prawie wszystko. Więc zhakowałem razem rozwiązanie, które według mnie może ci pomóc. To powinno działać, gdy

  • Masz tylko jedną kolumnę wartości w legendzie
  • ustawić auto.key=(..., points=T, lines=T)

Strategia tutaj jest dostarczanie niestandardowych funkcji legenda rysunek do działki. Próbuję ponownie wykorzystać tyle obliczeń, ile mogę, z Kraty.Przechodzę przez rzutnię siatki i wprowadzam kilka zmian, aby scalić linie i punkty. Oto dostosowane funkcja legenda rysunek:

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 
} 

Aby korzystać z tej funkcji, należy przejąć obiekt krata i ustawić go jako funkcji rysowania dla legendy. Tak więc, zaczynając od kodu z ostatniego czasu:

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; 

Tak więc w drugim wierszu do ostatniej linii podałem nową funkcję rysowania. I to już prawie wszystko. Ta funkcja jest dość delikatna i zasadniczo jest hackerem. Nie mogę zagwarantować, że zawsze będzie działać, jeśli Lattice zdecyduje się zmienić sposób budowania legend lub czegoś w tym stylu, więc używaj go na własne ryzyko. Niemniej jest to całkiem dobry przykład tego, co można zrobić z obiektami kratowymi, aby je dostosować.

A oto wynik:

legend with overplotted points and lines

+0

Niesamowite Muszę się dowiedzieć więcej o kratach i kratach. Dziękuję Master @MrFlick – Duck

3

umieścić legenda w środku, musisz ustawić elementy x= i y= z listy auto.key zamiast używać space=. Współrzędne, które zdałeś, są w skali 0-1, gdzie 0,0 oznacza lewy dolny. Musisz wypróbować liczby, dopóki nie dostaniesz go we właściwe miejsce.

A jeśli chcesz legendę pasujące do fabuły (która jest naprawdę chodzi po wszystkich), powinny być zmiany właściwości w parametrze par.settings i nie korzystając lwd= i pch= bezpośrednio w zaproszeniu do xyplot

wierzę, że to powinno wystarczyć

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

dałbym wam innego +1 dla 'superpose.symbol = list (PCH = 16)' gdybym mógł. –

+0

Dziękuję za twoją pomoc, kochany @MrFlick, ale chciałbym umieścić punkty w środku linii w legendzie, a nie w środku działki. Może to możliwe. – Duck

+0

Byłoby fantastycznie mieć w legendzie zarówno punkt i linię, a nie te dwa elementy oddzielone. – Duck

3

Alternatywnie można po prostu ustawić jakieś ustawienie w kluczu.

Zasadniczo ustawiając type = „b” w argumencie linii w kluczu, można łatwo dodać punkty wewnątrz linii

# 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]))) 

nie próbowałem dowiedzieć się, jak dostać tylko jeden punkt na linie w kluczu zamiast w 3, ale wykonuje to zadanie. Denerwujące jest ręczne określanie kolorów, ale jestem pewien, że istnieje sposób na zaimportowanie liczby poziomów kolorów bezpośrednio z ustawień kratki.

Nadzieję, że to pomaga.

Example of lattice key with superposed lines and points

Powiązane problemy