如何使用 ggplot2 在 y 截距(y 轴)上添加一个点
How to add a point on the y-intercept (y-axis) using ggplot2
我有一个散点图,其中 y 轴比例在特定点发生变化,以绘制具有某些极值的数据。我正在尝试在 y 轴上添加某种视觉提示,指示缩放在该点发生变化。
这是一个情节示例
library(scales)
library(ggplot2)
set.seed(104)
ggdata <- data.frame('x' = rep('a',100),
'y' = c(runif(90, 0, 20), runif(10, 90, 100)))
transformation <- trans_new(
"my_transformation",
transform = function(x) ifelse(x <= 30, x / 5, (x - 30) / 20 + 30 / 5),
inverse = function(x) ifelse(x <= 30 / 5, x * 5, (x - 30 / 5) * 20 + 30)
)
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous(trans = transformation, breaks = c(0, 10, 20, 30, 50, 70, 90, 110))
我想在 y 轴上向 "tick 30" 添加一些标记以进行缩放。
我想在轴上加一个双刻度,但是没有linetype
看起来像双线。该产品应类似于 this。我知道像 scale_y_log10
这样的转换,但我更愿意使用随数据动态变化的自定义缩放。
编辑:根据@Tjebo 的建议,我使用 annotate
将“=”添加到 y 轴断点:
library(scales)
library(ggplot2)
set.seed(104)
ggdata <- data.frame('x' = rep('a',100),
'y' = c(runif(90, 0, 20), runif(10, 90, 100)))
transformation <- trans_new(
"my_transformation",
transform = function(x) ifelse(x <= 30, x / 5, (x - 30) / 20 + 30 / 5),
inverse = function(x) ifelse(x <= 30 / 5, x * 5, (x - 30 / 5) * 20 + 30)
)
mybreaks <- c(0, 10, 20, 30, 50, 70, 90, 110)
tick_linetype <- rep("solid", length(mybreaks))
tick_linetype[4] <- "blank"
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
annotate(geom = "point", shape = "=", x = -Inf, y = 30, size = 3) +
scale_y_continuous(trans = transformation, breaks = mybreaks) +
theme(axis.ticks.y = element_line(linetype = tick_linetype)) +
coord_cartesian(clip = 'off')
我无法得到您链接到的确切外观,但也许其中一些想法对您有用。
您可以将您指定的值设置为次要中断,并只为次要中断添加一行(这里我无法选择 20 的确切值,因为那已经是一个主要中断,但也许您可以尝试用数字得到你喜欢的东西):
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous(trans = transformation, minor_breaks=20.05,breaks = c(0, 10,20, 30, 50, 70, 90, 110))+
theme(
panel.grid.minor.y = element_line(1)
)
另一种选择是自行更改标签。在这里,我将值 20 加粗并包裹在 ()
中,但您也可以添加其他符号:
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous(trans = transformation, minor_breaks = c(0, 10, 20, 30, 50, 70, 90, 110),
breaks = c(0, 10, 20, 30, 50, 70, 90, 110), labels=c(0, 10, expression(bold(("20"))), 30, 50, 70, 90, 110))
您可以在绘图中添加一个片段,这不是最好的选择,因为 x 轴不是连续的,但也许它会激发灵感:
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous(trans = transformation, breaks = c(0, 10, 20, 30, 50, 70, 90, 110))+
geom_segment(aes(x=-.01,y=19.5,xend=.01,yend=20.5),size=1.5)
也许您也可以只遮蔽绘图的底部(或顶部)部分:
ggplot(data = ggdata,aes(x = x, y = y)) +
geom_jitter() +
scale_y_continuous(trans = transformation,breaks = c(0, 10,20, 30, 50, 70, 90, 110))+
annotate("rect", xmin = .4, xmax = 1.6, ymin = 0, ymax = 21,
alpha = .2)
I was thinking of adding a double tick on the axis, but there is no
linetype that looks like a double line.
您可以使用任何字符作为点形。也可以是等号或反斜杠等。
例如:
library(scales)
library(ggplot2)
set.seed(104)
ggdata <- data.frame('x' = rep('a',100),
'y' = c(runif(90, 0, 20), runif(10, 90, 100)))
transformation <- trans_new(
"my_transformation",
transform = function(x) ifelse(x <= 30, x / 5, (x - 30) / 20 + 30 / 5),
inverse = function(x) ifelse(x <= 30 / 5, x * 5, (x - 30 / 5) * 20 + 30)
)
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
annotate(geom = "point", shape = "=", x = -Inf, y = 30, size = 8, color = 'red') +
scale_y_continuous(trans = transformation, breaks = c(0, 10, 20, 30, 50, 70, 90, 110))+
coord_cartesian(clip = 'off')
我删除了剪辑,但你也可以保留它。颜色只是为了突出显示而选择的。
或者,更好的是,使用文本注释。然后你也可以改变角度 - 有点不错。
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
annotate(geom = "text", label = "=", x = -Inf, y = 30, size = 8, color = "red", angle = 45) +
scale_y_continuous(trans = transformation, breaks = c(0, 10, 20, 30, 50, 70, 90, 110)) +
coord_cartesian(clip = "off")
由 reprex package (v0.3.0)
于 2020-04-21 创建
此解决方案应该可以帮助您了解轴的外观。 FWIW 我想警告不要打破轴,除非你明确告诉你的听众他们。在下面的代码中,我创建了两个图,一个用于 30 以下的数据,另一个数据用于极值点(并删除其 x 轴和标签)。然后我使用 plot.margin 来设置图边距,这样当我把它们放在 grid.arrange 中时它们会重叠一点。您可能不得不弄乱边距以使标签对齐。
library(scales)
library(ggplot2)
library(gridExtra)
set.seed(104)
ggdata <- data.frame('x' = rep('a',100),
'y' = c(runif(90, 0, 20), runif(10, 90, 100)))
p1 <- ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous(breaks = seq(0,30,5), limits = c(0,30))+
theme(plot.margin=unit(c(0,.83,0,1), "cm"))
p2 <- ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous( breaks = seq(60,100,10), limits = c(60,100)) +
scale_x_discrete()+
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
plot.margin=unit(c(0,1,-0.1,1), "cm"))
grid.arrange(p2,p1)
我有一个散点图,其中 y 轴比例在特定点发生变化,以绘制具有某些极值的数据。我正在尝试在 y 轴上添加某种视觉提示,指示缩放在该点发生变化。
这是一个情节示例
library(scales)
library(ggplot2)
set.seed(104)
ggdata <- data.frame('x' = rep('a',100),
'y' = c(runif(90, 0, 20), runif(10, 90, 100)))
transformation <- trans_new(
"my_transformation",
transform = function(x) ifelse(x <= 30, x / 5, (x - 30) / 20 + 30 / 5),
inverse = function(x) ifelse(x <= 30 / 5, x * 5, (x - 30 / 5) * 20 + 30)
)
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous(trans = transformation, breaks = c(0, 10, 20, 30, 50, 70, 90, 110))
我想在 y 轴上向 "tick 30" 添加一些标记以进行缩放。
我想在轴上加一个双刻度,但是没有linetype
看起来像双线。该产品应类似于 this。我知道像 scale_y_log10
这样的转换,但我更愿意使用随数据动态变化的自定义缩放。
编辑:根据@Tjebo 的建议,我使用 annotate
将“=”添加到 y 轴断点:
library(scales)
library(ggplot2)
set.seed(104)
ggdata <- data.frame('x' = rep('a',100),
'y' = c(runif(90, 0, 20), runif(10, 90, 100)))
transformation <- trans_new(
"my_transformation",
transform = function(x) ifelse(x <= 30, x / 5, (x - 30) / 20 + 30 / 5),
inverse = function(x) ifelse(x <= 30 / 5, x * 5, (x - 30 / 5) * 20 + 30)
)
mybreaks <- c(0, 10, 20, 30, 50, 70, 90, 110)
tick_linetype <- rep("solid", length(mybreaks))
tick_linetype[4] <- "blank"
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
annotate(geom = "point", shape = "=", x = -Inf, y = 30, size = 3) +
scale_y_continuous(trans = transformation, breaks = mybreaks) +
theme(axis.ticks.y = element_line(linetype = tick_linetype)) +
coord_cartesian(clip = 'off')
我无法得到您链接到的确切外观,但也许其中一些想法对您有用。
您可以将您指定的值设置为次要中断,并只为次要中断添加一行(这里我无法选择 20 的确切值,因为那已经是一个主要中断,但也许您可以尝试用数字得到你喜欢的东西):
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous(trans = transformation, minor_breaks=20.05,breaks = c(0, 10,20, 30, 50, 70, 90, 110))+
theme(
panel.grid.minor.y = element_line(1)
)
另一种选择是自行更改标签。在这里,我将值 20 加粗并包裹在 ()
中,但您也可以添加其他符号:
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous(trans = transformation, minor_breaks = c(0, 10, 20, 30, 50, 70, 90, 110),
breaks = c(0, 10, 20, 30, 50, 70, 90, 110), labels=c(0, 10, expression(bold(("20"))), 30, 50, 70, 90, 110))
您可以在绘图中添加一个片段,这不是最好的选择,因为 x 轴不是连续的,但也许它会激发灵感:
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous(trans = transformation, breaks = c(0, 10, 20, 30, 50, 70, 90, 110))+
geom_segment(aes(x=-.01,y=19.5,xend=.01,yend=20.5),size=1.5)
也许您也可以只遮蔽绘图的底部(或顶部)部分:
ggplot(data = ggdata,aes(x = x, y = y)) +
geom_jitter() +
scale_y_continuous(trans = transformation,breaks = c(0, 10,20, 30, 50, 70, 90, 110))+
annotate("rect", xmin = .4, xmax = 1.6, ymin = 0, ymax = 21,
alpha = .2)
I was thinking of adding a double tick on the axis, but there is no linetype that looks like a double line.
您可以使用任何字符作为点形。也可以是等号或反斜杠等。
例如:
library(scales)
library(ggplot2)
set.seed(104)
ggdata <- data.frame('x' = rep('a',100),
'y' = c(runif(90, 0, 20), runif(10, 90, 100)))
transformation <- trans_new(
"my_transformation",
transform = function(x) ifelse(x <= 30, x / 5, (x - 30) / 20 + 30 / 5),
inverse = function(x) ifelse(x <= 30 / 5, x * 5, (x - 30 / 5) * 20 + 30)
)
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
annotate(geom = "point", shape = "=", x = -Inf, y = 30, size = 8, color = 'red') +
scale_y_continuous(trans = transformation, breaks = c(0, 10, 20, 30, 50, 70, 90, 110))+
coord_cartesian(clip = 'off')
我删除了剪辑,但你也可以保留它。颜色只是为了突出显示而选择的。
或者,更好的是,使用文本注释。然后你也可以改变角度 - 有点不错。
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
annotate(geom = "text", label = "=", x = -Inf, y = 30, size = 8, color = "red", angle = 45) +
scale_y_continuous(trans = transformation, breaks = c(0, 10, 20, 30, 50, 70, 90, 110)) +
coord_cartesian(clip = "off")
由 reprex package (v0.3.0)
于 2020-04-21 创建此解决方案应该可以帮助您了解轴的外观。 FWIW 我想警告不要打破轴,除非你明确告诉你的听众他们。在下面的代码中,我创建了两个图,一个用于 30 以下的数据,另一个数据用于极值点(并删除其 x 轴和标签)。然后我使用 plot.margin 来设置图边距,这样当我把它们放在 grid.arrange 中时它们会重叠一点。您可能不得不弄乱边距以使标签对齐。
library(scales)
library(ggplot2)
library(gridExtra)
set.seed(104)
ggdata <- data.frame('x' = rep('a',100),
'y' = c(runif(90, 0, 20), runif(10, 90, 100)))
p1 <- ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous(breaks = seq(0,30,5), limits = c(0,30))+
theme(plot.margin=unit(c(0,.83,0,1), "cm"))
p2 <- ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous( breaks = seq(60,100,10), limits = c(60,100)) +
scale_x_discrete()+
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
plot.margin=unit(c(0,1,-0.1,1), "cm"))
grid.arrange(p2,p1)