首页 > 解决方案 > 如何处理ggplot2中的垂直渐近线

问题描述

考虑三个简单的数学函数:

f1 <- function(x) 1/x
f2 <- function(x) tan(x)
f3 <- function(x) 1 / sin(x)

分别存在一定的垂直渐近线,即当x接近某个值时f(x)几乎无穷大。我通过以下方式绘制这三个函数ggplot2::stat_function()

# x is between -5 to 5
ggplot(data.frame(x = c(-5, 5)), aes(x)) + 
  stat_function(fun = f1, n = 1000) +
  coord_cartesian(ylim = c(-50, 50))

# x is between -2*pi to 2*pi
ggplot(data.frame(x = c(-2*pi, 2*pi)), aes(x)) + 
  stat_function(fun = f2, n = 1000) +
  coord_cartesian(ylim = c(-50, 50))

# x is between -2*pi to 2*pi
ggplot(data.frame(x = c(-2*pi, 2*pi)), aes(x)) + 
  stat_function(fun = f3, n = 1000) +
  coord_cartesian(ylim = c(-50, 50))

在此处输入图像描述

渐近线分别出现在:

x1 <- 0
x2 <- c(-3/2*pi, -1/2*pi, 1/2*pi, 3/2*pi)
x3 <- c(-pi, 0, pi)

实际上,这些线并不存在,而是ggplot使它们可见。我试图用来geom_vline()覆盖它们,即:

+ geom_vline(xintercept = x1, color = "white")
+ geom_vline(xintercept = x2, color = "white")
+ geom_vline(xintercept = x3, color = "white")

输出看起来很粗糙,可以看到模糊的黑色标记。有没有更强大的方法?

在此处输入图像描述

标签: rggplot2

解决方案


与@Mojoesque 的评论相关的解决方案并不完美,但也相对简单并且有两个小缺点:需要知道渐近线(x1, x2, x3)并可能减少y.

eps <- 0.01
f1 <- function(x) if(min(abs(x - x1)) < eps) NA else 1/x
f2 <- function(x) if(min(abs(x - x2)) < eps) NA else tan(x)
f3 <- function(x) if(min(abs(x - x3)) < eps) NA else 1 / sin(x)

ggplot(data.frame(x = c(-5, 5)), aes(x)) + 
  stat_function(fun = Vectorize(f1), n = 1000) +
  coord_cartesian(ylim = c(-30, 30))

ggplot(data.frame(x = c(-2*pi, 2*pi)), aes(x)) + 
  stat_function(fun = Vectorize(f2), n = 1000) +
  coord_cartesian(ylim = c(-30, 30))

ggplot(data.frame(x = c(-2*pi, 2*pi)), aes(x)) + 
  stat_function(fun = Vectorize(f3), n = 1000) +
  coord_cartesian(ylim = c(-30, 30))

在此处输入图像描述


推荐阅读