首頁 後端開發 Python教學 如何使用Python的視覺化工具

如何使用Python的視覺化工具

May 08, 2023 pm 10:19 PM
python

探索資料集

在我們探討資料的視覺化之前,讓我們先來快速的瀏覽一下我們將要處理的資料集。我們將要使用的數據來自  openlights。我們將要使用航線資料集、機場資料集、航空公司資料集。其中,路徑資料的每一行對應的是兩個機場之間的飛行路徑;機場資料的每一行對應的是世界上的某一個機場,並且給出了相關資訊;航空公司的資料的每一行給出的是每一個航空公司。

首先我們先讀取資料:

# Import the pandas library. import pandas # Read in the airports data. airports = pandas.read_csv("airports.csv", header=None, dtype=str) airports.columns = ["id", "name", "city", "country", "code", "icao", "latitude", "longitude", "altitude", "offset", "dst", "timezone"] # Read in the airlines data. airlines = pandas.read_csv("airlines.csv", header=None, dtype=str) airlines.columns = ["id", "name", "alias", "iata", "icao", "callsign", "country", "active"] # Read in the routes data. routes = pandas.read_csv("routes.csv", header=None, dtype=str) routes.columns = ["airline", "airline_id", "source", "source_id", "dest", "dest_id", "codeshare", "stops", "equipment"]
登入後複製

這些資料沒有列的***項,因此我們透過賦值column 屬性來新增列的***項。我們想要將每一列作為字串進行讀取,因為這樣做可以簡化後續以行 id 為匹配,對不同的資料框架進行比較的步驟。我們在讀取資料時設定了 dtype 屬性值達到此目的。

那麼在此之前我們需要做一些資料清洗的工作。

routes = routes[routes["airline_id"] != "//N"]

這一行指令就確保了我們在 airline_id 這一列只含有數值型資料。

製作長條圖

現在我們理解了資料的結構,我們可以進一步地開始描點來繼續探索這個問題。首先,我們將要使用 matplotlib  這個工具,matplotlib 是一個相對底層的 Python  堆疊中的描點函式庫,所以它比其他的工具庫要多敲一些指令來做出一個好看的曲線。另外一方面,你可以使用 matplotlib  幾乎做出任何的曲線,這是因為它十分的靈活,而靈活的代價就是非常難於使用。

我們首先透過做出一個長條圖來顯示不同的航空公司的航線長度分佈。一個長條圖將所有的航線的長度分割到不同的值域,然後對落入不同的值域範圍內的航線進行計數。從中我們可以知道哪些航空公司的航線長,哪些航空公司的航線短。

為了達到這一點,我們需要先計算航線的長度,***步就要使用距離公式,我們將會使用餘弦半正矢距離公式來計算經緯度刻畫的兩個點之間的距離。

import math def haversine(lon1, lat1, lon2, lat2):     # Convert coordinates to floats.     lon1, lat1, lon2, lat2 = [float(lon1), float(lat1), float(lon2), float(lat2)]     # Convert to radians from degrees.     lon1, lat1, lon2, lat2 = map(math.radians, [lon1, lat1, lon2, lat2])     # Compute distance.     dlon = lon2 - lon1      dlat = lat2 - lat1      a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2     c = 2 * math.asin(math.sqrt(a))      km = 6367 * c     return km
登入後複製

然後我們就可以使用一個函數來計算起點機場和終點機場之間的單程距離。我們需要從路線資料框架得到機場資料框架所對應的source_id 和dest_id,然後與機場的資料集的id 列相匹配,然後就只要計算就行了,這個函數是這樣的:

def calc_dist(row):     dist = 0     try:         # Match source and destination to get coordinates.         source = airports[airports["id"] == row["source_id"]].iloc[0]         dest = airports[airports["id"] == row["dest_id"]].iloc[0]         # Use coordinates to compute distance.         dist = haversine(dest["longitude"], dest["latitude"], source["longitude"], source["latitude"])     except (ValueError, IndexError):         pass     return dist
登入後複製

如果source_id 和dest_id 欄位沒有有效值的話,那麼這個函數會報錯。因此我們需要增加 try/catch 模組對這種無效的情況進行捕捉。

***,我們將要使用 pandas 來將距離計算的函數運用到 routes 資料框架。這將會使我們得到包含所有的航線長度的 pandas 序列,其中航線線的長度都是以公里做單位。

route_lengths = routes.apply(calc_dist, axis=1)

現在我們就有了航線距離的序列了,我們將會建立一個長條圖,它將將資料歸類到對應的範圍之內,然後計數分別有多少的航線落入到不同的每個範圍:

import matplotlib.pyplot as plt  %matplotlib inline   plt.hist(route_lengths, bins=20)
登入後複製

我們用import matplotlib.pyplot as plt 導入matplotlib 描點函數。然後我們就使用  %matplotlib inline 來設定 matplotlib 在 ipython 的 notebook 中描點,最後我們就利用  plt.hist(route_lengths, bins=20)  得到了一個長條圖。正如我們所看到的,航空公司傾向於運行近距離的短程航線,而不是遠距離的遠程航線。

使用 seaborn

我們可以用 seaborn 來做類似的描點,seaborn 是一個 Python 的高階函式庫。 Seaborn 建立在 matplotlib  的基礎上,做一些類型的描點,這些工作常常與簡單的統計工作有關。我們可以基於一個核心的機率密度的期望,使用 distplot  函數來描繪一個長條圖。一個核心的密度期望是一個曲線 —— 本質上是一個比柱狀圖平滑一點的,更容易看出其中的規律的曲線。

import seaborn  seaborn.distplot(route_lengths, bins=20)
登入後複製

seaborn 同時有著更加好看的預設風格。 seaborn 不含有與每個 matplotlib  的版本相對應的版本,但是它的確是一個很好的快速描點工具,而且相比於 matplotlib  的預設圖表可以更好的幫助我們理解數據背後的含義。如果你想更深入的做一些統計方面的工作的話,seaborn 也不失為一個很好的庫。

長條圖

柱状图也虽然很好,但是有时候我们会需要航空公司的平均路线长度。这时候我们可以使用条形图--每条航线都会有一个单独的状态条,显示航空公司航线 的平均长度。从中我们可以看出哪家是国内航空公司哪家是国际航空公司。我们可以使用pandas,一个python的数据分析库,来酸楚每个航空公司的平 均航线长度。

import numpy # Put relevant columns into a dataframe. route_length_df = pandas.DataFrame({"length": route_lengths, "id": routes["airline_id"]}) # Compute the mean route length per airline. airline_route_lengths = route_length_df.groupby("id").aggregate(numpy.mean) # Sort by length so we can make a better chart. airline_route_lengths = airline_route_lengths.sort("length", ascending=False)
登入後複製

我们首先用航线长度和航空公司的id来搭建一个新的数据框架。我们基于airline_id把route_length_df拆分成组,为每个航空 公司建立一个大体的数据框架。然后我们调用pandas的aggregate函数来获取航空公司数据框架中长度列的均值,然后把每个获取到的值重组到一个 新的数据模型里。之后把数据模型进行排序,这样就使得拥有最多航线的航空公司拍到了前面。

这样就可以使用matplotlib把结果画出来。

plt.bar(range(airline_route_lengths.shape[0]), airline_route_lengths["length"])

Matplotlib的plt.bar方法根据每个数据模型的航空公司平均航线长度(airline_route_lengths["length"])来做图。

问题是我们想看出哪家航空公司拥有的航线长度是什么并不容易。为了解决这个问题,我们需要能够看到坐标轴标签。这有点难,毕竟有这么多的航空公司。 一个能使问题变得简单的方法是使图表具有交互性,这样能实现放大跟缩小来查看轴标签。我们可以使用bokeh库来实现这个--它能便捷的实现交互性,作出 可缩放的图表。

要使用booked,我们需要先对数据进行预处理:

def lookup_name(row):     try:         # Match the row id to the id in the airlines dataframe so we can get the name.         name = airlines["name"][airlines["id"] == row["id"]].iloc[0]     except (ValueError, IndexError):         name = ""     return name # Add the index (the airline ids) as a column. airline_route_lengths["id"] = airline_route_lengths.index.copy() # Find all the airline names. airline_route_lengths["name"] = airline_route_lengths.apply(lookup_name, axis=1) # Remove duplicate values in the index. airline_route_lengths.index = range(airline_route_lengths.shape[0])
登入後複製

上面的代码会获取airline_route_lengths中每列的名字,然后添加到name列上,这里存贮着每个航空公司的名字。我们也添加到id列上以实现查找(apply函数不传index)。

***,我们重置索引序列以得到所有的特殊值。没有这一步,Bokeh 无法正常运行。

现在,我们可以继续说图表问题:

import numpy as np from bokeh.io import output_notebook from bokeh.charts import Bar, show output_notebook() p = Bar(airline_route_lengths, 'name', values='length', title="Average airline route lengths") show(p)
登入後複製

用 output_notebook 创建背景虚化,在 iPython 的 notebook 里画出图。然后,使用数据帧和特定序列制作条形图。***,显示功能会显示出该图。

这个图实际上不是一个图像--它是一个 JavaScript 插件。因此,我们在下面展示的是一幅屏幕截图,而不是真实的表格。

有了它,我们可以放大,看哪一趟航班的飞行路线最长。上面的图像让这些表格看起来挤在了一起,但放大以后,看起来就方便多了。

水平条形图

Pygal 是一个能快速制作出有吸引力表格的数据分析库。我们可以用它来按长度分解路由。首先把我们的路由分成短、中、长三个距离,并在 route_lengths 里计算出它们各占的百分比。

long_routes = len([k for k in route_lengths if k > 10000]) / len(route_lengths) medium_routes = len([k for k in route_lengths if k < 10000 and k > 2000]) / len(route_lengths) short_routes = len([k for k in route_lengths if k < 2000]) / len(route_lengths)
登入後複製

然后我们可以在 Pygal 的水平条形图里把每一个都绘成条形图:

import pygal from IPython.display import SVG chart = pygal.HorizontalBar() chart.title = 'Long, medium, and short routes' chart.add('Long', long_routes * 100) chart.add('Medium', medium_routes * 100) chart.add('Short', short_routes * 100) chart.render_to_file('routes.svg') SVG(filename='routes.svg')
登入後複製

首先,我们使用 pandasapplymethod 计算每个名称的长度。它将找到每个航空公司的名字字符的数量。然后,我们使用  matplotlib 做一个散点图来比较航空 id 的长度。当我们绘制时,我们把 theidcolumn of airlines  转换为整数类型。如果我们不这样做是行不通的,因为它需要在 x 轴上的数值。我们可以看到不少的长名字都出现在早先的 id  中。这可能意味着航空公司在成立前往往有较长的名字。

我们可以使用 seaborn 验证这个直觉。Seaborn 增强版的散点图,一个联合的点,它显示了两个变量是相关的,并有着类似地分布。

data = pandas.DataFrame({"lengths": name_lengths, "ids": airlines["id"].astype(int)})
seaborn.jointplot(x="ids", y="lengths", data=data)

画弧线

在地图上看到所有的航空路线是很酷的,幸运的是,我们可以使用 basemap  来做这件事。我们将画弧线连接所有的机场出发地和目的地。每个弧线想展示一个段都航线的路径。不幸的是,展示所有的线路又有太多的路由,这将会是一团糟。 替代,我们只现实前 3000 个路由。

# Make a base map with a mercator projection.  Draw the coastlines. m = Basemap(projection='merc',llcrnrlat=-80,urcrnrlat=80,llcrnrlon=-180,urcrnrlon=180,lat_ts=20,resolution='c') m.drawcoastlines() # Iterate through the first 3000 rows. for name, row in routes[:3000].iterrows():     try:         # Get the source and dest airports.         source = airports[airports["id"] == row["source_id"]].iloc[0]         dest = airports[airports["id"] == row["dest_id"]].iloc[0]         # Don't draw overly long routes.         if abs(float(source["longitude"]) - float(dest["longitude"])) < 90:             # Draw a great circle between source and dest airports.             m.drawgreatcircle(float(source["longitude"]), float(source["latitude"]), float(dest["longitude"]), float(dest["latitude"]),linewidth=1,color='b')     except (ValueError, IndexError):         pass  # Show the map. plt.show()
登入後複製

我们将做的最终的探索是画一个机场网络图。每个机场将会是网络中的一个节点,并且如果两点之间有路由将划出节点之间的连线。如果有多重路由,将添加线的权重,以显示机场连接的更多。将使用 networkx 库来做这个功能。

首先,计算机场之间连线的权重。

# Initialize the weights dictionary. weights = {} # Keep track of keys that have been added once -- we only want edges with a weight of more than 1 to keep our network size manageable. added_keys = [] # Iterate through each route. for name, row in routes.iterrows():     # Extract the source and dest airport ids.     source = row["source_id"]     dest = row["dest_id"]      # Create a key for the weights dictionary.     # This corresponds to one edge, and has the start and end of the route.     key = "{0}_{1}".format(source, dest)     # If the key is already in weights, increment the weight.     if key in weights:         weights[key] += 1     # If the key is in added keys, initialize the key in the weights dictionary, with a weight of 2.     elif key in added_keys:         weights[key] = 2     # If the key isn't in added_keys yet, append it.     # This ensures that we aren't adding edges with a weight of 1.     else:         added_keys.append(key)
登入後複製

一旦上面的代码运行,这个权重字典就包含了每两个机场之间权重大于或等于 2 的连线。所以任何机场有两个或者更多连接的路由将会显示出来。

# Import networkx and initialize the graph. import networkx as nx graph = nx.Graph() # Keep track of added nodes in this set so we don't add twice. nodes = set() # Iterate through each edge. for k, weight in weights.items():     try:         # Split the source and dest ids and convert to integers.         source, dest = k.split("_")         source, dest = [int(source), int(dest)]         # Add the source if it isn't in the nodes.         if source not in nodes:             graph.add_node(source)         # Add the dest if it isn't in the nodes.         if dest not in nodes:             graph.add_node(dest)         # Add both source and dest to the nodes set.         # Sets don't allow duplicates.         nodes.add(source)         nodes.add(dest)          # Add the edge to the graph.         graph.add_edge(source, dest, weight=weight)     except (ValueError, IndexError):         pass pos=nx.spring_layout(graph) # Draw the nodes and edges. nx.draw_networkx_nodes(graph,pos, node_color='red', node_size=10, alpha=0.8) nx.draw_networkx_edges(graph,pos,width=1.0,alpha=1) # Show the plot. plt.show()
登入後複製

以上是如何使用Python的視覺化工具的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

vs code 可以在 Windows 8 中運行嗎 vs code 可以在 Windows 8 中運行嗎 Apr 15, 2025 pm 07:24 PM

VS Code可以在Windows 8上運行,但體驗可能不佳。首先確保系統已更新到最新補丁,然後下載與系統架構匹配的VS Code安裝包,按照提示安裝。安裝後,注意某些擴展程序可能與Windows 8不兼容,需要尋找替代擴展或在虛擬機中使用更新的Windows系統。安裝必要的擴展,檢查是否正常工作。儘管VS Code在Windows 8上可行,但建議升級到更新的Windows系統以獲得更好的開發體驗和安全保障。

visual studio code 可以用於 python 嗎 visual studio code 可以用於 python 嗎 Apr 15, 2025 pm 08:18 PM

VS Code 可用於編寫 Python,並提供許多功能,使其成為開發 Python 應用程序的理想工具。它允許用戶:安裝 Python 擴展,以獲得代碼補全、語法高亮和調試等功能。使用調試器逐步跟踪代碼,查找和修復錯誤。集成 Git,進行版本控制。使用代碼格式化工具,保持代碼一致性。使用 Linting 工具,提前發現潛在問題。

notepad 怎麼運行python notepad 怎麼運行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。

vscode 擴展是否是惡意的 vscode 擴展是否是惡意的 Apr 15, 2025 pm 07:57 PM

VS Code 擴展存在惡意風險,例如隱藏惡意代碼、利用漏洞、偽裝成合法擴展。識別惡意擴展的方法包括:檢查發布者、閱讀評論、檢查代碼、謹慎安裝。安全措施還包括:安全意識、良好習慣、定期更新和殺毒軟件。

See all articles