# Python怎么實現香港地圖、房價可視化和繪制氣泡圖
## 引言
在數據分析和可視化領域,地理空間數據的呈現一直是重要課題。香港作為國際金融中心,其房地產市場數據具有極高的分析價值。本文將詳細介紹如何利用Python實現香港地圖的可視化、房價數據的展示以及氣泡圖的繪制,幫助讀者掌握地理數據可視化的核心技能。
## 一、準備工作
### 1.1 所需工具和庫
實現地理可視化需要以下Python庫:
- `geopandas`:處理地理空間數據
- `matplotlib`/`seaborn`:基礎可視化
- `folium`/`plotly`:交互式地圖
- `contextily`:添加底圖
- `pandas`:數據處理
安裝命令:
```bash
pip install geopandas matplotlib seaborn folium plotly contextily pandas
需要準備兩類數據: 1. 香港行政區劃GeoJSON文件(可從Hong Kong GeoData Store獲?。?2. 香港房價數據集(示例數據可模擬生成)
import pandas as pd
import numpy as np
# 模擬生成2023年香港各區房價數據(單位:萬港元/平方米)
districts = ['中西區', '灣仔區', '東區', '南區',
'油尖旺區', '深水埗區', '九龍城區', '黃大仙區',
'觀塘區', '荃灣區', '屯門區', '元朗區',
'北區', '大埔區', '沙田區', '西貢區',
'離島區']
housing_data = pd.DataFrame({
'District': districts,
'AvgPrice': np.random.uniform(15, 30, len(districts)),
'TransactionCount': np.random.randint(100, 500, len(districts))
})
import geopandas as gpd
# 加載香港行政區劃數據
hk_map = gpd.read_file('path_to_hk_districts.geojson')
print(hk_map.head())
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(12, 10))
hk_map.plot(ax=ax, color='lightblue', edgecolor='black')
plt.title('香港行政區劃圖', fontsize=16)
plt.axis('off')
plt.show()
plt.rcParams['font.sans-serif'] = ['SimHei'] # 設置中文字體
plt.rcParams['axes.unicode_minus'] = False # 解決負號顯示問題
# 確保區名一致
housing_data['District'] = housing_data['District'].str.replace('區', '')
hk_map['name_zh'] = hk_map['name_zh'].str.replace('區', '')
# 合并地理數據與房價數據
merged_data = hk_map.merge(housing_data, left_on='name_zh', right_on='District')
fig, ax = plt.subplots(figsize=(14, 12))
# 繪制分級設色地圖
merged_data.plot(column='AvgPrice',
ax=ax,
legend=True,
scheme='quantiles',
cmap='OrRd',
edgecolor='black',
linewidth=0.5)
# 添加標注
for idx, row in merged_data.iterrows():
plt.annotate(text=f"{row['District']}\n{row['AvgPrice']:.1f}萬",
xy=row['geometry'].centroid.coords[0],
ha='center',
fontsize=9)
plt.title('香港各區平均房價(萬港元/平方米)', fontsize=18)
plt.axis('off')
plt.show()
import folium
# 計算地圖中心點
center = [hk_map.geometry.centroid.y.mean(), hk_map.geometry.centroid.x.mean()]
# 創建基礎地圖
m = folium.Map(location=center, zoom_start=11, tiles='CartoDB positron')
# 添加分級設色圖層
folium.Choropleth(
geo_data=hk_map,
name='choropleth',
data=housing_data,
columns=['District', 'AvgPrice'],
key_on='feature.properties.name_zh',
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.2,
legend_name='平均房價(萬港元/平方米)'
).add_to(m)
# 添加交互標簽
style_function = lambda x: {'fillColor': '#ffffff',
'color':'#000000',
'fillOpacity': 0.1,
'weight': 0.1}
highlight_function = lambda x: {'fillColor': '#000000',
'color':'#000000',
'fillOpacity': 0.50,
'weight': 0.1}
for idx, row in merged_data.iterrows():
html = f"""
<b>地區</b>: {row['District']}<br/>
<b>平均房價</b>: {row['AvgPrice']:.1f}萬/㎡<br/>
<b>交易量</b>: {row['TransactionCount']}宗
"""
popup = folium.Popup(html, max_width=300)
folium.GeoJson(
row['geometry'],
style_function=style_function,
highlight_function=highlight_function,
tooltip=row['District'],
).add_child(popup).add_to(m)
folium.LayerControl().add_to(m)
m.save('hk_housing.html')
fig, ax = plt.subplots(figsize=(14, 10))
# 繪制底圖
hk_map.plot(ax=ax, color='lightgrey', edgecolor='black')
# 繪制氣泡圖
scatter = merged_data.plot(ax=ax,
marker='o',
color='red',
markersize=merged_data['TransactionCount']/10,
alpha=0.6)
# 添加標注
for idx, row in merged_data.iterrows():
ax.annotate(text=f"{row['District']}\n{row['AvgPrice']:.1f}萬",
xy=(row['geometry'].centroid.x, row['geometry'].centroid.y),
xytext=(5, 5),
textcoords='offset points',
fontsize=9)
plt.title('香港各區房價氣泡圖(大小表示交易量)', fontsize=18)
plt.axis('off')
# 添加圖例
for size in [100, 200, 300]:
plt.scatter([], [], c='red', alpha=0.6, s=size/10,
label=f'{size}宗交易')
plt.legend(scatterpoints=1, frameon=False, labelspacing=1.5)
plt.show()
import plotly.express as px
# 準備數據
plotly_data = merged_data.copy()
plotly_data['lon'] = plotly_data.geometry.centroid.x
plotly_data['lat'] = plotly_data.geometry.centroid.y
fig = px.scatter_mapbox(plotly_data,
lon="lon",
lat="lat",
size="TransactionCount",
color="AvgPrice",
color_continuous_scale=px.colors.sequential.OrRd,
size_max=30,
zoom=10,
hover_name="District",
hover_data={"AvgPrice": ":.1f", "TransactionCount": True},
mapbox_style="carto-positron")
fig.update_layout(
title='香港各區房價氣泡圖(2023年)',
width=1000,
height=800,
coloraxis_colorbar=dict(title="平均房價(萬/㎡)")
)
fig.show()
import seaborn as sns
# 創建網格數據
grid = merged_data.copy()
grid['x'] = grid.geometry.centroid.x
grid['y'] = grid.geometry.centroid.y
fig, ax = plt.subplots(figsize=(14, 12))
hk_map.plot(ax=ax, color='lightgrey', edgecolor='black')
# 繪制熱力圖
sns.kdeplot(x=grid['x'],
y=grid['y'],
weights=grid['AvgPrice'],
cmap='Reds',
alpha=0.6,
levels=10,
thresh=0.3,
ax=ax)
# 添加氣泡
scatter = ax.scatter(x=grid['x'],
y=grid['y'],
s=grid['TransactionCount']/5,
c=grid['AvgPrice'],
cmap='OrRd',
alpha=0.8,
edgecolors='black')
# 添加顏色條
plt.colorbar(scatter, label='平均房價(萬/㎡)')
plt.title('香港房價熱力圖與交易量氣泡圖', fontsize=18)
plt.axis('off')
plt.show()
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(16, 14))
ax = fig.add_subplot(111, projection='3d')
# 創建3D柱狀圖
for idx, row in merged_data.iterrows():
poly = row['geometry']
if poly.geom_type == 'Polygon':
x, y = poly.exterior.xy
z = np.ones(len(x)) * row['AvgPrice']
ax.plot(x, y, z, color='black', linewidth=0.5)
ax.fill_between(x, y, z, color='red', alpha=0.3)
ax.set_title('香港3D房價地圖', fontsize=20)
ax.set_zlabel('平均房價(萬/㎡)')
ax.grid(False)
plt.axis('off')
plt.tight_layout()
plt.show()
通過上述可視化,我們可以得出以下觀察: 1. 香港島北部(中西區、灣仔區)房價明顯高于新界地區 2. 交易量最大的區域集中在九龍城區和沙田區 3. 房價與交易量呈現一定的負相關關系 4. 離島區雖然房價較低,但交易量也相對較少
本文完整介紹了: 1. 香港地理數據的加載和處理方法 2. 靜態和交互式地圖的創建技巧 3. 氣泡圖、熱力圖等多種可視化形式 4. 3D地理數據的展示方式
完整代碼和數據可參考:[GitHub倉庫鏈接]
”`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。