提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔
前言
分享一個交通大數(shù)據(jù)可視化的案例,本案例來自于transbigdata包的出租車數(shù)據(jù)分析案例的復(fù)現(xiàn),數(shù)據(jù)集采用的是成都市的出租車(網(wǎng)約車和傳統(tǒng)的出租車數(shù)據(jù)),文件內(nèi)容比較大,這里我會附帶數(shù)據(jù)集的下載鏈接,由于電腦運(yùn)行內(nèi)存有限,本案例分享選擇其中一個數(shù)據(jù)集中的一部分車輛軌跡進(jìn)行分析.廢話少說,直接上案例。數(shù)據(jù)鏈接如下
鏈接:https://pan.baidu.com/s/1OeNs36fZHEon2yNA2bhs9A
提取碼:hqen
–來自百度網(wǎng)盤超級會員V6的分享
一、數(shù)據(jù)集
大家提取完數(shù)據(jù)集后,建議先壓縮一個壓縮包中的一個txt文件,如果電腦空間大,當(dāng)我沒說。
不要試圖去打開這個 txt文檔,太大了根本打不開。這里直接將txt文檔的后綴改成csv后綴,如下圖
然后還有一個地理信息文件(JESON)要準(zhǔn)備
這些都準(zhǔn)備好之后我們就可以開始操作了。
二、操作步驟
1.引入庫
這里建議在jupyter notebook上進(jìn)行操作,并且假設(shè)你已經(jīng)裝好下面幾個庫。這里需要注意transbigdata、geopandas兩個庫如果之前沒有用過的同學(xué)可能會比較陌生,但這兩個庫是本案例的核心庫,具體的安裝與引入請參考https://transbigdata.readthedocs.io/zh_CN/latest/index.html。CoordinatesConverter庫用于轉(zhuǎn)換坐標(biāo)系。matplotlib、pandas庫應(yīng)該很常見,直接pip install就完事兒。
代碼如下(示例):
import transbigdata as tbd
import CoordinatesConverter #GPS數(shù)據(jù)轉(zhuǎn)換庫
import geopandas as gpd
import matplotlib.pyplot as plt
import pandas as pd
2.讀入數(shù)據(jù)
這里注意要將數(shù)據(jù)文件和jeson文件都放入.ipynb或者程序所在的文件夾下。
代碼如下(示例):
data = pd.read_csv('20140803_train.csv',header=None)
data
輸出結(jié)果如下
上述數(shù)據(jù)又500多萬條,如果電腦吃不消的話,可以篩選其中十幾萬條進(jìn)行分析。五個字段,分別為車輛編號,緯度,經(jīng)度,載客狀態(tài),時間??梢杂孟旅娲a給數(shù)據(jù)添加有意義的表頭
代碼如下(示例):
data.columns = ['VehicleNum','Lat','Lng','OpenStatus','Time']
data
data
查看數(shù)據(jù)統(tǒng)計
tbd.data_summary(data, col=['VehicleNum', 'Time'], show_sample_duration=False, roundnum=4)
這里的時間數(shù)據(jù)已經(jīng)被識別,從6-23:59:59,也可以用下面代碼識別數(shù)據(jù)集中的時間字段數(shù)據(jù)是否能夠在后續(xù)的操作中被運(yùn)用。
pd.to_datetime(data['Time'])
3.數(shù)據(jù)預(yù)處理
這里我電腦運(yùn)行內(nèi)存只有8GB,所以運(yùn)行不了那么大的數(shù)據(jù)量,需要篩選,經(jīng)過我多次的篩選,最終確定了70萬條數(shù)據(jù)為我電腦比較合適的數(shù)據(jù)處理量,如果各位讀者電腦很牛掰(比我電腦牛)的話,這段話及下面的提取前70多萬條數(shù)據(jù)的代碼塊可以跳過。
#提取前199倆車的軌跡數(shù)據(jù)
data = data[data['VehicleNum']<200] #篩選前199輛車的軌跡數(shù)據(jù)
tbd.data_summary(data, col=['VehicleNum', 'Time'], show_sample_duration=False, roundnum=4) #統(tǒng)計這199倆車的數(shù)據(jù)情況
考慮到不同數(shù)據(jù)記錄方式所用的坐標(biāo)系可能不同,這里可以用transbigdata庫的一個函數(shù)判斷是否大體與底圖配對。
tbd.visualization_data(data,col = ['Lng','Lat'],accuracy=20) #accuracy表示識別精度,建議50以下
很明顯車輛軌跡點(diǎn)與路網(wǎng)匹配的偏差比較大,所以需要對坐標(biāo)系進(jìn)行轉(zhuǎn)換。
data['Lng'],data['Lat'] = CoordinatesConverter.gcj02towgs84(data['Lng'],data['Lat']) #將數(shù)據(jù)點(diǎn)轉(zhuǎn)換為84坐標(biāo)系下的GPS點(diǎn)
tbd.visualization_data(data,col = ['Lng','Lat'],accuracy=20) #可視化
可以看出經(jīng)過坐標(biāo)轉(zhuǎn)換之后數(shù)據(jù)點(diǎn)與路網(wǎng)基本配對上。
4.數(shù)據(jù)柵格化處理
transbigdata包柵格化處理數(shù)據(jù)框架
讀取研究范圍內(nèi)的地圖信息,生成GeoDataFrame變量
#讀取區(qū)域信息
cd = gpd.read_file(r'citys_510100.json')
cd.crs = None
cd.head()#展示表格前五行的數(shù)據(jù)
也可以用plot方法把cd變量畫出來
cd.plot()
這里大概可以獲取到圖形的邊界bounds = [103, 30.2, 104.75, 31.4] (后面有用上)。需要根據(jù)研究范圍對數(shù)據(jù)集進(jìn)行異常數(shù)據(jù)的處理,主要處理掉不在研究范圍內(nèi)的數(shù)據(jù)與載客狀態(tài)變化異常的數(shù)據(jù)
data = tbd.clean_outofshape(data, cd, col=['Lng', 'Lat'], accuracy=1) #剔除研究范圍外的數(shù)據(jù),accuracy可以調(diào)整,越小越精確。
data = tbd.clean_taxi_status(data, col=['VehicleNum', 'Time', 'OpenStatus']) #剔除出租車數(shù)據(jù)中載客狀態(tài)瞬間變化的記錄
將研究范圍進(jìn)行柵格化,這里分兩步進(jìn)行,第一步先加載底圖和繪制研究范圍內(nèi)的圖像,第二步生成研究范圍柵格化的圖像。
第一步代碼:
bounds = [102.95, 30.08, 104.9, 31.45] #設(shè)定研究范圍的邊界
#繪制區(qū)域以及地圖底圖
fig = plt.figure(1, (6, 6), dpi=800)
ax = plt.subplot(111)
plt.sca(ax)
#plot_map函數(shù)加載底圖
tbd.plot_map(plt, bounds, zoom=12, style='OSM')
#繪制地理區(qū)域
cd.plot(ax=ax, alpha=0.5)
plt.axis('off');
第二步代碼:
import pprint
grid, params = tbd.area_to_grid(cd)
#柵格參數(shù),方形柵格下method參數(shù)是rect,代表方形柵格
pprint.pprint(params)
#柵格幾何圖形
grid.head()
柵格地圖的表格形式已經(jīng)生成好,同時柵格的切割參數(shù)如上圖字典中的內(nèi)容,下面代碼進(jìn)行切割后的柵格圖像的可視化。
#可視化剛才創(chuàng)建的方形柵格
#創(chuàng)建圖框
fig = plt.figure(1, (12, 8), dpi=800)
ax1 = plt.subplot(121)
plt.sca(ax1)
tbd.plot_map(plt, bounds, zoom=13, style='OSM')
#繪制方形柵格
grid.plot(ax=ax1, lw=0.2, edgecolor='blue', facecolor="None")
plt.axis('off');
這里我采用的樣式也就是tbd.plot_map方法里面style='OSM’為免費(fèi)的樣式(OpenStreetMap),如果想用其它的樣式可以參考https://transbigdata.readthedocs.io/zh_CN/latest/plot_map.html一共有12種樣式,這里的12種樣式都需要mapbox里面的Access token,可以通過申請mapbox并成為開發(fā)者免費(fèi)獲得Access token,這里我給大家展示一下style='streets’的樣式:
將獲得的GPS數(shù)據(jù)柵格化,生成車輛軌跡所在柵格地圖上的位置。
#GPS柵格化
data['LONCOL'], data['LATCOL'] = tbd.GPS_to_grid(data['Lng']
data['Lat'], params)
data
執(zhí)行后的結(jié)果可以看到右邊兩列表示該軌跡點(diǎn)在柵格地圖種的位置,0號軌跡在柵格中的位置為(215,126)。
#集計柵格數(shù)據(jù)量
datatest = data.groupby(['LONCOL', 'LATCOL'])
['VehicleNum'].count().reset_index()
#生成柵格地理圖形
datatest['geometry'] = tbd.grid_to_polygon([datatest['LONCOL'], datatest['LATCOL']], params)
#轉(zhuǎn)為GeoDataFrame
# import geopandas as gpd
datatest = gpd.GeoDataFrame(datatest)
datatest.head()
對車輛軌跡數(shù)據(jù)進(jìn)行柵格統(tǒng)計,并生成柵格地理圖形??梢哉{(diào)用變量datatest查看集計后的表格和地理圖形。
第一行的意思表示(237,399)柵格上有78條車輛軌跡數(shù)據(jù)。同時可以對該數(shù)據(jù)可視化。
不繪制底圖的可視化
# 繪制柵格
fig = plt.figure(1, (16, 6), dpi=600)
ax1 = plt.subplot(111)
# tbd.plot_map(plt, bounds, zoom=10, style=4)
datatest.plot(ax=ax1, column='VehicleNum', legend=True)
plt.xticks([], fontsize=10)
plt.yticks([], fontsize=10)
plt.title('Counting of Taxi GPS Trajectory Points', fontsize=12);
繪制底圖的可視化
bounds = [102.95, 30.08, 104.9, 31.45]
#創(chuàng)建圖框
fig = plt.figure(1, (10, 10), dpi=800)
ax = plt.subplot(111)
plt.sca(ax)
#添加地圖底圖
tbd.plot_map(plt, bounds, zoom=14, style='streets')
cd.plot(ax=ax, edgecolor=(0, 0, 0, 1), facecolor=(0, 0, 0, 0.2), linewidths=0.5)
datatest.plot(ax=ax, column='VehicleNum', scheme='quantiles')
plt.title('Counting of Taxi GPS Trajectory Points', fontsize=12);
注意這里我用的是mapbox的底圖,如果各位沒用Access token的話就將style改成OSM。接下來提取車輛OD,這里有兩種方法都可以提取OD。
#從GPS數(shù)據(jù)提取OD
#方法一:
oddata = tbd.taxigps_to_od(data,col = ['VehicleNum', 'Time', 'Lng', 'Lat', 'OpenStatus'])
#方法二:
'''data = data.sort_values(by = ['VehicleNum','Time'])
data['OpenStatus_pre'] = data['OpenStatus'].shift()
data['OpenStatus_next'] = data['OpenStatus'].shift(-1)
data = data[-((data['OpenStatus']!=data['OpenStatus_next'])&(data['OpenStatus']!=data['OpenStatus_pre'])&
(data['VehicleNum']==data['VehicleNum'].shift())&(data['VehicleNum']==data['VehicleNum'].shift(-1)))]
data['VehicleNum_next']=data['VehicleNum'].shift(-1)
oddata = data[(data['VehicleNum'] == data['VehicleNum_next']) & (data['OpenStatus'] != data['OpenStatus_next'])].copy()
oddata = oddata[['VehicleNum','Time','Lng','Lat','OpenStatus']].copy()
oddata['VehicleNum_next'] = oddata['VehicleNum'].shift(-1)
oddata['OpenStatus_next'] = oddata['OpenStatus'].shift(-1)
oddata['Lng_'] = oddata['Lng'].shift(-1)
oddata['Lat_'] = oddata['Lat'].shift(-1)
oddata['Time_next'] = oddata['Time'].shift(-1)
oddata = oddata[(oddata['OpenStatus'] == 0)&(oddata['VehicleNum'] ==oddata['VehicleNum_next'])
].drop(['OpenStatus','VehicleNum_next','OpenStatus_next'],axis = 1).copy()
oddata
oddata.columns=['VehicleNum','stime','slog','slat','elog','elat','etime']'''
oddata
OD數(shù)據(jù)提取后,也要將OD數(shù)據(jù)柵格化。
OD數(shù)據(jù)柵格化
od_gdf = tbd.odagg_grid(oddata, params)
od_gdf.head()
在執(zhí)行完這段代碼后可能會出現(xiàn)warning,不過對我們的結(jié)果不會有任何影響,我們繼續(xù)。下面繪制柵格OD
# 繪制柵格OD
fig = plt.figure(1, (16, 6), dpi=800) # 確定圖形高為6,寬為8;圖形清晰度
ax1 = plt.subplot(111)
# data_grid_count.plot(ax=ax1, column='VehicleNum', legend=True, cmap='OrRd', scheme='quantiles')
plt.sca(ax1)
od_gdf.plot(ax=ax1, column='count', legend=True, scheme='quantiles')
plt.xticks([], fontsize=10)
plt.yticks([], fontsize=10)
plt.title('OD Trips', fontsize=12);
bounds = [102.95, 30.08, 104.9, 31.45]
cd.plot(ax=ax1, edgecolor=(0, 0, 0, 1), facecolor=(0, 0, 0, 0.2), linewidths=0.5)
tbd.plot_map(plt, bounds, zoom=12, style='streets')
這段代碼執(zhí)行也會有warning,無傷大雅,可以繼續(xù)下面的步驟。將OD集計到小區(qū),并進(jìn)行可視化
od_gdf = tbd.odagg_shape(oddata, cd, round_accuracy=6) #OD集計到小區(qū)
bounds = [102.95, 30.08, 104.9, 31.45]
#創(chuàng)建圖框
fig = plt.figure(1, (10, 10), dpi=800)
ax = plt.subplot(111)
plt.sca(ax)
#添加地圖底圖
tbd.plot_map(plt, bounds, zoom=12, style='streets')
#繪制colorbar
cax = plt.axes([0.05, 0.33, 0.02, 0.3])
plt.title('OD\nMatrix')
plt.sca(ax)
#繪制OD
od_gdf.plot(ax=ax, vmax=100, column='count', cax=cax, legend=True)
#繪制小區(qū)底圖
cd.plot(ax=ax, edgecolor=(0, 0, 0, 1), facecolor=(0, 0, 0, 0.2), linewidths=0.5)
#添加比例尺和指北針
tbd.plotscale(ax, bounds=bounds, textsize=10, compasssize=1, accuracy=2000, rect=[0.06, 0.03], zorder=10)
plt.axis('off')
plt.xlim(bounds[0], bounds[2])
plt.ylim(bounds[1], bounds[3])
plt.show()
這樣基本上將出租車數(shù)據(jù)柵格化分析整完了,下面開始進(jìn)行可視化分析,進(jìn)行下面的分析時需要用到上面的代碼,所以請在上述程序下繼續(xù)進(jìn)行。
5.可視化分析
這里需要提取載客時的軌跡(data_deliver)和空載時的軌跡(data_idle),執(zhí)行如下代碼
data_deliver, data_idle = tbd.taxigps_traj_point(data,oddata,col=['VehicleNum',
'Time',
'Lng',
'Lat',
'OpenStatus'])
數(shù)據(jù)提取完畢之后可以將載客與空載的軌跡用圖形表示
載客
bounds = [102.95, 30.08, 104.9, 31.45]
#創(chuàng)建圖框
fig = plt.figure(1, (10, 10), dpi=800)
ax = plt.subplot(111)
plt.sca(ax)
#添加地圖底圖
tbd.plot_map(plt, bounds, zoom=12, style='streets')
#繪制colorbar
cax = plt.axes([0.05, 0.33, 0.02, 0.3])
plt.title('OD\nMatrix')
plt.sca(ax)
#繪制OD
traj_deliver = tbd.points_to_traj(data_deliver)
traj_deliver.plot(ax=ax);
#繪制小區(qū)底圖
cd.plot(ax=ax, edgecolor=(0, 0, 0, 1), facecolor=(0, 0, 0, 0.2), linewidths=0.5)
#添加比例尺和指北針
tbd.plotscale(ax, bounds=bounds, textsize=10, compasssize=1, accuracy=2000, rect=[0.06, 0.03], zorder=10)
plt.axis('off')
plt.xlim(bounds[0], bounds[2])
plt.ylim(bounds[1], bounds[3])
plt.title('zaike', fontsize=12);
plt.show()
空載
bounds = [102.95, 30.08, 104.9, 31.45]
#創(chuàng)建圖框
fig = plt.figure(1, (10, 10), dpi=800)
ax = plt.subplot(111)
plt.sca(ax)
#添加地圖底圖
tbd.plot_map(plt, bounds, zoom=12, style='streets')
#繪制colorbar
cax = plt.axes([0.05, 0.33, 0.02, 0.3])
plt.title('OD\nMatrix')
plt.sca(ax)
#繪制OD
traj_deliver = tbd.points_to_traj(data_idle)
traj_deliver.plot(ax=ax);
#繪制小區(qū)底圖
cd.plot(ax=ax, edgecolor=(0, 0, 0, 1), facecolor=(0, 0, 0, 0.2), linewidths=0.5)
#添加比例尺和指北針
tbd.plotscale(ax, bounds=bounds, textsize=10, compasssize=1, accuracy=2000, rect=[0.06, 0.03], zorder=10)
plt.axis('off')
plt.xlim(bounds[0], bounds[2])
plt.ylim(bounds[1], bounds[3])
plt.title('', fontsize=12);
plt.show()
根據(jù)處理后的數(shù)據(jù)可以生成相應(yīng)的軌跡移動視頻
from keplergl import KeplerGl
a=tbd.visualization_trip(data_deliver)
a.save_to_html(file_name='data_visua_vedio.html')
del a
這樣就在當(dāng)前文件夾目錄下生成了一共html文件
在文件目錄下打開html文件就可以顯示其軌跡的結(jié)果了。如果要將空載的軌跡可視化則把data_deliver替換成data_idle即可。也可以根據(jù)od數(shù)據(jù)生成OD圖
a=tbd.visualization_od(oddata,accuracy=2000)
a.save_to_html(file_name='od_visua.html')
del a
總結(jié)
本文主要運(yùn)用transbigdata庫對出租車數(shù)據(jù)進(jìn)行柵格化處理后再對其OD和軌跡數(shù)據(jù)進(jìn)行可視化。transbigdata庫上的案例是深圳市的,這里的案例是成都市的軌跡數(shù)據(jù)分析,通過數(shù)據(jù)預(yù)處理、數(shù)據(jù)柵格化、可視化三個步驟復(fù)現(xiàn),同時像文中的一些參數(shù)的調(diào)整將會生成不同的圖形樣式,如accuracy參數(shù)對應(yīng)精確度,style參數(shù)對應(yīng)底圖的樣式。對應(yīng)不同的樣式相關(guān)研究人員可以在此基礎(chǔ)上進(jìn)一步統(tǒng)計不同時間段不同區(qū)的訂單數(shù),行車速度等,也可以提取空間特征和時間特征并運(yùn)用機(jī)器學(xué)習(xí)的方法對速度或者出租車流量進(jìn)行預(yù)測。文章來源:http://www.zghlxwxcb.cn/news/detail-789736.html
存在的問題
交通小白剛?cè)腴T,文中難免存在不妥之處,也誠懇地希望大家能夠多多指出存在的問題,若有更好的處理意見也可以在評論區(qū)發(fā)言交流。愿本案例能夠?qū)Υ蠹姨幚斫煌ù髷?shù)據(jù)有所幫助,制作不易,多多支持文章來源地址http://www.zghlxwxcb.cn/news/detail-789736.html
到了這里,關(guān)于Transbigdata——交通出租車大數(shù)據(jù)可視化分析,以成都市為例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!