99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線(xiàn)電話(huà):13121318867

登錄
首頁(yè)精彩閱讀北京空氣質(zhì)量數(shù)據(jù)可視化
北京空氣質(zhì)量數(shù)據(jù)可視化
2017-04-10
收藏
還記得之前推送過(guò)的一篇講大連天氣數(shù)據(jù)可視化的文章嗎,后來(lái)有小伙伴兒直呼不過(guò)癮,墻裂要求來(lái)一個(gè)北京版。

小編我日夜趕工,終于出爐了北京版的空氣質(zhì)量數(shù)據(jù)可視化,而且相比之前大連版的有所升級(jí):

· 時(shí)間區(qū)間增加到了連續(xù)三個(gè)年度(2014~2016)
· 圖表形式不再局限于年度日歷熱圖,而且增加了矩陣熱圖和圓環(huán)堆積熱力圖。
· 圓環(huán)圖提供了基于 ggplot 函數(shù)的多種實(shí)現(xiàn)方法。

以下是整個(gè)數(shù)據(jù)可視化的處理過(guò)程

加載包:(我一向習(xí)慣在文首加載所有必要的軟件包)

library(RCurl)
library(XML)
library(dplyr)
library(ggplot2)
library(stringr)
library(rvest)
library(lubridate)
library("DT")
library(openair)
library(ggplot2)
library(reshape2)
library(RColorBrewer)
library(scales)
library(showtext)
library(grid)
library(Cairo)

根據(jù)要爬取網(wǎng)址的數(shù)據(jù)鏈接結(jié)構(gòu)手動(dòng)構(gòu)造網(wǎng)址鏈接使其遍歷所有需要爬取的網(wǎng)頁(yè)(當(dāng)然這個(gè)過(guò)時(shí)你完全可以通過(guò)請(qǐng)求網(wǎng)頁(yè)的形式篩選文本并提取目標(biāo) URL,但是這樣需要迂回很多步驟,需要考慮編碼,查找路徑,我也不是那種特勤快的人,看到有捷徑能偷懶就絕不花冤枉時(shí)間。)

year<-2014:2016
month<-sprintf("%02d",1:12)
url<- paste("https://www.aqistudy.cn/historydata/daydata.php?city=北京&month=",expand.grid(year,month)$Var1
,expand.grid(year,month)$Var2,sep="")

以上過(guò)程構(gòu)造了北京市 2014~2016 年三整年的歷史空氣質(zhì)量數(shù)據(jù)網(wǎng)址鏈接(月份鏈接):

接下來(lái) 進(jìn)入數(shù)據(jù)爬取階段:

先寫(xiě)完一個(gè)看下具體情況

tbls<-read_html(url[1],encoding="utf-8")%>%html_table(.,header=TRUE,trim=TRUE);tbls<-tbls[[1]]

檢查無(wú)誤之后,構(gòu)造下載循環(huán)函數(shù):

mytable<-data.frame()
for (i in url){
Sys.sleep(sample(1:5,1))
fun<-function(m){
table<-read_html(m,encoding="utf-8")%>%html_table(.,header=TRUE,trim=TRUE)
table<-table[[1]]
}
mytable<-rbind(mytable,fun(i))
}

這里預(yù)覽一下以上數(shù)據(jù)結(jié)構(gòu):

dim(mytable)
[1] 1096   11

attributes(mytable)$names
 [1] "日期"     "AQI"      "范圍"     "質(zhì)量等級(jí)" "PM2.5"    "PM10"     "SO2"     
 [8] "CO"       "NO2"      "O3"       "排名" 

datatable(mytable)

使用DT表格預(yù)覽數(shù)據(jù)集:

mytable<-read.csv("beijingtianqi.csv",stringsAsFactors=FALSE,check.names=FALSE) 

 
查看數(shù)據(jù)結(jié)構(gòu)和變量屬性是否符合分析需要:

str(mytable)
'data.frame': 1096 obs. of  11 variables:
 $ 日期    : chr  "2014-01-01" "2014-01-02" "2014-01-03" "2014-01-04" ...
 $ AQI     : int  87 119 81 151 121 181 144 29 44 86 ...
 $ 范圍    : chr  "76~99" "80~218" "38~202" "87~229" ...
 $ 質(zhì)量等級(jí): chr  "良" "輕度污染" "良" "中度污染" ...
 $ PM2.5   : num  45 111.4 46.5 114.4 90.5 ...
 $ PM10    : num  111.3 168.5 97.7 147 117.5 ...
 $ SO2     : num  27.7 69.3 29 40 35.9 46.3 34.4 13 19.3 53.2 ...
 $ CO      : num  1.5 3.43 1.31 2.82 2.31 ...
 $ NO2     : num  61.9 93.1 52 75.4 67 68.2 59.8 21.1 34.5 70.5 ...
 $ O3      : int  64 17 65 10 57 11 55 59 65 28 ...
 $ 排名    : int  32 66 41 112 67 104 85 9 25 58 ...

定義日期變量格式:

mytable$日期<-as.Date(mytable$日期)
names(mytable)[c(1,3,4,11)]<-c("date","Range","Level","Order")
mytable$Year<-year(mytable$date)
breaks<-c(0,50,100,150,200,300,500)
label<-c("excellent","good","Mild pollution","moderate pollution","heavy pollution ","serious pollution")

制作北京市 2014~2016三年度歷史空氣質(zhì)量數(shù)據(jù)年度日歷熱圖

filter(mytable,Year==2014)%>%calendarPlot(.,pollutant="AQI",breaks=breaks,labels=label,year=2014)
filter(mytable,Year==2015)%>%calendarPlot(.,pollutant="AQI",breaks=breaks,labels=label,year=2015)
filter(mytable,Year==2016)%>%calendarPlot(.,pollutant="AQI",breaks=breaks,labels=label,year=2016)



接下來(lái)讓我們瘋狂一把,將北京三年的空氣質(zhì)量指標(biāo)AQI用一幅圖形盡數(shù)呈現(xiàn)。

首先要生成一個(gè)副本數(shù)據(jù):

mydata1<-mytable

讀出數(shù)據(jù)存檔:

write.table (mytable,"beijingtianqi.csv",sep=",",row.names=FALSE)

提取需要使用的目標(biāo)變量:

mydata11<-mydata1[c("date","AQI","Year")]
myasst<-mydata11[mydata11$date %in% as.Date(c("2014-01-01","2015-01-01","2016-01-01")),]
mydata11<-rbind(mydata11,myasst)


因?yàn)樽鲌D需要,2016年是閏年,2月有29天,14、15年均為28天,會(huì)導(dǎo)致最終數(shù)據(jù)不等長(zhǎng),影響之后的圖表制作過(guò)程,這里暫且將其去除。

mydata11<-arrange(mydata11,Year,date)
mydata11<-mydata11[mydata11$date!="2016-02-29",]

提取月份數(shù)據(jù)并構(gòu)月份標(biāo)簽:

mydata11$Month<-month(mydata11$date)
mydata11$Monthdata<--5
mydata11$Monthjo<-ifelse(mydata11$Month%%2==0,"A","B")
circlemonth<-seq(15,345,length=12)
circlebj<-rep(c(-circlemonth[1:3],rev(circlemonth[1:3])),2)

構(gòu)造年度ID、年份、以及之后作圖需要用到的輔助數(shù)據(jù):

mydata11$ID<-rep(seq(from=0,to=365),3)
mydata11$Year<-factor(mydata11$Year,order=T)
mydata11$Asst<-5
mydata11$Asst[mydata11$Year==2015]<-10
mydata11$Asst[mydata11$Year==2016]<-15
mydata11A<-mydata11[mydata11$Year==2014&mydata11$Monthjo=="A",]
mydata11B<-mydata11[mydata11$Year==2014&mydata11$Monthjo=="B",]

構(gòu)造季度、季度標(biāo)簽,及其輔助數(shù)據(jù):

mydata11$Quarter<-quarter(mydata11$date)
mydata11$Quarterdata<-20
mydata11C<-mydata11%>%filter(mydata11$Year==2014)%>%filter(Quarter %in% c(1,3)) 
mydata11D<-mydata11%>%filter(mydata11$Year==2014)%>%filter(Quarter %in% c(2,4)) 
circlequarter<-seq(45,315,length=4)
circleqd<-rep(c(-circlequarter[1],circlequarter[1]),2)

將數(shù)值型的AQI指數(shù)根據(jù)行業(yè)標(biāo)準(zhǔn)進(jìn)行分割:

mydata11$FADD<-cut(mydata11$AQI,breaks=c(0,50,100,150,200,300,500),labels=c("0~50","51~100","101~150","151~200","201~300","301~500"),order=T)


作圖方法1:(簡(jiǎn)便方法,但效果不太好調(diào)整)

CairoPNG(file="ECOCirclejj.png",width=1488,height=996)
showtext.begin()
ggplot(data=mydata11)+
geom_tile(aes(ID,Year,fill=FADD))+
coord_polar(theta="x")+
expand_limits(ylim=c(-4,4))+
scale_fill_brewer(palette="YlOrRd",type="seq",direction=1,guide=guide_legend(reverse=TRUE))+
labs(title="2014~2016年度北京市空氣質(zhì)量水平可視化",subtitle="數(shù)據(jù)根據(jù)AQI指標(biāo)水平進(jìn)行分段分割",caption="Source:https://www.aqistudy.cn/",x="",y="",fill="")+
theme(
axis.text=element_blank(),
axis.title=element_blank(),
axis.ticks=element_blank(),
panel.background=element_blank(),
panel.grid=element_blank(),
panel.border=element_blank(),
legend.key.size=unit(1.2,'cm'),
legend.key.height=unit(1,'cm'),
legend.text.align=1, 
legend.position=c(1,0.95),legend.justification=c(1,1),
legend.text=element_text(size=20,hjust=3,vjust=3,face="bold"),
plot.background=element_blank(),
plot.title=element_text(size=50,lineheight=1.5),
plot.subtitle=element_text(size=35,lineheight=1.5),
plot.caption=element_text(size=25,hjust=0,lineheight=1.2),
plot.margin=unit(c(.5,.5,.5,.5),"lines")
)
showtext.end()
dev.off()


這里使用geom_raster()圖層進(jìn)行映射(不支持極坐標(biāo)轉(zhuǎn)換)
breaks<-aggregate(ID~Month,data=mydata11[mydata11$Year==2014,],FUN=median)
CairoPNG(file="ECOCirclejjj.png",width=1200,height=600)
showtext.begin()
ggplot(data=mydata11)+
geom_raster(aes(ID,Year,fill=FADD))+
scale_fill_brewer(palette="YlOrRd",type="seq",direction=1,guide=guide_legend(reverse=TRUE))+
scale_x_continuous(breaks=breaks[,2],labels=paste0(1:12,"月"))+
labs(title="2014~2016年度北京市空氣質(zhì)量水平可視化",subtitle="數(shù)據(jù)根據(jù)AQI指標(biāo)水平進(jìn)行分段分割",caption="Source:https://www.aqistudy.cn/",fill="")+
theme(
text=element_text(family="myfont"),
axis.text=element_text(size=20),
axis.title=element_blank(),
axis.ticks=element_blank(),
panel.background=element_blank(),
panel.grid=element_blank(),
panel.border=element_blank(),
legend.key.size=unit(1.2,'cm'),
legend.key.height=unit(1,'cm'),
legend.text.align=1,
legend.text=element_text(size=20,hjust=3,vjust=3,face="bold"),
plot.background=element_blank(),
plot.title=element_text(size=50,lineheight=1.5),
plot.subtitle=element_text(size=35,lineheight=1.5),
plot.caption=element_text(size=25,hjust=0,lineheight=1.2),
plot.margin=unit(c(.5,.5,.5,.5),"lines")
)
showtext.end()
dev.off()


作圖方法2:(雖然代碼多但是調(diào)整相對(duì)自由)
setwd("F:/微信公眾號(hào)/公眾號(hào)——數(shù)據(jù)小魔方/2017年4月/20170404")
font.add("myfont","msyhl.ttc")
CairoPNG(file="ECOCircle.png",width=1488,height=996)
showtext.begin()
ggplot()+
geom_bar(data=mydata11A,aes(x=ID,y=Monthdata),stat="identity",width=1,fill="#ECEDD1",col="#ECEDD1")+
geom_bar(data=mydata11B,aes(x=ID,y=Monthdata),stat="identity",width=1,fill="#DFE0B1",col="#DFE0B1")+
geom_bar(data=mydata11C,aes(x=ID,y=Quarterdata),stat="identity",width=1,fill="#BDBDBD",col="#BDBDBD")+
geom_bar(data=mydata11D,aes(x=ID,y=Quarterdata),stat="identity",width=1,fill="#D4D2D3",col="#D4D2D3")+
geom_bar(data=mydata11[mydata11$Year==2016,],aes(x=ID,y=Asst,fill=FADD),stat="identity",width=1)+
geom_bar(data=mydata11[mydata11$Year==2015,],aes(x=ID,y=Asst,fill=FADD),stat="identity",width=1)+
geom_bar(data=mydata11[mydata11$Year==2014,],aes(x=ID,y=Asst,fill=FADD),stat="identity",width=1)+
scale_fill_brewer(palette="YlOrRd",type="seq",direction=1,guide=guide_legend(reverse=TRUE))+
coord_polar(theta="x")+
ylim(-20,20)+
guides(colour=guide_legend(reverse=TRUE))+
geom_text(data=NULL,aes(x=circlemonth,y=-2.5,label=paste0(1:12,"月"),angle=circlebj),family="myfont",size=7,hjust=0.5,vjust=.5)+
geom_text(data=NULL,aes(x=circlequarter,y=17.5,label=paste0(c("一","二","三","四"),"季度"),angle=circleqd),family="myfont",size=7,hjust=0.5,vjust=.5)+
annotate("text",x=0,y=-15,label="北京",size=25,hjust=.5,vjust=1,family="myfont") +    
labs(title="2014~2016年度北京市空氣質(zhì)量水平可視化",subtitle="數(shù)據(jù)根據(jù)AQI指標(biāo)水平進(jìn)行分段分割",caption="Source:https://www.aqistudy.cn/",x="",y="",fill="")+
theme(
text=element_text(family="myfont"),
axis.text=element_blank(),
axis.title=element_blank(),
axis.ticks=element_blank(),
panel.background=element_blank(),
panel.grid=element_blank(),
panel.border=element_blank(),
legend.key.size=unit(1.2,'cm'),
legend.key.height=unit(1,'cm'),
legend.text.align=1, 
legend.position=c(1,0),legend.justification=c(1,0),
legend.text=element_text(size=20,hjust=3,vjust=3,face="bold"),
plot.background=element_blank(),
plot.title=element_text(size=50,lineheight=1.5),
plot.subtitle=element_text(size=35,lineheight=1.5),
plot.caption=element_text(size=25,hjust=0,lineheight=1.2),
plot.margin=unit(c(.5,.5,.5,.5),"lines"),
)
showtext.end()
dev.off()



以上整個(gè)過(guò)程涉及到的處理方法比綜合,有爬蟲(chóng)、數(shù)據(jù)清洗和字符串處理、時(shí)間格式轉(zhuǎn)換和 ggplot 高級(jí)制圖方法,如果感興趣可以作為練習(xí)。


作者   杜雨
本文轉(zhuǎn)自數(shù)據(jù)小魔方,轉(zhuǎn)載需授權(quán)


數(shù)據(jù)分析咨詢(xún)請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線(xiàn)
立即咨詢(xún)
客服在線(xiàn)
立即咨詢(xún)
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶(hù)后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說(shuō)明請(qǐng)參見(jiàn):http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }