How to deal with vertical asymptotes in ggplot2









up vote
3
down vote

favorite












Consider three simple mathematical functions :



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


There exist certain vertical asymptotes respectively, i.e. f(x) almost gets infinity when x approaches some values. I plot these three functions by 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))


enter image description here



The asymptotes appear respectively at :



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


Actually, these lines do not exist, but ggplot makes them visible. I attempted to use geom_vline() to cover them, namely :



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


The outputs seem rough and indistinct black marks can be seen. Are there any methods which are much robuster ?



enter image description here










share|improve this question

















  • 1




    Not really an acceptable solution, but a workaround without any "shades" would be to split the plotting of the functions at the positions of the asymptotes. For example for the first function: ggplot(data.frame(x = c(-5, 5)), aes(x)) + stat_function(fun = f1, n = 1000, xlim = c(-5,-1e-07)) + stat_function(fun = f1, n = 1000, xlim = c(1e-07, 5)) + coord_cartesian(ylim = c(-50, 50)) But there is surprisingly little documentation about this kind of plotting available online...
    – Mojoesque
    yesterday











  • So useful is your comment! But I think it’s inconvenient for something like f2 and f3. Thank you so much.
    – Darren Tsai
    yesterday











  • I agree, it's just another workaround. If there is no other solution it would probably be possible to write a function to add the layers automatically depending on the number of asymptotes, but that's also far from a good solution.
    – Mojoesque
    yesterday










  • @Mojoesque I make an answer according to your idea, you could give it a look.
    – Darren Tsai
    14 hours ago














up vote
3
down vote

favorite












Consider three simple mathematical functions :



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


There exist certain vertical asymptotes respectively, i.e. f(x) almost gets infinity when x approaches some values. I plot these three functions by 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))


enter image description here



The asymptotes appear respectively at :



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


Actually, these lines do not exist, but ggplot makes them visible. I attempted to use geom_vline() to cover them, namely :



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


The outputs seem rough and indistinct black marks can be seen. Are there any methods which are much robuster ?



enter image description here










share|improve this question

















  • 1




    Not really an acceptable solution, but a workaround without any "shades" would be to split the plotting of the functions at the positions of the asymptotes. For example for the first function: ggplot(data.frame(x = c(-5, 5)), aes(x)) + stat_function(fun = f1, n = 1000, xlim = c(-5,-1e-07)) + stat_function(fun = f1, n = 1000, xlim = c(1e-07, 5)) + coord_cartesian(ylim = c(-50, 50)) But there is surprisingly little documentation about this kind of plotting available online...
    – Mojoesque
    yesterday











  • So useful is your comment! But I think it’s inconvenient for something like f2 and f3. Thank you so much.
    – Darren Tsai
    yesterday











  • I agree, it's just another workaround. If there is no other solution it would probably be possible to write a function to add the layers automatically depending on the number of asymptotes, but that's also far from a good solution.
    – Mojoesque
    yesterday










  • @Mojoesque I make an answer according to your idea, you could give it a look.
    – Darren Tsai
    14 hours ago












up vote
3
down vote

favorite









up vote
3
down vote

favorite











Consider three simple mathematical functions :



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


There exist certain vertical asymptotes respectively, i.e. f(x) almost gets infinity when x approaches some values. I plot these three functions by 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))


enter image description here



The asymptotes appear respectively at :



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


Actually, these lines do not exist, but ggplot makes them visible. I attempted to use geom_vline() to cover them, namely :



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


The outputs seem rough and indistinct black marks can be seen. Are there any methods which are much robuster ?



enter image description here










share|improve this question













Consider three simple mathematical functions :



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


There exist certain vertical asymptotes respectively, i.e. f(x) almost gets infinity when x approaches some values. I plot these three functions by 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))


enter image description here



The asymptotes appear respectively at :



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


Actually, these lines do not exist, but ggplot makes them visible. I attempted to use geom_vline() to cover them, namely :



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


The outputs seem rough and indistinct black marks can be seen. Are there any methods which are much robuster ?



enter image description here







r ggplot2






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked yesterday









Darren Tsai

688116




688116







  • 1




    Not really an acceptable solution, but a workaround without any "shades" would be to split the plotting of the functions at the positions of the asymptotes. For example for the first function: ggplot(data.frame(x = c(-5, 5)), aes(x)) + stat_function(fun = f1, n = 1000, xlim = c(-5,-1e-07)) + stat_function(fun = f1, n = 1000, xlim = c(1e-07, 5)) + coord_cartesian(ylim = c(-50, 50)) But there is surprisingly little documentation about this kind of plotting available online...
    – Mojoesque
    yesterday











  • So useful is your comment! But I think it’s inconvenient for something like f2 and f3. Thank you so much.
    – Darren Tsai
    yesterday











  • I agree, it's just another workaround. If there is no other solution it would probably be possible to write a function to add the layers automatically depending on the number of asymptotes, but that's also far from a good solution.
    – Mojoesque
    yesterday










  • @Mojoesque I make an answer according to your idea, you could give it a look.
    – Darren Tsai
    14 hours ago












  • 1




    Not really an acceptable solution, but a workaround without any "shades" would be to split the plotting of the functions at the positions of the asymptotes. For example for the first function: ggplot(data.frame(x = c(-5, 5)), aes(x)) + stat_function(fun = f1, n = 1000, xlim = c(-5,-1e-07)) + stat_function(fun = f1, n = 1000, xlim = c(1e-07, 5)) + coord_cartesian(ylim = c(-50, 50)) But there is surprisingly little documentation about this kind of plotting available online...
    – Mojoesque
    yesterday











  • So useful is your comment! But I think it’s inconvenient for something like f2 and f3. Thank you so much.
    – Darren Tsai
    yesterday











  • I agree, it's just another workaround. If there is no other solution it would probably be possible to write a function to add the layers automatically depending on the number of asymptotes, but that's also far from a good solution.
    – Mojoesque
    yesterday










  • @Mojoesque I make an answer according to your idea, you could give it a look.
    – Darren Tsai
    14 hours ago







1




1




Not really an acceptable solution, but a workaround without any "shades" would be to split the plotting of the functions at the positions of the asymptotes. For example for the first function: ggplot(data.frame(x = c(-5, 5)), aes(x)) + stat_function(fun = f1, n = 1000, xlim = c(-5,-1e-07)) + stat_function(fun = f1, n = 1000, xlim = c(1e-07, 5)) + coord_cartesian(ylim = c(-50, 50)) But there is surprisingly little documentation about this kind of plotting available online...
– Mojoesque
yesterday





Not really an acceptable solution, but a workaround without any "shades" would be to split the plotting of the functions at the positions of the asymptotes. For example for the first function: ggplot(data.frame(x = c(-5, 5)), aes(x)) + stat_function(fun = f1, n = 1000, xlim = c(-5,-1e-07)) + stat_function(fun = f1, n = 1000, xlim = c(1e-07, 5)) + coord_cartesian(ylim = c(-50, 50)) But there is surprisingly little documentation about this kind of plotting available online...
– Mojoesque
yesterday













So useful is your comment! But I think it’s inconvenient for something like f2 and f3. Thank you so much.
– Darren Tsai
yesterday





So useful is your comment! But I think it’s inconvenient for something like f2 and f3. Thank you so much.
– Darren Tsai
yesterday













I agree, it's just another workaround. If there is no other solution it would probably be possible to write a function to add the layers automatically depending on the number of asymptotes, but that's also far from a good solution.
– Mojoesque
yesterday




I agree, it's just another workaround. If there is no other solution it would probably be possible to write a function to add the layers automatically depending on the number of asymptotes, but that's also far from a good solution.
– Mojoesque
yesterday












@Mojoesque I make an answer according to your idea, you could give it a look.
– Darren Tsai
14 hours ago




@Mojoesque I make an answer according to your idea, you could give it a look.
– Darren Tsai
14 hours ago












2 Answers
2






active

oldest

votes

















up vote
3
down vote



accepted










A solution related to @Mojoesque's comments that is not perfect, but also relatively simple and with two minor shortcomings: a need to know the asymptotes (x1, x2, x3) and possibly to reduce the range of 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))


enter image description here






share|improve this answer


















  • 1




    So excellent is your solution! I think the shortcoming that reduces the range of y can be conquered with two ways : (1) keep eps = 0.01 and increase n (2) reduce eps and increase n simultaneously.
    – Darren Tsai
    19 hours ago










  • @DarrenTsai, ah right, I didn't pay attention to n at all.
    – Julius Vainora
    19 hours ago










  • I make another answer. You could give it a look. Thank you so much.
    – Darren Tsai
    14 hours ago










  • @DarrenTsai, looks great!
    – Julius Vainora
    14 hours ago

















up vote
3
down vote













This solution is based on @Mojoesque's comment, which uses piecewise skill to partition x-axis into several subintervals, and then execute multiple stat_function() by purrr::reduce(). The restraint is that asymptotes need to be given.



Take tan(x) for example :



f <- function(x) tan(x)
asymp <- c(-3/2*pi, -1/2*pi, 1/2*pi, 3/2*pi)
left <- -2 * pi # left border
right <- 2 * pi # right border
d <- 0.001
interval <- data.frame(x1 = c(left, asymp + d),
x2 = c(asymp - d, right))

interval # divide the entire x-axis into 5 sections

# x1 x2
# 1 -6.283185 -4.713389
# 2 -4.711389 -1.571796
# 3 -1.569796 1.569796
# 4 1.571796 4.711389
# 5 4.713389 6.283185

library(tidyverse)

pmap(interval, function(x1, x2)
stat_function(fun = f, xlim = c(x1, x2), n = 1000)
) %>% reduce(.f = `+`,
.init = ggplot(data.frame(x = c(left, right)), aes(x)) +
coord_cartesian(ylim = c(-50, 50)))


enter image description here






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53222160%2fhow-to-deal-with-vertical-asymptotes-in-ggplot2%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    3
    down vote



    accepted










    A solution related to @Mojoesque's comments that is not perfect, but also relatively simple and with two minor shortcomings: a need to know the asymptotes (x1, x2, x3) and possibly to reduce the range of 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))


    enter image description here






    share|improve this answer


















    • 1




      So excellent is your solution! I think the shortcoming that reduces the range of y can be conquered with two ways : (1) keep eps = 0.01 and increase n (2) reduce eps and increase n simultaneously.
      – Darren Tsai
      19 hours ago










    • @DarrenTsai, ah right, I didn't pay attention to n at all.
      – Julius Vainora
      19 hours ago










    • I make another answer. You could give it a look. Thank you so much.
      – Darren Tsai
      14 hours ago










    • @DarrenTsai, looks great!
      – Julius Vainora
      14 hours ago














    up vote
    3
    down vote



    accepted










    A solution related to @Mojoesque's comments that is not perfect, but also relatively simple and with two minor shortcomings: a need to know the asymptotes (x1, x2, x3) and possibly to reduce the range of 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))


    enter image description here






    share|improve this answer


















    • 1




      So excellent is your solution! I think the shortcoming that reduces the range of y can be conquered with two ways : (1) keep eps = 0.01 and increase n (2) reduce eps and increase n simultaneously.
      – Darren Tsai
      19 hours ago










    • @DarrenTsai, ah right, I didn't pay attention to n at all.
      – Julius Vainora
      19 hours ago










    • I make another answer. You could give it a look. Thank you so much.
      – Darren Tsai
      14 hours ago










    • @DarrenTsai, looks great!
      – Julius Vainora
      14 hours ago












    up vote
    3
    down vote



    accepted







    up vote
    3
    down vote



    accepted






    A solution related to @Mojoesque's comments that is not perfect, but also relatively simple and with two minor shortcomings: a need to know the asymptotes (x1, x2, x3) and possibly to reduce the range of 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))


    enter image description here






    share|improve this answer














    A solution related to @Mojoesque's comments that is not perfect, but also relatively simple and with two minor shortcomings: a need to know the asymptotes (x1, x2, x3) and possibly to reduce the range of 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))


    enter image description here







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 22 hours ago

























    answered 23 hours ago









    Julius Vainora

    25.9k75877




    25.9k75877







    • 1




      So excellent is your solution! I think the shortcoming that reduces the range of y can be conquered with two ways : (1) keep eps = 0.01 and increase n (2) reduce eps and increase n simultaneously.
      – Darren Tsai
      19 hours ago










    • @DarrenTsai, ah right, I didn't pay attention to n at all.
      – Julius Vainora
      19 hours ago










    • I make another answer. You could give it a look. Thank you so much.
      – Darren Tsai
      14 hours ago










    • @DarrenTsai, looks great!
      – Julius Vainora
      14 hours ago












    • 1




      So excellent is your solution! I think the shortcoming that reduces the range of y can be conquered with two ways : (1) keep eps = 0.01 and increase n (2) reduce eps and increase n simultaneously.
      – Darren Tsai
      19 hours ago










    • @DarrenTsai, ah right, I didn't pay attention to n at all.
      – Julius Vainora
      19 hours ago










    • I make another answer. You could give it a look. Thank you so much.
      – Darren Tsai
      14 hours ago










    • @DarrenTsai, looks great!
      – Julius Vainora
      14 hours ago







    1




    1




    So excellent is your solution! I think the shortcoming that reduces the range of y can be conquered with two ways : (1) keep eps = 0.01 and increase n (2) reduce eps and increase n simultaneously.
    – Darren Tsai
    19 hours ago




    So excellent is your solution! I think the shortcoming that reduces the range of y can be conquered with two ways : (1) keep eps = 0.01 and increase n (2) reduce eps and increase n simultaneously.
    – Darren Tsai
    19 hours ago












    @DarrenTsai, ah right, I didn't pay attention to n at all.
    – Julius Vainora
    19 hours ago




    @DarrenTsai, ah right, I didn't pay attention to n at all.
    – Julius Vainora
    19 hours ago












    I make another answer. You could give it a look. Thank you so much.
    – Darren Tsai
    14 hours ago




    I make another answer. You could give it a look. Thank you so much.
    – Darren Tsai
    14 hours ago












    @DarrenTsai, looks great!
    – Julius Vainora
    14 hours ago




    @DarrenTsai, looks great!
    – Julius Vainora
    14 hours ago












    up vote
    3
    down vote













    This solution is based on @Mojoesque's comment, which uses piecewise skill to partition x-axis into several subintervals, and then execute multiple stat_function() by purrr::reduce(). The restraint is that asymptotes need to be given.



    Take tan(x) for example :



    f <- function(x) tan(x)
    asymp <- c(-3/2*pi, -1/2*pi, 1/2*pi, 3/2*pi)
    left <- -2 * pi # left border
    right <- 2 * pi # right border
    d <- 0.001
    interval <- data.frame(x1 = c(left, asymp + d),
    x2 = c(asymp - d, right))

    interval # divide the entire x-axis into 5 sections

    # x1 x2
    # 1 -6.283185 -4.713389
    # 2 -4.711389 -1.571796
    # 3 -1.569796 1.569796
    # 4 1.571796 4.711389
    # 5 4.713389 6.283185

    library(tidyverse)

    pmap(interval, function(x1, x2)
    stat_function(fun = f, xlim = c(x1, x2), n = 1000)
    ) %>% reduce(.f = `+`,
    .init = ggplot(data.frame(x = c(left, right)), aes(x)) +
    coord_cartesian(ylim = c(-50, 50)))


    enter image description here






    share|improve this answer


























      up vote
      3
      down vote













      This solution is based on @Mojoesque's comment, which uses piecewise skill to partition x-axis into several subintervals, and then execute multiple stat_function() by purrr::reduce(). The restraint is that asymptotes need to be given.



      Take tan(x) for example :



      f <- function(x) tan(x)
      asymp <- c(-3/2*pi, -1/2*pi, 1/2*pi, 3/2*pi)
      left <- -2 * pi # left border
      right <- 2 * pi # right border
      d <- 0.001
      interval <- data.frame(x1 = c(left, asymp + d),
      x2 = c(asymp - d, right))

      interval # divide the entire x-axis into 5 sections

      # x1 x2
      # 1 -6.283185 -4.713389
      # 2 -4.711389 -1.571796
      # 3 -1.569796 1.569796
      # 4 1.571796 4.711389
      # 5 4.713389 6.283185

      library(tidyverse)

      pmap(interval, function(x1, x2)
      stat_function(fun = f, xlim = c(x1, x2), n = 1000)
      ) %>% reduce(.f = `+`,
      .init = ggplot(data.frame(x = c(left, right)), aes(x)) +
      coord_cartesian(ylim = c(-50, 50)))


      enter image description here






      share|improve this answer
























        up vote
        3
        down vote










        up vote
        3
        down vote









        This solution is based on @Mojoesque's comment, which uses piecewise skill to partition x-axis into several subintervals, and then execute multiple stat_function() by purrr::reduce(). The restraint is that asymptotes need to be given.



        Take tan(x) for example :



        f <- function(x) tan(x)
        asymp <- c(-3/2*pi, -1/2*pi, 1/2*pi, 3/2*pi)
        left <- -2 * pi # left border
        right <- 2 * pi # right border
        d <- 0.001
        interval <- data.frame(x1 = c(left, asymp + d),
        x2 = c(asymp - d, right))

        interval # divide the entire x-axis into 5 sections

        # x1 x2
        # 1 -6.283185 -4.713389
        # 2 -4.711389 -1.571796
        # 3 -1.569796 1.569796
        # 4 1.571796 4.711389
        # 5 4.713389 6.283185

        library(tidyverse)

        pmap(interval, function(x1, x2)
        stat_function(fun = f, xlim = c(x1, x2), n = 1000)
        ) %>% reduce(.f = `+`,
        .init = ggplot(data.frame(x = c(left, right)), aes(x)) +
        coord_cartesian(ylim = c(-50, 50)))


        enter image description here






        share|improve this answer














        This solution is based on @Mojoesque's comment, which uses piecewise skill to partition x-axis into several subintervals, and then execute multiple stat_function() by purrr::reduce(). The restraint is that asymptotes need to be given.



        Take tan(x) for example :



        f <- function(x) tan(x)
        asymp <- c(-3/2*pi, -1/2*pi, 1/2*pi, 3/2*pi)
        left <- -2 * pi # left border
        right <- 2 * pi # right border
        d <- 0.001
        interval <- data.frame(x1 = c(left, asymp + d),
        x2 = c(asymp - d, right))

        interval # divide the entire x-axis into 5 sections

        # x1 x2
        # 1 -6.283185 -4.713389
        # 2 -4.711389 -1.571796
        # 3 -1.569796 1.569796
        # 4 1.571796 4.711389
        # 5 4.713389 6.283185

        library(tidyverse)

        pmap(interval, function(x1, x2)
        stat_function(fun = f, xlim = c(x1, x2), n = 1000)
        ) %>% reduce(.f = `+`,
        .init = ggplot(data.frame(x = c(left, right)), aes(x)) +
        coord_cartesian(ylim = c(-50, 50)))


        enter image description here







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 14 hours ago

























        answered 14 hours ago









        Darren Tsai

        688116




        688116



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53222160%2fhow-to-deal-with-vertical-asymptotes-in-ggplot2%23new-answer', 'question_page');

            );

            Post as a guest














































































            這個網誌中的熱門文章

            How to combine Bézier curves to a surface?

            Carbon dioxide

            Why am i infinitely getting the same tweet with the Twitter Search API?