您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么利用Python繪制酷炫的車輛軌跡”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么利用Python繪制酷炫的車輛軌跡”吧!
最近遇到了一類圖,非常好看,并且在其他論文中也多次遇到。比如,在 Trajectory data-based traffic flow studies: A revisit 一文中的圖 1 ,如下圖所示1:
由于原圖較長,這里僅引用了部分圖。從上圖中可以清楚的看出幾個關鍵信息:
橫軸表示時間變化,說明數據需要是時間序列的
縱軸表示空間位置,可以理解為從離開某一道路截面后,車輛行駛的距離
每條軌跡線均表示一輛車的行駛路徑變化,而線條的顏色則表示瞬時速度值
因此,如果想要繪制出上圖,那么就需要有車輛的瞬時軌跡、速度、時間等信息的數據集。
為了嘗試繪制出該圖像,現在需要做兩個工作。第一,找到合適的數據;第二,找到順手的繪圖工具。
對于 NGSIM 數據集,作簡要介紹2:其中包含 4 個路段的車輛軌跡數據,任何一個均是采用在路段的周邊高層建筑上設置高清攝像機錄像,然后通過圖像處理,將每輛車的軌跡變化采集出來,進而可計算出車輛所在的車道、瞬時速度、瞬時加速度、瞬時車頭時距等等。
作為與本次繪圖相關的關鍵信息,我們僅需知道以下數據:
作為演示,僅使用一個車道的數據即可
每輛車從進入攝像區域到離開,中間的瞬時速度信息,NGSIM 中對應的數據標簽是 v_Vel
每輛車從進入攝像區域到離開,中間的位置坐標變化,NGSIM 中對應的數據標簽是 Local_X、Local_Y
與之對應的時刻,NGSIM 中對應的數據標簽是 Global_Time
好了,知道了上述三個關鍵數據后,就可以利用繪圖工具繪制了。
考慮到可重復性、可移植性和方便程度,本次采用 Python 中的 Matplotlib 包來繪制
在開始繪圖之前,需要在 Python 環境中已經配置好以下三個包:
Pandas,本文主要作用在于讀取、處理數據
Numpy,本文主要用于科學計算
Matplotlib,本文主要用于繪圖
毫無疑問,這幾個包是會被用到的,因此,我們先在程序中導入它們:
import pandas as pd import numpy as np import matplotlib import matplotlib.pyplot as plt
然后,我們需要將包含時間、位移、速度的數據導入 Python 中。這里需要注意,按照常規思路,我們只需將這三類數據賦值給不同變量即可,但本次繪制的圖則不能直接這樣做。
因為,從圖 1 中我們可以看出,該圖是有很多軌跡線組成的,也就是說每輛車都是一組數據,并且依賴于時間變化,且存在先后順序。
比如,同一車道內,1 號先進入研究區域,那么它的數據則被記錄;隨后,2 號車進入研究區域,同樣被記錄位置變化、瞬時速度、時間。但是,這里的時間是不同的,是逐漸推移的。
一個思路是同時將所有車輛繪制在:X 軸是時間變化,Y 軸是位置變化的圖像中。但是,這個操作需要將每輛車的數據均準備好,這對于同時繪制 300~400 輛車的軌跡圖是不現實的。
為了解決這個問題,一個可行的思路是:循環繪制每輛車的軌跡隨時間變化。這樣可以只讀取一次數據,然后依據車輛 ID 來循環繪制在同一坐標象限內。由于每輛車存在先后順序,因此無需擔心每輛車之間的軌跡重疊。
于是,這一步我們需要做的是:
讀取基礎數據集,并篩選出需要使用的某車道數據,比如車道 3
需要將該車道中所有的車輛 ID 提取出來,并且是依據時間先后順序排序,也就是根據數據標簽 Global_Time 來排序,這個是全局時間
于是,我們可寫出以下代碼(所有代碼可以左右滑動):
# 讀取數據 data = pd.read_csv(r'F:\NGSIMData.csv') # 提取車道數據 lanedata = data[data.Lane_ID == 3] # 提取車輛編號 x_vehID = lanedata.drop_duplicates(['Vehicle_ID']) # 依據 Global_Time 按照時間先后順序排序 x_vehID = x_vehID.sort_values(by='Global_Time') # 對排序后的車輛 ID 的索引進行重置,方便索引 x_vehID = x_vehID.reset_index(drop = True)
到這里,我們已經將某個車道的數據提取了出來,并且將其中所有的車輛編號也提取出來了,且按照時間先后順序。此時,僅需要按照前文說的:循環繪制每輛車的軌跡即可。在開始之前,我們需要先預設一下圖的大小,以及字體屬性。
# 導入字體屬性相關的包或類 from matplotlib.font_manager import FontProperties # 預設字體類型、大小 font = FontProperties(fname=r"C:\Windows\Fonts\times.TTF", size=10) #設置畫布的尺寸 plt.figure(figsize=(10, 4))
接下來就是循環繪制軌跡圖了。這里有幾個問題需要解釋一下:
既然是循環繪制,自然就是每次繪制的思路完全一致,具體體現在代碼中
對于單次繪圖,僅需通過第一個車輛 ID 索引對應所有的數據,然后將時間、位移、速度分別賦值給 x、y、v
注意,對于時間,NGSIM 給出的是時間戳格式,需要轉換
注意,對于距離和速度,NGSIM 給出的單位是英尺,需要轉換
時間將體現在 X 軸,距離將體現在 Y 軸,速度將體現在軌跡線的顏色上
其中,也有一個棘手的問題。那就是,假設某一車輛進入某車道一段時間后,換道至其他車道,隨后過了一段時間,該車輛又換道至當前車道。這樣就會出現,在時間的前半部分有軌跡線,中間部分沒有軌跡線,后半部分有軌跡線。
對于這種情況,如果我們選擇折線圖繪制,其便會將斷開的部分直接用線段連接起來,這是折線圖的特征。但是,對于這類現象,我們并不期望它們是連接的,也就是沒有軌跡的時間段內,最好是空白的。
為了解決這個問題,我選擇了散點圖。由于 NGSIM 采集數據的頻率是 0.1s,數據點非常密集,也就是說對于連續的軌跡,即便我們用散點圖繪制,出來的效果也是類似于折線的。比如:
注意,右上角是有斷開的區域的,如果是用折線圖繪制,就不會出現這種應該出現的效果。
另一個問題是顏色的處理,也就是需要將每輛車的速度值對應到同一時刻的軌跡點上。而這一點,散點圖中可以將散點的顏色映射給數值,也就是我們需要的,具體就是代碼中的 c=v,但這個命令僅是將速度值映射給顏色。
如果要將某一顏色主題應用于軌跡圖中,那么就需要做兩個工作:
定義顏色主題,也就是散點圖中的命令 cmap='jet_r'
因為后邊我們需要設置顏色條圖例,所以需要將顏色條中的顏色數值與軌跡圖中的顏色歸一化,讓其一一對應。
我們給出這一循環繪制軌跡-速度圖的代碼:
i = 0 while i < (len(x_vehID)-1): # 循環繪制軌跡圖 cardata = lanedata[lanedata.Vehicle_ID == x_vehID[i]] # 將時間賦值給變量 x x = cardata['Global_Time'] # 計算相對移動距離,并賦值給變量 y y = np.sqrt(np.square(cardata['Local_Y']) + np.square(cardata['Local_X']) ) # 將速度賦值給變量 v,同時定義速度為顏色映射 v = cardata['v_Vel'] #設定每個圖的colormap和colorbar所表示范圍是一樣的,即歸一化 norm = matplotlib.colors.Normalize(vmin=0, vmax=25) # 繪制散點圖 ax = plt.scatter(x,y, marker = '.', s=1, c=v, cmap='jet_r', norm = norm) print(i) i = i + 1
其中,我們對 y 值求了平方和的開方,也就是根據車輛的橫縱坐標計算位移。我們還將繪制的散點圖 ax = plt.scatter 賦給了 ax ,方便后邊對散點圖的屬性進行設置。
這里需要注意的是,對于散點的繪制,我們利用循環解決。而對于坐標軸等的設置,只需設置一次,無需循環。到這里,我們可以得到一個不完美的軌跡-速度圖:
不知為何,初步繪制出來的圖的兩側存在大量的空缺,猜測可能是由于我在數據篩選階段出了問題,又或者這些本就沒有數據點。無論怎樣,這樣不影響我們來學習繪制該類圖像。
此時,需要再給上圖加一個顏色條圖例,以表示不同顏色對應的速度數值,這里只需要兩行代碼搞定:
# 添加顏色條 plt.clim(0, 25) plt.colorbar()
即可得到如下所示的圖像,圖中修改了一下顏色主題:
這里需要注意在循環繪圖的代碼內部的一行代碼:
# 設定每個圖的colormap和colorbar所表示范圍是一樣的,即歸一化 norm = matplotlib.colors.Normalize(vmin=0, vmax=25)
該行代碼決定了顏色條圖例中的顏色和左邊軌跡圖中的顏色是一致的,也就是必須按照顏色條設定的色階來繪制軌跡和呈現色彩。
如果沒有該行代碼,就算添加了顏色條的代碼,繪制出來的顏色條和左邊的軌跡圖也不對應,大家可以試試看~
這個操作就比較常規了,根據自己需要添加即可,常規的代碼隨便網上搜一個就有,包括刻度值得設置等等。
這一步僅重點說明一點:就是 X 軸繪制時利用的是時間戳數據,由于數值太密集,所以圖中我關掉了 X 軸的刻度值。如果想要顯示如圖 1 所示的時間格式,一個可行的辦法是向圖像中添加文字。
也就是說,手動將時間放置在想要防止的刻度下,我們先看一組代碼:
# 設置 X 坐標軸刻度 plt.text(x, y, '8:05', fontproperties=font2) plt.text(x, y, '8:10', fontproperties=font2) plt.text(x, y, '8:15', fontproperties=font2) plt.text(x, y, '8:20', fontproperties=font2)
通過這組代碼,我們便可以將制定的時間放置在圖中指定的位置,基于坐標(x,y)。
最后,附上一個個人認為比較完美的圖像,供大家參考:
將坐標軸設置為漢字,是因為漢字與英文同時出現時比較難處理,大家可以嘗試調一下。
到此,相信大家對“怎么利用Python繪制酷炫的車輛軌跡”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。