当制作同时具有
geom_point()
和 color = column_1
选项的 size = column_2
时,ggplot 提供了两个单独的图例。一种用于颜色列,另一种用于尺寸。这太棒了。
我想拆分两个图例,以便映射到
color
的位水平显示在顶部,映射到 size
的位垂直显示在绘图区域的右侧。
下面的数据和代码重现了如下所示的图表。在该图中,我希望垂直显示在图表右侧尺寸上的尺寸以及映射到演员姓名的位按原样沿顶部显示。
这种事情可能吗?我已经找到了将它们都放在左侧的方法,但这并不是我真正想要的,因为你在情节中从左到右阅读演员的名字,并且从上到下阅读尺寸,所以我希望图例以与读者自然读取数据相同的方式显示。
df <- structure(list(count = c(1025, 360, 625, 1108, 3018, 7376, 16318,
19114, 16947, 21532, 2088, 923, 1109, 1751, 3710, 7160, 13904,
20096, 17049, 24597, 2094, 607, 817, 1340, 2909, 6667, 13870,
18657, 17502, 34533, 1132, 447, 606, 940, 2038, 4564, 12141,
19197, 18426, 31272, 1144, 387, 646, 1081, 2164, 5451, 12343,
16194, 16783, 24880, 1450, 549, 759, 1278, 2568, 5623, 11406,
15957, 16445, 22850, 1707, 788, 1023, 1594, 3292, 6852, 14749,
18550, 13815, 19754, 1977, 819, 1051, 1522, 2873, 5469, 10692,
14740, 12352, 16335, 1256, 554, 633, 946, 1780, 3301, 6260, 10608,
11575, 20720, 1365, 547, 565, 1066, 2177, 4650, 9590, 11570,
8160, 11119, 13175, 3088, 2869, 3375, 5123, 7292, 9714, 9088,
5927, 10775, 8387, 1954, 1817, 1996, 2776, 3972, 5746, 5968,
3965, 5969), doctor = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L,
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L,
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L,
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L,
5L), .Label = c("Christopher Eccleston", "David Tennant", "Matt Smith",
"Peter Capaldi", "Jodie Whitaker"), class = "factor"), rating = c(1,
2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1,
2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1,
2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1,
2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1,
2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1,
2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10), season_num = c(27L,
27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 28L, 28L, 28L, 28L,
28L, 28L, 28L, 28L, 28L, 28L, 29L, 29L, 29L, 29L, 29L, 29L, 29L,
29L, 29L, 29L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L,
31L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 32L, 32L, 32L,
32L, 32L, 32L, 32L, 32L, 32L, 32L, 33L, 33L, 33L, 33L, 33L, 33L,
33L, 33L, 33L, 33L, 34L, 34L, 34L, 34L, 34L, 34L, 34L, 34L, 34L,
34L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 36L, 36L,
36L, 36L, 36L, 36L, 36L, 36L, 36L, 36L, 37L, 37L, 37L, 37L, 37L,
37L, 37L, 37L, 37L, 37L, 38L, 38L, 38L, 38L, 38L, 38L, 38L, 38L,
38L, 38L)), row.names = c(NA, -120L), groups = structure(list(
season_num = 27:38, .rows = structure(list(1:10, 11:20, 21:30,
31:40, 41:50, 51:60, 61:70, 71:80, 81:90, 91:100, 101:110,
111:120), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), row.names = c(NA, -12L), class = c("tbl_df",
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
df %>%
ggplot() +
geom_point(aes(x = factor(season_num), y = rating, size = count, color = doctor)) +
labs(x = "Season", y = "Rating (1-10)", title = "IMDb ratings distributions by Season") +
theme(legend.position = 'top',
legend.title = element_blank(),
plot.title = element_text(size = 10),
axis.title.x = element_text(size = 10),
axis.title.y = element_text(size = 10)) +
scale_size_continuous(range = c(1,8)) +
scale_y_continuous(limits=c(1, 10), breaks=c(seq(1, 10, by = 1))) +
scale_x_discrete(breaks=c(seq(27, 38, by = 1))) +
scale_color_brewer(palette = "Dark2")
我认为仅使用
ggplot2
功能是不可能的。然而,一个常见的技巧是:
cowplot
或 gridExtra
您可以在 SO 上找到此过程的一些示例:
这是一个提供数据的示例,我没有花太多精力来排列网格,因为它可能会根据您最终选择的包而发生很大变化。只是为了展示过程。
library(cowplot)
library(ggplot2)
# plot without legend
main_plot <- ggplot(data = df) +
geom_point(aes(x = factor(season_num), y = rating, size = count, color = doctor)) +
labs(x = "Season", y = "Rating (1-10)", title = "IMDb ratings distributions by Season") +
theme(legend.position = 'none',
legend.title = element_blank(),
plot.title = element_text(size = 10),
axis.title.x = element_text(size = 10),
axis.title.y = element_text(size = 10)) +
scale_size_continuous(range = c(1,8)) +
scale_y_continuous(limits=c(1, 10), breaks=c(seq(1, 10, by = 1))) +
scale_x_discrete(breaks=c(seq(27, 38, by = 1))) +
scale_color_brewer(palette = "Dark2")
# color legend, top, horizontally
color_plot <- ggplot(data = df) +
geom_point(aes(x = factor(season_num), y = rating, color = doctor)) +
theme(legend.position = 'top',
legend.title = element_blank()) +
scale_color_brewer(palette = "Dark2")
color_legend <- cowplot::get_legend(color_plot)
# size legend, right-hand side, vertically
size_plot <- ggplot(data = df) +
geom_point(aes(x = factor(season_num), y = rating, size = count)) +
theme(legend.position = 'right',
legend.title = element_blank()) +
scale_size_continuous(range = c(1,8))
size_legend <- cowplot::get_legend(size_plot)
# combine all these elements
cowplot::plot_grid(plotlist = list(color_legend,NULL, main_plot, size_legend),
rel_heights = c(1, 5),
rel_widths = c(4, 1))
输出:
在 ggplot 3.5.0 update 中通过
guide_legend()
position
参数解决。例如
ggplot(data = df) +
geom_point(aes(x = factor(season_num), y = rating, size = count, color = doctor)) +
labs(x = "Season", y = "Rating (1-10)", title = "IMDb ratings distributions by Season") +
theme_minimal() +
theme(
legend.title = element_blank(),
plot.title = element_text(size = 10),
axis.title.x = element_text(size = 10),
axis.title.y = element_text(size = 10)) +
scale_size_continuous(range = c(1,8)) +
scale_y_continuous(limits=c(1, 10), breaks=c(seq(1, 10, by = 1))) +
scale_x_discrete(breaks=c(seq(27, 38, by = 1))) +
scale_color_brewer(palette = "Dark2") +
guides(
colour = guide_legend(position = "top"),
size = guide_legend(position = "right")
)