Я создал два сюжета: Первый представляет собой диаграмму рассеяния, где ось X представляет время, а ось Y содержит дискретные значения, такие как имена «Том» и «Джерри». Второй представляет собой гистограмму, где ось X также представляет собой время, а ось Y показывает непрерывные значения, такие как высота. Сейчас я пытаюсь совместить эти два графика на одном графике, но не знаю, как это сделать.
Вот код, который я использовал для каждого графика:
Для диаграммы рассеяния:
data.scatter <- data.frame(x = c(1, 2, 3, 4, 5), y = c("Tom", "Jerry", "Tom", "Jerry", "Tom"))
ggplot(data.scatter, aes(x = x, y = y)) + geom_point()
Для гистограммы:
data.bar <- data.frame(x = c(1, 2, 3, 4, 5), y = c(10, 20, 30, 40, 50))
ggplot(data.bar, aes(x = x, y = y)) + geom_bar(stat = "identity")
Ниже представлена моя попытка, но этот код очень громоздкий. Есть ли более простой способ добиться этого эффекта?
library(tidyverse)
data.scatter <- data.frame(x = c(1, 2, 3, 4, 5), y = c("Tom", "Jerry", "Tom", "Jerry", "Tom"))
p1 <- ggplot(data.scatter, aes(x = x, y = y)) + geom_point()
p1_data <- ggplot_build(p1)$data[[1]]
data.bar <- data.frame(x = c(1, 2, 3, 4, 5), y = c(10, 20, 30, 40, 50))
p2 <- ggplot(data.bar, aes(x = x, y = y)) + geom_bar(stat = "identity")
p2_data <- ggplot_build(p2)$data[[1]]
p3 <- p2_data %>% ggplot() +
geom_rect(aes(ymin=ymin,ymax = ymax,xmin = xmin,xmax = xmax)) +
geom_text(aes(x=xmin+.45,y=ymax+1,label=ymax)) +
geom_point(data = p1_data, aes(x = x, y = y*20),inherit.aes = F) +
scale_y_continuous(breaks = c(20,40),labels = c("Tom","Jerry")) +
labs(x=NULL,y=NULL)
p3
Вы можете установить ограничения для осей Y на обоих графиках, чтобы гарантировать выравнивание осей при их объединении, используя align_plots
из пакета коровьего графика.
library(ggplot2)
library(cowplot)
p1 <- ggplot(data.bar, aes(x = x, y = y)) +
geom_bar(stat = "identity") +
scale_y_continuous(position = "right") +
scale_x_continuous(limits=c(0.5,5.5)) +
theme_minimal_hgrid()
p2 <- ggplot(data.scatter, aes(x = x, y = y)) +
geom_point() + labs(x = "x") +
scale_x_continuous(limits=c(0.5,5.5)) +
theme_cowplot()
aligned_plots <- align_plots(p1, p2, align = "hv", axis = "tblr")
ggdraw(aligned_plots[[1]]) + draw_plot(aligned_plots[[2]])
Смотрите мой отредактированный ответ.
Код упрощает построение графика, но усложняет подготовку данных. И он использует вспомогательную функцию и дополнительную переменную fac
. Дискретная ось отображается так, как если бы она была непрерывной, а непрерывные значения (столбцы) масштабируются до диапазона "tom" and "jerry"
.
library(ggplot2)
data.scatter <- data.frame(x = c(1, 2, 3, 4, 5), y = c("Tom", "Jerry", "Tom", "Jerry", "Tom"))
data.bar <- data.frame(x = c(1, 2, 3, 4, 5), y = c(10, 20, 30, 40, 50))
data.all <- merge(data.scatter, data.bar, by = "x", suffixes = c(".scatter", ".bar"))
# auxiliary function, makes the code below simpler
chr2int <- function(x, ...) as.integer(factor(x, ...))
# scale the bars ...
(fac <- with(data.all, range(chr2int(y.scatter))/range(y.bar)))
#> [1] 0.10 0.04
# ... to a bit above "jerry"
(fac <- min(fac) * 1.1)
#> [1] 0.044
ggplot(data.all, aes(x, y = y.bar * fac)) +
geom_col() +
geom_text(aes(label = y.bar), vjust = -0.5) +
geom_point(aes(y = chr2int(y.scatter)), color = "red", size = 3L) +
xlab("") +
scale_y_continuous(
name = "",
breaks = chr2int(data.all$y.scatter) |> unique(),
labels = levels(factor(data.all$y.scatter))
)
Created on 2024-07-24 with reprex v2.1.0
Спасибо за ваш ответ. Но я надеюсь объединить два графика, а не объединить их по вертикали.