如果分析的數據與地域相關,那麼,把分析結果結合地圖一起展示的話,會讓可視化的效果得到極大的提升。 比如,分析各省GDP數據,人口數據,用柱狀圖,餅圖之類的雖然都可以展示分析結果,不過,如果能在全國的地圖上展示各省的分析結果的話,會讓人留下更加深刻的印象。 將數據的分析結果展示在地圖上,難點在於: 如 ...
如果分析的數據與地域相關,那麼,把分析結果結合地圖一起展示的話,會讓可視化的效果得到極大的提升。
比如,分析各省GDP數據,人口數據,用柱狀圖,餅圖之類的雖然都可以展示分析結果,
不過,如果能在全國的地圖上展示各省的分析結果的話,會讓人留下更加深刻的印象。
將數據的分析結果展示在地圖上,難點在於:
- 如何繪製地圖,地圖是展示數據的基礎,如何繪製出需要的地圖區域是第一步
- 數據和地圖關聯,數據最終要顯示在地圖上,數據如何與地理坐標關聯也是重要的一步
- 地圖上展示數據,也就是要在地圖上繪製不同的顏色或者幾何形狀來表達不同的數據
解決了上面3個難題,就能夠結合地圖做一些基本的數據展示了。
本篇通過一個基於南京各個區地理信息的分析示例,來演示如何一步步通過地圖來展示分析結果。
1. 繪製地圖
第一步是繪製地圖,其實地圖就是一塊塊不規則的多邊形拼接起來的。
在本篇的示例中,各個多邊形就是南京的各個區。
繪製多邊形不難,難的是如何得到各個多邊形的頂點坐標。
好在現在有很多的開放地理信息平臺,可以讓我們獲取到想要的地理信息。
1.1. 獲取地理信息
比如,通過阿裡的DataV數據可視化平臺,可以獲取南京各個區的地理範圍信息。
在這個平臺上,左邊選擇區域,右邊會生成對應範圍的地理信息的數據。
地理信息數據是json
格式。
1.2. 展示地理信息
為了讀取地理信息數據並展示,需要用到一個 GeoPandas
的庫。
用 pip
安裝很簡單:
$ pip install geopandas
geopandas
可以直接讀取DataV數據可視化平臺生成的JSON數據並展示。
import geopandas as gpd
df_geo = gpd.read_file(
"https://geo.datav.aliyun.com/areas_v3/bound/320100_full.json"
)
df_geo
json
文件的HTTP
地址DataV數據可視化平臺就是在上生成的。
這個文件中的關鍵欄位就是 geometry,其中的內容就是各個區的多邊形形狀的各個頂點的經緯度坐標。
展示數據:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
fig.set_size_inches(8, 8)
# df_geo就是上面通過geopandas讀取的數據
df_geo.plot(
ax=ax,
column="name",
cmap="plasma",
edgecolor="k",
legend=True,
legend_kwds={"loc": "lower left"}
)
plt.show()
其中主要參數的含義:
ax
:matplotlib
生成的子圖,這裡就是數據要繪製的位置column
:作為不同區域的名稱,這裡就是南京各個區的名稱cmap
:一組顏色,分別對應不同的區edgecolor
:每個多邊形邊緣的顏色,這裡設置的是黑色legend
:是否顯示圖例legend_kwds
:設置圖例的配置信息,這裡只設置了圖例的位置
2. 地圖和數據關聯
首先生成一些測試數據:
# 刪除 df_geo 中一些不必要的列
df_geo = df_geo.drop(columns=["childrenNum", "level", "parent", "subFeatureIndex"])
# 南京各個區的名稱
area_names = df_geo.loc[:, "name"]
# df_val為測試數據,其中name列是各個區的名稱
# value 列是一些隨機數,模擬各個區的人口,GDP等數據
df_val = pd.DataFrame({
"name": area_names.tolist(),
"value": np.random.randint(10, 10000, len(area_names))
})
測試數據 df_val
模擬其他途徑得到的業務數據,
下麵要將 df_val
中的指展示到地圖上,就要先把 df_val
和 df_geo
結合起來。
# 以 name 列作為結合兩個數據集的依據
df = pd.merge(df_geo, df_val, on="name", how="left")
df
這樣,我們就得到了同時包含地理信息(geometry)和業務數據(value)的數據集了。
3. 地圖上展示數據
接下來就是展示數據了,下麵演示兩種在地圖上展示數據的方式。
3.1. 熱力圖方式
根據 value 值的不同,用漸變色來顯示不同區的顏色。
fig, ax = plt.subplots()
fig.set_size_inches(8, 8)
ax.axis("off")
df.plot(
ax=ax,
column="value",
cmap="plasma",
edgecolor="k",
legend=True,
legend_kwds={'label': "value", 'shrink':0.5},
)
for index in df.index:
x = df.iloc[index].geometry.centroid.x
y = df.iloc[index].geometry.centroid.y
name = df.iloc[index]["name"]
if name in ["建鄴區", "鼓樓區", "玄武區", "秦淮區"]:
ax.text(x, y, name, ha="center", va="center", fontsize=8)
else:
ax.text(x, y, name, ha="center", va="center")
plt.show()
其中,"建鄴區", "鼓樓區", "玄武區", "秦淮區" 四個區的面積比較小,
所以字體稍微調小了一些。
3.2. 分類展示
把 value
值分為3類,每類用不同的形式來表示。
- value < 3000
- 3000 <= value < 5000
- value >= 5000
import matplotlib.patches as mpatches
fig, ax = plt.subplots()
fig.set_size_inches(5, 10)
ax.axis("off")
legend_list = []
df[df["value"] < 3000].plot(
ax=ax,
color="lightblue",
edgecolor="k",
hatch="\\\\",
legend=False,
)
legend_list.append(
mpatches.Patch(
facecolor="lightblue",
edgecolor="black", hatch="\\\\", label="value<3000"
)
)
df[(df["value"] >= 3000) & (df["value"] < 5000)].plot(
ax=ax,
color="lightgreen",
edgecolor="k",
hatch="o",
legend=False,
)
legend_list.append(
mpatches.Patch(
facecolor="lightgreen",
edgecolor="black", hatch="o", label="3000<=value<5000")
)
df[df["value"] >= 5000].plot(
ax=ax,
color="r",
edgecolor="k",
hatch="*",
legend=False,
)
legend_list.append(mpatches.Patch(
facecolor="r",
edgecolor="black", hatch="*", label="value>=5000"))
ax.legend(handles = legend_list,
loc=(1, 0.5),
title="value 等級",
fontsize=12)
plt.show()
4. 總結
結合地理信息展示數據,讓數據更加的生動,特別是很多數據分析場景本身就和地理信息密切相關。
除了基於地域的各種經濟或者人口等等的相關數據,
還有各類氣象數據,如能和地理信息結合展示的話,會讓人對整體情況一目瞭然。
文中用到的主要資源:
- DataV數據可視化平臺:https://datav.aliyun.com/portal/school/atlas/area_selector
- GeoPandas:https://github.com/geopandas/geopandas