Python中如何使用Matplotlib偏移/平移绘图的网格位置
存在-缺失模式图网格偏移半个步长实现方案
问题本质是默认网格线与坐标轴整数刻度对齐,而表示存在/缺失的方块中心恰好落在整数刻度上,导致方块与网格线重叠、视觉杂乱。只要将网格线整体偏移0.5个步长,让网格线卡在相邻方块的缝隙位置即可,以下是两种最常用绘图工具的实现代码:
Python(Matplotlib/Seaborn环境)
- 实现逻辑:放弃默认自动生成的主网格,利用次刻度(minor ticks)设置偏移0.5单位的网格位置,同时将坐标轴主刻度移回整数位置对齐方块中心。
import matplotlib.pyplot as plt import numpy as np # 生成演示用存在-缺失矩阵:1=存在,0=缺失,维度为10个样本×15个特征 pa_matrix = np.random.randint(0, 2, size=(10, 15)) fig, ax = plt.subplots(figsize=(10, 6)) # 绘制方块热图,interpolation设为nearest保证方块边缘锐利无模糊 ax.imshow(pa_matrix, cmap="binary", aspect="auto", interpolation="nearest") # 核心:生成偏移0.5的网格线位置 x_lim = ax.get_xlim() y_lim = ax.get_ylim() x_grid = np.arange(np.floor(x_lim[0]), np.ceil(x_lim[1]) + 1) + 0.5 y_grid = np.arange(np.floor(y_lim[0]), np.ceil(y_lim[1]) + 1) + 0.5 # 将偏移位置设为次刻度,仅在次刻度位置绘制网格 ax.set_xticks(x_grid, minor=True) ax.set_yticks(y_grid, minor=True) ax.grid(which="minor", color="#e5e5e5", linewidth=0.7, linestyle="-") # 关闭默认主刻度网格,避免重叠 ax.grid(which="major", visible=False) # 将坐标轴标签刻度对齐到每个方块的中心 ax.set_xticks(np.arange(pa_matrix.shape[1])) ax.set_yticks(np.arange(pa_matrix.shape[0])) # 替换为实际的样本、特征标签即可 ax.set_xticklabels([f"Feature_{i+1}" for i in range(pa_matrix.shape[1])], rotation=90) ax.set_yticklabels([f"Sample_{i+1}" for i in range(pa_matrix.shape[0])]) plt.tight_layout() plt.show()
- 补充:如果用
seaborn.heatmap绘制,可直接传入linewidths=0.5, linecolor="#e5e5e5"参数,会自动在方块间隙生成分隔线,无需手动调整网格。
R(ggplot2环境)
- 实现逻辑:关闭默认主题自带的网格,手动添加横线、竖线作为网格,将线的位置统一偏移0.5单位。
library(ggplot2) set.seed(123) # 生成长格式演示数据 pa_df <- expand.grid( sample = paste0("Sample_", 1:10), feature = paste0("Feature_", 1:15) ) pa_df$present <- sample(c(0, 1), size = nrow(pa_df), replace = TRUE) ggplot(pa_df, aes(x = feature, y = sample, fill = factor(present))) + geom_tile() + # 移除坐标轴多余留白 scale_x_discrete(expand = c(0, 0)) + scale_y_discrete(expand = c(0, 0)) + # 核心:手动添加偏移0.5的网格线 geom_vline( xintercept = seq(0.5, length(unique(pa_df$feature)) + 0.5, 1), color = "grey90", linewidth = 0.3 ) + geom_hline( yintercept = seq(0.5, length(unique(pa_df$sample)) + 0.5, 1), color = "grey90", linewidth = 0.3 ) + # 存在状态用黑色填充,缺失用白色填充,隐藏图例 scale_fill_manual(values = c("white", "black"), guide = "none") + theme_minimal() + theme( axis.text.x = element_text(angle = 90, hjust = 1), panel.grid = element_blank() # 关闭默认网格 )
实现后的效果参考:
内容的提问来源于stack exchange,提问作者Martn
相关产品推荐
相关产品推荐

