R 在行尾打印标签

R 在行尾打印标签,r,ggplot2,legend,R,Ggplot2,Legend,我有以下数据(temp.dat完整数据见尾注) 我可以制作以下图表: ggplot(temp.dat) + geom_line(aes(x = Year, y = Capex, group = State, colour = State)) 而不是图例,我希望标签是 颜色与系列相同 在每个系列的最后一个数据点的右侧 我注意到巴普蒂斯特在下面链接的答案中的评论,但当我试图修改他的代码时(geom_text(aes(label=State,color=State,x=Inf,y=Capex

我有以下数据(
temp.dat
完整数据见尾注)

我可以制作以下图表:

ggplot(temp.dat) + 
  geom_line(aes(x = Year, y = Capex, group = State, colour = State))

而不是图例,我希望标签是

  • 颜色与系列相同
  • 在每个系列的最后一个数据点的右侧
  • 我注意到巴普蒂斯特在下面链接的答案中的评论,但当我试图修改他的代码时(
    geom_text(aes(label=State,color=State,x=Inf,y=Capex),hjust=-1)
    ),文本不会出现


    temp.dat不确定这是否是最好的方法,但您可以尝试以下方法(使用
    xlim
    来正确设置限制):

    库(dplyr)
    
    实验室你没有100%模仿@Baptiste的溶液。您需要使用
    annotation\u custom
    并循环所有
    Capex

    library(ggplot2)
    library(dplyr)
    library(grid)
    
    temp.dat <- structure(list(Year = c("2003", "2004", "2005", "2006", "2007", 
    "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2003", 
    "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", 
    "2012", "2013", "2014", "2003", "2004", "2005", "2006", "2007", 
    "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2003", 
    "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", 
    "2012", "2013", "2014"), State = structure(c(1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), .Label = c("VIC", 
    "NSW", "QLD", "WA"), class = "factor"), Capex = c(5.35641472365348, 
    5.76523240652641, 5.24727577535625, 5.57988239709746, 5.14246402568366, 
    4.96786288162828, 5.493190785287, 6.08500616799372, 6.5092228474591, 
    7.03813541623157, 8.34736513875897, 9.04992300432169, 7.15830329914056, 
    7.21247045701994, 7.81373928617117, 7.76610217197542, 7.9744994967006, 
    7.93734452080786, 8.29289899132255, 7.85222269563982, 8.12683746325074, 
    8.61903784301649, 9.7904327253813, 9.75021175267288, 8.2950673974226, 
    6.6272705639724, 6.50170524635367, 6.15609626379471, 6.43799637295979, 
    6.9869551384028, 8.36305663640294, 8.31382617231745, 8.65409824343971, 
    9.70529678167458, 11.3102788081848, 11.8696420977237, 6.77937303542605, 
    5.51242844820827, 5.35789621712839, 4.38699327451101, 4.4925792218211, 
    4.29934654081527, 4.54639175257732, 4.70040615159951, 5.04056109514957, 
    5.49921208937735, 5.96590909090909, 6.18700407463007)), class = "data.frame", row.names = c(NA, 
    -48L), .Names = c("Year", "State", "Capex"))
    
    temp.dat$Year <- factor(temp.dat$Year)
    
    color <- c("#8DD3C7", "#FFFFB3", "#BEBADA", "#FB8072")
    
    gg <- ggplot(temp.dat) 
    gg <- gg + geom_line(aes(x=Year, y=Capex, group=State, colour=State))
    gg <- gg + scale_color_manual(values=color)
    gg <- gg + labs(x=NULL)
    gg <- gg + theme_bw()
    gg <- gg + theme(legend.position="none")
    
    states <- temp.dat %>% filter(Year==2014)
    
    for (i in 1:nrow(states))  {
      print(states$Capex[i])
      print(states$Year[i])
      gg <- gg + annotation_custom(
        grob=textGrob(label=states$State[i], 
                        hjust=0, gp=gpar(cex=0.75, col=color[i])),
        ymin=states$Capex[i],
        ymax=states$Capex[i],
        xmin=states$Year[i],
        xmax=states$Year[i])
    }    
    
    gt <- ggplot_gtable(ggplot_build(gg))
    gt$layout$clip[gt$layout$name == "panel"] <- "off"
    grid.newpage()
    grid.draw(gt)
    
    库(ggplot2)
    图书馆(dplyr)
    图书馆(网格)
    
    temp.dat要使用Baptiste的想法,您需要关闭剪辑。但当你这样做的时候,你会得到垃圾。此外,您需要抑制图例,对于
    geom_text
    ,选择2014年的资本支出,并增加利润,为标签留出空间。(或者您可以调整
    hjust
    参数以在绘图面板内移动标签。)如下所示:

    library(ggplot2)
    library(grid)
    
    p = ggplot(temp.dat) + 
      geom_line(aes(x = Year, y = Capex, group = State, colour = State)) + 
      geom_text(data = subset(temp.dat, Year == "2014"), aes(label = State, colour = State, x = Inf, y = Capex), hjust = -.1) +
      scale_colour_discrete(guide = 'none')  +    
      theme(plot.margin = unit(c(1,3,1,1), "lines")) 
    
    # Code to turn off clipping
    gt <- ggplotGrob(p)
    gt$layout$clip[gt$layout$name == "panel"] <- "off"
    grid.draw(gt)
    

    编辑以增加端点和标签之间的空间:

    ggplot(temp.dat, aes(x = Year, y = Capex, group = State, colour = State)) + 
      geom_line() +
      scale_colour_discrete(guide = 'none') +
      scale_x_discrete(expand=c(0, 1)) +
      geom_dl(aes(label = State), method = list(dl.trans(x = x + 0.2), "last.points", cex = 0.8)) +
      geom_dl(aes(label = State), method = list(dl.trans(x = x - 0.2), "first.points", cex = 0.8)) 
    

    较新的解决方案是使用
    ggrepel

    library(ggplot2)
    library(ggrepel)
    library(dplyr)
    
    temp.dat %>%
      mutate(label = if_else(Year == max(Year), as.character(State), NA_character_)) %>%
      ggplot(aes(x = Year, y = Capex, group = State, colour = State)) + 
      geom_line() + 
      geom_label_repel(aes(label = label),
                      nudge_x = 1,
                      na.rm = TRUE)
    

    这个问题很古老,但很重要,我为疲惫的人们提供了另一个答案

    这个解决方案的原理可以非常普遍地应用

    Plot_df <- 
      temp.dat %>% mutate_if(is.factor, as.character) %>%  # Who has time for factors..
      mutate(Year = as.numeric(Year))
    
    最后一个漂亮的部分就是固定下面的轴


    我想为标签名称较长的情况添加一个解决方案。在提供的所有解决方案中,标签都位于绘图画布中,但如果名称较长,则标签将被截断。下面是我如何解决这个问题的:

    library(tidyverse)
    
    # Make the "State" variable have longer levels
    temp.dat <- temp.dat %>% 
        mutate(State = paste0(State, '-a-long-string'))
    
    ggplot(temp.dat, aes(x = Year, y = Capex, color = State, group = State)) + 
        geom_line() +
        # Add labels at the end of the line
        geom_text(data = filter(temp.dat, Year == max(Year)),
                  aes(label = State),
                  hjust = 0, nudge_x = 0.1) +
        # Allow labels to bleed past the canvas boundaries
        coord_cartesian(clip = 'off') +
        # Remove legend & adjust margins to give more space for labels
        # Remember, the margins are t-r-b-l
        theme(legend.position = 'none',
              plot.margin = margin(0.1, 2.6, 0.1, 0.1, "cm")) 
    
    库(tidyverse)
    #使“State”变量具有更长的级别
    温度数据%
    mutate(State=paste0(State,'-a-long-string'))
    ggplot(临时数据、不良事件(x=年度,y=资本支出,颜色=州,集团=州))+
    geom_线()+
    #在行尾添加标签
    geom_文本(数据=过滤器(温度数据,年份==最大年份)),
    aes(标签=状态),
    hjust=0,微移_x=0.1)+
    #允许标签溢出画布边界
    坐标笛卡尔(clip='off')+
    #删除图例并调整边距,为标签留出更多空间
    #记住,边距是t-r-b-l
    主题(legend.position='none',
    plot.margin=余量(0.1,2.6,0.1,0.1,“厘米”)
    

    我回答这个问题的目的是在最后一个装配点而不是最后一个数据点直接标记装配线(例如
    黄土()
    )。我最终找到了一种方法来实现这一点,主要是基于tidyverse,它应该也适用于带有一些MOD的线性回归,所以我把它留给子孙后代

    library(tidyverse)
    
    temp.dat$Year <- as.numeric(temp.dat$Year)
    temp.dat$State <- as.character(temp.dat$State)
    
    #example of loess for multiple models
    #https://stackoverflow.com/a/55127487/4927395
    
    models <- temp.dat %>%
      tidyr::nest(-State) %>%
      dplyr::mutate(
        # Perform loess calculation on each CpG group
        m = purrr::map(data, loess,
                       formula = Capex ~ Year, span = .75),
        # Retrieve the fitted values from each model
        fitted = purrr::map(m, `[[`, "fitted")
      )
    
    # Apply fitted y's as a new column
    results <- models %>%
      dplyr::select(-m) %>%
      tidyr::unnest()
    
    #find final x values for each group
    my_last_points <- results %>% group_by(State) %>% summarise(Year = max(Year, na.rm=TRUE))
    
    #Join dataframe of predictions to group labels
    my_last_points$pred_y <- left_join(my_last_points, results)
    
    # Plot with loess line for each group
    ggplot(results, aes(x = Year, y = Capex, group = State, colour = State)) +
      geom_line(alpha = I(7/10), color="grey", show.legend=F) +
      #stat_smooth(size=2, span=0.3, se=F, show_guide=F)
      geom_point(size=1) +
      geom_smooth(se=FALSE)+
      geom_text(data = my_last_points, aes(x=Year+0.5, y=pred_y$fitted, label = State))
    
    库(tidyverse)
    
    temp.dat$Year我只需要创建一个单独的数据框,其中只包含您想要绘制的数据,如so
    geom_text(data=temp.dat[cumsum(table(temp.dat$State)),],aes(label=State,color=State,x=Year,y=Capex))
    ,但可能还有一种更为gg的方法来做这件事,我不知道
    directlabels
    软件包。我在文档中看不到手动增加端点和文本标签之间水平间距的方法。最好的方法是什么?我添加了一个编辑。请参阅尝试安装软件包时的常见问题解答(第5条):
    软件包“directlabels”不可用(适用于R版本3.3.2)
    。我也找不到该软件包的常见问题解答网站。它还活着吗?@MERose嗯。我不知道发生了什么事。该链接仍处于活动状态。“常见问题”在第一页。我刚刚用cran检查过-directlabels可用。@slhck,看起来它还没有安装。您是否尝试过安装
    quadprog
    ?完美-但我添加了“scale\u color\u discrete(guide=FALSE)”以从图表外部删除现在不必要的图例(保存一些重要的屏幕不动产)。您好,您能否将其扩展到这种情况:?这会产生错误消息:“错误:美学必须为长度1或与数据(48)相同:x,y,label,hjust”如果我只想在一个较低的点上放置一些标记或x或坐标(在这种情况下,我如何在(2008,5)上放置一些标签,我将不胜感激在WA-a-long-string中?我将感谢您的回复!在我的解决方案中,我过滤数据以选择我想要的标签的精确x和y坐标。因为我希望它们位于行的末尾,所以我在
    geom_text()中使用了
    data=filter(temp.dat,Year==max(Year))
    call。在您的情况下,您可以将过滤器更改为
    data=filter(temp.dat,Year==2008,State=“WA”)
    ,这将只在2008年的x位置提供“WA”标签,并且您可以通过调整
    geom_text()中的
    轻推y
    参数来调整y位置
    我不认为这是一种改进,因为硬设置边距是不实际的。下面我的解决方案是:temp.dat%mutate(State=paste0(State,'-a-long-string'))Plot_df%mutate_if(is.factor,as.character)%>%mutate(Year=as.numeric(Year))ggplot()+geom_line(data=Plot_df,aes(Year,Capex,color=State))+geom_text(数据=Plot_df%>%过滤器(Year==last(Year)),aes(label=State,x=Year+3,y=Capex,color=State),hjust=1)+指南(color=FALSE)+主题bw()+比例x连续(breaks=scales::pretty_breaks(10))我不太清楚是什么使得硬设置的边距比硬设置的比例限制更不实用。排名靠前的解决方案会修改绘图边距。我看到的解决方案和你的解决方案之间的最大区别是,在我的解决方案中,x轴停止在最后一个数据点,而在你的解决方案中,它会根据需要继续延伸,这样标签名称就会变为fiT在p内
    library(ggplot2)
    library(ggrepel)
    library(dplyr)
    
    temp.dat %>%
      mutate(label = if_else(Year == max(Year), as.character(State), NA_character_)) %>%
      ggplot(aes(x = Year, y = Capex, group = State, colour = State)) + 
      geom_line() + 
      geom_label_repel(aes(label = label),
                      nudge_x = 1,
                      na.rm = TRUE)
    
    Plot_df <- 
      temp.dat %>% mutate_if(is.factor, as.character) %>%  # Who has time for factors..
      mutate(Year = as.numeric(Year))
    
    ggplot() + 
    geom_line(data = Plot_df, aes(Year, Capex, color = State)) +
    geom_text(data = Plot_df %>% filter(Year == last(Year)), aes(label = State, 
                                                               x = Year + 0.5, 
                                                               y = Capex, 
                                                               color = State)) + 
              guides(color = FALSE) + theme_bw() + 
              scale_x_continuous(breaks = scales::pretty_breaks(10))
    
    library(tidyverse)
    
    # Make the "State" variable have longer levels
    temp.dat <- temp.dat %>% 
        mutate(State = paste0(State, '-a-long-string'))
    
    ggplot(temp.dat, aes(x = Year, y = Capex, color = State, group = State)) + 
        geom_line() +
        # Add labels at the end of the line
        geom_text(data = filter(temp.dat, Year == max(Year)),
                  aes(label = State),
                  hjust = 0, nudge_x = 0.1) +
        # Allow labels to bleed past the canvas boundaries
        coord_cartesian(clip = 'off') +
        # Remove legend & adjust margins to give more space for labels
        # Remember, the margins are t-r-b-l
        theme(legend.position = 'none',
              plot.margin = margin(0.1, 2.6, 0.1, 0.1, "cm")) 
    
    library(tidyverse)
    
    temp.dat$Year <- as.numeric(temp.dat$Year)
    temp.dat$State <- as.character(temp.dat$State)
    
    #example of loess for multiple models
    #https://stackoverflow.com/a/55127487/4927395
    
    models <- temp.dat %>%
      tidyr::nest(-State) %>%
      dplyr::mutate(
        # Perform loess calculation on each CpG group
        m = purrr::map(data, loess,
                       formula = Capex ~ Year, span = .75),
        # Retrieve the fitted values from each model
        fitted = purrr::map(m, `[[`, "fitted")
      )
    
    # Apply fitted y's as a new column
    results <- models %>%
      dplyr::select(-m) %>%
      tidyr::unnest()
    
    #find final x values for each group
    my_last_points <- results %>% group_by(State) %>% summarise(Year = max(Year, na.rm=TRUE))
    
    #Join dataframe of predictions to group labels
    my_last_points$pred_y <- left_join(my_last_points, results)
    
    # Plot with loess line for each group
    ggplot(results, aes(x = Year, y = Capex, group = State, colour = State)) +
      geom_line(alpha = I(7/10), color="grey", show.legend=F) +
      #stat_smooth(size=2, span=0.3, se=F, show_guide=F)
      geom_point(size=1) +
      geom_smooth(se=FALSE)+
      geom_text(data = my_last_points, aes(x=Year+0.5, y=pred_y$fitted, label = State))