Python의 시각화 도구를 사용하는 방법

WBOY
풀어 주다: 2023-05-08 22:19:06
앞으로
1192명이 탐색했습니다.

데이터세트 탐색

데이터 시각화에 대해 논의하기 전에 작업할 데이터세트를 간단히 살펴보겠습니다. 우리가 사용할 데이터는 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"]
로그인 후 복사

이 데이터에는 열의 첫 번째 항목이 없으므로 열 속성을 할당하여 열의 첫 번째 항목을 추가합니다. 각 열을 문자열로 읽으려고 합니다. 그렇게 하면 행 ID를 일치 항목으로 사용하여 다양한 데이터 프레임을 비교하는 후속 단계가 단순화되기 때문입니다. 데이터를 읽을 때 dtype 속성 값을 설정하여 이를 달성합니다.

그래서 그 전에 데이터 정리 작업을 해야 합니다.

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

이 명령줄은 Airlines_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 열과 일치시켜야 합니다. 그런 다음 이 함수는 다음과 같습니다. source_id 및 dest_id 열에 유효한 값이 없으면 이 함수는 오류를 보고합니다. 따라서 이러한 잘못된 상황을 포착하려면 try/catch 모듈을 추가해야 합니다.

***, 우리는 경로 데이터 프레임에 거리 계산 기능을 적용하기 위해 팬더를 사용할 것입니다. 그러면 모든 경로 길이를 킬로미터 단위로 포함하는 팬더 시퀀스가 ​​제공됩니다.

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

이제 경로 거리 순서가 있으므로 데이터를 해당 범위로 분류하는 히스토그램을 만든 다음 각 경로에 속하는 경로 수를 계산합니다. 다른 범위:

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
로그인 후 복사

matplotlib 플롯 기능을 가져오기 위해 import matplotlib.pyplot을 plt로 사용합니다. 그런 다음 %matplotlib 인라인을 사용하여 ipython 노트북에 점을 그리도록 matplotlib를 설정했습니다. 마지막으로 plt.hist(route_lengths, bins=20)를 사용하여 히스토그램을 얻었습니다. 앞서 살펴보았듯이 항공사들은 멀리 떨어져 있는 장거리 노선보다는 서로 가까이 있는 단거리 노선을 운항하는 경향이 있습니다.

seaborn 사용하기

seaborn을 사용하여 비슷한 지점 추적을 수행할 수 있습니다. seaborn은 Python용 고급 라이브러리입니다. Seaborn은 matplotlib를 기반으로 구축되었으며 간단한 통계 작업과 관련된 몇 가지 유형의 플로팅을 수행합니다. distplot 함수를 사용하여 핵심 확률 밀도 기대치를 기반으로 히스토그램을 그릴 수 있습니다. 핵심 밀도 기대치는 곡선입니다. 기본적으로 히스토그램보다 부드럽고 규칙을 확인하기 쉬운 곡선입니다.

import matplotlib.pyplot as plt  %matplotlib inline   plt.hist(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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿