是Excel的圖,不!是R的圖

原文章來源連結:https://brucezhaor。github。io/blog/2016/06/13/excel2ggplot/原文章作者:BruceZhaoR(RStats, interested in Statistics Models, Machine/Deep Learning, Data visualization, High Performance Computing 。。。)作者主頁:https://github。com/BruceZhaoR

excel作為一個強大的統計工具,自身包含著一部分資料視覺化的功能。R作為視覺化的大勢,自然也可以畫出這些圖,有一篇就透過

ggplot2包

進行了部分總結,甚是有趣,小編復刻學習了一番,現對程式碼做簡單註釋,以作分享。

關於excel,ppt,你還可以get

是Excel的圖,不!是R的圖

Excel改變了你的基因名,30% 相關Nature文章受影響,NCBI也受波及

是Excel的圖,不!是R的圖

推薦 3 個超讚的 EXCEL 外掛,讓你 5 分鐘從小白變大神

是Excel的圖,不!是R的圖

你和PPT高手之間,就只差一個iSlide

載入所需工具包

library(ggplot2) #作圖包library(dplyr) #資料轉換包library(tidyr) #資料轉換包library(splines) #資料差值包

ggplot2的基本概念

資料data/對映美學asethetics/幾何物件geometries/分面facets/統計statistics/座標系coordinates/主題themes

資料準備

set。seed(123) #設定隨機種子,保證做的圖和樣例一致樣df <- data。frame( var=LETTERS[1:10], #字母A-J id=1:10, #數字1-10 a=runif(10), #10個隨機數 b=runif(10), #10個隨機數 c=runif(10), #10個隨機數 stringsAsFactors = F #不轉換為因子)print(df) #顯示資料

得到所需資料樣式(寬矩陣轉長矩陣)

df1<- df%>%gather(“item”,value,-1:-2)%>% bind_cols(data。frame(item_id=rep(1:3,each=10)))# 使用tidyr和dplyr包的gather函式進行資料樣式轉換,%>%是dplyr包的傳遞函式print(df1)

ggplot畫圖

ggplot2是圖層式繪圖,一層層新增修改,圖層需要指定資料集,資料集中的內容(ase資料),geom_圖形,stat統計轉換,position圖形位置

柱形圖——geom_bar,注意position引數

ggplot(df1,aes(var,value))+ geom_bar(aes(fill=item),stat = “identity”,position=“dodge”,width=0。8)+ labs(title=“柱形圖”) # geom_bar=stat_count,stat=identy接受兩個變數作圖,position預設引數是stack,position=“dodge”時,不同變數橫向排列ggplot(df1,aes(var,value))+ geom_bar(aes(fill=(item)),stat = “identity”,position=“stack”,width=0。8)+ labs(title=“堆積柱狀圖”)ggplot(df1,aes(var,value))+ geom_bar(aes(fill=item),stat = “identity”,position=“fill”,width=0。8)+ labs(title=“百分比堆積柱狀圖”)ggplot(df1,aes(var,value))+ geom_bar(aes(fill=item),stat = “identity”,width=0。8)+ facet_grid(item~。)+ # 垂直方向分割 labs(title=“三維柱形圖”) # 平面展示,(facet_grid)將三維圖平面展示

是Excel的圖,不!是R的圖

折線圖——geom_line

變數以點展示,然後連點成線

ggplot(df1,aes(id,value,colour=item))+ # 點 geom_line()+ # 連線 scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ #將X座標軸改為十等分並標以字母 labs(title=“折線圖”)ggplot(df1,aes(id,value,colour=item))+ geom_line(position=“stack”)+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ labs(title=“堆積折線圖”)ggplot(df1,aes(id,value,colour=item))+ geom_line(position=“fill”)+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ labs(title=“百分比堆積折線圖”)ggplot(df1,aes(id,value,colour=item))+ geom_line()+ geom_point()+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ labs(title=“帶標記的折線圖”) #增加了散點圖geom_pointggplot(df1,aes(id,value,colour=item))+ geom_line(position=“stack”)+ geom_point(position=“stack”)+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ labs(title=“帶標記的堆積折線圖”)ggplot(df1,aes(id,value,colour=item))+ geom_line(aes(ymin=0),position=“fill”)+ geom_point(aes(ymin=0),position=“fill”)+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ labs(title=“帶標記的百分比堆積折線圖”)ggplot(df1,aes(id,value,colour=item))+ facet_grid(item~。)+ # 垂直方向分割 geom_line()+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ labs(title=“三維折線圖”) #用facet_grid平面展示,

是Excel的圖,不!是R的圖

餅圖

餅圖,將一般的柱圖進行直角座標軸到極座標軸的轉換(coord_polar())

ggplot(df,aes(x=factor(1),a,fill=factor(var)))+ geom_bar(stat=“identity”,position=“fill”)+ coord_polar(theta=“y”)+ # 按Y軸極座標轉換 labs(title=“餅圖”)因為是在條形圖中對y軸進行極座標轉換,因此x軸長短需要一致,統一設為一個值,此處是x=factor(1)

是Excel的圖,不!是R的圖

複合餅圖和複合條餅圖

有巢狀類時,可以衍生一個圖形展現子類內容,下圖是一個demo,僅作為圖案參考樣式,還有許多需要改進的地方

df_tmp<-data。frame(x=1,y=1) #準備畫布所需資料base <- ggplot(df_tmp,aes(x,y))+ geom_blank()+ theme_void()+ xlim(c(0,2))+ ylim(c(0,2)) # 準備背景畫布base + annotation_custom( grob = ggplotGrob( ggplot(df,aes(x = “”,a,fill=factor(var)))+ # 註釋 geom_bar(stat=“identity”,position=“fill”, show。legend = F)+ labs(x=NULL,y=NULL)+ coord_polar(theta=“y”)+ theme_classic()), xmin =0,xmax=1, ymin=0。5,ymax = 1。5)+ # 圖左 annotation_custom( grob = ggplotGrob( ggplot(df,aes(x = “”,b,fill=factor(var)))+ geom_bar(stat=“identity”, position=“fill”, show。legend = F)+ labs(x=NULL,y=NULL)+ coord_polar(theta=“y”)+ theme_classic()), xmin =1。1,xmax=1。9, ymin=0。6,ymax = 1。4)+ # 圖右 annotate(“segment”,x=0。5,xend=1。5, y=0。69,yend=0。77)+ # 下線條 annotate(“segment”,x=0。5,xend=1。5, y=1。35,yend=1。28) # 上線條+ labs(title=“複合餅圖”)# 複合條餅圖base <- ggplot(df_tmp,aes(x,y))+geom_blank()+theme_void()+ xlim(c(0,2))+ylim(c(0,2)) # 背景畫布base + annotation_custom( grob = ggplotGrob( ggplot(df,aes(x = “”,a,fill=factor(var)))+ geom_bar(stat=“identity”, position=“fill”, show。legend = F)+ labs(x=NULL,y=NULL)+ coord_polar(theta=“y”)+theme_void()), # 餅圖比條形圖多了一個極座標轉換 xmin =0,xmax=1, ymin=0。5,ymax = 1。5)+ # 左圖 annotation_custom( grob = ggplotGrob( ggplot(df,aes(x = “”,b,fill=factor(var)))+ geom_bar(stat=“identity”, position=“fill”, show。legend = F)+ labs(x=NULL,y=NULL)+theme_void()), xmin =1。2,xmax=1。8,ymin=0。8,ymax = 1。2)+ # 右圖 annotate(“segment”,x=0。5,xend=1。24,y=0。64,yend=0。84)+ # 下線段 annotate(“segment”,x=0。5,xend=1。24,y=1。38,yend=1。18)+ # 上線段 labs(title=“複合條餅圖”)

是Excel的圖,不!是R的圖

圓環圖

一個圓環代表一個變數,顏色表示其屬性

ggplot(df1,aes(x = item,value,fill=var))+ geom_bar(stat=“identity”,position=“fill”,width=0。8,colour=“black”)+ coord_polar(theta=“y”)

是Excel的圖,不!是R的圖

其他圓形圖

用coord_polar作出的demo圖

demo1<-ggplot(df,aes(x = factor(1),a,fill=factor(var)))+ geom_bar(stat=“identity”,position=“dodge”)demo1 #柱形圖demo1+coord_polar(theta=“y”) # 按y軸極座標轉換demo1+coord_polar(theta=“x”) # 按X軸極座標轉換,此時x還可以等於vardemo2<-ggplot(df1,aes(x = id,value,fill=item))+ geom_bar(stat=“identity”,position=“fill”,width=0。8)demo2 # 百分比柱形圖demo2+coord_polar(theta=“x”) # 按x軸極座標轉換

是Excel的圖,不!是R的圖

條形圖

條形圖就是橫過來的柱形圖,用函式

coord_filp()

處理逆時針旋轉90°

ggplot(df1,aes(var,value))+ geom_bar(aes(fill=item),stat = “identity”,position=“dodge”,width=0。8)+ labs(title=“條形圖”)+ coord_flip() # 和柱形圖程式碼的唯一區別coord_flip()ggplot(df1,aes(var,value))+ geom_bar(aes(fill=item),stat = “identity”,position=“stack”,width=0。8)+ labs(title=“堆積條形圖”)+ coord_flip()ggplot(df1,aes(var,value))+ geom_bar(aes(fill=item),stat = “identity”,position=“fill”,width=0。8)+ labs(title=“百分比堆積條形圖”,fill=“”)+ coord_flip()ggplot(df1,aes(var,value))+ geom_bar(aes(fill=item),stat = “identity”,position=“dodge”,width=0。8)+ labs(title=“三維百分比條形圖”,fill=“”)+ coord_flip()+ facet_grid(。~item) # 水平方向分割,用多個分面展示多維

是Excel的圖,不!是R的圖

面積圖——geom_area

面積圖就是將折線圖下面的區域標註顏色,表示面積。

ggplot(df1,aes(id,value))+ geom_area(aes(fill=item),position=position_dodge(width = 0), alpha=0。5)+ # 暗色不透明度 labs(title=“面積圖”,fill=“”)+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])ggplot(df1,aes(id,value))+ geom_area(aes(fill=item),alpha=0。5)+ labs(title=“堆積面積圖”)+ # 區別堆積折線圖是少了`position=stack` scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])ggplot(df1,aes(id,value))+ geom_area(aes(fill=item),position=“fill”,alpha=0。5)+ labs(title=“百分比堆積面積圖”,fill=“”)+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])ggplot(df1,aes(id,value))+ geom_area(aes(fill=item),position=“stack”,alpha=0。5)+ # 區別於三維折線圖添加了`position=stack`,便於分割後更好觀察面積分布 labs(title=“三維百分比堆積面積圖”,fill=“”)+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ facet_grid(item~。) # 按垂直水平分割

是Excel的圖,不!是R的圖

XY散點圖

需要注意的是確定X,Y軸以後,需要把對應的值賦到圖中

ggplot(df1,aes(var,value))+ geom_point(aes(colour=item))+ labs(title = “散點圖”)df1_a<-df1 %>% filter(item==“a”) %>% select(value) %>% unlist %>% spline(,1000) %>% as。data。frame()df1_b<-df1 %>% filter(item==“b”) %>% select(value) %>% unlist %>% spline(,1000) %>% as。data。frame()df1_c<-df1 %>% filter(item==“c”) %>% select(value) %>% unlist %>% spline(,1000) %>% as。data。frame()# 分開獲得需要a,b,c的資料value,並被等分為1000份,用spline曲線連線,轉換為資料框格式df1_sp<-bind_rows(df1_a,df1_b,df1_c) %>% mutate(item=rep(letters[1:3],each=1000)) # 新增1列itemggplot()+ geom_point(data=df1,aes(id,value,colour=item))+ geom_line(data=df1_sp,aes(x,y,colour=item))+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ labs(title = “帶平滑線和資料標記的散點圖”) # 點加線ggplot(df1,aes(id,value,colour=item))+ geom_point()+ geom_line()+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ labs(title = “帶直線和點資料標記的散點圖”)ggplot(df1,aes(id,value,colour=item))+ geom_line()+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ labs(title = “帶直線的散點圖”) # 就是折線圖

是Excel的圖,不!是R的圖

氣泡圖

氣泡圖即點的大小表示數值大小的點圖

ggplot(df1,aes(id,value,colour=item))+ geom_point(aes(size=value))+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])# `size=value`給點賦予數值大小屬性

是Excel的圖,不!是R的圖

股價圖

ggplot(df)+ geom_point(aes(Sys。Date()-1:10,c))+ geom_linerange(aes(Sys。Date()-1:10,ymin=a,ymax=b))+ labs(title=“已知盤高-盤低-收盤圖”)# `Sys。Date`返還任一日期時間,c是收盤量# `geom_linerange`是由a,b兩個物件的ymin和ymax定義的垂直區間線圖ggplot(df)+ geom_point(aes(Sys。Date()-1:10,c))+ geom_linerange(aes(Sys。Date()-1:10,ymin=a,ymax=b))+ geom_crossbar(aes(Sys。Date()-1:10,c,ymin=a,ymax=c),width=0。2)+ labs(title=“已知開盤-盤高-盤低-收盤圖”)# 在已知盤高-盤底-收盤圖的基礎上加上`geom_crossbar`,這裡是連繫a的最小和c的最大值,# geom_crossbar(): 空心柱,上中下三條線分別代表ymax,mean,yminggplot(data = filter(df1,item != “c”), aes(rep(Sys。Date()-1:10,3),value))+ facet_grid(item~。,scale=“free”)+ geom_point(data = filter(df1,item == “a”), aes(Sys。Date()-1:10,value))+ geom_linerange(data = filter(df1,item == “a”), aes(Sys。Date()-1:10,value, ymin=value-runif(10), ymax=value+runif(10)))+ geom_bar(data = filter(df1,item == “b”), aes(Sys。Date()-1:10,value*1000), stat=“identity”)+ labs(title=“成交量-盤高-盤低-收盤圖”)# 點和線距圖是物件a的資料有盤高盤低,條形圖是關於物件b的圖,成交量# facet_grid(item~。,scale=“free”),垂直分割,且不同形式的圖表可以被分割出來ggplot(data = filter(df1,item != “c”), aes(rep(Sys。Date()-1:10,3),value))+ facet_grid(item~。,scale=“free”)+ geom_point(data = filter(df1,item == “a”), aes(Sys。Date()-1:10,value))+ geom_linerange(data = filter(df1,item == “a”), aes(Sys。Date()-1:10,value, ymin=value-runif(10), ymax=value+runif(10)))+ geom_crossbar(data = filter(df1,item == “a”), aes(Sys。Date()-1:10,value, ymin=value-runif(10), ymax=value+runif(10)), width=0。2)+ geom_bar(data = filter(df1,item == “b”), aes(Sys。Date()-1:10,value*1000), stat=“identity”)+ labs(title=“已知成交量-開盤-盤高-盤低-收盤圖”)# 在上一個圖的基礎上加了個`geom_crossbar`,篩選物件b作為開盤

是Excel的圖,不!是R的圖

曲面圖——geom_contour

三維圖形,下圖是對密度的一個二維密度估計

ggplot(df1,aes(id,item_id))+ geom_contour(aes(z=value,colour=。。level。。), binwidth=0。001)+ scale_colour_gradientn(colours = terrain。colors(10))+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ scale_y_continuous(breaks = 1:3,labels = letters[1:3])+ labs(title=“曲面圖”)# binwidth設定組距,值越小畫得線越多,密度圖函式colour設定等高線顏色ggplot(df1,aes(id,item_id))+ geom_contour(aes(z=value,colour=。。level。。), binwidth=0。1)+ scale_colour_gradientn(colours = terrain。colors(10))+ scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ scale_y_continuous(breaks = 1:3,labels = letters[1:3])+ labs(title=“曲面圖(框架圖)”)# 用不同顏色等高線畫框架圖,和上圖比增加了組距。

是Excel的圖,不!是R的圖

雷達圖

ggplot(df1,aes(id,value,colour=item))+ geom_bar(stat=“identity”, position=“dodge”, # 普通柱形圖 fill=“transparent”,# 填充透明度 size=1)+ coord_polar()+ #極座標轉換 scale_x_continuous(breaks = 1:5,labels = LETTERS[1:5])+ facet_wrap(~item,nrow=2)+ # 水平分割,分割後的圖呈兩行排列 labs(title=“雷達圖”)# 雷達圖就是極座標轉換後的普通柱形圖,加了透明背景框,相當於其他透明圖ggplot(df1,aes(id,value,colour=item))+ geom_bar(stat=“identity”, position=“dodge”, fill=“transparent”, size=1, width=0。5)+ geom_point()+ coord_polar()+ scale_x_continuous(breaks = 1:5,labels = LETTERS[1:5])+ facet_wrap(~item,nrow=2)+ labs(title=“帶資料標記的雷達圖”)# 在geom_bar的基礎上加上了以三個物件a,b,c,的值為點的點圖geom_pointggplot(df1,aes(id,value))+ geom_bar(aes(fill=item),stat=“identity”, position=“dodge”)+ # 以item項的值對映柱形圖的表達值 scale_x_continuous(breaks = 1:10,labels = LETTERS[1:10])+ # x軸分成了十等份 coord_polar()+ facet_wrap(~item,nrow=2)+ labs(title=“填充雷達圖”)

是Excel的圖,不!是R的圖

直方圖

直方圖是先把資料劃分區間,按從小到大的順序排列,並以柱狀圖的形式表現

ggplot(df1,aes(value))+ geom_histogram(bins=5,colour=“white”) # 對映value表達值,邊界框是白色# 排列圖(資料從小到大排列)df_tmp2<-df %>% select(1:3) %>% # 前三列 arrange(a) %>% #按列a的值從小到大排序 mutate(per = a/sum(a)) %>% # 增加per列,值為對應總數的比例 arrange(desc(a)) %>% # 重新按列a的值從達到小排列 mutate(new_id = 1:10)%>% # 增加new_id列 mutate(per = cumsum(per)) # 將per列的值按new_id的順序逐個疊加ggplot(df_tmp2)+ geom_bar(aes(new_id,a,fill=var),stat=“identity”)+ # fill=var新增圖例並按照圖例上色 geom_line(aes(new_id,per))+ scale_x_continuous(breaks = 1:10, labels = df_tmp2$var)# 令X軸的值為df_tmp2的var

是Excel的圖,不!是R的圖

箱型圖

箱型圖是用分位數表述資料的離散和集中趨勢

ggplot(df1,aes(item,value,colour=item))+ geom_boxplot(aes(fill=item),alpha=0。2, outlier。colour = “red”, outlier。shape = 2, outlier。size = 5, coef=1。5)+ # 箱線圖的異常值設定,邊框為紅色,形狀為2指代的三角形,大小為5,引數coef指定了“須”的長度的極限值,預設值是1。5,表示兩條須的極限不會超過盒型各端加1。5倍四分位距的範圍,如果被置為0,條須的延長極限就會在資料集中元素的極限位置,圖中不會有任何離群點。geom_jitter(width = 0。1) # geom_jitter()是geom_point(position=“jitter”)的簡稱,帶狀圖,一維散點圖。

是Excel的圖,不!是R的圖

瀑布圖

瀑布圖可表現圖形漲跌趨勢,後一個柱子和前一個柱子有增長和下降的關係。

df_tmp3 <- df %>%select(1:3)%>%mutate(cum=cumsum(a) ,low=lag(cum,default = 0))# 新增一列cum,值為對應a值逐個疊加,新增加一列low,對應的是同一行的cum的上一個值,開始值是0。ggplot(df_tmp3,aes(id,cum))+# geom_step(colour=“grey50”)+ 是梯線 geom_crossbar(aes(ymin=low,ymax=cum), size=0, fill=“skyblue”, colour=“grey50”, # 邊框顏色 width=1)+ scale_x_continuous(breaks = 1:10, labels = LETTERS[1:10]) #geom_crossbar(): 空心柱,上下兩條線分別代表ymax、ymin

是Excel的圖,不!是R的圖

漏斗圖

漏斗圖的資料分佈在圖形中間,用coord_flip()轉換方向,可以看到不同組的最大,最小值的差異

df_tmp4<-df %>% select(1:3) %>% arrange(a) %>% mutate(new_id=1:10, ymin = (1-a)/2, ymax = a+(1-a)/2, mid = 0。5) # 新增四列,new_id,ymin,ymax和min列ggplot(df_tmp4,aes(new_id,mid))+ # geom_step(colour=“grey50”)+ geom_crossbar(aes(ymin=ymin,ymax=ymax), size=0, fill=“skyblue”, colour=“grey50”, width=1)+ scale_x_continuous(breaks = 1:10, labels = df_tmp4$var)+ coord_flip() # 整個圖形逆時針轉90度# geom_crossbar()空心柱ggplot(df_tmp4,aes(new_id,mid))+ geom_linerange(aes(ymin=ymin,ymax=ymax, colour=factor(new_id)), size=15, alpha=0。5,show。legend = F)+ scale_x_continuous(breaks = 1:10, labels = df_tmp4$var)+ coord_flip()

是Excel的圖,不!是R的圖