如何用Python创建滴谱仪数据的时间序列热力图?
如何用Python绘制滴谱仪数据的时间序列热力图?
我有一组滴谱仪(disdrometer)数据集,包含变量:
- Time stamp (LST) – 当地标准时间
- Rainrate(Disdro RR (mmhr))– 降雨强度,单位mm/hr
- Mass weighted mean D (mm) – 雨滴质量加权平均直径
- log N(D) – 滴谱分布的对数
我想要绘制时间序列热力图:X轴为时间戳,Y轴为Rainrate或log N(D),颜色深浅代表log N(D)的数值。但自己写的代码生成的图Y轴是倒置的,也没达到预期效果,求正确示例代码。
样本数据如下:
Time stamp (LST),Disdro RR (mmhr),Mass weighted mean D (mm),log N(D) 900,0,0,0 905,0,0,0 910,0,0,0 915,0,0,0 920,0,0,0 925,0,0,0 930,0,0,0 935,0,0,0 940,0,0,0 945,0,0,0 950,0,0,0 955,0,0,0 1000,0,0,0 1005,0,0,0 1010,0,0,0 1015,0,0,0 1020,0,0,0 1025,0,0,0 1030,0,0,0 1035,0,0,0 1040,0,0,0 1045,0,0,0 1050,0.583,0.67,1.94 1055,0.435,0.64,1.19 1100,0.141,0.748,1.74 1105,0.593,0.88,2.13 1110,1.339,0.87,1.82 1115,1.42,0.72,2.17 1120,3.615,0.85,2.79 1125,3.51,0.961,2.69 1130,4.75,0.82,2.56 1135,4.61,0.85,2.79 1140,5.546,0.95,2.96 1145,6.052,1.03,3.06 1150,7.18,0.856,3.28 1155,7.83,1.23,2.88 1200,13.21,1.382,2.85
我尝试的代码:
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # Load your data file_path = "07292024_Disdrometer.csv" # Replace with your file path df = pd.read_csv(file_path) # Convert Time to HH:MM format df["Time stamp (LST)"] = df["Time stamp (LST)"].astype(str).str.zfill(4) df["Time (HH:MM)"] = df["Time stamp (LST)"].str[:2] + ":" + df["Time stamp (LST)"].str[2:] # Pivot the table to prepare for heatmap pivot_df = df.pivot(index="log N(D)", columns="Time (HH:MM)", values="log N(D)") # Create the heatmap plt.figure(figsize=(12, 6)) sns.heatmap(pivot_df, cmap="viridis", cbar_kws={'label': 'log N(D)'}, linewidths=0.1) # Formatting the plot plt.xlabel("Time (LST)") plt.ylabel("log N(D)") plt.title("Heatmap of Drop Size Distribution Over Time") # Rotate x-axis labels for better readability plt.xticks(rotation=45, ha="right") plt.show()
问题分析与解决方案
原代码的问题
- Y轴倒置:Seaborn的
heatmap默认将索引从上到下按升序排列,导致log N(D)最小值在顶部、最大值在底部,视觉上呈现倒置效果。 - 数据透视逻辑错误:用
log N(D)同时作为行索引和值,每个时间点仅对应一个log N(D)值,导致大量单元格为空,无法形成连续的热力图。 - 未覆盖Y轴为Rainrate的需求:原代码仅实现了Y轴为log N(D)的场景,未用到Rainrate变量。
修正后的代码(两种Y轴选项)
选项1:Y轴为Rainrate,颜色代表log N(D)
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 加载数据 df = pd.read_csv("07292024_Disdrometer.csv") # 替换为你的文件路径 # 时间格式转换:将数字时间转为HH:MM字符串 df["Time stamp (LST)"] = df["Time stamp (LST)"].astype(str).str.zfill(4) df["Time (HH:MM)"] = df["Time stamp (LST)"].str[:2] + ":" + df["Time stamp (LST)"].str[2:] # 数据透视:行是Rainrate,列是时间,值是log N(D),用mean聚合重复值 pivot_df = df.pivot_table(index="Disdro RR (mmhr)", columns="Time (HH:MM)", values="log N(D)", aggfunc="mean") # 创建热力图 plt.figure(figsize=(14, 7)) sns.heatmap(pivot_df, cmap="viridis", cbar_kws={'label': 'log N(D)'}, linewidths=0.1, yticklabels=5, annot=False) # 格式调整 plt.xlabel("Time (LST)") plt.ylabel("Rainrate (mm/hr)") plt.title("Rainrate vs Time Heatmap (Color: log N(D))") plt.xticks(rotation=45, ha="right") # 反转Y轴,让降雨强度从低到高向上排列 plt.gca().invert_yaxis() plt.tight_layout() plt.show()
选项2:Y轴为log N(D),颜色代表log N(D)(修复原代码问题)
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 加载数据 df = pd.read_csv("07292024_Disdrometer.csv") # 时间格式转换 df["Time stamp (LST)"] = df["Time stamp (LST)"].astype(str).str.zfill(4) df["Time (HH:MM)"] = df["Time stamp (LST)"].str[:2] + ":" + df["Time stamp (LST)"].str[2:] # 数据透视:行是log N(D),列是时间,值是log N(D),用mean聚合空值 pivot_df = df.pivot_table(index="log N(D)", columns="Time (HH:MM)", values="log N(D)", aggfunc="mean") plt.figure(figsize=(14, 7)) sns.heatmap(pivot_df, cmap="viridis", cbar_kws={'label': 'log N(D)'}, linewidths=0.1, yticklabels=5) # 格式调整 plt.xlabel("Time (LST)") plt.ylabel("log N(D)") plt.title("log N(D) vs Time Heatmap (Color: log N(D))") plt.xticks(rotation=45, ha="right") # 反转Y轴,让log N(D)从低到高向上排列 plt.gca().invert_yaxis() plt.tight_layout() plt.show()
关键说明
- 解决Y轴倒置:通过
plt.gca().invert_yaxis()反转Y轴,让数值从下到上递增,符合常规视觉习惯。 - 数据透视优化:使用
pivot_table替代pivot,指定聚合函数(如mean)处理重复值或空值,保证热力图的连续性。 - 标签可读性:设置
yticklabels=5每隔5个Y轴标签显示一个,避免重叠;tight_layout()自动调整布局,防止标签被截断。
内容的提问来源于stack exchange,提问作者CGHA
相关产品推荐
相关产品推荐

