使用ggplot绘制可能水平或垂直的直线

时间:2019-10-18 15:05:47

标签: r ggplot2

使用ggplot我想绘制ax + by + c = 0形式的直线,其中三个参数由我的代码生成。如果a和b都不为零,则ggplot要求我使用what_i_wanted = data.frame( another_regular_column = c(42, 24, 4242), thelistcol = I(list(as.raw(c(0,1,2)), as.raw(c(3, 4)), as.raw(c(5, 6, 7, 8, 9, 10)))) ) str(what_i_wanted) # 'data.frame': 3 obs. of 2 variables: # $ another_regular_column: num 42 24 4242 # $ thelistcol :List of 3 # ..$ : raw 00 01 02 # ..$ : raw 03 04 # ..$ : raw 05 06 07 08 ... # ..- attr(*, "class")= chr "AsIs" all.equal(a, what_i_wanted) # [1] TRUE ,但是如果a = 0或b = 0,则分别需要使用geom_ablinegeom_vline

必须测试a = 0和b = 0才能选择正确的几何图形,这很麻烦。我真正想要的是一个像这样的geom:

geom_hline

,但似乎不存在。

我的问题有没有凌乱的解决方案?

2 个答案:

答案 0 :(得分:3)

没有一些示例数据很难帮助,但是假设您在像这样的数据框中有参数:

df.params <- data.frame(
  a = c(0, 0, 1, .3),
  b = c(1, .27, 0, 0),
  c = c(1, 2, 3, 4)
)

    a    b c
1 0.0 1.00 1
2 0.0 0.27 2
3 1.0 0.00 3
4 0.3 0.00 4

由此,您可以使用一次调用geom_segment来使用Inf值绘制垂直或水平线。您可以使用ifelse来测试参数是否为零,并为每行交换Inf或拦截值:

ggplot(data = df.params) +
  geom_segment(aes(
    x =    ifelse(a == 0, -Inf, c),
    xend = ifelse(a == 0, Inf, c),
    y =    ifelse(b == 0, -Inf, c),
    yend = ifelse(b == 0, Inf, c)
  )
)

enter image description here

答案 1 :(得分:0)

为了记录,这是我在给出非常有用的注释后编写的包装函数。我认为这不太雅致。

line <- function(a, b, c) { 
  if (a == 0 & b == 0) {
    warning('Invalid parameters for line') 
   } else if (b == 0) {
    geom <- geom_vline(xintercept = -c / a) 
   } else {
    geom <- geom_abline(intercept = -c / b, slope = -a / b) 
   }
  return(geom) 
}