如何在ggplotly的facet_wrap中按指定垂直顺序排列密度图?
问题:调整facet_wrap子图排列顺序,实现A1&B1、A2&B2、A3&B3同行展示
我有一个7列的数据集,首列为Majority protein IDs,其余6列为数值列(A1、A2、A3、B1、B2、B3)。用ggplot2的facet_wrap绘制密度图并转为ggplotly后,子图排列不符合需求,想要实现如下布局:
A1 B1 A2 B2 A3 B3
数据集示例
structure(list(`Majority protein IDs` = c("P19882", "P38999", "P34227", "Q12335", "P40893", "P33416", "Q04947", "Q12074", "P38116", "P32598", "P38221", "P52910", "P0CX51;P0CX52", "Q02805", "P50861", "Q02821", "P53691", "P19414", "Q04013", "Q07799", "P47039"), A1 = c(964860000, 46301000, 135090000, 126280000, 96191000, 91552000, 75231000, 76684000, 6150500, 21904000, 55134000, 231070000, 259060000, 7304500, 180320000, 22025000, 79510000, 677560000, 5994400, 18950000, 3468200), A2 = c(1074500000, 42888000, 125590000, 1.27e+08, 68911000, 93280000, 66457000, 69568000, 4848600, 20342000, 52573000, 242230000, 286970000, 5770200, 190140000, 22305000, 87598000, 673050000, 6459300, 21634000, 3115400), A3 = c(1021200000, 56550000, 117190000, 124730000, 69026000, 80712000, 55917000, 71989000, 5390500, 19299000, 51348000, 213050000, 254080000, 6976000, 181280000, 20951000, 83504000, 664590000, 6155300, 21158000, 2940600), B1 = c(846340000, 34713000, 95928000, 121440000, 16256000, 63182000, 46570000, 59008000, 1465600, 24838000, 48464000, 176140000, 175320000, 8738500, 120870000, 24496000, 75694000, 524780000, 4373900, 16281000, 5801700), B2 = c(921740000, 35240000, 109990000, 111250000, 39047000, 74125000, 51027000, 65971000, 3027100, 36529000, 39712000, 179630000, 218240000, 8092500, 152610000, 26032000, 62681000, 587100000, 4887000, 18454000, 3811100), B3 = c(908710000, 38475000, 106400000, 113590000, 36745000, 74175000, 48912000, 64201000, 3073300, 39069000, 40650000, 206350000, 220280000, 8673100, 154260000, 30254000, 61422000, 617900000, 5561000, 17102000, 5486600)), row.names = c(NA, -21L), class = c("tbl_df", "tbl", "data.frame"))
现有实现代码
Densityplot_data <- function (data){ variable <- value <- NULL new_data <- as.data.frame(data) new_data <- new_data[,-1] options(warn = -1) density_plot <- new_data %>% tibble::as.tibble() %>% tidyr::gather(variable, value) %>% ggplot2::ggplot(ggplot2::aes(x=value) ) + ggplot2::geom_density (fill= "#69b3a2") + ggplot2::facet_wrap(~variable, scales="free", nrow = 3, dir = "v")+ ggplot2::theme_gray()+ ggplot2::theme(text = ggplot2::element_text(size = 20)) return(plotly::ggplotly(density_plot)) } Densityplot_data(testdata)
解决方案
要实现目标布局,核心是强制指定子图的排列顺序,让facet_wrap按照需求的顺序渲染。修改步骤如下:
- 将
variable转为有序因子:按照A1, B1, A2, B2, A3, B3的顺序定义因子水平,确保facet严格按此顺序排列。 - 调整facet_wrap参数:保持
scales="free",指定nrow=3,使用默认的横向填充方式(无需dir="v")。
修改后的完整代码
Densityplot_data <- function (data){ variable <- value <- NULL new_data <- as.data.frame(data)[,-1] options(warn = -1) density_plot <- new_data %>% tibble::as.tibble() %>% tidyr::gather(variable, value) %>% # 强制指定变量的展示顺序 dplyr::mutate(variable = factor(variable, levels = c("A1", "B1", "A2", "B2", "A3", "B3"))) %>% ggplot2::ggplot(ggplot2::aes(x=value) ) + ggplot2::geom_density(fill= "#69b3a2") + # 设置3行,按因子顺序横向填充子图 ggplot2::facet_wrap(~variable, scales="free", nrow = 3)+ ggplot2::theme_gray()+ ggplot2::theme(text = ggplot2::element_text(size = 20)) return(plotly::ggplotly(density_plot)) } # 调用函数生成符合要求的图 Densityplot_data(testdata)
关键说明
factor(variable, levels = ...):直接定义子图的展示顺序,facet_wrap会严格遵循这个顺序排列。nrow=3:指定3行布局,ggplot默认的横向填充(dir="h")会自动将前两个因子放在第一行,中间两个在第二行,最后两个在第三行,正好匹配需求的A1&B1、A2&B2、A3&B3同行布局。- 移除
dir="v":该参数会让子图纵向填充,不符合目标排列逻辑。
内容的提问来源于stack exchange,提问作者KABILAN
相关产品推荐
相关产品推荐

