如何用Matplotlib实现湖泊纵剖面温度的平滑等高线与湖底可视化?
温度可视化优化:平滑等高线+湖底线条实现
问题描述
现有Python脚本可基于Excel温度数据生成等高线图,但需要优化为带有平滑等高线和湖底轮廓线条的效果。原始代码如下:
import matplotlib.pyplot as plt import pandas as pd import numpy as np # 导入Excel数据 df = pd.read_excel('temperature_data.xlsx', index_col=0) # 变量赋值 places = df.columns depth = df.index temperature = np.ma.masked_invalid(df.to_numpy()) # 绘图 fig, ax = plt.subplots() min_temp = temperature.min() max_temp = temperature.max() cs = plt.contourf(places, depth, temperature, cmap='coolwarm', vmin=min_temp, vmax=max_temp) cs2 = plt.contour(places, depth, temperature, levels=range(round(min_temp), round(max_temp)+1, 1), colors='black') plt.clabel(cs2, inline=1, fontsize=10, fmt='%d') plt.title('Teplota vody [°C]') plt.ylabel('hloubka [m]') plt.colorbar(cs, cmap='coolwarm') plt.gca().invert_yaxis() plt.show()
解决方案
通过数据插值实现平滑等高线,同时提取无效数据边界绘制湖底线条,修改后的代码如下:
import matplotlib.pyplot as plt import pandas as pd import numpy as np from scipy.interpolate import griddata # 导入Excel数据 df = pd.read_excel('temperature_data.xlsx', index_col=0) # 提取原始有效数据点 places = df.columns.astype(float) # 若地点为字符串,需先做编码转换 depth = df.index.astype(float) x, y = np.meshgrid(places, depth) valid_mask = ~np.isnan(df.to_numpy()) x_valid = x[valid_mask] y_valid = y[valid_mask] temp_valid = df.to_numpy()[valid_mask] # 生成高密度网格用于平滑插值 x_new = np.linspace(places.min(), places.max(), 100) y_new = np.linspace(depth.min(), depth.max(), 100) x_grid, y_grid = np.meshgrid(x_new, y_new) # 三次插值生成平滑温度场 temp_smooth = griddata((x_valid, y_valid), temp_valid, (x_grid, y_grid), method='cubic') temp_smooth_masked = np.ma.masked_invalid(temp_smooth) # 提取湖底边界:每个地点的最大有效深度 lake_bottom = [] for col in df.columns: col_data = df[col].dropna() if not col_data.empty: max_depth = col_data.index.max() lake_bottom.append((col, max_depth)) lake_bottom_x = np.array([float(p) for p, d in lake_bottom]) lake_bottom_y = np.array([d for p, d in lake_bottom]) # 绘图 fig, ax = plt.subplots(figsize=(10,6)) min_temp = temp_valid.min() max_temp = temp_valid.max() # 平滑填充等高线 cs = plt.contourf(x_new, y_new, temp_smooth_masked, cmap='coolwarm', vmin=min_temp, vmax=max_temp, levels=20) # 平滑等高线线条 cs2 = plt.contour(x_new, y_new, temp_smooth_masked, levels=range(round(min_temp), round(max_temp)+1, 1), colors='black', linewidths=0.8) plt.clabel(cs2, inline=1, fontsize=10, fmt='%d') # 绘制湖底线条 ax.plot(lake_bottom_x, lake_bottom_y, color='darkblue', linewidth=2, label='Hnoje jezera') plt.title('Teplota vody [°C]') plt.ylabel('hloubka [m]') plt.xlabel('Místa') plt.colorbar(cs, cmap='coolwarm') plt.gca().invert_yaxis() plt.legend() plt.tight_layout() plt.show()
关键改动说明
- 平滑等高线:借助
scipy.interpolate.griddata的三次插值方法,在高密度网格上生成平滑温度场,替代原始稀疏数据直接绘图的生硬效果 - 湖底线条:遍历每个地点的列数据,提取该列非空值对应的最大深度,将这些点连接成湖底轮廓线
- 细节优化:调整图表尺寸、恢复x轴标签、增加图例、细化等高线线条宽度,提升可视化清晰度
内容的提问来源于stack exchange,提问作者Dušan K.
相关产品推荐
相关产品推荐

