基于ggmosaic实现与观测数成比例的分面Mosaic Plot
问题描述
我有一份包含两个逻辑变量(处理变量tx、结果变量permissive)和一个分类变量organism的数据集,需要以organism为分面绘制马赛克图(部分样本属于多个分类)。但不同分类的观测数相差一个数量级,用facet_wrap时分面会被自动缩放,没法体现观测数的比例——我希望spe分面的面积是ory分面的10倍,以此匹配两者的观测数差异。目前使用ggmosaic包的代码如下:
total_plot <- ggplot(tx_fig_data) + geom_mosaic(aes(x = product(permissive), fill = tx), show.legend = FALSE) + theme_mosaic() + geom_mosaic_text(aes(x = product(permissive), fill = tx, label = after_stat(.wt)), show.legend = FALSE) + facet_wrap(facets = vars(organism))
解决方法
ggmosaic配合facet_wrap无法直接实现分面面积与观测数成比例,可通过patchwork包手动按比例拼接子图,步骤如下:
1. 拆分数据集并计算观测数比例
先统计每个分类的观测数,计算占比以确定子图尺寸比例:
library(dplyr) library(ggmosaic) library(patchwork) # 统计各organism的观测数及占比 count_stats <- tx_fig_data %>% count(organism) %>% mutate(prop = n / sum(n)) # 按organism拆分数据集 split_datasets <- split(tx_fig_data, tx_fig_data$organism)
2. 生成单个分类的马赛克图
循环为每个分类绘制独立的马赛克图:
subplots <- lapply(names(split_datasets), function(org) { ggplot(split_datasets[[org]]) + geom_mosaic(aes(x = product(permissive), fill = tx), show.legend = FALSE) + theme_mosaic() + geom_mosaic_text(aes(x = product(permissive), fill = tx, label = after_stat(.wt)), show.legend = FALSE) + labs(title = org) })
3. 按观测数比例拼接子图
根据观测数占比设置子图的宽度/高度比例,比如spe与ory观测数为10:1时:
# 提取目标分类的比例 spe_prop <- count_stats$prop[count_stats$organism == "spe"] ory_prop <- count_stats$prop[count_stats$organism == "ory"] # 按宽度比例拼接图 final_plot <- subplots[[which(names(split_datasets) == "spe")]] + subplots[[which(names(split_datasets) == "ory")]] + plot_layout(widths = c(spe_prop, ory_prop))
补充说明
- 若有多个分类,直接将
widths参数设为所有分类的观测数比例向量即可 - 如需按高度比例调整,将
widths替换为heights - 该方法可精准控制分面大小,完全匹配观测数的差异
内容的提问来源于stack exchange,提问作者MZimbric
相关产品推荐
相关产品推荐

