Я пытаюсь нарисовать три гистограммы в одном изображении.
Что касается данных примера, у меня есть вопрос об установке ширины каждого графика.
df <- data.frame(group=c('A', 'B', 'C', 'D', 'E'),
valueA=c(0.1, 0.06, 0.02, 0.09, 0.12),
valueB=c(0.4, 0.6, 0.55, 0.45, 0.52),
valueC=c(0.76, 0.79, 0.85, 0.94, 0.89))
A_bar <- ggplot(df, aes(x=group, y=valueA, fill=group))+
geom_bar(stat='identity')+
theme_bw()+
labs(x = "Group", y = "ValueA", fill = "Group") +
scale_y_continuous(limits=c(0,0.2),oob = rescale_none)+
coord_flip()
A_bar <- A_bar + theme(legend.position = "none",
axis.text=element_text(size=12),
axis.title=element_text(size=14))
B_bar <- ggplot(df, aes(x=group, y=valueB, fill=group))+
geom_bar(stat='identity')+
theme_bw()+
labs(x = "Group", y = "ValueB", fill = "Group") +
scale_y_continuous(limits=c(0.4,0.65),oob = rescale_none)+
theme(axis.title.y = element_blank())+
coord_flip()
B_bar <- B_bar + theme(legend.position = "none",
axis.text=element_text(size=12),
axis.title=element_text(size=14),
axis.text.y=element_blank())
C_bar <- ggplot(df, aes(x=group, y=valueC, fill=group))+
geom_bar(stat='identity')+
theme_bw()+
labs(x = "Group", y = "ValueC", fill = "Group") +
scale_y_continuous(limits=c(0.7,1),oob = rescale_none)+
theme(axis.title.y = element_blank())+
coord_flip()
C_bar <- C_bar + theme(legend.position = "none",
axis.text=element_text(size=12),
axis.title=element_text(size=14),
axis.text.y=element_blank())
ggarrange(A_bar, B_bar, C_bar, ncol=3, nrow=1)
Пусть результат будет следующим:
Вы можете видеть, что ширина первого и других графиков немного различается из-за названия оси Y и меток на первом графике.
Я хочу унифицировать их ширину вот так.
Я также пытался использовать facet_grid
или facet_wrap
, но это сбивало с толку из-за переменных.
Второстепенный вопрос: как я могу вставить границу между осью Y и гистограммой так же, как и графиком ValueA?
Кроме того, как я могу изменить порядок графиков с E~A на A~E?
Одним из простых способов достижения желаемого результата с меньшим количеством кода является использование фасетирования, которое, однако, требует изменения формы ваших данных. Дополнительно, чтобы применить ограничения индивидуально для каждой панели, я использую ggh4x::facetted_pos_scales
:
library(scales)
library(ggpubr)
#> Loading required package: ggplot2
library(ggplot2)
library(ggh4x)
#>
#> Attaching package: 'ggh4x'
#> The following object is masked from 'package:ggplot2':
#>
#> guide_axis_logticks
library(tidyr)
df <- data.frame(
group = c("A", "B", "C", "D", "E"),
valueA = c(0.1, 0.06, 0.02, 0.09, 0.12),
valueB = c(0.4, 0.6, 0.55, 0.45, 0.52),
valueC = c(0.76, 0.79, 0.85, 0.94, 0.89)
)
df |>
tidyr::pivot_longer(-group) |>
ggplot(aes(x = value, y = group, fill = group)) +
geom_col() +
ggh4x::facetted_pos_scales(
x = list(
name == "valueA" ~ scale_x_continuous(limits = c(0, 0.2), oob = rescale_none),
name == "valueB" ~ scale_x_continuous(limits = c(0.4, 0.65), oob = rescale_none),
name == "valueC" ~ scale_x_continuous(limits = c(0.7, 1), oob = rescale_none)
)
) +
facet_wrap(~name, scales = "free_x", strip.position = "bottom") +
guides(fill = "none") +
theme_bw() +
labs(y = "Group", x = NULL, fill = "Group") +
theme(
strip.placement = "outside",
strip.background.x = element_blank()
)
Но если вы хотите использовать отдельные графики, я бы предложил переключиться на patchwork
, который, начиная с версии 1.2.0
, также позволяет собирать оси, т. е. нет необходимости удалять заголовки или текст из крайних правых графиков:
A_bar <- ggplot(df, aes(x = group, y = valueA, fill = group)) +
geom_bar(stat = "identity") +
theme_bw() +
labs(x = "Group", y = "ValueA", fill = "Group") +
scale_y_continuous(limits = c(0, 0.2), oob = rescale_none) +
coord_flip()
A_bar <- A_bar + theme(
legend.position = "none",
axis.text = element_text(size = 12),
axis.title = element_text(size = 14)
)
B_bar <- ggplot(df, aes(x = group, y = valueB, fill = group)) +
geom_bar(stat = "identity") +
theme_bw() +
labs(x = "Group", y = "ValueB", fill = "Group") +
scale_y_continuous(limits = c(0.4, 0.65), oob = rescale_none) +
coord_flip()
B_bar <- B_bar + theme(
legend.position = "none",
axis.text = element_text(size = 12),
axis.title = element_text(size = 14)
)
C_bar <- ggplot(df, aes(x = group, y = valueC, fill = group)) +
geom_bar(stat = "identity") +
theme_bw() +
labs(x = "Group", y = "ValueC", fill = "Group") +
scale_y_continuous(limits = c(0.7, 1), oob = rescale_none) +
coord_flip()
C_bar <- C_bar + theme(
legend.position = "none",
axis.text = element_text(size = 12),
axis.title = element_text(size = 14)
)
library(patchwork)
list(A_bar, B_bar, C_bar) |>
wrap_plots(ncol = 3, nrow = 1) +
plot_layout(axes = "collect")
Я решил свою проблему, изменив |>
на %>%
и plot_layout(axes = "collect")
на plot_layout(guides = "collect")
. Тогда это работает хорошо. Большое спасибо!
Вы можете создать четвертую панель, содержащую только метки групп по оси Y:
old_bw <- theme_set(theme_bw())
theme_update(legend.position = "none",
axis.title.y=element_blank(),
axis.title.x=element_text(size=14),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
plot.margin = unit(c(0.2,0.1,0.2,0.1), "cm"))
Y_axis <- ggplot(df, aes(x=group, y=valueA, fill=group)) +
labs(x = "Group", y = "") +
theme_minimal() +
theme(axis.title.y=element_text(size=14),
axis.text.y=element_text(size=14),
axis.text.x=element_text(size=14, color=0),
plot.margin = unit(c(0.2,0,0.2,0.2), "cm")) +
scale_y_continuous(limits=c(0,0), oob = scales::rescale_none)+
coord_flip(); Y_axis
A_bar <- ggplot(df, aes(x=group, y=valueA, fill=group))+
geom_bar(stat='identity')+
labs(x = "", y = "ValueA", fill = "Group") +
scale_y_continuous(limits=c(0,0.2), oob = scales::rescale_none)+
coord_flip()
B_bar <- ggplot(df, aes(x=group, y=valueB, fill=group))+
geom_bar(stat='identity')+
labs(x = "", y = "ValueB", fill = "Group") +
scale_y_continuous(limits=c(0.4,0.65), oob = scales::rescale_none)+
coord_flip()
C_bar <- ggplot(df, aes(x=group, y=valueC, fill=group))+
geom_bar(stat='identity')+
labs(x = "", y = "ValueC", fill = "Group") +
scale_y_continuous(limits=c(0.7,1),oob = scales::rescale_none)+
coord_flip()
Затем используйте ggarrange
, чтобы установить одинаковую ширину на трех участках.
ggpubr::ggarrange(Y_axis, A_bar, B_bar, C_bar, ncol=4, nrow=1,
widths=c(1,6,6,6))
theme_set(old_bw)
Спасибо за ваш добрый ответ! Попробую и скажу если будут проблемы. :)
Без проблем. Чтобы повернуть ось Y (ось X до переворота), вы можете добавить scale_x_discrete(limits=rev)
к каждому графику, включая, что немаловажно, график оси Y.
Спасибо за подробный ответ! К сожалению, мне не удалось установить и вызвать в
ggh4x
библиотеку. Итак, я попробовал ваше второе решение, но оно вернуло ошибкуError in is_valid_plot(..1) : the ... list contains fewer than 1 element
...