我正在处理包含(几个)跳转的信号,并希望通过将它们绘制为虚线来区分这些部分与实际信号。跳跃的确切位置是已知的。
下面是几乎(几乎)实现所需结果的几种方法,但对于这样一个看似简单的任务来说,它们对我来说都显得相当费力。主要问题似乎是,跳跃点之间没有数据点,可以设置为“NA”。
所以我想我的问题是,是否有更直接/简洁这样做?
library( "ggplot2")
s <- rep( sin( 2*pi*0:9/40), 2)
t <- seq_along( s)
jumps <- ifelse( t == 10 | t == 11, TRUE, FALSE)
ggplot() + geom_line( aes( t, s)) +
geom_point( aes( t[ jumps], s[ jumps]), 'color' = 'red')
s_on <- ifelse( jumps, NA, s)
s_off <- ifelse( jumps, s, NA)
ggplot() + geom_line( aes( t, s_on)) +
geom_line( aes( t, s_off), 'linetype' = 2)
s_off <- ifelse( jumps, s, NA)
ggplot() + geom_line( aes( t, s)) +
geom_line( aes( t, s_off), 'linetype' = 2, 'color' = 'white', 'alpha' = .8)
t_jumps <- t[ jumps]
odd_idxs <- rep_len( c( TRUE, FALSE), length( t_jumps))
t_gaps <- ( t_jumps[ odd_idxs] + t_jumps[ !odd_idxs]) / 2
s_gaps <- rep( NA, length( t_gaps))
s_off <- ifelse( jumps, s, NA)
ggplot() + geom_line( aes( c( t, t_gaps), c( s, s_gaps))) +
geom_line( aes( t, s_off), 'linetype' = 2)
t_os <- seq( min( t), max( t), 'by' = .5)
s_os <- approx( t, s, t_os)$y
jumps_os <- approx( t, jumps, t_os)$y >= 1
gaps_os <- c( FALSE, jumps_os[ -length( jumps_os)]) & c( jumps_os[ -1], FALSE)
s_os_on <- ifelse( gaps_os, NA, s_os)
s_os_off <- ifelse( jumps_os, s_os, NA)
ggplot() + geom_line( aes( t_os, s_os_on)) +
geom_line( aes( t_os, s_os_off), 'linetype' = 2)
编辑:以下是实际数据的摘录。索引50和51之间有一个跳转的100个数据点。数据没有时间码,但是连续采样没有任何间隙;即,索引可以被解释为时间码。连续值通常非常接近,因此如果两个连续值之间的差异大于某个阈值(在这种情况下> 0.5),我们就会跳跃。
s <- c(1.11297501465306, 0.998232815600932, 1.00542810484767, 0.882111160457134,
0.864832695387304, 0.875465966481715, 0.814592253696173, 0.911200049519539,
0.729520738497376, 0.643376989290118, 0.511524957325309, 0.421549461968243,
0.499176602717489, 0.638274888228625, 0.641277324035764, 0.822692758217454,
0.653877788316458, 0.662919995840639, 0.752974952850491, 0.59309477712959,
0.706765754334629, 0.686750632990152, 0.665331035014242, 0.757375655323267,
0.754760862141848, 0.597661179304123, 0.765902449004352, 0.66198324309662,
0.723390854336321, 0.877095195278525, 1.0325927500613, 1.22280563246459,
1.21561478627846, 1.05408674599603, 1.22628475017846, 1.15282000247389,
1.14075413802639, 1.16317573199049, 1.29142561722547, 1.3457714674063,
1.29182361606508, 1.28387220101431, 1.1401680175215, 1.03548344178125,
1.17217653244734, 1.29718279903755, 1.49284766763449, 1.58462042240426,
1.53352373661473, 1.5376752092503, 0.709300844464451, 0.740689239930362,
0.703234727680683, 0.587989527359605, 0.716839470714331, 0.71350401584059,
0.578017875924706, 0.661974735092372, 0.705410783644766, 0.549552099686116,
0.438565947301686, 0.457195165939629, 0.292463065031916, 0.144086477160454,
0.241596068348736, 0.394813115056604, 0.573318116273731, 0.476153524685651,
0.362233571987599, 0.245603948552161, 0.120956567674875, 0.000272847153246339,
-0.14302936391905, -0.0648500232025982, -0.135479792486876, -0.183215864375234,
-0.0843432129360736, -0.171867656242102, -0.0671323497779668,
-0.237922695651651, -0.169482465460897, -0.00180741865187888,
0.108692320249975, 0.20488171428442, 0.132713130954653, 0.186498426925391,
0.159074306581169, 0.0921048566699027, 0.193063378147781, 0.00139091908931722,
-0.0429555546492339, -0.121841486822814, -0.254593643080443,
-0.20847160955891, -0.374809342063964, -0.488266025483608, -0.289662906434387,
-0.439308459591121, -0.621471555065364, -0.461930149141699)
答案 0 :(得分:1)
我最终创建了一个新的ggplot geom (基于geom_linerange
)我打电话给 geom_conline
(对于连线),基本上是geom_line
添加了属性con
(用于连接)。它需要一个布尔矢量,您可以在其中为每个点指定,如果它应该连接到下一个点。
这稍微改变了表示不连续性的向量格式(以前的#39;跳转&#39;现在&#39;连接&#39;在示例中)。
s <- rep( sin( 2*pi*0:9/40), 2)
t <- seq_along( s)
connections <- ifelse( t == 10, FALSE, TRUE)
ggplot() +
geom_conline( aes( t, s, 'con' = connections)) +
geom_conline( aes( t, s, 'con' = !connections), 'linetype' = 2)
<强> geom_conline:强>
geom_conline <- function(
mapping = NULL,
data = NULL,
stat = "identity",
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE
)
{
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomConLine,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
na.rm = na.rm,
...
)
)
}
GeomConLine <- ggproto(
"GeomConLine",
Geom,
default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA),
draw_key = draw_key_vpath,
# required_aes = c("x", "ymin", "ymax"),
required_aes = c("x", "y", "con"),
draw_panel = function( data, panel_scales, coord) {
# data <- transform(data, xend = x, y = ymin, yend = ymax)
data <- subset(
transform(
data,
'xend' = c( x[ 2:nrow( data)], NA),
'yend' = c( y[ 2:nrow( data)], NA),
'con' = c( con[ 1:nrow( data)-1], FALSE)
),
'subset' = con,
'select' = -con
)
ggplot2:::ggname("geom_stem", GeomSegment$draw_panel(data, panel_scales, coord))
}
)