如何绘制不连续 y-axis 的构面
How to plot facets with discontinuous y-axis
我正在尝试制作一个不连续的情节 y-axis 但无法让分面标题只显示一次:
示例数据:
data(mpg)
library(ggplot2)
> ggplot(mpg, aes(displ, cty)) +
+ geom_point() +
+ facet_grid(. ~ drv)
经过大量挖掘,这似乎在 ggplot2
中是不可能的,但我发现了 gg.gap
包。但是,此包会为情节的每个部分复制分面标题。假设我想在 y 轴上从 22-32 中断,如下所示:
library(gg.gap)
gg.gap(plot = p,
segments = c(22, 32),
ylim = c(0, 35))
每个情节片段都会出现分面标题,但这显然很混乱,而且在美学上很糟糕。如果有人能提供帮助,我将不胜感激!我被难住了。
我知道如果我在 base R 中绘图是可能的,但考虑到其他限制我无法这样做(我需要 ggplot2
提供的 graphics/grammar。
提前致谢!
这是一个有点丑陋的解决方法。这个想法是将断开部分的 y 值设置为 NA
,这样就不会在那里绘制任何点。然后,我们在 findInterval()
上用轴的中断进行分面(负数,因为我们想保留自下而上的轴)。最后,我们使用 ggh4x::force_panelsizes()
手动调整面板大小,将第二个面板设置为 0 高度。完全免责声明,我写了 ggh4x 所以我有偏见。
一些细节:通过将相关主题元素设置为空白来隐藏沿 y 方向的条带。此外,理想情况下,您会计算上表面相对于下表面的比例,并将 0.2
替换为该数字。
library(ggplot2)
library(ggh4x)
ggplot(mpg, aes(displ, cty)) +
geom_point(aes(y = ifelse(cty >= 22 & cty < 32, NA, cty))) +
facet_grid(-findInterval(cty, c(-Inf, 22, 32, Inf)) ~ drv,
scales = "free_y", space = "free_y") +
theme(strip.background.y = element_blank(),
strip.text.y = element_blank(),
panel.spacing.y = unit(5.5/2, "pt")) +
force_panelsizes(rows = c(0.2, 0, 1))
#> Warning: Removed 20 rows containing missing values (geom_point).
箱线图的替代方法:
您可以复制数据并操纵位置刻度以显示您想要的内容,而不是在中断时审查位。我们依靠坐标系对数据的裁剪来裁剪图形对象。
library(ggplot2)
library(ggh4x)
ggplot(mpg, aes(class, cty)) +
geom_boxplot(data = ~ transform(., facet = 2)) +
geom_boxplot(data = ~ transform(., facet = 1)) +
facet_grid(facet ~ drv, scales = "free_y", space = "free_y") +
facetted_pos_scales(y = list(
scale_y_continuous(limits = c(32, NA), oob = scales::oob_keep, # <- keeps data
expand = c(0, 0, 0.05, 0)),
scale_y_continuous(limits= c(NA, 21), oob = scales::oob_keep,
expand = c(0.05, 0, 0, 0))
)) +
theme(strip.background.y = element_blank(),
strip.text.y = element_blank())
这是一种依赖于在 ggplot2 之前更改数据,然后调整比例标签的方法,类似于您对辅助 y 轴所做的操作。
library(dplyr)
low_max <- 22.5
high_min <- 32.5
adjust <- high_min - low_max
mpg %>%
mutate(cty2 = as.numeric(cty),
cty2 = case_when(cty < low_max ~ cty2,
cty > high_min ~ cty2 - adjust,
TRUE ~ NA_real_)) %>%
ggplot(aes(displ, cty2)) +
geom_point() +
annotate("segment", color = "white", size = 2,
x = -Inf, xend = Inf, y = low_max, yend = low_max) +
scale_y_continuous(breaks = 1:50,
label = function(x) {x + ifelse(x>=low_max, adjust, 0)}) +
facet_grid(. ~ drv)
我正在尝试制作一个不连续的情节 y-axis 但无法让分面标题只显示一次:
示例数据:
data(mpg)
library(ggplot2)
> ggplot(mpg, aes(displ, cty)) +
+ geom_point() +
+ facet_grid(. ~ drv)
经过大量挖掘,这似乎在 ggplot2
中是不可能的,但我发现了 gg.gap
包。但是,此包会为情节的每个部分复制分面标题。假设我想在 y 轴上从 22-32 中断,如下所示:
library(gg.gap)
gg.gap(plot = p,
segments = c(22, 32),
ylim = c(0, 35))
每个情节片段都会出现分面标题,但这显然很混乱,而且在美学上很糟糕。如果有人能提供帮助,我将不胜感激!我被难住了。
我知道如果我在 base R 中绘图是可能的,但考虑到其他限制我无法这样做(我需要 ggplot2
提供的 graphics/grammar。
提前致谢!
这是一个有点丑陋的解决方法。这个想法是将断开部分的 y 值设置为 NA
,这样就不会在那里绘制任何点。然后,我们在 findInterval()
上用轴的中断进行分面(负数,因为我们想保留自下而上的轴)。最后,我们使用 ggh4x::force_panelsizes()
手动调整面板大小,将第二个面板设置为 0 高度。完全免责声明,我写了 ggh4x 所以我有偏见。
一些细节:通过将相关主题元素设置为空白来隐藏沿 y 方向的条带。此外,理想情况下,您会计算上表面相对于下表面的比例,并将 0.2
替换为该数字。
library(ggplot2)
library(ggh4x)
ggplot(mpg, aes(displ, cty)) +
geom_point(aes(y = ifelse(cty >= 22 & cty < 32, NA, cty))) +
facet_grid(-findInterval(cty, c(-Inf, 22, 32, Inf)) ~ drv,
scales = "free_y", space = "free_y") +
theme(strip.background.y = element_blank(),
strip.text.y = element_blank(),
panel.spacing.y = unit(5.5/2, "pt")) +
force_panelsizes(rows = c(0.2, 0, 1))
#> Warning: Removed 20 rows containing missing values (geom_point).
箱线图的替代方法:
您可以复制数据并操纵位置刻度以显示您想要的内容,而不是在中断时审查位。我们依靠坐标系对数据的裁剪来裁剪图形对象。
library(ggplot2)
library(ggh4x)
ggplot(mpg, aes(class, cty)) +
geom_boxplot(data = ~ transform(., facet = 2)) +
geom_boxplot(data = ~ transform(., facet = 1)) +
facet_grid(facet ~ drv, scales = "free_y", space = "free_y") +
facetted_pos_scales(y = list(
scale_y_continuous(limits = c(32, NA), oob = scales::oob_keep, # <- keeps data
expand = c(0, 0, 0.05, 0)),
scale_y_continuous(limits= c(NA, 21), oob = scales::oob_keep,
expand = c(0.05, 0, 0, 0))
)) +
theme(strip.background.y = element_blank(),
strip.text.y = element_blank())
这是一种依赖于在 ggplot2 之前更改数据,然后调整比例标签的方法,类似于您对辅助 y 轴所做的操作。
library(dplyr)
low_max <- 22.5
high_min <- 32.5
adjust <- high_min - low_max
mpg %>%
mutate(cty2 = as.numeric(cty),
cty2 = case_when(cty < low_max ~ cty2,
cty > high_min ~ cty2 - adjust,
TRUE ~ NA_real_)) %>%
ggplot(aes(displ, cty2)) +
geom_point() +
annotate("segment", color = "white", size = 2,
x = -Inf, xend = Inf, y = low_max, yend = low_max) +
scale_y_continuous(breaks = 1:50,
label = function(x) {x + ifelse(x>=low_max, adjust, 0)}) +
facet_grid(. ~ drv)