重要的是圖表思維,而不是工具

很久沒有作圖了,主要是一時找不到應該練手的案例。

然後昨天逛網易數獨欄目的數據新聞,看到一幅還不錯的案例,對於我來說值得一試,然後就手癢給照葫蘆畫瓢弄出來了。(主要是其中涉及到的細節處理很麻煩)

當然過程是花了些時間的,主要是需要慢慢打磨其中的細節,需要利用很多技術來處理圖形版面的交接位置。

令我感觸最深的是,想要用ggplot2隨心所欲的畫圖,ggplot2掌握的再熟練,也只是勉強過的了技術關,而圖表背後的思維和結構更考驗人,更具有挑戰性。

好在我學習R語言之前,就已經利用Excel臨摹了大量的高難度信息圖,這一點可視化素養的積累,再結合對ggplot2勤加練習獲得的圖感,分分鐘做出一副自己喜歡的作品,已經不在話下了。

以下是該案例涉及到的擴展包:

library("plyr")nlibrary("tidyr")nlibrary("ggthemes")nlibrary("sca")nlibrary("dplyr")nlibrary("showtext")nlibrary("Cairo")nlibrary("grid")nfont.add("myfont","msyh.ttc")nfont.add("myfzhzh","方正正粗黑簡體.TTF")n

我把該案例切割成了兩部分來做:

(實際上如果放在一個圖裡做也是可以實現的,無非是多寫一些代碼罷了,但是涉及到顏色標度重複的問題,一時半會兒找不到解決方案,為了更加逼真的還原案例效果,我決定分開來做)。

  • 原圖中的下半部分(條形圖)(以下簡稱模塊1)

  • 上半部分(堆積柱形圖+連接帶)(以下簡稱模塊2)

導入數據源:

tea_data<-read.csv("D:/R/File/tea_data.csv",stringsAsFactors=FALSE,check.names=FALSE)ntea_data$State[12]<-"印度尼n西亞"n

tea_bump是上半部分(模塊2)中堆積柱形圖的數據源,我沒有使用傳統的堆積柱形圖去做,而是使用了矩形幾何對象,所以數據源中需要指定X軸起始點,Y軸起始點。

tea_bump<-na.omit(tea_data[,c("State","Yield","Ratio")])ntea_bump<-arrange(tea_bump,-Yield)nother_Ratio<-1-sum(tea_bump$Ratio)nother_Yield<-sum(tea_bump$Yield)/sum(tea_bump$Ratio)-sum(tea_bump$Yield)ndata1<-data.frame(State="其他",Yield=other_Yield,Ratio=other_Ratio)ntea_bump<-rbind(tea_bump,data1)n

tea_bump$end<-cumsum(tea_bump$Yield)ntea_bump$start<-c(0,tea_bump$end[1:nrow(tea_bump)-1])ntea_bump$id<-1:nrow(tea_bump)ntea_bump<-merge(tea_bump,tea_data[,c("State","Consum")],by="State",all.x=TRUE)ntea_bump<-arrange(tea_bump,-Yield)n

以下是下半部分柱形圖的數據源,同樣我也沒有使用普通的柱形圖幾何對象去做,而是使用了範圍線圖(geom_linerange),這樣可以節省調整步驟,但須額外設置線的起始點。

tea_bar<-tea_data[,c("State","Consum")]ntea_bar$id<-1:nrow(tea_bar)ncolorpal<-ifelse(tea_data$State %in% tea_bump$State,"#B4BFB4","#E5E5E5")n

library("ggplot2")nlibrary("showtext")nlibrary("Cairo")n

底部柱形圖對象:

(因為需要拼圖,所以圖形對象要臨時存儲)

p1<-ggplot()+ngeom_hline(aes(yintercept=1:7*400),colour="grey",linetype=2)+ngeom_linerange(data=tea_bar,aes(x=id,ymin=max(tea_bar$Consum)-Consum,ymax=max(tea_bar$Consum),colour=Consum),size=24)+ngeom_point(data=tea_bar,aes(x=id,y=max(tea_bar$Consum)+165,fill=colorpal),shape=22,colour="white",size=37.5)+ngeom_text(data=tea_bar,aes(x=id,y=max(tea_bar$Consum)+165,label=State),size=6,family="myfont",vjust=.5)+ngeom_text(data=tea_bar,aes(x=id,y=max(tea_bar$Consum)-Consum+80,label=Consum),size=6,family="myfont",vjust=0.5,colour="white")+nannotate("text",x =5,y=80,label="各國每年人均茶葉消費量(克)",family="myfzhzh",size=11,colour="#515551")+nylim(0,4800)+ngeom_linerange()+nguides(fill=FALSE,colour=FALSE)+nscale_colour_gradient(low="#A1C997",high="#47734A")+nscale_fill_manual(values=c("#B4BFB4","#E5E5E5"))+ntheme_map(base_family="myfont") %+replace% ntheme(n plot.margin=unit(c(0,1.5,0,1.5), "cm"),n )n

以下數據是構造模塊2輔助數據:

(上半部分堆積柱形圖的下側連接帶數據)的輔助數據,我打算使用多邊形幾何對象了來模擬那些參差交錯的連接帶。這就意味著我要找到每一條帶子,即四邊形的四個拐點坐標,並按順序排列。)

如果你看的不是很懂,實屬正常,這種笨拙的想法,我也不知道是從哪裡學來的。

tea_chord<-data.frame(State=tea_data$State)ntea_chord$id<-1:nrow(tea_chord)ntea_chord$mean<-sum(tea_bump$Yield)/nrow(tea_chord)ntea_chord$xend<-cumsum(tea_chord$mean)ntea_chord$xstart<-c(0,tea_chord$xend[1:nrow(tea_chord)-1])n

tea_chord_data<-tea_chord[tea_chord$State %in% tea_bump$State,c("State","xstart","xend")]ntea_chord_data<-merge(tea_chord_data,tea_bump[tea_bump$State!="其他",c("State","start","end")],by="State")ntea_chord_data<-tea_chord_data[,c("State","start","end","xend","xstart")]n

tea_chord_newdata<-data.frame(t(tea_chord_data),stringsAsFactors=FALSE)nnames(tea_chord_newdata)<-tea_chord_data$State;tea_chord_newdata<-tea_chord_newdata[-1,]nrownames(tea_chord_newdata)<-NULLntea_chord_newdata$order<-1:nrow(tea_chord_newdata)n

tea_chord_newdata_final<-gather(tea_chord_newdata,State,long,-order)ntea_chord_newdata_final$lat<-5ntea_chord_newdata_final$lat[tea_chord_newdata_final$order==3|tea_chord_newdata_final$order==4]<--5ntea_chord_newdata_final$long<-as.numeric(tea_chord_newdata_final$long)n

所以說上半部分的堆積柱形圖(附加連接帶)其實是用了兩份不同的數據源模擬出來的。

以下是模塊2的可視化代碼部分:

(也需臨時存儲)

p2<-ggplot()+ngeom_rect(data=tea_bump,aes(xmin=start,xmax=end,ymin=5,ymax=15,fill=Consum),colour="white")+ngeom_polygon(data=tea_chord_newdata_final,aes(x=long,y=lat,group=State),fill="#B1C6B0",colour=NA,size=.25,alpha=.8)+nlabs(title="全國茶葉年產量406.7(萬噸)")+ngeom_text(data=tea_bump[tea_bump$State!="其他",],aes(x=start+5.5,y=13,label=round(Yield,1)),size=5.5,family="myfont",vjust=0.5,colour="white")+ngeom_text(data=tea_bump[tea_bump$State!="其他",],aes(x=start+6,y=7,label=percent(Ratio,d=1,sep="")),size=5.5,family="myfont",vjust=0.5,colour="white")+nscale_fill_gradient(low="#A1C997",high="#47734A",na.value="#E5E5E5",guide=FALSE)+ntheme_map() %+replace% ntheme(n plot.title=element_text(size=35,family="myfzhzh",hjust=.5)n )n

有了上下兩部分的對象,剩下的就好辦了,無非就是拼接起來嘛,但是拼接的過程相當考驗人的耐性和毅力,不適合浮躁型的人來做。

CairoPNG(file="E:/bump_bar.png",width_=1550,height=1200)nshowtext.begin()nvie<-viewport(width_=1,height=0.215,x=0.5,y=0.8)np1;print(p2,vp=vie)ngrid.text(label="全球茶葉消費排行榜n喝茶最多的不是中國人",x=.80,y=.20,gp=gpar(col="black",fontsize=45,fontfamily="myfzhzh",draw=TRUE,just="right"))ngrid.text(label="數據來源:Euromonitor、國際茶葉委員會(ITC)",x=.80,y=.13,gp=gpar(col="black",fontsize=20,fontfamily="myfzhzh",draw=TRUE,just="right"))nshowtext.end()ndev.off()n

為了與原圖對比,我使用PS修飾了一些細節:

做完回頭想想,做這個圖我也是真夠無聊的,大概要耗費半天的時間去調試,不過調試的過程能學到的東西倒是很有趣,最近看了不起的匠人,感覺多少有些被感染到了,這算不算是強迫症~_~

聯繫方式:

微信:ljty1991

博客主頁:raindus home

個人公眾號:數據小魔方(datamofang)

團隊公眾號:EasyCharts

qq交流群:[魔方學院]298236508


推薦閱讀:

利用R語言製作出14種漂亮的交互數據可視化
另一版的「知乎答案的時間段分布」
Gartner 2016年商業智能與分析平台魔力象限
數據可視化基礎——數據模型
R語言可視化學習筆記之ggpubr包

TAG:R编程语言 | 数据可视化 | 信息图Infographic |