import matplotlib.colors as mc
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib.cm import ScalarMappable
import calendar
# 本数据只保留了stationid='T0001'
data = pd.read_csv("https://raw.githubusercontent.com/holtzy/The-Python-Graph-Gallery/master/static/data/trentino_temperature.csv")
data.head()
image-20240129172458936
stationid:站点 date:日期 hour:小时 temp:温度
# 转化日期格式
data["date"] = pd.to_datetime(data["date"])
# 简单查看2004年1月的数据:x轴为日期,y轴为小时,颜色为温度
# 构造2004年1月数据
subset = data[(data["date"].dt.year == 2004) & (data["date"].dt.month == 1)]
# 提取小时、日期、温度
hour = subset["hour"]
day = subset["date"].dt.day
temp = subset["temp"]
temp = temp.values.reshape(24, len(day.unique()), order="F") # 生成温度数组24*31
# 生成x轴和y轴的范围
xgrid = np.arange(day.max() + 1) + 1 # 天从1开始计数
ygrid = np.arange(25) # 小时从0开始
fig, ax = plt.subplots()
ax.pcolormesh(xgrid, ygrid, temp)
ax.set_frame_on(False) # 删除所有边框
output_9_0
将上述热图扩展为两年,即查看2004-2005年间的温度变化。
# 为防止两年间的温度颜色分配不一致,计算出最小和最大温度。便于温度的颜色分配保持一致
MIN_TEMP = data["temp"].min()
MAX_TEMP = data["temp"].max()
# 将上述的单月热图抽象成自定义函数
def single_plot(data, month, year, ax):
data = data[(data["date"].dt.year == year) & (data["date"].dt.month == month)]
hour = data["hour"]
day = data["date"].dt.day
temp = data["temp"]
temp = temp.values.reshape(24, len(day.unique()), order="F")
xgrid = np.arange(day.max() + 1) + 1
ygrid = np.arange(25)
ax.pcolormesh(xgrid, ygrid, temp, cmap="magma", vmin=MIN_TEMP, vmax=MAX_TEMP)
# 反转y轴
ax.set_ylim(24, 0)
# 设置坐标轴的标签、范围
ax.yaxis.set_ticks([0, 6, 12, 18, 23])
ax.xaxis.set_ticks([])
# 删除刻度线(通过设置参数为0实现)
ax.yaxis.set_tick_params(length=0)
ax.xaxis.set_tick_params(length=0)
# 移除所有边框
ax.set_frame_on(False)
# 设置X轴标签
ax.set_xlabel(calendar.month_abbr[month], fontsize=10) # 使用月份的缩写
# 循环创建所有的热图
# 初始化布局
fig, axes = plt.subplots(2, 12, figsize=(14, 10), sharey=True)
for i, year in enumerate([2004, 2005]):
for j, month in enumerate(range(1, 13)):
single_plot(data, month, year, axes[i, j])
# 调整布局,并预留空间
fig.subplots_adjust(left=0.05, right=0.98, top=0.9, hspace=0.08, wspace=0)
output_14_0
# 增加颜色bar
# 调整空间,为底部的颜色bar腾出空间
fig.subplots_adjust(bottom=0.15)
# 为颜色bar创建新轴
cbar_ax = fig.add_axes([0.3, 0.05, 0.4, 0.025]) #参数:x坐标,y坐标,width,height
norm = mc.Normalize(MIN_TEMP, MAX_TEMP) # 创建最低温度到最高温度的标准器
# 创建颜色bar
cb = fig.colorbar(
ScalarMappable(norm=norm, cmap="magma"),
cax=cbar_ax, # 将新创建的轴传递给cax
orientation = "horizontal"
)
# 删除刻度线
cb.ax.xaxis.set_tick_params(size=0)
# 设置颜色bar图例
cb.set_label("Temperature", size=12)
fig
output_15_0
# 增加标题等适当信息进行完善
# y轴标题
fig.text(0.5, 0.1, "date", ha="center", va="center", fontsize=14)
fig.text(0.055, 0.92, 'Hour', ha="center", va="center", fontsize=14)
# 添加y轴标签
fig.text(0.01, 0.71, 'Y2004', ha='center', va='center', rotation='vertical')
fig.text(0.01, 0.33, 'Y2005', ha='center', va='center', rotation='vertical')
# 添加子标题
fig.suptitle("Hourly temperatures - Station T0001", fontsize=20, y=0.95)
fig
output_16_0
参考:Heatmap for timeseries with Python and Matplotlib[1]
共勉~
[1]
Heatmap for timeseries with Python and Matplotlib: https://python-graph-gallery.com/heatmap-for-timeseries-matplotlib/