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

如何用geom_tile实现单瓦片多颜色填充的矩阵图?

解决geom_tile同一瓦片多数据的分块填充问题

我使用geom_tile创建矩阵图时,发现同一瓦片对应多行数据,导致颜色叠加。希望为每个瓦片填充其对应的多种颜色,理想效果为矩形分块填充。

当前代码

# Create color palette
par(mar=c(0,0,1,0))

coul <- brewer.pal(9, "Set3") 

ggplot(plot_data, aes(x = from, y = to, fill = agreement_num)) +
  geom_tile() +
  scale_fill_manual(values = coul) +
  theme_bw() +
  scale_x_discrete(drop = FALSE) +
  scale_y_discrete(drop = FALSE) +
  theme(
    axis.text.x = element_text(size = 9,angle = 270, hjust = 0,vjust=0),
    axis.text.y = element_text(size = 9),
    aspect.ratio = 1)

可复现数据

plot_data <- structure(list(from = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, NA, NA, NA, NA), levels = c("Afghanistan", 
"Kazakhstan", "Kyrgyzstan", "Tajikistan", "Turkmenistan", "Uzbekistan"
), class = "factor"), to = structure(c(1L, 3L, 3L, 3L, 3L, 3L, 
3L, 4L, 4L, 4L, 5L, 5L, 6L, 6L, 2L, 6L, NA, NA, NA, NA), levels = c("Afghanistan", 
"Kazakhstan", "Kyrgyzstan", "Tajikistan", "Turkmenistan", "Uzbekistan"
), class = "factor"), weight = c(1291072130433.34, 480160896152.234, 
480160896152.234, 480160896152.234, 480160896152.234, 480160896152.234, 
480160896152.234, 3474907531417.02, 3474907531417.02, 3474907531417.02, 
867103764128.709, 867103764128.709, 7791981051421.92, 7791981051421.92, 
133799551.098735, 1102379004.66647, NA, NA, NA, NA), agreement_num = structure(c(NA, 
1L, 5L, 2L, 6L, 3L, 4L, 2L, 1L, 6L, 1L, 6L, 1L, 6L, NA, NA, NA, 
NA, NA, NA), levels = c("51", "58", "133", "135", "176", "224"
), class = "factor")), row.names = c("1", "2", "3", "4", "5", 
"6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", 
"NA", "NA.1", "NA.2", "NA.3"), class = "data.frame")

解决方案

要实现瓦片内的分块填充,需将单个瓦片拆分为对应数量的小矩形,每个小矩形对应一个agreement_num。以下是完整实现代码:

library(ggplot2)
library(dplyr)
library(RColorBrewer)

# 清理数据:移除含NA的行
clean_data <- plot_data %>%
  filter(!is.na(from), !is.na(to), !is.na(agreement_num)) %>%
  # 按from和to分组,给每个组内的条目分配顺序
  group_by(from, to) %>%
  mutate(
    group_size = n(),
    tile_width = 1 / group_size,
    # 将离散的from转换为数值,计算每个小矩形的x范围
    x_num = as.integer(from),
    xmin = x_num - 0.5 + (row_number() - 1) * tile_width,
    xmax = x_num - 0.5 + row_number() * tile_width,
    # y轴同理转换为数值,保持整个瓦片的y范围
    y_num = as.integer(to),
    ymin = y_num - 0.5,
    ymax = y_num + 0.5
  ) %>%
  ungroup()

# 创建调色板
coul <- brewer.pal(9, "Set3")

# 绘制分块矩阵图
ggplot(clean_data) +
  geom_rect(aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = agreement_num)) +
  # 设置x、y轴的刻度和标签,还原离散分类
  scale_x_continuous(
    breaks = 1:length(levels(plot_data$from)),
    labels = levels(plot_data$from),
    expand = c(0, 0)
  ) +
  scale_y_continuous(
    breaks = 1:length(levels(plot_data$to)),
    labels = levels(plot_data$to),
    expand = c(0, 0)
  ) +
  scale_fill_manual(values = coul, na.value = "white") +
  theme_bw() +
  theme(
    axis.text.x = element_text(size = 9, angle = 270, hjust = 0, vjust = 0),
    axis.text.y = element_text(size = 9),
    aspect.ratio = 1
  )

代码说明

  • 数据处理:先过滤无效的NA行,再按from和to分组,计算每个瓦片内的条目数量,进而得到每个小矩形的宽度比例。将离散的分类轴转换为数值,计算每个小矩形的边界坐标。
  • 绘图逻辑:用geom_rect替代geom_tile,直接绘制每个小分块,确保每个agreement_num对应独立的矩形区域,避免颜色叠加。
  • 轴设置:通过scale_x_continuous和scale_y_continuous还原离散分类的标签和刻度,保持原矩阵图的外观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 11:04:55