You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Matplotlib中自定义热力图的X轴刻度与标签?

自定义热力图X轴标签与刻度样式

我正尝试自定义热力图的X轴标签与刻度,使其和之前创建的另一张图表样式一致。以下是我的实现代码:

import matplotlib as mplt
from matplotlib import dates, pyplot
from matplotlib.transforms import ScaledTranslation
import numpy as np
import pandas as pd
import datetime

s_names = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # categories
dates_ = pd.date_range('2023/01/01', '2023/01/08', freq='3H', tz='utc') # Creating a list of date time for index.
matrix = pd.DataFrame(columns=s_names, index=dates_) # initializing the df.

matrix = matrix.applymap(lambda l: l if not np.isnan(l) else np.random.choice(range(1, 10))) # replacing nan in the df with random number.

matrix.sort_values(by=matrix.index[0], ascending=True, axis=1, inplace=True) # Sorting by the first date (row), columns get ordered in from lowest to highest.

params = {"ytick.color" : "b",
          "xtick.color" : "b",
          "axes.labelcolor" : "w",
          "axes.edgecolor" : "w"}

pyplot.rcParams.update(params)
fig, ax = pyplot.subplots(figsize = (14, 4))
ax = pyplot.gca();
extent = (0, matrix.shape[0], matrix.shape[1], 0)
ax.imshow(matrix.transpose(), cmap=pyplot.cm.RdYlGn)

ax.set_yticks(np.arange(len(s_names)), labels = list(matrix.columns))
ax.set_yticks(np.arange(-0.5, len(s_names),1), minor=True)
ax.set_xticks(np.arange(-0.5, len(dates_),1), minor=True)
pyplot.xticks(rotation=90)


ax.set_aspect(1)
ax.grid(color="w", linewidth=3, which='minor')

当前代码生成的热力图X轴效果:
当前X轴效果

我期望实现的X轴样式:
期望X轴效果


修改方案

要实现目标样式,核心是只在日期分界点显示主刻度标签,同时保留网格分隔每个时间段。修改后的完整代码如下:

import matplotlib as mplt
from matplotlib import dates, pyplot
import numpy as np
import pandas as pd
import datetime

s_names = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 分类
dates_ = pd.date_range('2023/01/01', '2023/01/08', freq='3H', tz='utc') # 创建时间索引
matrix = pd.DataFrame(columns=s_names, index=dates_) # 初始化DataFrame

# 填充随机数
matrix = matrix.applymap(lambda l: l if not np.isnan(l) else np.random.choice(range(1, 10))) 

# 按第一行排序列
matrix.sort_values(by=matrix.index[0], ascending=True, axis=1, inplace=True) 

# 设置全局参数
params = {"ytick.color" : "b",
          "xtick.color" : "b",
          "axes.labelcolor" : "w",
          "axes.edgecolor" : "w"}

pyplot.rcParams.update(params)
fig, ax = pyplot.subplots(figsize = (14, 4))

# 绘制热力图
ax.imshow(matrix.transpose(), cmap=pyplot.cm.RdYlGn)

# Y轴设置
ax.set_yticks(np.arange(len(s_names)), labels = list(matrix.columns))
ax.set_yticks(np.arange(-0.5, len(s_names),1), minor=True)

# -------------------------- 关键修改:X轴设置 --------------------------
# 1. 获取每天起始时刻对应的索引位置
daily_starts = dates_.to_series().groupby(dates_.date).first().index
tick_positions = [dates_.get_loc(dt) for dt in daily_starts]

# 2. 设置主刻度:只显示每天的日期标签
ax.set_xticks(tick_positions, labels=[dt.strftime('%Y-%m-%d') for dt in daily_starts])

# 3. 设置次要刻度:用于分隔每个3小时时间段,显示网格
ax.set_xticks(np.arange(-0.5, len(dates_), 1), minor=True)

# 旋转X轴标签,优化可读性
pyplot.xticks(rotation=45)

# 网格和比例设置
ax.set_aspect('auto') # 避免图形被过度压缩
ax.grid(color="w", linewidth=3, which='minor')

pyplot.tight_layout()
pyplot.show()

修改说明

  • 提取每天的起始位置作为主刻度,仅显示日期标签,避免过多刻度重叠
  • 保留次要刻度用于分隔每个3小时时间段,维持原有的白色网格线样式
  • 将set_aspect(1)改为set_aspect('auto'),防止热力图被压缩导致X轴拥挤
  • 调整标签旋转角度为45度,比90度更易阅读
  • 加入tight_layout()优化整体布局,避免标签被截断

内容的提问来源于stack exchange,提问作者AGS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 19:15:02