How to deal with vertical asymptotes in ggplot2









up vote
4
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
    Nov 9 at 9:24











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











  • 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
    Nov 9 at 9:52










  • @Mojoesque I make an answer according to your idea, you could give it a look.
    – Darren Tsai
    Nov 9 at 20:48














up vote
4
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
    Nov 9 at 9:24











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











  • 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
    Nov 9 at 9:52










  • @Mojoesque I make an answer according to your idea, you could give it a look.
    – Darren Tsai
    Nov 9 at 20:48












up vote
4
down vote

favorite









up vote
4
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 Nov 9 at 8:27









Darren Tsai

767116




767116







  • 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
    Nov 9 at 9:24











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











  • 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
    Nov 9 at 9:52










  • @Mojoesque I make an answer according to your idea, you could give it a look.
    – Darren Tsai
    Nov 9 at 20:48












  • 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
    Nov 9 at 9:24











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











  • 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
    Nov 9 at 9:52










  • @Mojoesque I make an answer according to your idea, you could give it a look.
    – Darren Tsai
    Nov 9 at 20:48







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
Nov 9 at 9:24





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
Nov 9 at 9:24













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





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













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
Nov 9 at 9:52




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
Nov 9 at 9:52












@Mojoesque I make an answer according to your idea, you could give it a look.
– Darren Tsai
Nov 9 at 20:48




@Mojoesque I make an answer according to your idea, you could give it a look.
– Darren Tsai
Nov 9 at 20:48












2 Answers
2






active

oldest

votes

















up vote
4
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
    Nov 9 at 15:27










  • @DarrenTsai, ah right, I didn't pay attention to n at all.
    – Julius Vainora
    Nov 9 at 15:28










  • I make another answer. You could give it a look. Thank you so much.
    – Darren Tsai
    Nov 9 at 20:54










  • @DarrenTsai, looks great!
    – Julius Vainora
    Nov 9 at 20:55

















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















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    4
    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
      Nov 9 at 15:27










    • @DarrenTsai, ah right, I didn't pay attention to n at all.
      – Julius Vainora
      Nov 9 at 15:28










    • I make another answer. You could give it a look. Thank you so much.
      – Darren Tsai
      Nov 9 at 20:54










    • @DarrenTsai, looks great!
      – Julius Vainora
      Nov 9 at 20:55














    up vote
    4
    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
      Nov 9 at 15:27










    • @DarrenTsai, ah right, I didn't pay attention to n at all.
      – Julius Vainora
      Nov 9 at 15:28










    • I make another answer. You could give it a look. Thank you so much.
      – Darren Tsai
      Nov 9 at 20:54










    • @DarrenTsai, looks great!
      – Julius Vainora
      Nov 9 at 20:55












    up vote
    4
    down vote



    accepted







    up vote
    4
    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 Nov 9 at 12:17

























    answered Nov 9 at 11:08









    Julius Vainora

    27k75877




    27k75877







    • 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
      Nov 9 at 15:27










    • @DarrenTsai, ah right, I didn't pay attention to n at all.
      – Julius Vainora
      Nov 9 at 15:28










    • I make another answer. You could give it a look. Thank you so much.
      – Darren Tsai
      Nov 9 at 20:54










    • @DarrenTsai, looks great!
      – Julius Vainora
      Nov 9 at 20:55












    • 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
      Nov 9 at 15:27










    • @DarrenTsai, ah right, I didn't pay attention to n at all.
      – Julius Vainora
      Nov 9 at 15:28










    • I make another answer. You could give it a look. Thank you so much.
      – Darren Tsai
      Nov 9 at 20:54










    • @DarrenTsai, looks great!
      – Julius Vainora
      Nov 9 at 20:55







    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
    Nov 9 at 15:27




    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
    Nov 9 at 15:27












    @DarrenTsai, ah right, I didn't pay attention to n at all.
    – Julius Vainora
    Nov 9 at 15:28




    @DarrenTsai, ah right, I didn't pay attention to n at all.
    – Julius Vainora
    Nov 9 at 15:28












    I make another answer. You could give it a look. Thank you so much.
    – Darren Tsai
    Nov 9 at 20:54




    I make another answer. You could give it a look. Thank you so much.
    – Darren Tsai
    Nov 9 at 20:54












    @DarrenTsai, looks great!
    – Julius Vainora
    Nov 9 at 20:55




    @DarrenTsai, looks great!
    – Julius Vainora
    Nov 9 at 20:55












    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 Nov 9 at 20:50

























        answered Nov 9 at 20:41









        Darren Tsai

        767116




        767116



























             

            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















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Darth Vader #20

            How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

            Ondo