python画画用哪库好_数据可视化哪款工具更好用?对比7款Python 数据图表工具的性能...
更多騰訊海量技術(shù)文章,請關(guān)注云加社區(qū):https://cloud.tencent.com/developer/column
作者:CDA數(shù)據(jù)分析師
摘要:Python 的科學(xué)棧相當(dāng)成熟,各種應(yīng)用場景都有相關(guān)的模塊,包括機(jī)器學(xué)習(xí)和數(shù)據(jù)分析。數(shù)據(jù)可視化是發(fā)現(xiàn)數(shù)據(jù)和展示結(jié)果的重要一環(huán)。
本文會(huì)基于一份真實(shí)的數(shù)據(jù),對比7款數(shù)據(jù)可視化庫matplotlib、vispy、bokeh、 seaborn、pyga, foliumnetworkx,通過這些對比,我們期望了解每個(gè)庫所適用的范圍,以及如何更好的利用整個(gè) Python 的數(shù)據(jù)可視化的生態(tài)系統(tǒng)。
Python 的科學(xué)棧相當(dāng)成熟,各種應(yīng)用場景都有相關(guān)的模塊,包括機(jī)器學(xué)習(xí)和數(shù)據(jù)分析。數(shù)據(jù)可視化是發(fā)現(xiàn)數(shù)據(jù)和展示結(jié)果的重要一環(huán),只不過過去以來,相對于 R 這樣的工具,發(fā)展還是落后一些。
幸運(yùn)的是,過去幾年出現(xiàn)了很多新的Python數(shù)據(jù)可視化庫,彌補(bǔ)了一些這方面的差距。matplotlib 已經(jīng)成為事實(shí)上的數(shù)據(jù)可視化方面最主要的庫,此外還有很多其他庫,例如vispy,bokeh, seaborn, pyga, folium 和 networkx,這些庫有些是構(gòu)建在 matplotlib 之上,還有些有其他一些功能。
本文會(huì)基于一份真實(shí)的數(shù)據(jù),使用這些庫來對數(shù)據(jù)進(jìn)行可視化。通過這些對比,我們期望了解每個(gè)庫所適用的范圍,以及如何更好的利用整個(gè) Python 的數(shù)據(jù)可視化的生態(tài)系統(tǒng)。
探索數(shù)據(jù)集
在我們探討數(shù)據(jù)的可視化之前,讓我們先來快速的瀏覽一下我們將要處理的數(shù)據(jù)集。我們將要使用的數(shù)據(jù)來自 openflights。我們將要使用航線數(shù)據(jù)集、機(jī)場數(shù)據(jù)集、航空公司數(shù)據(jù)集。其中,路徑數(shù)據(jù)的每一行對應(yīng)的是兩個(gè)機(jī)場之間的飛行路徑;機(jī)場數(shù)據(jù)的每一行對應(yīng)的是世界上的某一個(gè)機(jī)場,并且給出了相關(guān)信息;航空公司的數(shù)據(jù)的每一行給出的是每一個(gè)航空公司。
首先我們先讀取數(shù)據(jù):
這些數(shù)據(jù)沒有列的首選項(xiàng),因此我們通過賦值 column 屬性來添加列的首選項(xiàng)。我們想要將每一列作為字符串進(jìn)行讀取,因?yàn)檫@樣做可以簡化后續(xù)以行 id 為匹配,對不同的數(shù)據(jù)框架進(jìn)行比較的步驟。我們在讀取數(shù)據(jù)時(shí)設(shè)置了 dtype 屬性值達(dá)到這一目的。
我們可以快速瀏覽一下每一個(gè)數(shù)據(jù)集的數(shù)據(jù)框架。
我們可以分別對每一個(gè)單獨(dú)的數(shù)據(jù)集做許多不同有趣的探索,但是只要將它們結(jié)合起來分析才能取得最大的收獲。Pandas 將會(huì)幫助我們分析數(shù)據(jù),因?yàn)樗軌蛴行У倪^濾權(quán)值或者通過它來應(yīng)用一些函數(shù)。我們將會(huì)深入幾個(gè)有趣的權(quán)值因子,比如分析航空公司和航線。
那么在此之前我們需要做一些數(shù)據(jù)清洗的工作。
這一行命令就確保了我們在 airline_id 這一列只含有數(shù)值型數(shù)據(jù)。
制作柱狀圖
現(xiàn)在我們理解了數(shù)據(jù)的結(jié)構(gòu),我們可以進(jìn)一步地開始描點(diǎn)來繼續(xù)探索這個(gè)問題。首先,我們將要使用 matplotlib 這個(gè)工具,matplotlib 是一個(gè)相對底層的 Python 棧中的描點(diǎn)庫,所以它比其他的工具庫要多敲一些命令來做出一個(gè)好看的曲線。另外一方面,你可以使用 matplotlib 幾乎做出任何的曲線,這是因?yàn)樗值撵`活,而靈活的代價(jià)就是非常難于使用。
我們首先通過做出一個(gè)柱狀圖來顯示不同的航空公司的航線長度分布。一個(gè)柱狀圖將所有的航線的長度分割到不同的值域,然后對落入到不同的值域范圍內(nèi)的航線進(jìn)行計(jì)數(shù)。從中我們可以知道哪些航空公司的航線長,哪些航空公司的航線短。
為了達(dá)到這一點(diǎn),我們需要首先計(jì)算一下航線的長度,第一步就要使用距離公式,我們將會(huì)使用余弦半正矢距離公式來計(jì)算經(jīng)緯度刻畫的兩個(gè)點(diǎn)之間的距離。
然后我們就可以使用一個(gè)函數(shù)來計(jì)算起點(diǎn)機(jī)場和終點(diǎn)機(jī)場之間的單程距離。我們需要從路線數(shù)據(jù)框架得到機(jī)場數(shù)據(jù)框架所對應(yīng)的 source_id 和 dest_id,然后與機(jī)場的數(shù)據(jù)集的 id 列相匹配,然后就只要計(jì)算就行了,這個(gè)函數(shù)是這樣的:
如果 source_id 和 dest_id 列沒有有效值的話,那么這個(gè)函數(shù)會(huì)報(bào)錯(cuò)。因此我們需要增加 try/catch 模塊對這種無效的情況進(jìn)行捕捉。
最后,我們將要使用 pandas 來將距離計(jì)算的函數(shù)運(yùn)用到 routes 數(shù)據(jù)框架。這將會(huì)使我們得到包含所有的航線線長度的 pandas 序列,其中航線線的長度都是以公里做單位。
現(xiàn)在我們就有了航線距離的序列了,我們將會(huì)創(chuàng)建一個(gè)柱狀圖,它將會(huì)將數(shù)據(jù)歸類到對應(yīng)的范圍之內(nèi),然后計(jì)數(shù)分別有多少的航線落入到不同的每個(gè)范圍:
我們用 import matplotlib.pyplot as plt 導(dǎo)入 matplotlib 描點(diǎn)函數(shù)。然后我們就使用 %matplotlib inline 來設(shè)置 matplotlib 在 ipython 的 notebook 中描點(diǎn),最終我們就利用 plt.hist(route_lengths, bins=20) 得到了一個(gè)柱狀圖。正如我們看到的,航空公司傾向于運(yùn)行近距離的短程航線,而不是遠(yuǎn)距離的遠(yuǎn)程航線。
使用 seaborn
我們可以利用 seaborn 來做類似的描點(diǎn),seaborn 是一個(gè) Python 的高級庫。Seaborn 建立在 matplotlib 的基礎(chǔ)之上,做一些類型的描點(diǎn),這些工作常常與簡單的統(tǒng)計(jì)工作有關(guān)。我們可以基于一個(gè)核心的概率密度的期望,使用 distplot 函數(shù)來描繪一個(gè)柱狀圖。一個(gè)核心的密度期望是一個(gè)曲線 —— 本質(zhì)上是一個(gè)比柱狀圖平滑一點(diǎn)的,更容易看出其中的規(guī)律的曲線。
正如你所看到的那樣,seaborn 同時(shí)有著更加好看的默認(rèn)風(fēng)格。seaborn 不含有與每個(gè) matplotlib 的版本相對應(yīng)的版本,但是它的確是一個(gè)很好的快速描點(diǎn)工具,而且相比于 matplotlib 的默認(rèn)圖表可以更好的幫助我們理解數(shù)據(jù)背后的含義。如果你想更深入的做一些統(tǒng)計(jì)方面的工作的話,seaborn 也不失為一個(gè)很好的庫。
條形圖
柱狀圖也雖然很好,但是有時(shí)候我們會(huì)需要航空公司的平均路線長度。這時(shí)候我們可以使用條形圖--每條航線都會(huì)有一個(gè)單獨(dú)的狀態(tài)條,顯示航空公司航線的平均長度。從中我們可以看出哪家是國內(nèi)航空公司哪家是國際航空公司。我們可以使用pandas,一個(gè)python的數(shù)據(jù)分析庫,來酸楚每個(gè)航空公司的平均航線長度。
我們首先用航線長度和航空公司的id來搭建一個(gè)新的數(shù)據(jù)框架。我們基于airline_id把route_length_df拆分成組,為每個(gè)航空公司建立一個(gè)大體的數(shù)據(jù)框架。然后我們調(diào)用pandas的aggregate函數(shù)來獲取航空公司數(shù)據(jù)框架中長度列的均值,然后把每個(gè)獲取到的值重組到一個(gè)新的數(shù)據(jù)模型里。之后把數(shù)據(jù)模型進(jìn)行排序,這樣就使得擁有最多航線的航空公司拍到了前面。
這樣就可以使用matplotlib把結(jié)果畫出來。
Matplotlib的plt.bar方法根據(jù)每個(gè)數(shù)據(jù)模型的航空公司平均航線長度(airline_route_lengths["length"])來做圖。
問題是我們想看出哪家航空公司擁有的航線長度是什么并不容易。為了解決這個(gè)問題,我們需要能夠看到坐標(biāo)軸標(biāo)簽。這有點(diǎn)難,畢竟有這么多的航空公司。一個(gè)能使問題變得簡單的方法是使圖表具有交互性,這樣能實(shí)現(xiàn)放大跟縮小來查看軸標(biāo)簽。我們可以使用bokeh庫來實(shí)現(xiàn)這個(gè)--它能便捷的實(shí)現(xiàn)交互性,作出可縮放的圖表。
要使用booked,我們需要先對數(shù)據(jù)進(jìn)行預(yù)處理:
上面的代碼會(huì)獲取airline_route_lengths中每列的名字,然后添加到name列上,這里存貯著每個(gè)航空公司的名字。我們也添加到id列上以實(shí)現(xiàn)查找(apply函數(shù)不傳index)。
最后,我們重置索引序列以得到所有的特殊值。沒有這一步,Bokeh 無法正常運(yùn)行。
現(xiàn)在,我們可以繼續(xù)說圖表問題:
用 output_notebook 創(chuàng)建背景虛化,在 iPython 的 notebook 里畫出圖。然后,使用數(shù)據(jù)幀和特定序列制作條形圖。最后,顯示功能會(huì)顯示出該圖。
這個(gè)圖實(shí)際上不是一個(gè)圖像--它是一個(gè) JavaScript 插件。因此,我們在下面展示的是一幅屏幕截圖,而不是真實(shí)的表格。
有了它,我們可以放大,看哪一趟航班的飛行路線最長。上面的圖像讓這些表格看起來擠在了一起,但放大以后,看起來就方便多了。
水平條形圖
Pygal 是一個(gè)能快速制作出有吸引力表格的數(shù)據(jù)分析庫。我們可以用它來按長度分解路由。首先把我們的路由分成短、中、長三個(gè)距離,并在 route_lengths 里計(jì)算出它們各占的百分比。
然后我們可以在 Pygal 的水平條形圖里把每一個(gè)都繪成條形圖:
首先,我們創(chuàng)建一個(gè)空圖。然后,我們添加元素,包括標(biāo)題和條形圖。每個(gè)條形圖通過百分比值(最大值是100)顯示出該類路由的使用頻率。
最后,我們把圖表渲染成文件,用 IPython 的 SVG 功能載入并展示文件。這個(gè)圖看上去比默認(rèn)的 matplotlib 圖好多了。但是為了制作出這個(gè)圖,我們要寫的代碼也多很多。因此,Pygal 可能比較適用于制作小型的展示用圖表。
散點(diǎn)圖
在散點(diǎn)圖里,我們能夠縱向比較數(shù)據(jù)。我們可以做一個(gè)簡單的散點(diǎn)圖來比較航空公司的 id 號和航空公司名稱的長度:
首先,我們使用 pandasapplymethod 計(jì)算每個(gè)名稱的長度。它將找到每個(gè)航空公司的名字字符的數(shù)量。然后,我們使用 matplotlib 做一個(gè)散點(diǎn)圖來比較航空 id 的長度。當(dāng)我們繪制時(shí),我們把 theidcolumn of airlines 轉(zhuǎn)換為整數(shù)類型。如果我們不這樣做是行不通的,因?yàn)樗枰?x 軸上的數(shù)值。我們可以看到不少的長名字都出現(xiàn)在早先的 id 中。這可能意味著航空公司在成立前往往有較長的名字。
我們可以使用 seaborn 驗(yàn)證這個(gè)直覺。Seaborn 增強(qiáng)版的散點(diǎn)圖,一個(gè)聯(lián)合的點(diǎn),它顯示了兩個(gè)變量是相關(guān)的,并有著類似地分布。
上面的圖表明,兩個(gè)變量之間的相關(guān)性是不明確的——r 的平方值是低的。
靜態(tài) maps
我們的數(shù)據(jù)天然的適合繪圖-機(jī)場有經(jīng)度和緯度對,對于出發(fā)和目的機(jī)場來說也是。
第一張圖做的是顯示全世界的所有機(jī)場。可以用擴(kuò)展于 matplotlib 的 basemap 來做這個(gè)。這允許畫世界地圖和添加點(diǎn),而且很容易定制。
在上面的代碼中,首先用 mercator projection 畫一個(gè)世界地圖。墨卡托投影是將整個(gè)世界的繪圖投射到二位曲面。然后,在地圖上用紅點(diǎn)點(diǎn)畫機(jī)場。
上面地圖的問題是找到每個(gè)機(jī)場在哪是困難的-他們就是在機(jī)場密度高的區(qū)域合并城一團(tuán)紅色斑點(diǎn)。
就像聚焦不清楚,有個(gè)交互制圖的庫,folium,可以進(jìn)行放大地圖來幫助我們找到個(gè)別的機(jī)場。
Folium 使用 leaflet.js 來制作全交互式地圖。你可以點(diǎn)擊每一個(gè)機(jī)場在彈出框中看名字。在上邊顯示一個(gè)截屏,但是實(shí)際的地圖更令人印象深刻。Folium 也允許非常廣闊的修改選項(xiàng)來做更好的標(biāo)注,或者添加更多的東西到地圖上。
畫弧線
在地圖上看到所有的航空路線是很酷的,幸運(yùn)的是,我們可以使用 basemap 來做這件事。我們將畫弧線連接所有的機(jī)場出發(fā)地和目的地。每個(gè)弧線想展示一個(gè)段都航線的路徑。不幸的是,展示所有的線路又有太多的路由,這將會(huì)是一團(tuán)糟。替代,我們只現(xiàn)實(shí)前 3000 個(gè)路由。
上面的代碼將會(huì)畫一個(gè)地圖,然后再在地圖上畫線路。我們添加一了寫過濾器來阻止過長的干擾其他路由的長路由。
畫網(wǎng)絡(luò)圖
我們將做的最終的探索是畫一個(gè)機(jī)場網(wǎng)絡(luò)圖。每個(gè)機(jī)場將會(huì)是網(wǎng)絡(luò)中的一個(gè)節(jié)點(diǎn),并且如果兩點(diǎn)之間有路由將劃出節(jié)點(diǎn)之間的連線。如果有多重路由,將添加線的權(quán)重,以顯示機(jī)場連接的更多。將使用 networkx 庫來做這個(gè)功能。
首先,計(jì)算機(jī)場之間連線的權(quán)重。
一旦上面的代碼運(yùn)行,這個(gè)權(quán)重字典就包含了每兩個(gè)機(jī)場之間權(quán)重大于或等于 2 的連線。所以任何機(jī)場有兩個(gè)或者更多連接的路由將會(huì)顯示出來。
總結(jié)
有一個(gè)成長的數(shù)據(jù)可視化的 Python 庫,它可能會(huì)制作任意一種可視化。大多數(shù)庫基于 matplotlib 構(gòu)建的并且確保一些用例更簡單。
總結(jié)
以上是生活随笔為你收集整理的python画画用哪库好_数据可视化哪款工具更好用?对比7款Python 数据图表工具的性能...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 内核 82540网卡,Lin
- 下一篇: matlab 发送 126 邮件,pyt