如何防止 geom_segment 中的段重叠
how to prevent an overlapped segments in geom_segment
我正在尝试使用 geom_segment
将不同的范围(线)映射到图中的不同区域(见下文),但有些范围重叠,根本无法显示。
这是数据帧的最小示例:
start = c(1, 5,8, 14)
end =c(3, 6,12, 16)
regions = c(1,2,3, 4)
regions = data_frame(regions, start, end)
from = c(1,2, 5.5, 13.5)
to = c(3,2.5,6, 15)
lines = data_frame(from, to)
我用 geom_rect
绘制了区域,然后用 geom_segment
绘制了范围(线)。
这是情节:
plot_splice <- ggplot() +
scale_x_continuous(breaks = seq(1,16)) +
scale_y_continuous() +
geom_hline(yintercept = 1.6,
size = 20,
alpha = 0.1) +
geom_rect(
data = regions,
mapping = aes(
xmin = start,
xmax = end,
ymin = 1.5,
ymax = 1.8,
)) +
geom_segment(
data = lines,
x = (lines$from),
xend = (lines$to),
y = 1.48,
yend = 1.48,
colour = "red",
size = 3
) +
ylim(1.0, 2.2) +
xlab("") +
theme_minimal()
第一个图是用代码生成的图,而第二个图是所需的图。
如您所见,第二行与第一行重叠,因此您根本看不到第二行。
如何更改代码以生成第二个图?
我正在尝试使用 ifelse
语句但不确定 test
参数应该是什么:
我希望它检查每个范围(线)是否与任何先前的范围(线)重叠,以将 y
位置更改 .05
左右,因此它不会重叠。
lines <- lines %>%
dplyr::arrange(desc(from))
new_y$lines = ifelse(from[1] < to[0], 1.48, 1.3)
geom_segment(
data = lines,
x = (lines$from),
xend = (lines$to),
y = new_y,
yend = new_y,
colour = "red",
size = 3
)
您的 geom_segment
调用未使用任何美学映射,这通常是您让 ggplot 元素根据特定变量(或变量集)改变位置的方式。
最好在调用 ggplot 之前计算基于重叠区域数量的 geom_segment
堆叠。这允许您将 x 和 y 值传递到美学映射中:
# First ensure that the data feame is ordered by the start time
lines <- lines[order(lines$from),]
# Now iterate through each row, calculating how many previous rows have
# earlier starts but haven't yet finished when the current row starts.
# Multiply this number by a small negative offset and add the 1.48 baseline value
lines$offset <- 1.48 - 0.03 * sapply(seq(nrow(lines)), function(i) {
with(lines[seq(i),], length(which(from < from[i] & to > from[i])))
})
现在做同样的情节,但在内部使用美学映射 geom_segment
:
ggplot() +
scale_x_continuous(breaks = seq(1,16), name = "") +
scale_y_continuous(limits = c(1, 2.2), name = "") +
geom_hline(yintercept = 1.6,
size = 20,
alpha = 0.1) +
geom_rect(
data = regions,
mapping = aes(
xmin = start,
xmax = end,
ymin = 1.5,
ymax = 1.8,
)) +
geom_segment(
data = lines,
mapping = aes(
x = from,
xend = to,
y = offset,
yend = offset),
colour = "red",
size = 3
) +
theme_minimal()
我正在尝试使用 geom_segment
将不同的范围(线)映射到图中的不同区域(见下文),但有些范围重叠,根本无法显示。
这是数据帧的最小示例:
start = c(1, 5,8, 14)
end =c(3, 6,12, 16)
regions = c(1,2,3, 4)
regions = data_frame(regions, start, end)
from = c(1,2, 5.5, 13.5)
to = c(3,2.5,6, 15)
lines = data_frame(from, to)
我用 geom_rect
绘制了区域,然后用 geom_segment
绘制了范围(线)。
这是情节:
plot_splice <- ggplot() +
scale_x_continuous(breaks = seq(1,16)) +
scale_y_continuous() +
geom_hline(yintercept = 1.6,
size = 20,
alpha = 0.1) +
geom_rect(
data = regions,
mapping = aes(
xmin = start,
xmax = end,
ymin = 1.5,
ymax = 1.8,
)) +
geom_segment(
data = lines,
x = (lines$from),
xend = (lines$to),
y = 1.48,
yend = 1.48,
colour = "red",
size = 3
) +
ylim(1.0, 2.2) +
xlab("") +
theme_minimal()
第一个图是用代码生成的图,而第二个图是所需的图。
如您所见,第二行与第一行重叠,因此您根本看不到第二行。
如何更改代码以生成第二个图?
我正在尝试使用 ifelse
语句但不确定 test
参数应该是什么:
我希望它检查每个范围(线)是否与任何先前的范围(线)重叠,以将 y
位置更改 .05
左右,因此它不会重叠。
lines <- lines %>%
dplyr::arrange(desc(from))
new_y$lines = ifelse(from[1] < to[0], 1.48, 1.3)
geom_segment(
data = lines,
x = (lines$from),
xend = (lines$to),
y = new_y,
yend = new_y,
colour = "red",
size = 3
)
您的 geom_segment
调用未使用任何美学映射,这通常是您让 ggplot 元素根据特定变量(或变量集)改变位置的方式。
最好在调用 ggplot 之前计算基于重叠区域数量的 geom_segment
堆叠。这允许您将 x 和 y 值传递到美学映射中:
# First ensure that the data feame is ordered by the start time
lines <- lines[order(lines$from),]
# Now iterate through each row, calculating how many previous rows have
# earlier starts but haven't yet finished when the current row starts.
# Multiply this number by a small negative offset and add the 1.48 baseline value
lines$offset <- 1.48 - 0.03 * sapply(seq(nrow(lines)), function(i) {
with(lines[seq(i),], length(which(from < from[i] & to > from[i])))
})
现在做同样的情节,但在内部使用美学映射 geom_segment
:
ggplot() +
scale_x_continuous(breaks = seq(1,16), name = "") +
scale_y_continuous(limits = c(1, 2.2), name = "") +
geom_hline(yintercept = 1.6,
size = 20,
alpha = 0.1) +
geom_rect(
data = regions,
mapping = aes(
xmin = start,
xmax = end,
ymin = 1.5,
ymax = 1.8,
)) +
geom_segment(
data = lines,
mapping = aes(
x = from,
xend = to,
y = offset,
yend = offset),
colour = "red",
size = 3
) +
theme_minimal()