多維放射狀流向圖的最佳布局方案
最近,有很多小夥伴兒跟我諮詢一個比較複雜的地圖圖表畫法。
需求是這樣的,一個國家各省或者全球各國之間存在的貿易關係、或者其他經濟往來。想要用線條來表達這些指標的流向,同時使用線條粗細來表達指標流向的量級,我給他們的建議是,雖然你很明確要表達的意思,但是實際上這種形式所呈現的最終結果,可能並非你想要的。
如果在一個地圖中這些線條都是從一個點發散出來的,這種表達形式雖說不妥,但是不算糟糕,但是倘若你的數據中是多個發散中心,即每個城市都會向其他各個城市發散出一組放射線條,同時線條還有粗細之分,那麼最終的效果簡直慘不忍睹。
當然我還是會用案例來把這種常規的想法用代碼演示一遍,同時給出自己覺得最優的兩種解決思路:
#載入包:library(ggplot2)library(dplyr)library(rgdal)library(shiny)library(shinythemes)
##轉換為數據框併合並城市數據:china_map <-readOGR("D:/R/mapdata/State/china.geojson","OGRGeoJSON",stringsAsFactors=FALSE)Encoding(china_map@data$name)<-"UTF-8"china_map <- fortify(china_map) province_city <- read.csv("D:/R/rstudy/Province/chinaprovincecity.csv",stringsAsFactors = FALSE,check.names = FALSE) ###構造線條起始點數據:city<-c("北京","上海","重慶","天津","武漢","南京","廣州","瀋陽","西安","鄭州")city_data<-merge(city,city)%>%rename(Start=x,End=y)%>%arrange(Start)city_data<-city_data%>%merge(province_city[,c("city","jd","wd")],by.x="Start",by.y="city",all.x=TRUE)%>%rename(Start_long=jd,Start_lat=wd)city_data<-city_data%>%merge(province_city[,c("city","jd","wd")],by.x="End",by.y="city",all.x=TRUE)%>%rename(End_long=jd,End_lat=wd)city_data<-transform(city_data,zhibiao1=runif(nrow(city_data),0,100),zhibiao2=runif(nrow(city_data),0,100),zhibiao3=runif(nrow(city_data),0,100))
###理所當然的普通做法1:ggplot()+geom_polygon(data=china_data,aes(x=long,y=lat,group=group),fill="white",colour="grey60")+geom_segment(data=city_data,aes(x=Start_long,y=Start_lat,xend=End_long,yend=End_lat,size=zhibiao1),colour="black")+coord_map("polyconic") + scale_size_area(max_size=2)+theme_void()
###最合適的做法1:圖形分面:ggplot()+ geom_polygon(data=china_data,aes(x=long,y=lat,group=group),fill="white",colour="grey60")+geom_segment(data=city_data,aes(x=Start_long,y=Start_lat,xend=End_long,yend=End_lat),colour="black")+geom_point(data =city_data,aes(x=End_long,y=End_lat,size=zhibiao1),shape=21,fill="#8E0F2E",colour="black",alpha=0.4)+scale_size_area(max_size=6)+coord_map("polyconic") + facet_wrap(~Start,nrow = 2)+theme_void()
###最合適的做法2:
Shiny動態交互圖:
city_list<-list("北京"="北京","上海"="上海","重慶"="重慶","天津"="天津","武漢"="武漢","南京"="南京","廣州"="廣州","瀋陽"="瀋陽","西安"="西安","鄭州"="鄭州")ui <-shinyUI(fluidPage( theme=shinytheme("cerulean"), titlePanel("Population Structure Data"), sidebarLayout( sidebarPanel( radioButtons("var1","City",city_list,inline=FALSE), selectInput("var2","Value",c("zhibiao1"="zhibiao1","zhibiao2"="zhibiao2","zhibiao3"="zhibiao3"),selected="zhibiao1") ), mainPanel(h2("Trade Stream"),plotOutput("distPlot")) )))
server<-shinyServer(function(input,output){output$distPlot <- renderPlot({ mydata=filter(city_data%>%filter(Start==input$var1)) argu<-switch(input$var2,zhibiao1=mydata$zhibiao1,zhibiao2=mydata$zhibiao2,zhibiao3=mydata$zhibiao3) ggplot(mydata)+ geom_polygon(data=china_data,aes(x=long,y=lat,group=group),fill="white",colour="grey60")+ geom_segment(aes(x=Start_long,y=Start_lat,xend=End_long,yend=End_lat),colour="black")+ geom_point(aes(x=End_long,y=End_lat,size=argu),shape=21,fill="#8E0F2E",colour="black",alpha=0.4)+ scale_size_area(max_size=6)+ coord_map("polyconic") + theme_void() })})shinyApp(ui=ui,server=server)
好了乾貨完了,接下來打一波廣告:
之前很多熱情的小夥伴兒們一直在問我有木有開課程的打算,因為自己一直在忙,再加上錄製課程比較麻煩,一直動沒有動靜,最近機緣巧合,跟知名的大數據在線分享平台——天善智能有了合作,打算做一個關於ggplot2的微課分享。
課程時長很短,大約兩個小時,時間定在9月12日晚8:00~10:00,內容是ggplot2入門,當然我口中的入門你絕對無法從百度、谷歌和知乎的所謂雜貨鋪里尋到,不過如果你願意一絲不苟的去閱讀源文檔,那麼我所講的內容你也許都可以學到,但是基於我一年的高強度實戰經驗,也許我可以幫你你理解的更更深入一些,不太會講也不願意講天花亂墜的宣傳詞,不做任何承諾,能學到什麼,全憑悟性和造化。
兩個小時雖然很短,但是也要賺一口喝水的錢對吧,不然對不起知識,定價19.9!
內容嗎,無外乎這些:(時間有限不應定能夠全部都涉及到)
1、ggplot2圖層語法的核心理念
2、ggplot函數與geom_xxx函數間的父子繼承關係
3、美學映射參數寫在ggplot函數內與寫在geom_xxx內的差異
4、美學映射參數寫在aes函數內部和寫在aes函數外部的差異
5、顏色標度一共有幾種類型和寫法,在不同模塊中是否能夠共用
6、如何結合實際業務與引用場景進行顏色標度選擇
7、多圖層疊加時,如何解決顏色標度衝突的問題
8、分面函數的許可權控制
9、主題框架與模塊間的繼承關係
10、主題函數更新與替換方案
11、圖形輸出與高清抗鋸齒渲染
其實這些問題都是之前我學習過程中走過的彎路,隨著練習的案例越來越多,這些問題一步步全都解決了,其實如果你能有心看完我的所有關於ggplot講解部分,差不多這些問題也都能全部理解。
閱讀原文報名:
推薦閱讀:
※開發一個自動交易系統需要哪些步驟和準備?
※大數據分析到底是應該以洞察總體或群體的特徵為目標,挖掘潛在客戶需求方向?還是應該以洞察個體消費特徵為目標,制定針對性的營銷方案和服務?