一、實驗目的
1. 掌握使用Python的pandas、matplotlib和seaborn庫進行數據可視化的方法
2. 學習制作杠鈴圖、堆積柱狀圖和折線圖等多種圖表類型
3. 分析北京市各區在特定時間段內的降雨量的變化規律
4. 培養數據分析和可視化的實踐能力
二、實驗數據
數據來源:北京市水務局官網(http://swj.beijing.gov.cn/)
數據內容:包含北京市各行政區在2023年7月30日至8月5日期間的降雨量數據
三、實驗內容與步驟
1. 數據準備與預處理
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np# 讀取數據
df1 = pd.read_excel('C:/Users/ASUS/Desktop/數據可視化文件/實驗4/rain_data.xlsx')
#print(df1.head())
2. 制作杠鈴圖對比7月30日與8月5日降雨量
步驟:
計算各行政區兩天的平均降雨量
使用灰色線條連接兩個時間點的數據
分別用藍色和橙色點表示7月30日和8月5日的降雨量
添加數據標簽顯示具體數值
# 計算每個區7.30和8.5兩天的平均降雨量
region_rain = df1.groupby('region')[['7.30', '8.5']].mean().reset_index()# 排序數據以便更好的可視化
region_rain = region_rain.sort_values('7.30')
region_rain.reset_index(drop=True, inplace=True) # 重置索引確保順序正確# 創建圖形
plt.figure(figsize=(12, 10))
#plt.style.use('seaborn-v0_8-whitegrid')
sns.set_style("whitegrid") # 使用seaborn的白色網格風格
plt.rcParams['font.family'] = 'SimHei'
# 繪制杠鈴圖
for idx, row in region_rain.iterrows():plt.plot([row['7.30'], row['8.5']], [idx, idx], color='grey', alpha=0.4, linewidth=3)# 繪制兩個時間點的點
plt.scatter(region_rain['7.30'], region_rain.index, color='#1f77b4', label='7月30日', s=100)
plt.scatter(region_rain['8.5'], region_rain.index, color='#ff7f0e', label='8月5日', s=100)# 添加標簽和標題
plt.yticks(region_rain.index, region_rain['region'], fontsize=12)
plt.xlabel('降雨量(mm)', fontsize=14)
plt.title('北京市各區7月30日與8月5日平均降雨量對比', fontsize=16, pad=20)
plt.legend(fontsize=12)# 獲取區域數量用于y軸定位
n_regions = len(region_rain)# 添加數值標簽 - 確保與點對應
for i in range(n_regions):# 7月30日數據標簽plt.text(region_rain.loc[i, '7.30']+3, i, f"{region_rain.loc[i, '7.30']:.1f}", ha='right', va='center', fontsize=10)# 8月5日數據標簽plt.text(region_rain.loc[i, '8.5']-3, i, f"{region_rain.loc[i, '8.5']:.1f}", ha='left', va='center', fontsize=10)# 添加數值標簽
#for i, (val1, val2) in enumerate(zip(region_rain['7.30'], region_rain['8.5'])):
# plt.text(val1, i, f'{val1:.1f}', ha='right', va='center', fontsize=10)
# plt.text(val2, i, f'{val2:.1f}', ha='left', va='center', fontsize=10)# 美化圖形
sns.despine(left=True)
plt.grid(axis='x', linestyle='--', alpha=0.7)
plt.tight_layout()plt.show()
輸出的杠鈴圖如下:
通過杠鈴圖可以直觀看出:
大部分行政區8月5日的降雨量明顯高于7月30日;
降雨量分布存在明顯的區域差異;
某些區域兩日降雨量變化較小(如密云區、延慶區),而某些區域變化顯著(如海淀區、石景山區)。
3. 制作堆積柱狀圖展示7天內降雨總量分布
步驟:
計算各區每日平均降雨量
使用不同顏色表示不同日期的降雨量貢獻
采用彩虹色系從淺藍到深紫,增強視覺效果
添加總計數據標簽
# 選擇7天的降雨數據列
rain_columns = ['7.30', '7.31', '8.1', '8.2', '8.3', '8.4', '8.5']
date_labels = ['7月30日', '7月31日', '8月1日', '8月2日', '8月3日', '8月4日', '8月5日']# 計算各區每日平均降雨量
region_daily = df1.groupby('region')[rain_columns].mean()# 轉置數據以便繪圖
plot_data = region_daily.T
plot_data.index = date_labels # 使用中文日期標簽# 設置顏色
#colors = plt.cm.viridis(np.linspace(0, 1, len(date_labels)))# 或者使用雨量專用色系:從淺藍到深藍再到紫色
colors = ['#6a3d9a','#e31a1c','#fb9a99','#33a02c','#b2df8a','#1f78b4','#a6cee3']# 創建圖形
plt.figure(figsize=(14, 8))
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei'] # 設置中文字體
plt.rcParams['axes.unicode_minus'] = False# 繪制堆積柱狀圖
bottom = np.zeros(len(region_daily))
for i, date in enumerate(date_labels):plt.bar(region_daily.index, plot_data.loc[date], bottom=bottom, label=date,color=colors[i])bottom += plot_data.loc[date]# 添加圖表元素
plt.title('北京市各區7天內降雨總量分布(按日期堆積)', fontsize=16, pad=20)
plt.xlabel('行政區', fontsize=14)
plt.ylabel('降雨量(mm)', fontsize=14)
plt.xticks(rotation=45, ha='right')# 添加圖例
plt.legend(title='日期', bbox_to_anchor=(1.05, 1), loc='upper left')# 添加數據標簽(可選)
for region in region_daily.index:height = bottom[region_daily.index.get_loc(region)]plt.text(region_daily.index.get_loc(region), height, f'{height:.1f}', ha='center', va='bottom')plt.tight_layout()
plt.show()
輸出的堆積圖如下:
通過堆積柱狀圖可以發現:
不同行政區的總降雨量存在顯著差異;
降雨時間分布不均,某些日期貢獻了大部分降雨量;
顏色堆疊效果清晰展示了每日降雨在各區的占比情況。
4. 制作折線圖分析降雨變化最大的前5個區
步驟:
計算各行政區降雨量的標準差作為變化幅度指標
選取變化幅度最大的5個區
標注每個區的降雨量峰值
在圖例中顯示各區的變化幅度值
# 計算各區每日平均降雨量
region_daily = df1.groupby('region')[rain_columns].mean().T
region_daily.index = date_labels# 計算變化幅度(標準差)并取前5個區
region_std = df1.groupby('region')[rain_columns].std().mean(axis=1)
top5_regions = region_std.nlargest(5).index.tolist()# 創建圖形
plt.figure(figsize=(12, 6))
#plt.rcParams['font.family'] = 'SimHei'
sns.set_style("whitegrid")
colors = plt.cm.tab10(np.linspace(0, 1, 5))# 繪制前5個區折線
for i, region in enumerate(top5_regions):line = plt.plot(date_labels, region_daily[region], marker='o', linewidth=2.5,markersize=8,color=colors[i],label=f"{region} (Δ:{region_std[region]:.1f})")[0]# 標注最大值(修正后的部分)max_val = region_daily[region].max()max_idx = region_daily[region].idxmax()x_pos = date_labels.index(max_idx)plt.annotate(f'{max_val:.1f}',xy=(x_pos, max_val),xytext=(0, 10),textcoords='offset points',ha='center',color=line.get_color(),fontsize=10,arrowprops=dict(arrowstyle='->', color=line.get_color()))# 圖表美化
plt.rcParams['font.sans-serif'] = ['SimHei'] # 設置中文字體
plt.rcParams['axes.unicode_minus'] = False
plt.title('北京市降雨量變化最大的前5個區趨勢\n(按標準差排序)', fontsize=14, pad=20)
plt.xlabel('日期', fontsize=12)
plt.ylabel('降雨量(mm)', fontsize=12)
plt.xticks(fontsize=11)
plt.yticks(fontsize=11)# 輔助元素
plt.grid(axis='y', linestyle=':', alpha=0.6)
plt.axhline(y=0, color='gray', linewidth=0.5)# 圖例優化
legend = plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left',title='行政區(變化幅度)',frameon=True,borderpad=1)
legend.get_frame().set_facecolor('#f9f9f9')plt.tight_layout()
plt.savefig('top5_rainfall_trend.png', dpi=300, bbox_inches='tight')
plt.show()
輸出的折線圖如下:
通過折線圖可以看出:
前5個變化幅度最大的行政區降雨模式各異;
某些區呈現單峰特征,某些區呈現多峰波動;
峰值出現的時間點不同,反映了降雨時空分布的不均勻性。
?四、實驗總結
????????本次實驗通過三種不同的可視化方式,全面分析了北京市各行政區在7天內的降雨量分布和變化規律。杠鈴圖適合對比兩個時間點的數據,堆積柱狀圖適合展示總量和構成,折線圖適合分析變化趨勢。實驗結果表明,北京市降雨存在明顯的時空分布差異,不同行政區的降雨模式和變化特征各不相同。
????????通過本實驗,掌握了多種數據可視化技術的實際應用,提高了從數據中提取信息和分析問題的能力,為后續的數據分析工作奠定了基礎。