手把手教你使用ggplot2繪製折線圖
作者:劉順祥 R語言中文社區作者
公眾號:數據分析1480(微信ID:lsxxx2011)配套教程:手把手教你做文本挖掘 https://edu.hellobi.com/course/181
折線圖同樣是應用非常廣泛的統計圖之一,通過折線圖可以反映某種現象的趨勢。通常折線圖的橫坐標是為時間變數,縱坐標則是一般性的數值型變數,當然,折線圖也允許橫坐標為離散型數值和數值型數值。下面來解釋一下關於折線圖的繪製。
一、繪製單條折線圖
有關時間序列的折線圖
library(ggplot2)library(lubridate) #處理日期時間相關的R包,非常有用,強烈推薦Year <- year(seq(from = as.Date(2006-01-01), to = as.Date(2015-01-01), by = year))Weight <- c(23,35,43,57,60,62,63,66,61,62)df <- data.frame(Year = Year, Weight = Weight)ggplot(data = df, mapping = aes(x = factor(Year), y = Weight, group = 1)) + geom_line() + xlab(Year)
有關離散變數的折線圖
type <- c(A,B,C,D,E)quanlity <- c(1,1.1,2.1,1.5,1.7)df <- data.frame(type = type, quanlity = quanlity)ggplot(data = df, mapping = aes(x = type, y = quanlity, group = 1)) + geom_line()
有關連續變數的折線圖
set.seed(1234)times <- 1:15value <- runif(15,min = 5,max = 15)df <- data.frame(times = times, value = value)ggplot(data = df, mapping = aes(x = times, y = value)) + geom_line()
善於發現的你,可能會注意到上面三段代碼有一個重要的不同之處,那就是第一段和第二段代碼中含有『group = 1』的設置。這樣做是因為橫坐標的屬性設置為了因子,即將連續型的年份和離散型的字元轉換為因子,如果不添加『group = 1』這樣的條件,繪圖將會報錯。故務必需要記住這裡的易犯錯誤的點!
往折線圖中添加標記(點)
當數據點密度比較小或採集分布(間隔)不均勻時,為折線圖做上標記將會產生非常好的效果。處理的方法非常簡單,只需在折線圖的基礎上再加上geom_point()函數即可。
set.seed(1234)year <- c(1990,1995,2000,2003,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015)value <- runif(15, min = 10, max = 50)df <- data.frame(year = year, value = vlaue)ggplot(data = df, mapping = aes(x = year, y = value)) + geom_line() + geom_point()
從圖中就可以非常明顯的看出,剛開始採集的點分布非常散,而後面採集的點就比較密集,這也有助於對圖的理解和應用。
二、繪製多條折線圖
上面繪製的都是單條這折線圖,對於兩個或兩個以上的折線圖該如何繪製呢?也很簡單,只需將其他離散變數賦給諸如colour(線條顏色)和linetype(線條形狀)的屬性即可,具體參見下文例子。
基於顏色的多條折線圖
set.seed(1234)year <- rep(1990:2015, times = 2)type <- rep(c(A,B),each = 26)value <- c(runif(26),runif(26, min = 1,max = 1.5))df <- data.frame(year = year, type = type, value = value)ggplot(data = df, mapping = aes(x = year, y = value, colour = type)) + geom_line()
基於形狀的多條折線圖
ggplot(data = df, mapping = aes(x = year, y = value, linetype = type)) + geom_line()
同樣需要注意的是,在繪製多條折線圖時,如果橫坐標為因子,必須還得加上『group=分組變數』的參數,否則報錯或繪製出錯誤的圖形。
以上繪製的折線圖,均採用默認格式,不論是顏色、形狀、大小還是透明度,均沒有給出自定義的格式。其實ggplot2包也是允許用戶根據自己的想法設置這些屬性的。
#自定義線條或點的顏色--scale_color_manual()
#自定義線條類型--scale_linetype_manual()
#自定義點的形狀--scale_shape__manual()
#自定義點的大小或線條的寬度--scale_size__manual()
#自定義透明度--scale_alpha__manual()
綜合的例子:
ggplot(data = df, mapping = aes(x = year, y = value, linetype = type, colour = type, shape = type, fill = type))+ geom_line() + geom_point() #繪製線圖和點圖+ scale_linetype_manual(values = c(1,2)) #自定義線條類型+ scale_color_manual(values = c(steelblue,darkred)) #自定義顏色+ scale_shape_manual(values = c(21,23)) #自定義點形狀+ scale_fill_manual(values = c(red,black)) #自定義點的填充色
雖然這幅圖畫的優點誇張,目的是想說明可以通過自定義的方式,想怎麼改就可以怎麼改。前提是aes()屬性的內容與自定義的內容對應上。
三、繪製堆積面積圖
繪製堆疊的面積圖只需要geom_area()函數再加上一個離散變數映射到fill就可以輕鬆實現,先忙咱小試牛刀一下。
set.seed(1234)year <- rep(1990:2015, times = 2)type <- rep(c(A,B),each = 26)value <- c(runif(26),runif(26, min = 1,max = 1.5))df <- data.frame(year = year, type = type, value = value)ggplot(data = df, mapping = aes(x = year, y = value, fill = type)) + geom_area()
一幅堆疊的面積圖就輕鬆繪製成功,但我們發現,堆疊的順序與圖例的順序恰好相反,不用急,只需要加一句命令即可:
ggplot(data = df, mapping = aes(x = year, y = value, fill = type)) + geom_area() + guides(fill = guide_legend(reverse = TRUE))
如果需要為每一塊面積圖的頂部加上一條直線,可以通過如下兩種方式:
ggplot(data = df, mapping = aes(x = year, y = value, fill = type)) + geom_area(colour = black, size =1, alpha = .7) + guides(fill = guide_legend(reverse = TRUE))
其中,colour設置面積圖邊框的顏色;size設置邊框線的粗細;alpha設置面積圖和邊框線的透明度。
ggplot(data = df, mapping = aes(x = year, y = value, fill = type)) + geom_area(alpha = 0.6) + geom_line(colour = black, size = 1, position = stack, alpha = 0.6) + guides(fill = guide_legend(reverse = TRUE))
該方法是通過添加堆疊線條(必須設置geom_line()中position參數為『stack』,否則只是添加了兩條線,無法與面積圖的頂部重合)。這兩幅圖的區別在於第二種方式沒有繪製面積圖左右邊框和底邊框。在實際應用中,建議不要在面積圖中繪製邊框線,因為邊框的存在可能產生誤導。
四、繪製百分比堆積面積圖
在上一期中,我們繪製了堆疊條形圖和百分比堆疊面積圖,具體可參見:
手把手教你使用ggplot2繪製條形圖
在面積圖中,也可以方便快捷的繪製出百分比堆積面積圖,具體操作如下:
set.seed(1234)year <- rep(1990:2015, times = 4)type <- rep(c(A,B,C,D),each = 26)value <- c(runif(26),runif(26, min = 1,max = 1.5), runif(26, min = 1.5,max = 2), runif(26, min = 2,max = 2.5))df <- data.frame(year = year, type = type, value = value)ggplot(data = df, mapping = aes(x = year, y = value, fill = type)) + geom_area(position = fill, alpha = 0.6) + guides(fill = guide_legend(reverse = TRUE))
但通過這種方式(設置面積圖的positon=fill)存在一點點小缺陷,即無法繪製出百分比堆積面積圖頂部的線條,該如何實現呢?這裡只需要對原始數據集做一步匯總工作,讓後按部就班的繪製面積圖即可。
library(dplyr)df_by_type <- group_by(.data = df, year)df_summarize <- mutate(.data = df_by_type, value2 = value/sum(value))
有關dplyr包的用法可參考:
強大的dplyr包實現數據預處理
ggplot(data = df_summarize, mapping = aes(x = year, y = value2, fill = type)) + geom_area(alpha = 0.6) + geom_line(colour = black, size = 1, position = stack, alpha = 0.6) + guides(fill = guide_legend(reverse = TRUE))
哈哈,大功告成,就這麼簡單。
參考資料:
R語言_ggplot2:數據分析與圖形藝術
R數據可視化手冊
推薦閱讀: