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

ggplot2中geom_tile的动态缩放实现技术问询

问题需求

我有如下结构的数据框:

x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 proportion index cumulative_proportion
1  0 -1  0  0  0 -1  1  1  0   1   0   0    0.28423     1               0.28423
2  0 -1  0  0  0 -1  1  1  1   1   0   0    0.20511     2               0.48934
3  1 -1  0  0  0 -1  1  1  0   1   0   0    0.05751     3               0.54685
4  0 -1  0  0  1 -1  1  1  0   1   0   0    0.02388     4               0.57073
5  0 -1  0  0  0 -1  1  1  0   1   1   0    0.02217     5               0.59290
6  0 -1  0  0  0 -1  1  1  0   1   0   1    0.02098     6               0.61388

我想用geom_tile()做可视化,要求:

  • 将变量x1至x12放在y轴
  • x轴基于分类变量index,但要显示cumulative_proportion的数值
  • 瓷砖填充色由变量值-1、0、1决定
  • 瓷砖按proportion的大小进行宽度缩放

以下是未按比例缩放的基础代码:

plot.df <- reshape2::melt(plot.df, id.vars=c("index", "proportion", "cumulative_proportion"))
ggplot(plot.df, aes(x=index, y=variable, fill=as.factor(value))) +
  geom_tile() 

完整的数据框结构如下:

structure(list(x1 = c(0, 0, 1, 0, 0, 0, 1, 0, 0, 1), x2 = c(-1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1), x3 = c(0, 0, 0, 0, 0, 0, 
0, 0, 0, 1), x4 = c(0, 0, 0, 0, 0, 0, 0, 1, 1, 0), x5 = c(0, 
0, 0, 1, 0, 0, 0, 0, 0, 0), x6 = c(-1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1), x7 = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), x8 = c(1, 
1, 1, 1, 1, 1, 1, 1, 1, 1), x9 = c(0, 1, 0, 0, 0, 0, 0, 0, 0, 
0), x10 = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), x11 = c(0, 0, 0, 0, 
1, 0, 0, 0, 0, 0), x12 = c(0, 0, 0, 0, 0, 1, 1, 0, 1, 0), proportion = c(0.28423, 
0.20511, 0.05751, 0.02388, 0.02217, 0.02098, 0.0165, 0.01383, 
0.01185, 0.01013), index = 1:10, cumulative_proportion = c(0.28423, 
0.48934, 0.54685, 0.57073, 0.5929, 0.61388, 0.63038, 0.64421, 
0.65606, 0.66619)), row.names = c(NA, -10L), class = "data.frame")
解决方案

要实现瓷砖按proportion缩放,同时x轴显示cumulative_proportion,需要先计算每个瓷砖的左右边界位置,再映射到geom_tile()的参数中:

  1. 数据预处理:
library(tidyverse)
library(reshape2)

# 加载完整数据框
plot.df <- structure(list(x1 = c(0, 0, 1, 0, 0, 0, 1, 0, 0, 1), x2 = c(-1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1), x3 = c(0, 0, 0, 0, 0, 0, 
0, 0, 0, 1), x4 = c(0, 0, 0, 0, 0, 0, 0, 1, 1, 0), x5 = c(0, 
0, 0, 1, 0, 0, 0, 0, 0, 0), x6 = c(-1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1), x7 = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), x8 = c(1, 
1, 1, 1, 1, 1, 1, 1, 1, 1), x9 = c(0, 1, 0, 0, 0, 0, 0, 0, 0, 
0), x10 = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), x11 = c(0, 0, 0, 0, 
1, 0, 0, 0, 0, 0), x12 = c(0, 0, 0, 0, 0, 1, 1, 0, 1, 0), proportion = c(0.28423, 
0.20511, 0.05751, 0.02388, 0.02217, 0.02098, 0.0165, 0.01383, 
0.01185, 0.01013), index = 1:10, cumulative_proportion = c(0.28423, 
0.48934, 0.54685, 0.57073, 0.5929, 0.61388, 0.63038, 0.64421, 
0.65606, 0.66619)), row.names = c(NA, -10L), class = "data.frame")

# 计算每个瓷砖的左右边界:x_start为前一组的累积比例(第一组为0),x_end为当前组的累积比例
plot.df <- plot.df %>%
  mutate(x_start = lag(cumulative_proportion, default = 0),
         x_end = cumulative_proportion)

# 宽表转长表,保留边界信息
plot.df_long <- reshape2::melt(plot.df, id.vars=c("index", "proportion", "cumulative_proportion", "x_start", "x_end"))
  1. 绘制可视化图形:
ggplot(plot.df_long, aes(y = variable)) +
  # 用xmin/xmax定义瓷砖宽度,ymin/ymax确保瓷砖与y轴变量对齐
  geom_tile(aes(xmin = x_start, xmax = x_end, ymin = as.numeric(variable)-0.5, ymax = as.numeric(variable)+0.5, fill = as.factor(value))) +
  # 设置x轴刻度为累积比例值,保留4位小数
  scale_x_continuous(breaks = plot.df$cumulative_proportion, labels = round(plot.df$cumulative_proportion, 4)) +
  # 手动指定-1/0/1对应的填充色,提升可读性
  scale_fill_manual(values = c("-1" = "darkblue", "0" = "white", "1" = "darkred"), name = "变量值") +
  # 设置标签和标题
  labs(x = "累积比例", y = "变量", title = "按比例缩放的瓷砖图") +
  theme_bw()

核心说明:

  • 通过x_start和x_end的差值(即proportion)实现瓷砖宽度的按比例缩放
  • scale_x_continuous直接将x轴刻度替换为cumulative_proportion的数值,满足显示需求
  • 手动映射填充色让不同取值的瓷砖区分度更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:35:06