一場用R語言打造的商務圖表視覺盛宴~
之前已經模仿了挺多網路上流行的高難度商務圖表案例,自覺功力有所小成,就想著趁熱打鐵,把那些剩餘的還沒有被挖掘出來了的商務圖表案例全部補全。
本篇給出不等寬柱形圖案例以及MEKKO(也稱市場細分矩陣)圖案例全部四張圖的R語言代碼,作為ggplot商務圖表進階道路上的一個小小一步。
因為需要構造自定義標度,這裡需要scale包的支持
library(ggplot2)nlibrary(scales)n
構造不等寬柱形圖的案例數據(本案例模仿對象是劉萬祥老師的《Excel圖表之道》,感謝老師在業界的無私奉獻精神,給我等後輩留下了如此豐富的圖表案例資源,這裡再次向老師致敬!)。
mydata<-data.frame(Name=paste0("項目",1:5),Scale=c(35,30,20,10,5),ARPU=c(56,37,63,57,59))n
因為本篇 所構造的不等寬柱形圖、MEKKO矩陣圖等都是建立在四邊形(或者呈為矩陣)的基礎圖形之上的,即物理的二維空間中,四個點坐標可以定位出一個四邊形,利用R語言的向量化操作,就可以同時操縱n組長度為4的向量,來批量生成矩形塊,這裡的核心技巧只是在數據源中準確的生成每一組向量(也即每一個矩形塊的水平軸起點、終點、垂直軸的起點、終點)。
在ggplot系統中,生成矩形的圖層函數是geom_rect()函數,內置四個參數:
xminxmaxyminymaxn
不等寬柱形圖:
#構造矩形X軸的起點(最小點)nmydata$xmin<-0nfor (i in 2:5){nmydata$xmin[i]<-sum(mydata$Scale[1:i-1])n}n#構造矩形X軸的終點(最大點)nfor (i in 1:5){nmydata$xmax[i]<-sum(mydata$Scale[1:i])n}n#構造數據標籤的橫坐標:nfor (i in 1:5){nmydata$label[i]<-sum(mydata$Scale[1:i])-mydata$Scale[i]/2n}n
定義字體:
windowsFonts(myFont = windowsFont("微軟雅黑"))
運行ggplot函數:
-----------------------------------------------------------------------------------------------------------
ggplot(mydata)+ngeom_rect(aes(xmin=xmin,xmax=xmax,ymin=0,ymax=ARPU,fill=Name))+nscale_fill_manual(values=c("#54576B","#BD1F12","#E8BA11","#62962A","#9B56AF"))+ngeom_text(aes(x=label,y=ARPU-3,label=ARPU),size=6,col="white",family="myFont")+ngeom_text(aes(x=label,y=-2.5,label=Scale),size=4,col="black",family="myFont")+ngeom_text(aes(x=label,y=-5.5,label=Name),size=4,col="black",family="myFont")+nannotate("text",x=16,y=70,label="不等寬柱形圖",size=8,family="myFont")+ nannotate("text",x=14,y=64,label="這是一幅很用心的圖表",size=4,family="myFont")+ nannotate("text",x=11,y=-9.8,label="Source:EasyCharts",size=4,family="myFont")+ nylim(-10,80)+ntheme_nothing()n
不等寬條形圖:
該案例來自於本人小號數據小魔方,也曾在本平台轉發過:
圖表案例——全球創新國家1000強研發投入變動趨勢
設置目錄並導入數據
setwd("F:/微信公眾號/公眾號——數據小魔方/2017年3月/20170330")nmydata<-read.csv("barchart.csv",stringsAsFactors = FALSE) nnames(mydata)[1:5]<-c("State","RD","Betw","Cumcost","class")n
#構造矩形X軸的起點(最小點)nmydata$xmin<-0nfor (i in 2:nrow(mydata)){nmydata$xmin[i]<-sum(mydata$RD[1:i-1])n}n#構造矩形X軸的終點(最大點)nfor (i in 1:nrow(mydata)){nmydata$xmax[i]<-sum(mydata$RD[1:i])n}n#構造數據標籤的橫坐標:nfor (i in 1:nrow(mydata)){nmydata$label[i]<-sum(mydata$RD[1:i])-mydata$RD[i]/2n}nmydata$class<-factor(mydata$class,levels=c("亞洲","歐洲","北美","其他地區"))n
運行作圖函數:
ggplot(mydata)+ngeom_rect(aes(xmin=xmin,xmax=xmax,ymin=0,ymax=Betw,fill=class),col="white")+ncoord_flip()+nscale_x_reverse()+nscale_y_continuous(limits=c(-.45,.7),breaks=seq(-.4,.7,.1),labels=percent_format(),position = "top")+nscale_fill_manual(values=c("#802428","#AB6661","#D1A6A1","#A89B94"))+ngeom_text(aes(x=label,y=Betw/2,label=Betw),size=3,col="white",family="myFont")+ngeom_text(aes(x=label,y=ifelse(Betw>0,Betw+.03,Betw-.033),label=mydata$RD),size=4,col="black",family="myFont")+ngeom_text(aes(x=label,y=ifelse(Betw>0,-.07,.07),label=State),size=4,col="black",family="myFont")+nlabs(title="不等寬柱形圖",subtitle="這是一幅很用心的圖表",caption="Source:EasyCharts",x="",y="")+ntheme(ntext=element_text(family="myFont"),nplot.title=element_text(size=18),nplot.subtitle=element_text(size=14),nplot.caption=element_text(size=10,hjust=0),nplot.background=element_blank(),npanel.background=element_blank(),npanel.grid=element_blank(),naxis.text.y=element_blank(),naxis.ticks.y=element_blank(),nlegend.position=c(0.9,0.2),naxis.line.x=element_line()n)n
--------------------------------------------------------------------------------------------------------
MEKKO(也稱市場細分矩陣)
該圖表同樣來源於劉老師的圖表寶典——《Excel圖表之道》
Mekko<-read.csv("Mekko.csv",stringsAsFactors = FALSE) nMekko$Class<-factor(Mekko$Class,order=T)n#構造矩形(Obama)X軸的起點(最小點)nMekko$xmin<-0nfor (i in 2:nrow(Mekko)){nMekko$xmin[i]<-sum(Mekko$percent[1:i-1])n}n#構造矩形(Obama)X軸的終點(最大點)nfor (i in 1:nrow(Mekko)){nMekko$xmax[i]<-sum(Mekko$percent[1:i])n}n#構造數據標籤的橫坐標:nfor (i in 1:nrow(Mekko)){nMekko$label[i]<-sum(Mekko$percent[1:i])-Mekko$percent[i]/2n}n
這裡我不想重複映射兩次geom_rect()圖層函數,所以從新整理了數據源,一定要記得ggplot的作圖體系中使用因子變數進行分類作圖的思想,這裡完全可以用一個類別標量賦給fill屬性,避免代碼冗餘。
mynewdata1<-Mekko[,c(1,6,7)];mynewdata1$ymin<-0;mynewdata1$ymax<-Mekko$Obama;mynewdata1$Type<-"Obama"nmynewdata2<-Mekko[,c(1,6,7)];mynewdata2$ymin<-Mekko$Obama+Mekko$m;mynewdata2$ymax<-Mekko$Obama+Mekko$m+Mekko$McCain;mynewdata2$Type<-"McCain"nmynewdata<-rbind(mynewdata1,mynewdata2)nmynewdata$Type<-factor(mynewdata$Type,levels=c("Obama","McCain"),order=T)n
運行作圖函數:
ggplot(mynewdata)+ngeom_rect(aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax,fill=Type),col="white")+nscale_fill_manual(values=c("#004C7F","#B70023"))+nscale_x_continuous(breaks=Mekko$label,labels=Mekko$Class)+ngeom_text(data=Mekko,aes(x=label,y=.25,label=percent(Obama)),size=3.5,col="white",family="myFont")+ngeom_text(data=Mekko,aes(x=label,y=.8,label=percent(McCain)),size=3.5,col="white",family="myFont")+nlabs(title="MEKKO-市場細分矩陣圖",subtitle="這是一幅用心良苦的圖表",caption="Source:EasyCharts",x="",y="")+ntheme(nplot.margin=unit(c(2,0,0.5,0),"lines"),npanel.spacing=unit(c(0,0,0,0),"lines"),naxis.text.x=element_text(angle=90,size=10),npanel.background=element_blank(),naxis.ticks=element_blank(),naxis.text.y=element_blank(),nlegend.position=c(.78,1),nlegend.direction="horizontal",ntext=element_text(family="myFont"),nplot.title=element_text(size=18),nplot.subtitle=element_text(size=14),nplot.caption=element_text(size=10,hjust=0),nlegend.title=element_blank()n)n
以下同樣的數據源,只是通過坐標旋轉,換成了條形圖的風格。
ggplot(mynewdata)+ngeom_rect(aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax,fill=Type),col="white")+ncoord_flip()+nscale_fill_manual(values=c("#004C7F","#B70023"))+nscale_x_continuous(breaks=Mekko$label,labels=Mekko$Class)+ngeom_text(data=Mekko,aes(x=label,y=.25,label=percent(Obama)),size=3.5,col="white",family="myFont")+ngeom_text(data=Mekko,aes(x=label,y=.8,label=percent(McCain)),size=3.5,col="white",family="myFont")+nlabs(title="MEKKO-市場細分矩陣圖",subtitle="這是一幅用心良苦的圖表",caption="Source:EasyCharts",x="",y="")+ntheme(nplot.margin=unit(c(0,0,0,0),"lines"),npanel.spacing=unit(c(0,0,0,0),"lines"),naxis.text.y=element_text(size=10),npanel.background=element_blank(),naxis.ticks=element_blank(),naxis.text.x=element_blank(),nlegend.position=c(.78,1),nlegend.direction="horizontal",ntext=element_text(family="myFont"),nplot.title=element_text(size=18),nplot.subtitle=element_text(size=14),nplot.caption=element_text(size=10,hjust=0),nlegend.title=element_blank()n)n
因水平有限,代碼寫的比較糟糕,圖表如有可改善的細節,還請的各位多多指點。
聯繫方式:
wechat:ljty1991
Mail:578708965@qq.com 個人公眾號:數據小魔方(datamofang) 團隊公眾號:EasyCharts qq交流群:[魔方學院]553270834推薦閱讀:
※Excel繪製多種風格「柱形圖」
※來來來,測試一下你的 Excel 水平,順便學會製作一個小模型
※ICT 出口發展的趨勢
※空間數據可視化之——人類的 「鬼斧神工」
※Three.js 入門與掃盲-基礎結構,坐標系與幾何類型介紹