繁体   English   中英

R:如何重新排序 ggplot2 行 plot 中的图例键以匹配每个系列中的最终值?

[英]R: how to reorder legend key in ggplot2 line plot to match the final values in each series?

我正在绘制折线图,显示多种工具的价格随时间的变化,使用 ggplot2。我已经成功地在 plot 上获得多条线并添加显示最近价格变化的值。 我想做的(还没有实现)是重新排序图例键,使涨幅最大的价格序列位于图例的顶部,其次是涨幅第二大的价格序列的键,很快。

在下面的 plot 中,图例按字母顺序显示了密钥。 我想要它做的是按 DDD、AAA、CCC 然后 BBB 的顺序显示图例键条目,这是截至最近日期的性能顺序。 我怎样才能做到这一点?

显示图例顺序的 ggplo2 图表

最小的代码如下。

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)

试试这个:

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)

在此处输入图像描述

我融化了你的完整数据集,为你节省了几行用于绘制代码的代码。 像往常一样,关键是要确保变量是一个有序的因素。

要解决评论中出现的问题,您可以传递任何您喜欢出现在图例中的标签,只要您的顺序正确即可:

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

在此处输入图像描述

注意:自 0.9.2 版本以来, opts已被theme取代,例如:

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

试试这个

  • 指南(颜色= guide_legend(反向= T))

我认为有更简单的方法。 融化 dataframe 后,按日期值对其排序并使用最后日期的值来创建图例。 由于您按值排序,因此图例将按照您对值的排序方式(从最大值到最小值或从最小值到最大值)对应的顺序显示行。 下面的代码。

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)

暂无
暂无

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

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