如何将两个数据框组合成一个图表,其中每个 class 有两个并排的堆叠条形图?
How to combine two data frames into one graph where I will have two stacked bars side by side for each class?
我专门为此注册的
基本上我有两个数据框,它们具有完全相同的信息,但来自两个不同的年份。
这里是其中一个数据帧的 head():
species dbh_cm height_m f plot dbh_m ba
1 1 0.7 1.34 7.1627066 16 0.007 3.848451e-05
2 3 1.9 1.95 2.0018036 16 0.019 2.835287e-04
3 3 4.0 3.05 0.9120516 16 0.040 1.256637e-03
4 1 3.5 2.27 1.0072122 16 0.035 9.621128e-04
5 3 0.6 1.52 6.9312671 16 0.006 2.827433e-05
6 3 4.2 2.70 0.9406631 16 0.042 1.385442e-03
volume class Sp
1 0.0003693754 (0,5] Spruce
2 0.0011067593 (0,5] Larch
3 0.0034956596 (0,5] Larch
4 0.0021997474 (0,5] Spruce
5 0.0002978850 (0,5] Larch
6 0.0035187332 (0,5] Larch
为了绘制每一个图表,我使用了:
ggplot(data=trees_b, aes(x=class, fill = Sp)) +
geom_bar(stat = "count") +
labs( x = "DBH classes [cm]", y = "Number of trees [n]", fill="Species") +
scale_x_discrete(labels=c("(0,5]" = "2.5","(5,10]" = "7.5", "(10,15]" = "12.5",
"(15,20]" = "17.5", "(20,25]" = "22.5", "(25,30]" = "27.5",
"(30,35]" = "32.5", "(35,40]" = "37.5", "(40,45]" = "42.5",
"(45,50]" = "47.5", "(50,55]" = "52.5", "(55,60]" = "57.5",
"(60,65]" = "62.5", "(65,70]" = "67.5","(70,75]" = "72.5",
"(75,80]" = "77.5", "(80,85]" = "82.5")) +
scale_fill_viridis(direction = -1, discrete = T) +
theme(axis.text.x = element_text( size = 15),
axis.text.y = element_text (size = 15),
axis.title = element_text(size = 15),
legend.text = element_text (size = 15),
legend.title = element_text (size = 16, face = "bold"))
我知道代码不是最干净的,但它完美地满足了我的需要,就是这样:
enter image description here
现在我想基本上将两个图合二为一进行比较,有没有办法做到这一点?
组合图表的一种方法是使用分面。为此,我使用 dplyr::bind_rows
按行绑定数据集,这使得向数据中添加标识符列变得容易,然后可以将其用作分面变量:
注意:我还添加了一个简单的函数来计算 class 均值。
trees_b <- trees_a
trees <- list(a = trees_a, b = trees_b) |>
dplyr::bind_rows(.id = "id")
library(ggplot2)
library(viridis)
#> Loading required package: viridisLite
class_mean <- function(x) {
sapply(stringr::str_extract_all(x, "\d+"), function(x) mean(as.numeric(x)))
}
ggplot(data = trees, aes(x = class, fill = Sp)) +
geom_bar(stat = "count") +
labs(x = "DBH classes [cm]", y = "Number of trees [n]", fill = "Species") +
scale_x_discrete(labels = class_mean) +
scale_fill_viridis(direction = -1, discrete = T) +
theme(
axis.text.x = element_text(size = 15),
axis.text.y = element_text(size = 15),
axis.title = element_text(size = 15),
legend.text = element_text(size = 15),
legend.title = element_text(size = 16, face = "bold")
) +
facet_wrap(~id)
编辑 正如您在评论中澄清的那样,您需要一个堆叠和闪避的条形图。实现这一目标的一种方法是通过“看起来不像刻面的刻面”技巧。基本思想是根据映射到 x
的变量进行分面,而不是将分面变量映射到 x
。之后,我们通过主题选项使用一些样式来摆脱分面外观。有关更多选项,请查看 ggplot2 - bar plot with both stack and dodge.
ggplot(data = trees, aes(x = id, fill = Sp)) +
geom_bar(stat = "count") +
labs(x = "DBH classes [cm]", y = "Number of trees [n]", fill = "Species") +
scale_fill_viridis(direction = -1, discrete = T) +
theme(
axis.text.x = element_text(size = 15),
axis.text.y = element_text(size = 15),
axis.title = element_text(size = 15),
legend.text = element_text(size = 15),
legend.title = element_text(size = 16, face = "bold")
) +
facet_wrap(~class, labeller = labeller(class = class_mean), strip.position = "bottom", nrow = 1) +
theme(strip.placement = "outside", strip.background.x = element_blank(), panel.spacing.x = unit(0, "pt"))
数据
trees_a <- structure(list(
species = c(1L, 3L, 3L, 1L, 3L, 3L), dbh_cm = c(
0.7,
1.9, 4, 3.5, 0.6, 4.2
), height_m = c(
1.34, 1.95, 3.05, 2.27,
1.52, 2.7
), f = c(
7.1627066, 2.0018036, 0.9120516, 1.0072122,
6.9312671, 0.9406631
), plot = c(16L, 16L, 16L, 16L, 16L, 16L),
dbh_m = c(0.007, 0.019, 0.04, 0.035, 0.006, 0.042), ba = c(
3.848451e-05,
0.0002835287, 0.001256637, 0.0009621128, 2.827433e-05, 0.001385442
), volume = c(
0.0003693754, 0.0011067593, 0.0034956596, 0.0021997474,
0.000297885, 0.0035187332
), class = c(
"(0,5]", "(0,5]", "(0,5]",
"(0,5]", "(0,5]", "(0,5]"
), Sp = c(
"Spruce", "Larch", "Larch",
"Spruce", "Larch", "Larch"
)
), class = "data.frame", row.names = c(
"1",
"2", "3", "4", "5", "6"
))
我专门为此注册的
基本上我有两个数据框,它们具有完全相同的信息,但来自两个不同的年份。
这里是其中一个数据帧的 head():
species dbh_cm height_m f plot dbh_m ba
1 1 0.7 1.34 7.1627066 16 0.007 3.848451e-05
2 3 1.9 1.95 2.0018036 16 0.019 2.835287e-04
3 3 4.0 3.05 0.9120516 16 0.040 1.256637e-03
4 1 3.5 2.27 1.0072122 16 0.035 9.621128e-04
5 3 0.6 1.52 6.9312671 16 0.006 2.827433e-05
6 3 4.2 2.70 0.9406631 16 0.042 1.385442e-03
volume class Sp
1 0.0003693754 (0,5] Spruce
2 0.0011067593 (0,5] Larch
3 0.0034956596 (0,5] Larch
4 0.0021997474 (0,5] Spruce
5 0.0002978850 (0,5] Larch
6 0.0035187332 (0,5] Larch
为了绘制每一个图表,我使用了:
ggplot(data=trees_b, aes(x=class, fill = Sp)) +
geom_bar(stat = "count") +
labs( x = "DBH classes [cm]", y = "Number of trees [n]", fill="Species") +
scale_x_discrete(labels=c("(0,5]" = "2.5","(5,10]" = "7.5", "(10,15]" = "12.5",
"(15,20]" = "17.5", "(20,25]" = "22.5", "(25,30]" = "27.5",
"(30,35]" = "32.5", "(35,40]" = "37.5", "(40,45]" = "42.5",
"(45,50]" = "47.5", "(50,55]" = "52.5", "(55,60]" = "57.5",
"(60,65]" = "62.5", "(65,70]" = "67.5","(70,75]" = "72.5",
"(75,80]" = "77.5", "(80,85]" = "82.5")) +
scale_fill_viridis(direction = -1, discrete = T) +
theme(axis.text.x = element_text( size = 15),
axis.text.y = element_text (size = 15),
axis.title = element_text(size = 15),
legend.text = element_text (size = 15),
legend.title = element_text (size = 16, face = "bold"))
我知道代码不是最干净的,但它完美地满足了我的需要,就是这样:
enter image description here
现在我想基本上将两个图合二为一进行比较,有没有办法做到这一点?
组合图表的一种方法是使用分面。为此,我使用 dplyr::bind_rows
按行绑定数据集,这使得向数据中添加标识符列变得容易,然后可以将其用作分面变量:
注意:我还添加了一个简单的函数来计算 class 均值。
trees_b <- trees_a
trees <- list(a = trees_a, b = trees_b) |>
dplyr::bind_rows(.id = "id")
library(ggplot2)
library(viridis)
#> Loading required package: viridisLite
class_mean <- function(x) {
sapply(stringr::str_extract_all(x, "\d+"), function(x) mean(as.numeric(x)))
}
ggplot(data = trees, aes(x = class, fill = Sp)) +
geom_bar(stat = "count") +
labs(x = "DBH classes [cm]", y = "Number of trees [n]", fill = "Species") +
scale_x_discrete(labels = class_mean) +
scale_fill_viridis(direction = -1, discrete = T) +
theme(
axis.text.x = element_text(size = 15),
axis.text.y = element_text(size = 15),
axis.title = element_text(size = 15),
legend.text = element_text(size = 15),
legend.title = element_text(size = 16, face = "bold")
) +
facet_wrap(~id)
编辑 正如您在评论中澄清的那样,您需要一个堆叠和闪避的条形图。实现这一目标的一种方法是通过“看起来不像刻面的刻面”技巧。基本思想是根据映射到 x
的变量进行分面,而不是将分面变量映射到 x
。之后,我们通过主题选项使用一些样式来摆脱分面外观。有关更多选项,请查看 ggplot2 - bar plot with both stack and dodge.
ggplot(data = trees, aes(x = id, fill = Sp)) +
geom_bar(stat = "count") +
labs(x = "DBH classes [cm]", y = "Number of trees [n]", fill = "Species") +
scale_fill_viridis(direction = -1, discrete = T) +
theme(
axis.text.x = element_text(size = 15),
axis.text.y = element_text(size = 15),
axis.title = element_text(size = 15),
legend.text = element_text(size = 15),
legend.title = element_text(size = 16, face = "bold")
) +
facet_wrap(~class, labeller = labeller(class = class_mean), strip.position = "bottom", nrow = 1) +
theme(strip.placement = "outside", strip.background.x = element_blank(), panel.spacing.x = unit(0, "pt"))
数据
trees_a <- structure(list(
species = c(1L, 3L, 3L, 1L, 3L, 3L), dbh_cm = c(
0.7,
1.9, 4, 3.5, 0.6, 4.2
), height_m = c(
1.34, 1.95, 3.05, 2.27,
1.52, 2.7
), f = c(
7.1627066, 2.0018036, 0.9120516, 1.0072122,
6.9312671, 0.9406631
), plot = c(16L, 16L, 16L, 16L, 16L, 16L),
dbh_m = c(0.007, 0.019, 0.04, 0.035, 0.006, 0.042), ba = c(
3.848451e-05,
0.0002835287, 0.001256637, 0.0009621128, 2.827433e-05, 0.001385442
), volume = c(
0.0003693754, 0.0011067593, 0.0034956596, 0.0021997474,
0.000297885, 0.0035187332
), class = c(
"(0,5]", "(0,5]", "(0,5]",
"(0,5]", "(0,5]", "(0,5]"
), Sp = c(
"Spruce", "Larch", "Larch",
"Spruce", "Larch", "Larch"
)
), class = "data.frame", row.names = c(
"1",
"2", "3", "4", "5", "6"
))