ggplot2 轴自定义缩放后缺少标签
ggplot2 missing labels after custom scaling of axis
我正在尝试使用 ggplot2
和 scales::trans_new()
对我的 x 轴应用自定义缩放。但是,当我这样做时,一些轴标签会丢失。谁能帮我弄清楚为什么?
设置:
library(tidyverse)
# the data
ds <- tibble(
myx = c(1, .5, .1, .01, .001, 0),
myy = 1:6
)
# the custom transformation
forth_root_trans_rev <- scales::trans_new(
name = "sign_fourth_root_rev",
transform = function (x) { - abs(x)^(1/4) },
inverse = function (x) { x^4 }
)
地块 1:
当我尝试绘制此图时,x = 0
的标签丢失了。
# plot - missing x-label at `0`
ggplot(ds, aes(x = myx, y = myy)) +
geom_line() +
geom_point() +
scale_x_continuous(
trans = forth_root_trans_rev,
breaks = sort(unique(ds$myx)),
)
情节 2
当我在图表的两边添加一些 space 时,更多的 x 标签丢失了。
# plot - missing x-labels below 0.5
ggplot(ds, aes(x = myx, y = myy)) +
geom_line() +
geom_point() +
scale_x_continuous(
trans = forth_root_trans_rev,
breaks = sort(unique(ds$myx)),
expand = expand_scale(mult = c(.1, .6))
)
我认为这与这个旧问题有关:https://github.com/tidyverse/ggplot2/issues/980。不过,我不知道如何应用此转换并保留所有 x 标签。
我哪里错了?
这里的问题是由两个因素共同造成的:
您的 x-axis 值(转换后)落在 [-1, 0] 范围内,因此任何扩展(无论是加法还是乘法)都会推动最终范围以涵盖正数和负值。
您的自定义转换 one-to-one 不在 [<some negative number>, <some positive number>]
区域。
怎么发生的
在用于构建 ggplot 对象的所有代码深处的某处(您可以 运行 ggplot2:::ggplot_build.ggplot
在打印绘图之前进入 layout$setup_panel_params()
,但我不推荐这样做对于临时用户...兔子洞真的很深),x-axis 中断按以下方式计算:
- 获取转换值的限制(对于问题中的
c(1, .5, .1, .01, .001, 0)
,这将是 (-1, 0)
)。
- 如果适用,将扩展添加到限制(连续轴的默认扩展是两侧各 5%,因此限制变为
(-1.05, 0.05)
)。
- 对极限应用逆变换(对极限进行
x^4
得到 (1.215506, 0.000006)
)。
- 对 user-inputted 个中断和限制应用转换(对于中断,
c(1, .5, .1, .01, .001, 0)
变为 (-1.0000000, ..., 0.0000000)
,但对于限制,(1.215506, 0.000006)
现在变为 (-1.05, -0.05)
,比 (-1.05, 0.05)
). 窄
- 超出限制范围的中断被删除(因为限制现在停止在 -0.05,0 处的中断被删除)。
如何解决这个问题
您可以使用 sign()
修改您的转换以保留正值/负值,这样转换在整个范围内为 one-to-one,正如 Hadley 在关于你链接的GH问题。例如:
# original
forth_root_trans_rev <- scales::trans_new(
name = "sign_fourth_root_rev",
transform = function (x) { - abs(x)^(1/4) },
inverse = function (x) { x^4 }
)
# new
forth_root_trans_rev2 <- scales::trans_new(
name = "sign_fourth_root_rev",
transform = function (x) { -sign(x) * abs(x)^(1/4) },
inverse = function (x) { -sign(x) * abs(x)^4 }
)
library(dplyr)
library(tidyr)
# comparison of two transformations
# y1 shows a one-to-one mapping in either (-Inf, 0] or [0, Inf) but not both;
# y2 shows a one-to-one mapping in (-Inf, Inf)
data.frame(x = seq(-1, 1, 0.01)) %>%
mutate(y1 = x %>% forth_root_trans_rev$transform() %>% forth_root_trans_rev$inverse(),
y2 = x %>% forth_root_trans_rev2$transform() %>% forth_root_trans_rev2$inverse()) %>%
gather(trans, y, -x) %>%
ggplot(aes(x, y, colour = trans)) +
geom_line() +
geom_vline(xintercept = 0, linetype = "dashed") +
facet_wrap(~trans)
用法
p <- ggplot(ds, aes(x = myx, y = myy)) +
geom_line() +
geom_point() +
theme(panel.grid.minor = element_blank())
p +
scale_x_continuous(
trans = forth_root_trans_rev2,
breaks = sort(unique(ds$myx))
)
p +
scale_x_continuous(
trans = forth_root_trans_rev2,
breaks = sort(unique(ds$myx)),
expand = expand_scale(mult = c(.1, .6)) # with different expansion factor, if desired
)
我正在尝试使用 ggplot2
和 scales::trans_new()
对我的 x 轴应用自定义缩放。但是,当我这样做时,一些轴标签会丢失。谁能帮我弄清楚为什么?
设置:
library(tidyverse)
# the data
ds <- tibble(
myx = c(1, .5, .1, .01, .001, 0),
myy = 1:6
)
# the custom transformation
forth_root_trans_rev <- scales::trans_new(
name = "sign_fourth_root_rev",
transform = function (x) { - abs(x)^(1/4) },
inverse = function (x) { x^4 }
)
地块 1:
当我尝试绘制此图时,x = 0
的标签丢失了。
# plot - missing x-label at `0`
ggplot(ds, aes(x = myx, y = myy)) +
geom_line() +
geom_point() +
scale_x_continuous(
trans = forth_root_trans_rev,
breaks = sort(unique(ds$myx)),
)
情节 2
当我在图表的两边添加一些 space 时,更多的 x 标签丢失了。
# plot - missing x-labels below 0.5
ggplot(ds, aes(x = myx, y = myy)) +
geom_line() +
geom_point() +
scale_x_continuous(
trans = forth_root_trans_rev,
breaks = sort(unique(ds$myx)),
expand = expand_scale(mult = c(.1, .6))
)
我认为这与这个旧问题有关:https://github.com/tidyverse/ggplot2/issues/980。不过,我不知道如何应用此转换并保留所有 x 标签。
我哪里错了?
这里的问题是由两个因素共同造成的:
您的 x-axis 值(转换后)落在 [-1, 0] 范围内,因此任何扩展(无论是加法还是乘法)都会推动最终范围以涵盖正数和负值。
您的自定义转换 one-to-one 不在
[<some negative number>, <some positive number>]
区域。
怎么发生的
在用于构建 ggplot 对象的所有代码深处的某处(您可以 运行 ggplot2:::ggplot_build.ggplot
在打印绘图之前进入 layout$setup_panel_params()
,但我不推荐这样做对于临时用户...兔子洞真的很深),x-axis 中断按以下方式计算:
- 获取转换值的限制(对于问题中的
c(1, .5, .1, .01, .001, 0)
,这将是(-1, 0)
)。 - 如果适用,将扩展添加到限制(连续轴的默认扩展是两侧各 5%,因此限制变为
(-1.05, 0.05)
)。 - 对极限应用逆变换(对极限进行
x^4
得到(1.215506, 0.000006)
)。 - 对 user-inputted 个中断和限制应用转换(对于中断,
c(1, .5, .1, .01, .001, 0)
变为(-1.0000000, ..., 0.0000000)
,但对于限制,(1.215506, 0.000006)
现在变为(-1.05, -0.05)
,比(-1.05, 0.05)
). 窄
- 超出限制范围的中断被删除(因为限制现在停止在 -0.05,0 处的中断被删除)。
如何解决这个问题
您可以使用 sign()
修改您的转换以保留正值/负值,这样转换在整个范围内为 one-to-one,正如 Hadley 在关于你链接的GH问题。例如:
# original
forth_root_trans_rev <- scales::trans_new(
name = "sign_fourth_root_rev",
transform = function (x) { - abs(x)^(1/4) },
inverse = function (x) { x^4 }
)
# new
forth_root_trans_rev2 <- scales::trans_new(
name = "sign_fourth_root_rev",
transform = function (x) { -sign(x) * abs(x)^(1/4) },
inverse = function (x) { -sign(x) * abs(x)^4 }
)
library(dplyr)
library(tidyr)
# comparison of two transformations
# y1 shows a one-to-one mapping in either (-Inf, 0] or [0, Inf) but not both;
# y2 shows a one-to-one mapping in (-Inf, Inf)
data.frame(x = seq(-1, 1, 0.01)) %>%
mutate(y1 = x %>% forth_root_trans_rev$transform() %>% forth_root_trans_rev$inverse(),
y2 = x %>% forth_root_trans_rev2$transform() %>% forth_root_trans_rev2$inverse()) %>%
gather(trans, y, -x) %>%
ggplot(aes(x, y, colour = trans)) +
geom_line() +
geom_vline(xintercept = 0, linetype = "dashed") +
facet_wrap(~trans)
用法
p <- ggplot(ds, aes(x = myx, y = myy)) +
geom_line() +
geom_point() +
theme(panel.grid.minor = element_blank())
p +
scale_x_continuous(
trans = forth_root_trans_rev2,
breaks = sort(unique(ds$myx))
)
p +
scale_x_continuous(
trans = forth_root_trans_rev2,
breaks = sort(unique(ds$myx)),
expand = expand_scale(mult = c(.1, .6)) # with different expansion factor, if desired
)