2017-09-13 50 views
2

我很好奇,如果有一種方法來覆蓋ggplot2上的線圖上的標籤,以避免通過線。我已經使用了vjust,它在大多數情況下都能正常工作,但是當兩個日期之間有很大的增加或減少時,線會通過標籤使其難以閱讀。我會把我目前使用的情節和代碼放在一起。在這種情況下,我想要移動920; 1,467;和1,480下線。我正在通過Reporters軟件包輸出劇情,所以我可以手動移動它,我只是想知道是否有辦法避免這種情況。線圖上的程序標籤,以避免線ggplot2

簡介: enter image description here

代碼:

library("ggplot2") 
library("scales") 

line_data <- c(276, 475, 753, 840, 931, 962, 801, 920, 1467, 1840, 1737, 1638, 1789, 1733, 1480, 1464, 1538) 
year_data <- c(2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 
       2017) 

line_data_total <- as.data.frame(cbind(line_data, year_data)) 

limit_func <- function(x) { 
    if (nchar(max(x)) == 2){ 
    round(max(x +5), digits = -1) 
    } else if (nchar(max(x)) == 3){ 
    round(max(x +50), digits = -2) 
    } else if (nchar(max(x)) == 4){ 
    round(max(x +500), digits = -3) 
    } 
} 

ggplot(data = line_data_total, aes(x = year_data, y = line_data, group = 1)) + 
    geom_line(color = "red", size = 1.2)+ 
    geom_point(color = "red", fill = "red", shape = 23, size = 1.75) + 
    geom_text(aes(label = paste0(format(round(as.numeric(line_data), 1), nsmall = 0, big.mark = ","))), 
      size = 3, fontface = "bold", vjust = -2) + 
    labs(x = '', y = '') + 
    expand_limits(y = c(0, limit_func(line_data_total$line_data))) + 
    scale_x_continuous(breaks = seq(min(line_data_total$year_data), max(line_data_total$year_data), 1)) + 
    scale_y_continuous(labels = comma) + 
    theme(panel.grid.major.x = element_blank() , 
     panel.grid.major.y = element_line(size=.1, color="light gray"), 
     panel.background = element_rect(fill = "transparent"), 
     plot.background = element_rect(fill = "transparent"), 
     axis.text.x = element_text(face = "bold", size = 10), 
     axis.text.y = element_text(face = "bold", size = 10), 
     axis.ticks.y = element_blank()) 
+0

如果其中一個答案解決了您的問題,您應該用複選標記將其標記爲最佳答案。 – Mako212

回答

3

如何使用ggplot2擴展ggrepel

require(ggrepel)

替換爲您geom_text()

geom_text_repel(aes(label = paste0(format(round(as.numeric(line_data), 1), nsmall = 0, big.mark = ","))), 
      size = 3, fontface = "bold", nudge_y=150) 

nudge_y是什麼推動了標籤斷了線,你可以使用的nudge_xnudge_y的結合進行更多的控制。而看到包小插曲:https://github.com/slowkow/ggrepel/blob/master/vignettes/ggrepel.md

enter image description here

1

不與設置爲擺弄geom_text_repel,我想嘗試這是概括爲這樣的時間序列的解決方案。我寫了一個函數,它查看兩個x鄰點,並計算它們之間的斜率,以及中點是低一點還是高點,還是在它的x-方向上的鄰居之間。

  • 如果點是ý -between其X -neighbors,標籤將被斜移出去,遠離連接它們的線的斜率。
  • 如果要點是y - 它的下一個x-鄰居,標籤居中,但向下移動。
  • 如果要點是y-在其上面x-鄰居,標籤居中,但向上移動。

library(dplyr) 

adjust_away_from_line <- function(df, x, y, vextend = 0.5) { 
    if(!is.data.frame(df)) {return(df)} 

    x <- enquo(x) 
    y <- enquo(y) 

    if(!(quo_name(x) %in% names(df))) { 
    warning(paste0("Column '", quo_name(x), "' not found in data.")) 
    return(df) 
    } 

    if(!(quo_name(y) %in% names(df))) { 
    warning(paste0("Column '", quo_name(y), "' not found in data.")) 
    return(df) 
    } 


    df %>% arrange(!!x) %>% 
    mutate(nb.slope = case_when(
     is.na(lead(!!y)) ~ ( (!!y) - lag(!!y))/( (!!x) - lag(!!x)), 
     is.na(lag(!!y)) ~ (lead(!!y) - (!!y))/(lead(!!x) - (!!x)), 
     TRUE    ~ (lead(!!y) - lag(!!y))/(lead(!!x) - lag(!!x)) 
    ), 
    nb.pos = case_when(
     is.na(lead(!!y))        ~ -sign(nb.slope), 
     is.na(lag(!!y))        ~ -sign(nb.slope), 
     (lead(!!y) >= (!!y)) & (lag(!!y) >= (!!y)) ~ 1.1, 
     !(lead(!!y) >= (!!y)) & !(lag(!!y) >= (!!y)) ~ -1.1, 
     TRUE           ~ -1 
    ), 
    hjust = case_when(
     nb.pos > 1 ~ 0.5, 
     nb.pos < -1 ~ 0.5, 
     nb.slope > 0 ~ 1, 
     nb.slope < 0 ~ 0, 
     TRUE   ~ 0.5 
    ), 
    vjust = scales::rescale(round(nb.pos), to = c(0-vextend, 1+vextend))) %>% 
    select(-nb.slope, -nb.pos) 


} 

由於需要一個數據幀作爲第一個參數,你可以在管道使用此功能,賦予它你X變量的裸名稱和ÿ爲了變量:

data.frame(line_data = c(276, 475, 753, 840, 931, 962, 801, 920, 1467, 
         1840, 1737, 1638, 1789, 1733, 1480, 1464, 1538), 
      year_data = c(2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 
         2011, 2012, 2013, 2014, 2015, 2016, 2017) 
      ) %>% 
    adjust_away_from_line(year_data, line_data) %>% 
    ggplot(aes(year_data, line_data)) + 
    geom_line() + 
    geom_point() + 
    geom_text(aes(label = line_data, hjust = hjust, vjust = vjust)) 

enter image description here

我如果想要將標籤進一步上下移動,可以使用adjust_away_from_line(..., vextend = ##)參數進行設置。默認值是0。5,但在不同的應用程序中可能需要0.75或1。