首页 > 解决方案 > 是否可以以编程方式添加 ggplot2 注释

问题描述

我有以下代码片段:

  for(j in 1:10){
    max_value[j] <- round(value * 1.1 ^ j, 2)
    min_value[j] <- round(value * 0.9 ^ j, 2)
    max_estimate[j] <- round(log(max_value[j]) + 0.2775, 3)
    min_estimate[j] <- round(log(min_value[j]) + 0.2775, 3)
  }

gg <- ggplot(data, aes(x = as.Date(rowname), y = get(ticker))) +
      geom_line() +
      # value calulation date vline
      geom_vline(xintercept = date_value, col = "Gray", size = 1) +
      # Index value at value calculation date hline
      geom_hline(yintercept = value_value, col = "Gray", size = 1) +
      # Max values hlines
      geom_hline(yintercept = pre_values_max, col = "Red", size = 1) +
      # value and return estimate for the value calculation date
      annotate("text", as.Date("2013-12-31"), value_value * 1.02,
               label = paste0(value, ", ", percent(return_estimate)), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_max[1] * 1.02,
               label = paste0(max_value[1], ", ", percent(max_estimate[1])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_max[2] * 1.02 ^ 1,
               label = paste0(max_value[2], ", ", percent(max_estimate[2])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_max[3] * 1.02,
               label = paste0(max_value[3], ", ", percent(max_estimate[3])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_max[4] * 1.02,
               label = paste0(max_value[4], ", ", percent(max_estimate[4])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_max[5] * 1.02,
               label = paste0(max_value[5], ", ", percent(max_estimate[5])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_max[6] * 1.02,
               label = paste0(max_value[6], ", ", percent(max_estimate[6])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_max[7] * 1.02 ^ 1,
               label = paste0(max_value[7], ", ", percent(max_estimate[7])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_max[8] * 1.02,
               label = paste0(max_value[8], ", ", percent(max_estimate[8])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_max[9] * 1.02,
               label = paste0(max_value[9], ", ", percent(max_estimate[9])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_max[10] * 1.02,
               label = paste0(max_value[10], ", ", percent(max_estimate[10])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_min[1] * 1.02,
               label = paste0(min_value[1], ", ", percent(min_estimate[1])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_min[2] * 1.02,
               label = paste0(min_value[2], ", ", percent(min_estimate[2])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_min[3] * 1.02,
               label = paste0(min_value[3], ", ", percent(min_estimate[3])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_min[4] * 1.02,
               label = paste0(min_value[4], ", ", percent(min_estimate[4])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_min[5] * 1.02,
               label = paste0(min_value[5], ", ", percent(min_estimate[5])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_min[6] * 1.02,
               label = paste0(min_value[6], ", ", percent(min_estimate[6])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_min[7] * 1.02,
               label = paste0(min_value[7], ", ", percent(min_estimate[7])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_min[8] * 1.02,
               label = paste0(min_value[8], ", ", percent(min_estimate[8])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_min[9] * 1.02,
               label = paste0(min_value[9], ", ", percent(min_estimate[9])), color = "Blue") +
      annotate("text", as.Date("2013-12-31"), pre_values_min[10] * 1.02,
               label = paste0(min_value[10], ", ", percent(min_estimate[10])), color = "Blue") +
      # Min values hlines
      geom_hline(yintercept = pre_values_min, col = "Green", size = 1) +
      ggtitle(paste0(country, ", ", ticker)) +
      xlab("Date") + ylab("Index")
    print(gg)

如您所见,有 21 个注释,但它们的值是在第一个循环中生成的。有没有办法以编程方式添加注释?For 循环或 if 语句似乎在 ggplot 中不起作用。如果我有一百个这样的值,那么如何在没有额外一百行的情况下制作情节?抱歉没有代表,但代码和目标应该很清楚。

标签: rggplot2

解决方案


您可以将绘图保存为字符串,annotate()在循环中添加行,然后执行生成的字符串:

library(ggplot2)


data <- data.frame(x=rnorm(100),y=rnorm(100)) #example data
annotations <- data.frame(x=c(-2,-1,-1),      #annotation information
                          y=c(0,1,2),
                          text=c("An. 1","An. 2", "An. 3"))
p <- "ggplot(data, aes(x,y)) + geom_point()"  #save plot as character string

eval(parse( text=p )) #execute character string


for(i in 1:nrow(annotations)){

  #in each iteration, add one annotate line 
  #with info from the annotations dataframe

  p <- paste(p,paste0('+ annotate("text",',annotations[i,1],',',annotations[i,2],', label ="', annotations[i,3],'", color = "Blue")'))


}

eval(parse( text=p )) #new plot with all annotations

推荐阅读