基于其他列的 ggplot2 构面中的自定义轴中断
Custom axis breaks in ggplot2 facets based on other columns
我有要绘制的数据,其中 x 轴位于一列中,x 轴主要中断位于其他列中。
对于我的示例数据,我将从 ggplot2
修改 iris
数据集。注意:low
和 high
在这里是任意计算的——我只选择了最小值和最大值以便于重现。
library(dplyr)
library(ggplot2)
df <- iris %>%
group_by(Species) %>%
mutate(low = min(Sepal.Length),
high = max(Sepal.Length)) %>%
ungroup()
> df
# A tibble: 150 x 7
Sepal.Length Sepal.Width Petal.Length Petal.Width Species low high
<dbl> <dbl> <dbl> <dbl> <fct> <dbl> <dbl>
1 5.1 3.5 1.4 0.2 setosa 4.3 5.8
2 4.9 3 1.4 0.2 setosa 4.3 5.8
3 4.7 3.2 1.3 0.2 setosa 4.3 5.8
4 4.6 3.1 1.5 0.2 setosa 4.3 5.8
5 5 3.6 1.4 0.2 setosa 4.3 5.8
6 5.4 3.9 1.7 0.4 setosa 4.3 5.8
7 4.6 3.4 1.4 0.3 setosa 4.3 5.8
8 5 3.4 1.5 0.2 setosa 4.3 5.8
9 4.4 2.9 1.4 0.2 setosa 4.3 5.8
10 4.9 3.1 1.5 0.1 setosa 4.3 5.8
# ... with 140 more rows
我希望为 Species
绘制 x = Sepal.Length
分面,但只有两个主要突破点是 df$min
和 df$max
。
我无法在正确的方面取得突破。
df %>%
ggplot(aes(x = Sepal.Length,
y = Petal.Length)) +
geom_point() +
facet_wrap(. ~ Species) +
scale_x_continuous(breaks = c(df$low, df$high))
如您所见,df$low
和 df$high
中的值应用于所有方面。我希望 facet setosa
仅在 4.3 和 5.8 处有重大突破,versicolor
仅在 4.9 和 7.0 处出现重大突破,virginica
仅在 4.9 和 7.9 处出现重大突破。
有没有办法将 facet 变量传递给 scale_x_continuous
中的 breaks
?或者我应该放弃这种方法并创建三个单独的 ggplots 并将它们与 gridExtra
?
合并在一起
如有任何帮助,我们将不胜感激!
这是一个可能的解决方案,使用 patchwork:
library(ggplot2)
library(purrr)
library(patchwork)
df %>%
split(.$Species) %>%
map(~{
.x %>%
ggplot(aes(x = Sepal.Length,
y = Petal.Length)) +
geom_point() +
facet_wrap(~ Species) +
scale_x_continuous(breaks = c(max(.x$low), max(.x$high))) +
# assuming you want to use same y axis for each plot
scale_y_continuous(limits = c(min(df$Petal.Length), max(df$Petal.Length)))
}) %>%
reduce(`+`)
我认为这是最简单的方法,不需要弄乱 ggproto
在传递给主 ggplot2 调用的 data.frame 上下文中,比例尺的 break 参数不支持整洁评估。如果您的中断可以从 facet 限制计算(通常是数据限制 + 扩展,当 scales = "free"
时),您可以将一个函数传递给 breaks 参数,该参数根据限制计算中断。
如果您真的希望每个方面都有单独的比例尺,github 上有一些软件包支持为图的各个方面提供自定义比例尺。两者都要求您手动为每个方面指定比例。免责声明:我为第一个包做出了贡献,并且是第二个包的作者。
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(ggplot2)
df <- iris %>%
group_by(Species) %>%
mutate(low = min(Sepal.Length),
high = max(Sepal.Length)) %>%
ungroup()
# Forgive the clunky tidyverse syntax
scale_list <- df$Species %>% levels() %>% setNames(.,.) %>% lapply(., function(i) {
scale_x_continuous(breaks = unique(unlist(df[df$Species == i, c("low", "high")])))
})
#devtools::install_github("zeehio/facetscales")
library(facetscales)
df %>%
ggplot(aes(x = Sepal.Length,
y = Petal.Length)) +
geom_point() +
facet_grid_sc(cols = vars(Species), scales = list(x = scale_list))
#devtools::install_github("teunbrand/ggnomics")
library(ggnomics)
df %>%
ggplot(aes(x = Sepal.Length,
y = Petal.Length)) +
geom_point() +
facet_wrap(. ~ Species, scales = "free_x") +
facetted_pos_scales(x = scale_list)
由 reprex package (v0.3.0)
于 2020 年 2 月 11 日创建
我有要绘制的数据,其中 x 轴位于一列中,x 轴主要中断位于其他列中。
对于我的示例数据,我将从 ggplot2
修改 iris
数据集。注意:low
和 high
在这里是任意计算的——我只选择了最小值和最大值以便于重现。
library(dplyr)
library(ggplot2)
df <- iris %>%
group_by(Species) %>%
mutate(low = min(Sepal.Length),
high = max(Sepal.Length)) %>%
ungroup()
> df
# A tibble: 150 x 7
Sepal.Length Sepal.Width Petal.Length Petal.Width Species low high
<dbl> <dbl> <dbl> <dbl> <fct> <dbl> <dbl>
1 5.1 3.5 1.4 0.2 setosa 4.3 5.8
2 4.9 3 1.4 0.2 setosa 4.3 5.8
3 4.7 3.2 1.3 0.2 setosa 4.3 5.8
4 4.6 3.1 1.5 0.2 setosa 4.3 5.8
5 5 3.6 1.4 0.2 setosa 4.3 5.8
6 5.4 3.9 1.7 0.4 setosa 4.3 5.8
7 4.6 3.4 1.4 0.3 setosa 4.3 5.8
8 5 3.4 1.5 0.2 setosa 4.3 5.8
9 4.4 2.9 1.4 0.2 setosa 4.3 5.8
10 4.9 3.1 1.5 0.1 setosa 4.3 5.8
# ... with 140 more rows
我希望为 Species
绘制 x = Sepal.Length
分面,但只有两个主要突破点是 df$min
和 df$max
。
我无法在正确的方面取得突破。
df %>%
ggplot(aes(x = Sepal.Length,
y = Petal.Length)) +
geom_point() +
facet_wrap(. ~ Species) +
scale_x_continuous(breaks = c(df$low, df$high))
如您所见,df$low
和 df$high
中的值应用于所有方面。我希望 facet setosa
仅在 4.3 和 5.8 处有重大突破,versicolor
仅在 4.9 和 7.0 处出现重大突破,virginica
仅在 4.9 和 7.9 处出现重大突破。
有没有办法将 facet 变量传递给 scale_x_continuous
中的 breaks
?或者我应该放弃这种方法并创建三个单独的 ggplots 并将它们与 gridExtra
?
如有任何帮助,我们将不胜感激!
这是一个可能的解决方案,使用 patchwork:
library(ggplot2)
library(purrr)
library(patchwork)
df %>%
split(.$Species) %>%
map(~{
.x %>%
ggplot(aes(x = Sepal.Length,
y = Petal.Length)) +
geom_point() +
facet_wrap(~ Species) +
scale_x_continuous(breaks = c(max(.x$low), max(.x$high))) +
# assuming you want to use same y axis for each plot
scale_y_continuous(limits = c(min(df$Petal.Length), max(df$Petal.Length)))
}) %>%
reduce(`+`)
我认为这是最简单的方法,不需要弄乱 ggproto
在传递给主 ggplot2 调用的 data.frame 上下文中,比例尺的 break 参数不支持整洁评估。如果您的中断可以从 facet 限制计算(通常是数据限制 + 扩展,当 scales = "free"
时),您可以将一个函数传递给 breaks 参数,该参数根据限制计算中断。
如果您真的希望每个方面都有单独的比例尺,github 上有一些软件包支持为图的各个方面提供自定义比例尺。两者都要求您手动为每个方面指定比例。免责声明:我为第一个包做出了贡献,并且是第二个包的作者。
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(ggplot2)
df <- iris %>%
group_by(Species) %>%
mutate(low = min(Sepal.Length),
high = max(Sepal.Length)) %>%
ungroup()
# Forgive the clunky tidyverse syntax
scale_list <- df$Species %>% levels() %>% setNames(.,.) %>% lapply(., function(i) {
scale_x_continuous(breaks = unique(unlist(df[df$Species == i, c("low", "high")])))
})
#devtools::install_github("zeehio/facetscales")
library(facetscales)
df %>%
ggplot(aes(x = Sepal.Length,
y = Petal.Length)) +
geom_point() +
facet_grid_sc(cols = vars(Species), scales = list(x = scale_list))
#devtools::install_github("teunbrand/ggnomics")
library(ggnomics)
df %>%
ggplot(aes(x = Sepal.Length,
y = Petal.Length)) +
geom_point() +
facet_wrap(. ~ Species, scales = "free_x") +
facetted_pos_scales(x = scale_list)
由 reprex package (v0.3.0)
于 2020 年 2 月 11 日创建