2012-04-09 4 views
5

ggplot2를 사용하여 여러 계측기의 가격 변동을 보여주는 꺾은 선형 차트를 그려 봅니다. 플롯에서 여러 줄을 얻고 가장 최근의 가격 변화를 보여주는 값을 추가하는 데 성공했습니다. 내가하고 싶은 것은 (그리고 아직 성취하지 못했던) 범례 키의 순서를 바꾸어서 가장 많이 올랐던 가격 시리즈가 전설의 맨 위에 오도록하고 두 번째로 많이 오른 가격 시리즈의 키와 곧.R : 각 시리즈의 최종 값과 일치하도록 ggplot2 선 그림의 범례 키를 재정렬하는 방법은 무엇입니까?

아래 그림에서 범례는 키를 사전 순으로 보여줍니다. 내가하고 싶은 것은 DDD, AAA, CCC, BBB 순으로 범례 키 항목을 표시하는 것입니다. 가장 최근 날짜의 성능 순서입니다. 어떻게해야합니까?

ggplo2 chart showing legend order

최소 틱 코드는 다음과 같다.

require(ggplot2) 
require(scales) 
require(gridExtra) 
require(lubridate) 
require(reshape) 

# create fake price data 
set.seed(123) 
monthsback <- 15 
date <- as.Date(paste(year(now()), month(now()),"1", sep="-")) - months(monthsback) 
mydf <- data.frame(mydate = seq(as.Date(date), by = "month", length.out = monthsback), 
         aaa = runif(monthsback, min = 600, max = 800), 
         bbb = runif(monthsback, min = 100, max = 200), 
         ccc = runif(monthsback, min = 1400, max = 2000), 
         ddd = runif(monthsback, min = 50, max = 120)) 

# function to calculate change 
change_from_start <- function(x) { 
    (x - x[1])/x[1] 
} 

# for appropriate columns (i.e. not date), replace fake price data with change in price 
mydf[, 2:5] <- lapply(mydf[, 2:5], function(myparam){change_from_start(myparam)}) 

# get most recent values and reshape 
myvals <- mydf[mydf$mydate == mydf$mydate[nrow(mydf)],] 
myvals <- melt(myvals, id = c('mydate')) 

# plot multiple lines 
p <- ggplot(data = mydf) + 
    geom_line(aes(x = mydate, y = aaa, colour = "AAA"), size = 1) + 
    geom_line(aes(x = mydate, y = bbb, colour = "BBB"), size = 1) + 
    geom_line(aes(x = mydate, y = ccc, colour = "CCC"), size = 1) + 
    geom_line(aes(x = mydate, y = ddd, colour = "DDD"), size = 1) + 
    scale_colour_manual("", values = c("AAA" = "red", "BBB" = "black", "CCC" = "blue", "DDD" = "green")) + 
    scale_y_continuous(label = percent_format()) + 
    geom_text(data = myvals, aes(x = mydate + 30, y = value, label = sprintf("%+1.1f%%", myvals$value * 100)), size = 4, colour = "grey50") + 
    opts(axis.title.y = theme_blank()) + 
    opts() 

# and output 
print(p) 

답변

9

이 시도 :

mydf <- melt(mydf,id.var = 1) 
mydf$variable <- factor(mydf$variable,levels = rev(myvals$variable[order(myvals$value)]),ordered = TRUE) 

# plot multiple lines 
p <- ggplot(data = mydf) + 
    geom_line(aes(x = mydate,y = value,colour = variable,group = variable),size = 1) + 
    scale_colour_manual("", values = c("aaa" = "red", "bbb" = "black", "ccc" = "blue", "ddd" = "green")) + 
    scale_y_continuous(label = percent_format()) + 
    geom_text(data = myvals, aes(x = mydate + 30, y = value, label = sprintf("%+1.1f%%", myvals$value * 100)), 
       size = 4, colour = "grey50") + 
    opts(axis.title.y = theme_blank()) + 
    opts() 

# and output 
print(p) 

enter image description here

내가 당신에게 코드를 플로팅 여러 줄을 저장하도록 설정하여 전체 데이터 녹은. 평소와 마찬가지로 키는 변수가 정렬 된 요소인지 확인하는 것입니다.

ggplot(data = mydf) + 
    geom_line(aes(x = mydate,y = value,colour = variable,group = variable),size = 1) + 
    scale_colour_manual("", values = c("aaa" = "red", "bbb" = "black", "ccc" = "blue", "ddd" = "green"),labels = c('Company D','Company A','Company C','Company B')) + 
    scale_y_continuous(label = percent_format()) + 
    geom_text(data = myvals, aes(x = mydate + 30, y = value, label = sprintf("%+1.1f%%", myvals$value * 100)), 
       size = 4, colour = "grey50") + 
    opts(axis.title.y = theme_blank()) + 
    opts() 

enter image description here

: 코멘트에 발생한 문제를 해결하기 위해

, 당신은 당신이 아니라 당신이 올바른 순서를 얻을로, 전설 자체에 표시 할 어떤 레이블을 전달할 수 있습니다 참고 : 버전부터 0.9.2 opts는, 예를 들어 theme에 의해 replaced있다 :

+ theme(axis.title.y = element_blank()) 
+3

Perfect! 'ordered factor'는 불필요합니다. 수준의 순서는 중요하지만 ggplot2는 요인이 주문되었는지 여부에 대해 신경 쓰지 않습니다. – kohske

+0

알다시피, @kohske, 감사합니다! 나는 인자가 주문되지 않았다면 나는 그들 자신의 주문에 대해 결정하는 다른 사람들의 암호에 대해 지나치게 편집증 적이라고 생각한다. – joran

+0

joran에게 감사드립니다. 주요 데이터 프레임에 대해 녹을 피했지만 실제 결과는 아니며 많은 보일러 판을 절약 할 수 있다고 지적했습니다. 나는'values ​​= c ("aaa"= "red")'부분을리스트를 사용하여 따로 정의 할 수 있기 때문에 내가 만들고 싶을 때마다 코드의 ggplot 부분을 발견 할 필요가 없다고 생각한다. 내가 음모를 꾸미고 싶은 항목을 변경 ...? 의견을 보내 주신 kohske에게도 감사드립니다. – SlowLearner

0

더 쉬운 방법이 있다고 생각합니다. 데이터 프레임을 녹이면 날짜 - 값으로 정렬하고 마지막 날짜의 값을 사용하여 범례를 만듭니다. 값순으로 주문 했으므로 값을 주문한 방식 (최대에서 최소 또는 최소까지)에 해당하는 순서로 선이 표시됩니다. 아래 코드.

require(ggplot2) 
require(scales) 
require(gridExtra) 
require(lubridate) 
require(reshape) 

# create fake price data 
set.seed(123) 
monthsback <- 15 
date <- as.Date(paste(year(now()), month(now()),"1", sep="-")) - months(monthsback) 
mydf <- data.frame(mydate = seq(as.Date(date), by = "month", length.out = monthsback), 
         aaa = runif(monthsback, min = 600, max = 800), 
         bbb = runif(monthsback, min = 100, max = 200), 
         ccc = runif(monthsback, min = 1400, max = 2000), 
         ddd = runif(monthsback, min = 50, max = 120)) 

# function to calculate change 
change_from_start <- function(x) { 
    (x - x[1])/x[1] 
} 

# for appropriate columns (i.e. not date), replace fake price data with change in price 
mydf[, 2:5] <- lapply(mydf[, 2:5], function(myparam){change_from_start(myparam)}) 

mydf <- melt(mydf, id.var=1) 

#Order by date and value. Decreasing since want to order greatest to least 
mydf <- mydf[order(mydf$mydate, mydf$value, decreasing = TRUE),] 

#Create legend breaks and labels 
legend_length <- length(unique(mydf$variable)) 
legend_breaks <- mydf$variable[1:legend_length] 

#Pass order through scale_colour_discrete 
ggplot(data=mydf) + geom_line(aes(x = mydate,y = value,colour = variable,group = variable),size = 1) + scale_colour_discrete(breaks=legend_breaks) 
관련 문제