在空的分面中移动图例。
我在使用 facet_wrap2 为不同染色体绘制一些数据。问题是,在 chr19 和 chr20 下方有一些空白区域,我想把图例移到那里。
因此,我在参考了这篇帖子,并且特别使用 shift_legend2() 函数,但在运行时
grid.draw(shift_legend2(p))
我总是得到如下信息:
There are no unfilled facet panels to shift legend into. Returning original plot.
这是我的代码、输出(期望值),以及数据的一个 dput()。
library(grid)
library(ggh4x)
library(ggsci)
library(ggplot2)
library(cowplot)
library(ggchicklet)
p <- ggplot(excel_m) +
geom_chicklet(mapping=aes(x=SAMPLE, y=COUNT, fill=V_TYPE), position="dodge2", radius=grid:: unit(1, "mm")) +
facet_wrap2(~CHR, ncol=5, strip.position="left", scale="free_y") + theme_bw() +
scale_fill_npg() + guides(fill=guide_legend(title='variants', title.position='top',
title.hjust=.5, position="bottom")) +
theme(legend.title=element_text(face='italic', size=16), legend.position='bottom',
panel.grid=element_blank(), axis.text.x=element_text(face='bold',
angle=45,
hjust=1),
axis.title.x=element_blank(), axis.title.y=element_blank(),
legend.text=element_text(size=12),
axis.title=element_text(size=14),
axis.text=element_text(size=10)) +
xlab(NULL) + ylab(NULL)
p

excel_m <- structure(list(CHR = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L,
10L, 10L, 10L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L,
11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L,
12L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L,
14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 15L,
15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L,
16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 17L, 17L, 17L,
17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L,
18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 19L,
19L, 19L, 19L, 19L, 19L, 19L, 19L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L,
20L, 20L, 20L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L,
21L, 21L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L,
22L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L,
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L,
5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L,
6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L,
8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L,
9L, 9L, 9L, 9L, 9L, 9L, 23L, 23L, 23L, 23L, 23L, 23L, 23L, 23L,
23L, 23L, 23L, 23L), levels = c("chr1", "chr2", "chr3", "chr4",
"chr5", "chr6", "chr7", "chr8", "chr9", "chr10", "chr11", "chr12",
"chr13", "chr14", "chr15", "chr16", "chr17", "chr18", "chr19",
"chr20", "chr21", "chr22", "chrX"), class = "factor"), GRAPH = c("clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt",
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt",
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt",
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt",
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt",
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt",
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt",
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt",
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt",
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt",
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt",
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt",
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt",
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt",
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt",
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt",
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt",
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt",
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt",
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt",
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt",
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt",
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt",
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt",
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt",
"irradiated_prt"), SAMPLE = structure(c(1L, 1L, 1L, 2L, 2L, 2L,
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L,
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L,
1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L,
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L,
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L,
1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L,
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L,
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L,
1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L,
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L,
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L,
1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L,
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L,
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L,
1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L,
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L,
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L), levels = c("clone4_12w",
"clone5_12w", "clone7_12w", "irradiated_24h"), class = "factor"),
V_TYPE = structure(c(2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L), levels = c("all",
"SNPs", "INDELs"), class = "factor"), COUNT = c(7736, 1179,
8915, 7737, 1178, 8915, 7724, 1178, 8902, 7737, 1179, 8916,
4015, 1234, 5249, 4042, 1252, 5294, 4054, 1227, 5281, 4091,
1269, 5360, 56568, 14994, 71562, 56505, 14984, 71489, 56567,
15021, 71588, 56499, 15005, 71504, 2280, 392, 2672, 2277,
392, 2669, 2280, 393, 2673, 2280, 391, 2671, 1194, 315, 1509,
1155, 312, 1467, 1238, 330, 1568, 1244, 339, 1583, 5842,
1311, 7153, 7214, 1527, 8741, 7267, 1586, 8853, 7117, 1491,
8608, 2170, 461, 2631, 2539, 485, 3024, 2689, 532, 3221,
2556, 485, 3041, 490, 122, 612, 506, 124, 630, 493, 124,
617, 495, 125, 620, 1944, 253, 2197, 1935, 253, 2188, 1934,
250, 2184, 1919, 252, 2171, 1437, 223, 1660, 1436, 221, 1657,
1437, 220, 1657, 1446, 220, 1666, 2308, 220, 2528, 2293,
216, 2509, 2242, 208, 2450, 2276, 217, 2493, 43954, 11844,
55798, 43993, 11820, 55813, 43969, 11822, 55791, 44112, 11855,
55967, 2305, 414, 2719, 2303, 409, 2712, 2321, 397, 2718,
2272, 412, 2684, 1392, 275, 1667, 1432, 274, 1706, 1709,
315, 2024, 1590, 284, 1874, 4535, 1079, 5614, 5119, 1203,
6322, 4933, 1182, 6115, 4629, 1096, 5725, 2342, 348, 2690,
2351, 349, 2700, 2321, 340, 2661, 2326, 350, 2676, 62163,
16474, 78637, 61949, 16370, 78319, 62092, 16438, 78530, 62055,
16364, 78419, 66217, 17925, 84142, 66188, 17884, 84072, 66283,
17937, 84220, 66346, 17931, 84277, 2176, 382, 2558, 2145,
379, 2524, 2175, 389, 2564, 2264, 386, 2650, 5047, 912, 5959,
5099, 918, 6017, 5107, 911, 6018, 5141, 921, 6062, 787, 138,
925, 792, 140, 932, 799, 142, 941, 780, 137, 917, 23656,
8408, 32064, 23644, 8407, 32051, 23743, 8415, 32158, 23661,
8397, 32058, 1215, 118, 1333, 1167, 111, 1278, 1218, 119,
1337, 1242, 123, 1365)), row.names = c(NA, -276L), spec = structure(list(
cols = list(CHR = structure(list(), class = c("collector_character",
"collector")), GRAPH = structure(list(), class = c("collector_character",
"collector")), SAMPLE = structure(list(), class = c("collector_character",
"collector")), V_TYPE = structure(list(), class = c("collector_character",
"collector")), COUNT = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), delim = "\t"), class = "col_spec"), problems = <pointer: 0x835b80460>, class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"))
解决方案
Following and updating my comment, you can use lemon::reposition_legend() to bring the legend into one of the facets. Up front, though, we can't use facet_wrap2() since that doesn't label the empty panes in a way that lemon expects to see; fortunately I think you are not using anything that causes facet_wrap2() to look different from ggplot2::facet_wrap, so the shift is easy enough. Shift to the bottom if you want to see how I came about this.
If we start with your vanilla code, adjusted to not use facet_wrap2(), then
p <- ggplot(excel_m) +
geom_chicklet(mapping=aes(x=SAMPLE, y=COUNT, fill=V_TYPE), position="dodge2", radius=grid:: unit(1, "mm")) + theme_bw() +
facet_wrap(~CHR, ncol = 5, strip.position = "left", scales = "free_y") +
scale_fill_npg() + guides(fill=guide_legend(title='variants', title.position='top',
title.hjust=.5, position="bottom")) +
theme(legend.title=element_text(face='italic', size=16), legend.position='bottom',
panel.grid=element_blank(), axis.text.x=element_text(face='bold',
angle=45,
hjust=1),
axis.title.x=element_blank(), axis.title.y=element_blank(),
legend.text=element_text(size=12),
axis.title=element_text(size=14),
axis.text=element_text(size=10)) +
xlab(NULL) + ylab(NULL)
Now all we need to do is
lemon::reposition_legend(p, position="bottom right", panel = "panel-5-5")
Why not facet_wrap2()
reposition_legend() 需要同时具备 position=(例如“右下”)和 pane=,这是面板的其中一个名称。阅读 ?reposition_legend,它友好地给出两种确定它们的方法;因为第一种方法提供了可视化参考,所以我会使用它。
lemon::gtable_show_names(p)
[
显然,目标窗格没有名称使这件事变得困难。我没有在 facet_wrap2() 中看到一个能让这件事变得简单的选项,因此我选择使用 ggplot2::facet_wrap(),它的绘图略有不同,从 panel-19 命名法转变为 panel-{col}-{row}:

