交通時空大數據_基礎
須預先下載的Modules:
pip install matplotlib
、pip install pandas
、pip install geopandas
整理出需要的data
若資料集有太多不需要的資訊,可以進行這一步驟整理資料
若不整理也可以直接使用的程式碼
- 車輛ID
car_id
- 時間
_time
- 經度
lon
- 緯度
lat
- 速度
cal_spd
時間完整性評估
hourly_data_statistics.py
處理時間
-
使用日期格式轉換
-
使用字串分割
日期格式是:2020-09-04 23:53:44
索引從0開始,故小時(23)為11(包括)~13(不包括)
-
使用apply方法 (須較長的處理時間)
定義一function,會對dataframe的每列進行操作
亦可使用lambda匿名函數
axis=1
表示你要對每一行應用 lambda 函數
-
完整程式碼
.astype(int)
將結果轉換為整數型別
字串分割、
統計每小時的數據量
統計每個小時內有多少唯一的 'car_id'
(同一台車不重複計算)
- 使用
groupby()
,按照 'Hour'
欄位對資料進行分組
reset_index()
重置索引,使 'Hour'
成為一列
transpose()
將資料表轉置(可以不用)

繪製圖表

完整程式碼
空間完整性評估
建立空間分布柵格圖
spatial_distribution_grid_map.py
須預先下載的Modules:pip install keplergl
、pip install -U transbigdata

import geopandas as gpd
import transbigdata as tbd
import pandas as pd
import matplotlib.pyplot as plt
input_csv = 'merge0509.csv'
input_shp = 'shp\\kuohsiung.shp'
data = pd.read_csv(input_csv, dtype={'car_id': int, '_time': str, 'lon': float, 'lat': float, 'cal_spd': float})
sz = gpd.read_file(input_shp)
sz = sz.to_crs(epsg=4326)
accuracy = 500
data = tbd.clean_outofshape(data, sz, col=['lon', 'lat'], accuracy = accuracy)
minx, miny, maxx, maxy = sz.total_bounds
bound = [minx, miny, maxx, maxy]
params = tbd.area_to_params(bound, accuracy = accuracy)
print(params)
data['LonCol'], data['LatCol'] = tbd.GPS_to_grid(data['lon'], data['lat'], params)
grid_agg = data.groupby(['LonCol', 'LatCol'])['car_id'].count().reset_index()
grid_agg['geometry'] = tbd.grid_to_polygon([grid_agg['LonCol'], grid_agg['LatCol']], params)
grid_agg = gpd.GeoDataFrame(grid_agg)
fig = plt.figure(1, figsize=(8, 8), dpi=100)
ax = fig.add_subplot(111)
sz.plot(ax = ax, edgecolor = (0,0,0,0), facecolor = (0,0,0,0.1), linewidth = 0.5)
cax = plt.axes([0.1, 0.33, 0.02, 0.3])
plt.title('Data count')
plt.sca(ax)
grid_agg.plot(column = 'car_id', cmap = 'autumn_r', ax=ax, cax = cax, legend=True)
tbd.plotscale(ax, bounds = bound, textsize = 10, compasssize = 1, accuracy = 2000, rect = [0.6, 0.03], zorder = 10)
plt.axis('off')
plt.xlim(bound[0], bound[2])
plt.ylim(bound[1], bound[3])
plt.show()
建立空間分布散點圖
spatial_distribution_scatter_plot.py
須預先下載的Modules:pip install seaborn

import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib as mpl
import transbigdata as tbd
input_csv = 'merge0509.csv'
input_shp = 'shp\\kuohsiung.shp'
data = pd.read_csv(input_csv, dtype={'car_id': int, '_time': str, 'lon': float, 'lat': float, 'cal_spd': float})
sz = gpd.read_file(input_shp)
sz = sz.to_crs(epsg=4326)
data = data[['lon','lat']].round(3).copy()
data['count'] = 1
data = data.groupby(['lon', 'lat'])['count'].count().reset_index()
data = data.sort_values(by='count')
fig = plt.figure(1, (8, 8), dpi=80)
ax = plt.subplot(111)
plt.sca(ax)
minx, miny, maxx, maxy = sz.total_bounds
bounds = [minx, miny, maxx, maxy]
sz.plot(ax=ax, edgecolor=(0, 0, 0, 0), facecolor=(0, 0, 0, 0.1), linewidths=0.5)
pallete_name = "BuPu"
colors = sns.color_palette(pallete_name, 3)
colors.reverse()
cmap = mpl.colors.LinearSegmentedColormap.from_list(pallete_name, colors)
vmax = data['count'].quantile(0.99)
norm = mpl.colors.Normalize(vmin=0, vmax=vmax)
plt.scatter(data['lon'], data['lat'], s=1, alpha=1, c=data['count'], cmap=cmap, norm=norm)
tbd.plotscale(ax, bounds=bounds, textsize=10, compasssize=1, accuracy=2000, rect=[0.6, 0.03])
plt.axis('off')
plt.xlim(bounds[0], bounds[2])
plt.ylim(bounds[1], bounds[3])
cax = plt.axes([0.15, 0.33, 0.02, 0.3])
plt.colorbar(cax=cax)
plt.title('count')
plt.show()
建立空間分布熱力圖
spatial_distribution_heatmap.py

import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
import transbigdata as tbd
import numpy as np
input_csv = 'merge0509.csv'
input_shp = 'shp\\kuohsiung.shp'
data = pd.read_csv(input_csv, dtype={'car_id': int, '_time': str, 'lon': float, 'lat': float, 'cal_spd': float})
sz = gpd.read_file(input_shp)
sz = sz.to_crs(epsg=4326)
data = data[['lon','lat']].round(3).copy()
data['count'] = 1
data = data.groupby(['lon', 'lat'])['count'].count().reset_index()
data = data.sort_values(by='count')
d = data.pivot(columns = 'lon',index = 'lat',values = 'count').fillna(0)
z = np.log(d.values)
x = d.columns
y = d.index
levels = np.linspace(0, z.max(), 25)
fig = plt.figure(1, (8, 8), dpi=80)
ax = plt.subplot(111)
plt.sca(ax)
fig.tight_layout(rect=(0.05, 0.1, 1, 0.9))
minx, miny, maxx, maxy = sz.total_bounds
bounds = [minx, miny, maxx, maxy]
sz.plot(ax=ax, edgecolor=(0, 0, 0, 0), facecolor=(0, 0, 0, 0.1), linewidths=0.5)
cmap = mpl.colors.LinearSegmentedColormap.from_list('cmap', ['#9DCC42', '#FFFE03', '#F7941D', '#E9420E', '#FF0000'], 256)
plt.contourf(x, y, z, levels=levels, cmap=cmap, origin='lower')
tbd.plotscale(ax, bounds=bounds, textsize=10, compasssize=1, accuracy=2000, rect=[0.6, 0.03])
plt.axis('off')
plt.xlim(bounds[0], bounds[2])
plt.ylim(bounds[1], bounds[3])
cax = plt.axes([0.13, 0.32, 0.02, 0.3])
cbar = plt.colorbar(cax=cax)
val = [1, 10, 100, 1000]
pos = np.log(np.array(val))
cbar.set_ticks(pos)
cbar.set_ticklabels(val)
plt.title('Count')
plt.show()
建立空間核密度
spatial_kernel_density.py

import geopandas as gpd
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import transbigdata as tbd
import seaborn as sns
import numpy as np
input_csv = 'merge0509.csv'
input_shp = 'shp\\kuohsiung.shp'
data = pd.read_csv(input_csv, dtype={'car_id': int, '_time': str, 'lon': float, 'lat': float, 'cal_spd': float})
sz = gpd.read_file(input_shp)
sz = sz.to_crs(epsg=4326)
data = data[['lon','lat']].round(3).copy()
data['count'] = 1
data = data.groupby(['lon', 'lat'])['count'].count().reset_index()
fig = plt.figure(1, (10, 10), dpi=60)
ax = plt.subplot(111)
plt.sca(ax)
fig.tight_layout(rect=(0.05, 0.1, 1, 0.9))
minx, miny, maxx, maxy = sz.total_bounds
bounds = [minx, miny, maxx, maxy]
sz.plot(ax=ax, edgecolor=(0, 0, 0, 0), facecolor=(0, 0, 0, 0.1), linewidths=0.5)
cmap = mpl.colors.LinearSegmentedColormap.from_list('cmap', ['#9DCC42', '#FFFE03', '#F7941D', '#E9420E', '#FF0000'], 256)
plt.axis('off')
plt.xlim(bounds[0], bounds[2])
plt.ylim(bounds[1], bounds[3])
cax = plt.axes([0.13, 0.32, 0.02, 0.3])
sns.kdeplot(x='lon', y='lat',
data=data[data['count'] > 1],
weights='count',
alpha=0.8,
gridsize=120,
bw=0.03,
cmap=cmap,
ax=ax,
shade=True,
shade_lowest=False,
cbar=True,
cbar_ax=cax
)
plt.show()
Seaborn
Seaborn是基於matplotlib的Python視覺化函式庫
-
sns.kdeplot() https://seaborn.pydata.org/generated/seaborn.kdeplot.html
-
來ChatGPT的介紹與作者的補充:)
sns.kdeplot()
是 seaborn 庫中的一個函數,用於繪製單變量或雙變量的核密度估計(Kernel Density Estimation)。核密度估計是一種用來估計概率密度函數的非參數方法,它會通過對數據進行平滑處理來估計數據的分佈情況。
sns.kdeplot()
可以繪製單變量數據的核密度估計曲線,也可以繪製雙變量數據的核密度等值線圖或二維核密度圖。它的用法如下:
主要參數包括:
data
: 要繪製的數據,可以是一維或二維數組。
data2
: 用於繪製雙變量核密度估計的第二組數據(可選)。
shade
: 是否給密度曲線下方區域填充顏色,默認為 False。
vertical
: 是否將密度估計曲線繪製為垂直方向,默認為 False。
kernel
: 用於估計密度的核函數,可選值包括 'gau'(高斯核)、'cos'(餘弦核)、'biw'(雙重三角核)等,默認為 'gau'。
- 即為kernel shape
'biw'
等同GIS的 Quartic
'tri'
等同GIS的 Triangular
'epa'
等同GIS的 Epanechnikov
'uni'
等同GIS的 Uniform
'triw'
等同GIS的 Triweight
bw
: 控制核密度估計帶寬的方法,可選值包括 'scott'、'silverman' 或一個標量,默認為 'scott'。
- 即為Radius, 單位則依輸入的資料而定
- 因這邊輸入的值是經緯度,所以這邊的單位都是度,如需使用公尺等單位,可能須再自行轉換
gridsize
: 用於計算核密度的網格大小,默認為 100。
cut
: 在繪製雙變量核密度估計時,用於裁剪數據的標準差數,默認為 3。
clip
: 用於裁剪核密度估計的範圍。
legend
: 是否顯示圖例,默認為 True。
cumulative
: 是否繪製累積密度圖,默認為 False。
shade_lowest
: 是否給最低密度區域填充顏色,默認為 True。
cbar
: 是否在繪製雙變量核密度圖時繪製顏色條,默認為 False。
cbar_ax
: 顏色條的 Axes 對象。
cbar_kws
: 顏色條的其他參數。
ax
: 繪製圖形的 Axes 對象,如果沒有提供,則使用當前 Axes。
sns.kdeplot()
可以幫助你快速了解數據的分佈情況,並且支持許多參數來定制化你的圖形。