Plot ribbon between lines created with geom_abline2019 Community Moderator ElectionPlot two graphs in same plot in Rr - ggplot2 - create a shaded region between two geom_abline layersA better way to build confidence bands around mean/median of an observed sample using ggplot2How can I color region between two lines specified by slope and intercept on a ggplot R in a log scalegeom_abline for logistic regression (ggplot2)ggplot2: fill color behaviour of geom_ribbonAdding a ribbon when faceting in ggplot2ggplot2 manually adjust linetype of main plot but remove outline of geom_ribbonHow do I shade between lines with identical “y”s?Shade area between two lines defined with function in ggplot

Book about a time-travel war fought by computers

Being asked to review a paper in conference one has submitted to

School performs periodic password audits. Is my password compromised?

Reason why dimensional travelling would be restricted

PTIJ: Aharon, King of Egypt

Giving a talk in my old university, how prominently should I tell students my salary?

How do you say “my friend is throwing a party, do you wanna come?” in german

In which way proportional valves are controlled solely by current?

Should I use HTTPS on a domain that will only be used for redirection?

PTIJ: What’s wrong with eating meat and couscous?

Why is it "take a leak?"

How can I handle a player who pre-plans arguments about my rulings on RAW?

How do I deal with being envious of my own players?

Draw bounding region by list of points

Difference between 'stomach' and 'uterus'

Sometimes a banana is just a banana

The need of reserving one's ability in job interviews

3.5% Interest Student Loan or use all of my savings on Tuition?

Rationale to prefer local variables over instance variables?

Can we carry rice to Japan?

Is there a full canon version of Tyrion's jackass/honeycomb joke?

Can a space-faring robot still function over a billion years?

Is there a math equivalent to the conditional ternary operator?

Why is my Contribution Detail Report (native CiviCRM Core report) not accurate?



Plot ribbon between lines created with geom_abline



2019 Community Moderator ElectionPlot two graphs in same plot in Rr - ggplot2 - create a shaded region between two geom_abline layersA better way to build confidence bands around mean/median of an observed sample using ggplot2How can I color region between two lines specified by slope and intercept on a ggplot R in a log scalegeom_abline for logistic regression (ggplot2)ggplot2: fill color behaviour of geom_ribbonAdding a ribbon when faceting in ggplot2ggplot2 manually adjust linetype of main plot but remove outline of geom_ribbonHow do I shade between lines with identical “y”s?Shade area between two lines defined with function in ggplot










3















I am trying to create a shaded area between lines created with geom_abline



require(ggplot2)

val_intcpt <- c(-1,1)

ggplot() +
geom_point(data = iris, mapping = aes(x = Petal.Length, y = Sepal.Width)) +
geom_abline(intercept = 0, slope = 1, linetype = 'dashed') +
geom_abline(intercept = val_intcpt, slope = 1, linetype = 'dotted')


enter image description here



The idea would be to shade the area between the dotted lines.




  • geom_ribbon doesn't work because it requires ymin/ymax and I do not have this information (of course, I could just hardcode a data frame, but this is not exactly a great solution, as it would not work automatically for any given data.)

  • Using ggplot_build doesn't help because the data frames do not provide x/y data.

I am sure I am missing something very obvious:(










share|improve this question


























    3















    I am trying to create a shaded area between lines created with geom_abline



    require(ggplot2)

    val_intcpt <- c(-1,1)

    ggplot() +
    geom_point(data = iris, mapping = aes(x = Petal.Length, y = Sepal.Width)) +
    geom_abline(intercept = 0, slope = 1, linetype = 'dashed') +
    geom_abline(intercept = val_intcpt, slope = 1, linetype = 'dotted')


    enter image description here



    The idea would be to shade the area between the dotted lines.




    • geom_ribbon doesn't work because it requires ymin/ymax and I do not have this information (of course, I could just hardcode a data frame, but this is not exactly a great solution, as it would not work automatically for any given data.)

    • Using ggplot_build doesn't help because the data frames do not provide x/y data.

    I am sure I am missing something very obvious:(










    share|improve this question
























      3












      3








      3








      I am trying to create a shaded area between lines created with geom_abline



      require(ggplot2)

      val_intcpt <- c(-1,1)

      ggplot() +
      geom_point(data = iris, mapping = aes(x = Petal.Length, y = Sepal.Width)) +
      geom_abline(intercept = 0, slope = 1, linetype = 'dashed') +
      geom_abline(intercept = val_intcpt, slope = 1, linetype = 'dotted')


      enter image description here



      The idea would be to shade the area between the dotted lines.




      • geom_ribbon doesn't work because it requires ymin/ymax and I do not have this information (of course, I could just hardcode a data frame, but this is not exactly a great solution, as it would not work automatically for any given data.)

      • Using ggplot_build doesn't help because the data frames do not provide x/y data.

      I am sure I am missing something very obvious:(










      share|improve this question














      I am trying to create a shaded area between lines created with geom_abline



      require(ggplot2)

      val_intcpt <- c(-1,1)

      ggplot() +
      geom_point(data = iris, mapping = aes(x = Petal.Length, y = Sepal.Width)) +
      geom_abline(intercept = 0, slope = 1, linetype = 'dashed') +
      geom_abline(intercept = val_intcpt, slope = 1, linetype = 'dotted')


      enter image description here



      The idea would be to shade the area between the dotted lines.




      • geom_ribbon doesn't work because it requires ymin/ymax and I do not have this information (of course, I could just hardcode a data frame, but this is not exactly a great solution, as it would not work automatically for any given data.)

      • Using ggplot_build doesn't help because the data frames do not provide x/y data.

      I am sure I am missing something very obvious:(







      r ggplot2






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Oct 22 '18 at 14:55









      TjeboTjebo

      2,5251529




      2,5251529






















          1 Answer
          1






          active

          oldest

          votes


















          3














          Plot a polygon, perhaps?



          # let ss be the slope for geom_abline
          ss <- 1

          p <- ggplot() +
          geom_point(data = iris, mapping = aes(x = Petal.Length, y = Sepal.Width)) +
          geom_abline(intercept = 0, slope = ss, linetype = 'dashed') +
          geom_abline(intercept = val_intcpt, slope = ss, linetype = 'dotted')

          # get plot limits
          p.x <- layer_scales(p)$x$get_limits()
          p.y <- layer_scales(p)$y$get_limits()

          # create polygon coordinates, setting x positions somewhere
          # beyond the current plot limits
          df <- data.frame(
          x = rep(c(p.x[1] - (p.x[2] - p.x[1]),
          p.x[2] + (p.x[2] - p.x[1])), each = 2),
          intcpt = c(val_intcpt, rev(val_intcpt))
          ) %>%
          mutate(y = intcpt + ss * x)

          # add polygon layer, & constrain to previous plot limits
          p +
          annotate(geom = "polygon",
          x = df$x,
          y = df$y,
          alpha = 0.2) +
          coord_cartesian(xlim = p.x, ylim = p.y)


          plot



          Explanation for why it works



          Let's consider a normal plot:



          ss <- 0.75 # this doubles up as illustration for different slope values

          p <- ggplot() +
          geom_point(data = iris, aes(x = Petal.Length, y = Sepal.Width), color = "grey75") +
          geom_abline(intercept = val_intcpt, slope = ss, linetype = 'dashed',
          color = c("blue", "red"), size = 1) +
          annotate(geom = "text", x = c(6, 3), y = c(2.3, 4), color = c("blue", "red"), size = 4,
          label = c("y == a[1] + b*x", "y == a[2] + b*x"), parse = TRUE)
          coord_fixed(ratio = 1.5) +
          theme_classic()

          p + ggtitle("Step 0: Construct plot")


          step 0



          Get the limits p.x / p.y from the p, & take a look at the corresponding locations in the plot itself (in purple):



          p.x <- layer_scales(p)$x$get_limits()
          p.y <- layer_scales(p)$y$get_limits()

          p1 <- p +
          geom_point(data = data.frame(x = p.x, y = p.y) %>% tidyr::complete(x, y),
          aes(x = x, y = y),
          size = 2, stroke = 1, color = "purple")

          p1 + ggtitle("Step 1: Get plot limits")


          step 1



          Take note of the values for the x-axis limits (still in purple):



          p2 <- p1 +
          annotate(geom = "text", x = p.x, y = min(p.y), label = c("x[0]", "x[1]"),
          vjust = -1, parse = TRUE, color = "purple", size = 4)

          p2 +
          ggtitle("Step 2: Note x-axis coordinates of limits") +
          annotate(geom = "segment",
          x = p.x[1] + diff(p.x),
          xend = p.x[2] - diff(p.x),
          y = min(p.y), yend = min(p.y),
          color = "purple", linetype = "dashed", size = 1,
          arrow = arrow(ends = "both")) +
          annotate(geom = "text", x = mean(p.x), y = min(p.y), label = "x[1] - x[0]",
          vjust = -1, parse = TRUE, color = "purple", size = 4)


          step 2



          We want to construct a polygon (a parallelogram, to be precise) with corners far beyond the original plot's range, so that none of it is visible within the plot. One way to achieve this is to take the existing plot's x-axis limits & shifting them outwards by the same amount as the existing plot's x-axis range: the resulting positions (in black) are pretty far out:



          p3 <- p2 +
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)), y = min(p.y),
          shape = 4, size = 1, stroke = 2) +
          annotate(geom = "text",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)), y = min(p.y),
          label = c("x[0] - (x[1] - x[0])", "x[1] + (x[1] - x[0])"),
          vjust = -1, parse = TRUE, size = 5, hjust = c(0, 1))

          p3 +
          ggtitle("Calculate x-axis coordinates of two points far beyond the limits") +
          annotate(geom = "segment",
          x = p.x,
          xend = p.x + c(-diff(p.x), diff(p.x)),
          y = min(p.y), yend = min(p.y),
          linetype = "dashed", size = 0.5,
          arrow = arrow(ends = "both", length = unit(0.1, "inches")))


          step 3



          We can derive the corresponding y values associated with the x-axis positions, for each geom_abline (in red / blue), using the standard y = a + b * x formula:



          p4 <- p3 + 
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          y = val_intcpt[2] + ss * c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          shape = 8, size = 2, stroke = 2, col = "red") +
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          y = val_intcpt[1] + ss * c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          shape = 8, size = 2, stroke = 2, col = "blue")

          p4 +
          ggtitle("Calculate the corresponding y coordinates for both ab-lines") +
          annotate(geom = "text",
          x = p.x[1] - diff(p.x),
          y = val_intcpt + ss * (p.x[1] - diff(p.x)),
          label = c("y == a[1] + b * (x[0] - (x[1] - x[0]))",
          "y == a[2] + b * (x[0] - (x[1] - x[0]))"),
          hjust = -0.2, parse = TRUE,
          color = c("blue", "red")) +
          annotate(geom = "text",
          x = p.x[2] + diff(p.x),
          y = val_intcpt + ss * (p.x[2] + diff(p.x)),
          label = c("y == a[1] + b * (x[1] + (x[1] - x[0]))",
          "y == a[2] + b * (x[1] + (x[1] - x[0]))"),
          hjust = 1.2, parse = TRUE,
          color = c("blue", "red"))


          step 4



          Now that we have the x / y coordinates for the corners, constructing the polygon is a simple matter of joining them together:



          p5 <- p4 +
          annotate(geom = "polygon",
          x = rep(c(p.x[1] - diff(p.x),
          p.x[2] + diff(p.x)),
          each = 2),
          y = c(val_intcpt + ss * (p.x[1] - diff(p.x)),
          rev(val_intcpt) + ss * (p.x[2] + diff(p.x))),
          fill = "yellow", alpha = 0.4)

          p5 +
          ggtitle("Step 5: Draw polygon based on calculated coordinates") +
          annotate(geom = "label",
          x = rep(c(p.x[1] - diff(p.x),
          p.x[2] + diff(p.x)),
          each = 2),
          y = c(val_intcpt + ss * (p.x[1] - diff(p.x)),
          rev(val_intcpt) + ss * (p.x[2] + diff(p.x))),
          label = c("list(x[0] - (x[1] - x[0]), a[1] + b*(x[0] - (x[1] - x[0])))",
          "list(x[0] - (x[1] - x[0]), a[2] + b*(x[0] - (x[1] - x[0])))",
          "list(x[1] + (x[1] - x[0]), a[2] + b*(x[1] + (x[1] - x[0])))",
          "list(x[1] + (x[1] - x[0]), a[1] + b*(x[1] + (x[1] - x[0])))"),
          parse = TRUE, hjust = rep(c(0, 1), each = 2))


          step 5



          Apply the original plot range, & we have a polygon pretending to be a filled ribbon, with corners safely hidden out of the way beyond view:



          p5 +
          ggtitle("Step 6: Reset plot range to original range") +
          coord_fixed(ratio = 1.5, xlim = p.x, ylim = p.y)


          step 6



          (Note: There's a lot of unnecessary code here, to label & colour intermediate steps for illustration purpose. For actual use, as per my original solution, none of that is necessary. But as far as explanation goes, it's either this or sketch + scan in my crappy handwriting...)






          share|improve this answer

























          • yeah That is a nice hack :) I didn't know layer_scales. Again, I learned a lot from you :) I will wait a tiny bit with accepting the answer though, there might be other suggestions out there

            – Tjebo
            Oct 22 '18 at 15:40











          • The solution is great for my example (and also for my requirements) but would not work for different slopes. Do you suggest editing the question to make it more general or ask a new question? Happy to do both

            – Tjebo
            Oct 22 '18 at 15:53











          • (Sorry, I feel very stupid). I admit I just do not manage to understand why your solution works at all. Why does using the coordinates of the plot limits result in the correct polygon?? That is beyond my ken

            – Tjebo
            Oct 22 '18 at 16:02






          • 1





            @Tjebo I just saw your questions & now I feel really bad. >_< Will update my answer to incorporate different slopes.

            – Z.Lin
            17 hours ago






          • 1





            @Tjebo I've updated my answer.

            – Z.Lin
            15 hours ago










          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',
          autoActivateHeartbeat: false,
          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%2f52932253%2fplot-ribbon-between-lines-created-with-geom-abline%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          Plot a polygon, perhaps?



          # let ss be the slope for geom_abline
          ss <- 1

          p <- ggplot() +
          geom_point(data = iris, mapping = aes(x = Petal.Length, y = Sepal.Width)) +
          geom_abline(intercept = 0, slope = ss, linetype = 'dashed') +
          geom_abline(intercept = val_intcpt, slope = ss, linetype = 'dotted')

          # get plot limits
          p.x <- layer_scales(p)$x$get_limits()
          p.y <- layer_scales(p)$y$get_limits()

          # create polygon coordinates, setting x positions somewhere
          # beyond the current plot limits
          df <- data.frame(
          x = rep(c(p.x[1] - (p.x[2] - p.x[1]),
          p.x[2] + (p.x[2] - p.x[1])), each = 2),
          intcpt = c(val_intcpt, rev(val_intcpt))
          ) %>%
          mutate(y = intcpt + ss * x)

          # add polygon layer, & constrain to previous plot limits
          p +
          annotate(geom = "polygon",
          x = df$x,
          y = df$y,
          alpha = 0.2) +
          coord_cartesian(xlim = p.x, ylim = p.y)


          plot



          Explanation for why it works



          Let's consider a normal plot:



          ss <- 0.75 # this doubles up as illustration for different slope values

          p <- ggplot() +
          geom_point(data = iris, aes(x = Petal.Length, y = Sepal.Width), color = "grey75") +
          geom_abline(intercept = val_intcpt, slope = ss, linetype = 'dashed',
          color = c("blue", "red"), size = 1) +
          annotate(geom = "text", x = c(6, 3), y = c(2.3, 4), color = c("blue", "red"), size = 4,
          label = c("y == a[1] + b*x", "y == a[2] + b*x"), parse = TRUE)
          coord_fixed(ratio = 1.5) +
          theme_classic()

          p + ggtitle("Step 0: Construct plot")


          step 0



          Get the limits p.x / p.y from the p, & take a look at the corresponding locations in the plot itself (in purple):



          p.x <- layer_scales(p)$x$get_limits()
          p.y <- layer_scales(p)$y$get_limits()

          p1 <- p +
          geom_point(data = data.frame(x = p.x, y = p.y) %>% tidyr::complete(x, y),
          aes(x = x, y = y),
          size = 2, stroke = 1, color = "purple")

          p1 + ggtitle("Step 1: Get plot limits")


          step 1



          Take note of the values for the x-axis limits (still in purple):



          p2 <- p1 +
          annotate(geom = "text", x = p.x, y = min(p.y), label = c("x[0]", "x[1]"),
          vjust = -1, parse = TRUE, color = "purple", size = 4)

          p2 +
          ggtitle("Step 2: Note x-axis coordinates of limits") +
          annotate(geom = "segment",
          x = p.x[1] + diff(p.x),
          xend = p.x[2] - diff(p.x),
          y = min(p.y), yend = min(p.y),
          color = "purple", linetype = "dashed", size = 1,
          arrow = arrow(ends = "both")) +
          annotate(geom = "text", x = mean(p.x), y = min(p.y), label = "x[1] - x[0]",
          vjust = -1, parse = TRUE, color = "purple", size = 4)


          step 2



          We want to construct a polygon (a parallelogram, to be precise) with corners far beyond the original plot's range, so that none of it is visible within the plot. One way to achieve this is to take the existing plot's x-axis limits & shifting them outwards by the same amount as the existing plot's x-axis range: the resulting positions (in black) are pretty far out:



          p3 <- p2 +
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)), y = min(p.y),
          shape = 4, size = 1, stroke = 2) +
          annotate(geom = "text",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)), y = min(p.y),
          label = c("x[0] - (x[1] - x[0])", "x[1] + (x[1] - x[0])"),
          vjust = -1, parse = TRUE, size = 5, hjust = c(0, 1))

          p3 +
          ggtitle("Calculate x-axis coordinates of two points far beyond the limits") +
          annotate(geom = "segment",
          x = p.x,
          xend = p.x + c(-diff(p.x), diff(p.x)),
          y = min(p.y), yend = min(p.y),
          linetype = "dashed", size = 0.5,
          arrow = arrow(ends = "both", length = unit(0.1, "inches")))


          step 3



          We can derive the corresponding y values associated with the x-axis positions, for each geom_abline (in red / blue), using the standard y = a + b * x formula:



          p4 <- p3 + 
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          y = val_intcpt[2] + ss * c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          shape = 8, size = 2, stroke = 2, col = "red") +
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          y = val_intcpt[1] + ss * c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          shape = 8, size = 2, stroke = 2, col = "blue")

          p4 +
          ggtitle("Calculate the corresponding y coordinates for both ab-lines") +
          annotate(geom = "text",
          x = p.x[1] - diff(p.x),
          y = val_intcpt + ss * (p.x[1] - diff(p.x)),
          label = c("y == a[1] + b * (x[0] - (x[1] - x[0]))",
          "y == a[2] + b * (x[0] - (x[1] - x[0]))"),
          hjust = -0.2, parse = TRUE,
          color = c("blue", "red")) +
          annotate(geom = "text",
          x = p.x[2] + diff(p.x),
          y = val_intcpt + ss * (p.x[2] + diff(p.x)),
          label = c("y == a[1] + b * (x[1] + (x[1] - x[0]))",
          "y == a[2] + b * (x[1] + (x[1] - x[0]))"),
          hjust = 1.2, parse = TRUE,
          color = c("blue", "red"))


          step 4



          Now that we have the x / y coordinates for the corners, constructing the polygon is a simple matter of joining them together:



          p5 <- p4 +
          annotate(geom = "polygon",
          x = rep(c(p.x[1] - diff(p.x),
          p.x[2] + diff(p.x)),
          each = 2),
          y = c(val_intcpt + ss * (p.x[1] - diff(p.x)),
          rev(val_intcpt) + ss * (p.x[2] + diff(p.x))),
          fill = "yellow", alpha = 0.4)

          p5 +
          ggtitle("Step 5: Draw polygon based on calculated coordinates") +
          annotate(geom = "label",
          x = rep(c(p.x[1] - diff(p.x),
          p.x[2] + diff(p.x)),
          each = 2),
          y = c(val_intcpt + ss * (p.x[1] - diff(p.x)),
          rev(val_intcpt) + ss * (p.x[2] + diff(p.x))),
          label = c("list(x[0] - (x[1] - x[0]), a[1] + b*(x[0] - (x[1] - x[0])))",
          "list(x[0] - (x[1] - x[0]), a[2] + b*(x[0] - (x[1] - x[0])))",
          "list(x[1] + (x[1] - x[0]), a[2] + b*(x[1] + (x[1] - x[0])))",
          "list(x[1] + (x[1] - x[0]), a[1] + b*(x[1] + (x[1] - x[0])))"),
          parse = TRUE, hjust = rep(c(0, 1), each = 2))


          step 5



          Apply the original plot range, & we have a polygon pretending to be a filled ribbon, with corners safely hidden out of the way beyond view:



          p5 +
          ggtitle("Step 6: Reset plot range to original range") +
          coord_fixed(ratio = 1.5, xlim = p.x, ylim = p.y)


          step 6



          (Note: There's a lot of unnecessary code here, to label & colour intermediate steps for illustration purpose. For actual use, as per my original solution, none of that is necessary. But as far as explanation goes, it's either this or sketch + scan in my crappy handwriting...)






          share|improve this answer

























          • yeah That is a nice hack :) I didn't know layer_scales. Again, I learned a lot from you :) I will wait a tiny bit with accepting the answer though, there might be other suggestions out there

            – Tjebo
            Oct 22 '18 at 15:40











          • The solution is great for my example (and also for my requirements) but would not work for different slopes. Do you suggest editing the question to make it more general or ask a new question? Happy to do both

            – Tjebo
            Oct 22 '18 at 15:53











          • (Sorry, I feel very stupid). I admit I just do not manage to understand why your solution works at all. Why does using the coordinates of the plot limits result in the correct polygon?? That is beyond my ken

            – Tjebo
            Oct 22 '18 at 16:02






          • 1





            @Tjebo I just saw your questions & now I feel really bad. >_< Will update my answer to incorporate different slopes.

            – Z.Lin
            17 hours ago






          • 1





            @Tjebo I've updated my answer.

            – Z.Lin
            15 hours ago















          3














          Plot a polygon, perhaps?



          # let ss be the slope for geom_abline
          ss <- 1

          p <- ggplot() +
          geom_point(data = iris, mapping = aes(x = Petal.Length, y = Sepal.Width)) +
          geom_abline(intercept = 0, slope = ss, linetype = 'dashed') +
          geom_abline(intercept = val_intcpt, slope = ss, linetype = 'dotted')

          # get plot limits
          p.x <- layer_scales(p)$x$get_limits()
          p.y <- layer_scales(p)$y$get_limits()

          # create polygon coordinates, setting x positions somewhere
          # beyond the current plot limits
          df <- data.frame(
          x = rep(c(p.x[1] - (p.x[2] - p.x[1]),
          p.x[2] + (p.x[2] - p.x[1])), each = 2),
          intcpt = c(val_intcpt, rev(val_intcpt))
          ) %>%
          mutate(y = intcpt + ss * x)

          # add polygon layer, & constrain to previous plot limits
          p +
          annotate(geom = "polygon",
          x = df$x,
          y = df$y,
          alpha = 0.2) +
          coord_cartesian(xlim = p.x, ylim = p.y)


          plot



          Explanation for why it works



          Let's consider a normal plot:



          ss <- 0.75 # this doubles up as illustration for different slope values

          p <- ggplot() +
          geom_point(data = iris, aes(x = Petal.Length, y = Sepal.Width), color = "grey75") +
          geom_abline(intercept = val_intcpt, slope = ss, linetype = 'dashed',
          color = c("blue", "red"), size = 1) +
          annotate(geom = "text", x = c(6, 3), y = c(2.3, 4), color = c("blue", "red"), size = 4,
          label = c("y == a[1] + b*x", "y == a[2] + b*x"), parse = TRUE)
          coord_fixed(ratio = 1.5) +
          theme_classic()

          p + ggtitle("Step 0: Construct plot")


          step 0



          Get the limits p.x / p.y from the p, & take a look at the corresponding locations in the plot itself (in purple):



          p.x <- layer_scales(p)$x$get_limits()
          p.y <- layer_scales(p)$y$get_limits()

          p1 <- p +
          geom_point(data = data.frame(x = p.x, y = p.y) %>% tidyr::complete(x, y),
          aes(x = x, y = y),
          size = 2, stroke = 1, color = "purple")

          p1 + ggtitle("Step 1: Get plot limits")


          step 1



          Take note of the values for the x-axis limits (still in purple):



          p2 <- p1 +
          annotate(geom = "text", x = p.x, y = min(p.y), label = c("x[0]", "x[1]"),
          vjust = -1, parse = TRUE, color = "purple", size = 4)

          p2 +
          ggtitle("Step 2: Note x-axis coordinates of limits") +
          annotate(geom = "segment",
          x = p.x[1] + diff(p.x),
          xend = p.x[2] - diff(p.x),
          y = min(p.y), yend = min(p.y),
          color = "purple", linetype = "dashed", size = 1,
          arrow = arrow(ends = "both")) +
          annotate(geom = "text", x = mean(p.x), y = min(p.y), label = "x[1] - x[0]",
          vjust = -1, parse = TRUE, color = "purple", size = 4)


          step 2



          We want to construct a polygon (a parallelogram, to be precise) with corners far beyond the original plot's range, so that none of it is visible within the plot. One way to achieve this is to take the existing plot's x-axis limits & shifting them outwards by the same amount as the existing plot's x-axis range: the resulting positions (in black) are pretty far out:



          p3 <- p2 +
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)), y = min(p.y),
          shape = 4, size = 1, stroke = 2) +
          annotate(geom = "text",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)), y = min(p.y),
          label = c("x[0] - (x[1] - x[0])", "x[1] + (x[1] - x[0])"),
          vjust = -1, parse = TRUE, size = 5, hjust = c(0, 1))

          p3 +
          ggtitle("Calculate x-axis coordinates of two points far beyond the limits") +
          annotate(geom = "segment",
          x = p.x,
          xend = p.x + c(-diff(p.x), diff(p.x)),
          y = min(p.y), yend = min(p.y),
          linetype = "dashed", size = 0.5,
          arrow = arrow(ends = "both", length = unit(0.1, "inches")))


          step 3



          We can derive the corresponding y values associated with the x-axis positions, for each geom_abline (in red / blue), using the standard y = a + b * x formula:



          p4 <- p3 + 
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          y = val_intcpt[2] + ss * c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          shape = 8, size = 2, stroke = 2, col = "red") +
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          y = val_intcpt[1] + ss * c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          shape = 8, size = 2, stroke = 2, col = "blue")

          p4 +
          ggtitle("Calculate the corresponding y coordinates for both ab-lines") +
          annotate(geom = "text",
          x = p.x[1] - diff(p.x),
          y = val_intcpt + ss * (p.x[1] - diff(p.x)),
          label = c("y == a[1] + b * (x[0] - (x[1] - x[0]))",
          "y == a[2] + b * (x[0] - (x[1] - x[0]))"),
          hjust = -0.2, parse = TRUE,
          color = c("blue", "red")) +
          annotate(geom = "text",
          x = p.x[2] + diff(p.x),
          y = val_intcpt + ss * (p.x[2] + diff(p.x)),
          label = c("y == a[1] + b * (x[1] + (x[1] - x[0]))",
          "y == a[2] + b * (x[1] + (x[1] - x[0]))"),
          hjust = 1.2, parse = TRUE,
          color = c("blue", "red"))


          step 4



          Now that we have the x / y coordinates for the corners, constructing the polygon is a simple matter of joining them together:



          p5 <- p4 +
          annotate(geom = "polygon",
          x = rep(c(p.x[1] - diff(p.x),
          p.x[2] + diff(p.x)),
          each = 2),
          y = c(val_intcpt + ss * (p.x[1] - diff(p.x)),
          rev(val_intcpt) + ss * (p.x[2] + diff(p.x))),
          fill = "yellow", alpha = 0.4)

          p5 +
          ggtitle("Step 5: Draw polygon based on calculated coordinates") +
          annotate(geom = "label",
          x = rep(c(p.x[1] - diff(p.x),
          p.x[2] + diff(p.x)),
          each = 2),
          y = c(val_intcpt + ss * (p.x[1] - diff(p.x)),
          rev(val_intcpt) + ss * (p.x[2] + diff(p.x))),
          label = c("list(x[0] - (x[1] - x[0]), a[1] + b*(x[0] - (x[1] - x[0])))",
          "list(x[0] - (x[1] - x[0]), a[2] + b*(x[0] - (x[1] - x[0])))",
          "list(x[1] + (x[1] - x[0]), a[2] + b*(x[1] + (x[1] - x[0])))",
          "list(x[1] + (x[1] - x[0]), a[1] + b*(x[1] + (x[1] - x[0])))"),
          parse = TRUE, hjust = rep(c(0, 1), each = 2))


          step 5



          Apply the original plot range, & we have a polygon pretending to be a filled ribbon, with corners safely hidden out of the way beyond view:



          p5 +
          ggtitle("Step 6: Reset plot range to original range") +
          coord_fixed(ratio = 1.5, xlim = p.x, ylim = p.y)


          step 6



          (Note: There's a lot of unnecessary code here, to label & colour intermediate steps for illustration purpose. For actual use, as per my original solution, none of that is necessary. But as far as explanation goes, it's either this or sketch + scan in my crappy handwriting...)






          share|improve this answer

























          • yeah That is a nice hack :) I didn't know layer_scales. Again, I learned a lot from you :) I will wait a tiny bit with accepting the answer though, there might be other suggestions out there

            – Tjebo
            Oct 22 '18 at 15:40











          • The solution is great for my example (and also for my requirements) but would not work for different slopes. Do you suggest editing the question to make it more general or ask a new question? Happy to do both

            – Tjebo
            Oct 22 '18 at 15:53











          • (Sorry, I feel very stupid). I admit I just do not manage to understand why your solution works at all. Why does using the coordinates of the plot limits result in the correct polygon?? That is beyond my ken

            – Tjebo
            Oct 22 '18 at 16:02






          • 1





            @Tjebo I just saw your questions & now I feel really bad. >_< Will update my answer to incorporate different slopes.

            – Z.Lin
            17 hours ago






          • 1





            @Tjebo I've updated my answer.

            – Z.Lin
            15 hours ago













          3












          3








          3







          Plot a polygon, perhaps?



          # let ss be the slope for geom_abline
          ss <- 1

          p <- ggplot() +
          geom_point(data = iris, mapping = aes(x = Petal.Length, y = Sepal.Width)) +
          geom_abline(intercept = 0, slope = ss, linetype = 'dashed') +
          geom_abline(intercept = val_intcpt, slope = ss, linetype = 'dotted')

          # get plot limits
          p.x <- layer_scales(p)$x$get_limits()
          p.y <- layer_scales(p)$y$get_limits()

          # create polygon coordinates, setting x positions somewhere
          # beyond the current plot limits
          df <- data.frame(
          x = rep(c(p.x[1] - (p.x[2] - p.x[1]),
          p.x[2] + (p.x[2] - p.x[1])), each = 2),
          intcpt = c(val_intcpt, rev(val_intcpt))
          ) %>%
          mutate(y = intcpt + ss * x)

          # add polygon layer, & constrain to previous plot limits
          p +
          annotate(geom = "polygon",
          x = df$x,
          y = df$y,
          alpha = 0.2) +
          coord_cartesian(xlim = p.x, ylim = p.y)


          plot



          Explanation for why it works



          Let's consider a normal plot:



          ss <- 0.75 # this doubles up as illustration for different slope values

          p <- ggplot() +
          geom_point(data = iris, aes(x = Petal.Length, y = Sepal.Width), color = "grey75") +
          geom_abline(intercept = val_intcpt, slope = ss, linetype = 'dashed',
          color = c("blue", "red"), size = 1) +
          annotate(geom = "text", x = c(6, 3), y = c(2.3, 4), color = c("blue", "red"), size = 4,
          label = c("y == a[1] + b*x", "y == a[2] + b*x"), parse = TRUE)
          coord_fixed(ratio = 1.5) +
          theme_classic()

          p + ggtitle("Step 0: Construct plot")


          step 0



          Get the limits p.x / p.y from the p, & take a look at the corresponding locations in the plot itself (in purple):



          p.x <- layer_scales(p)$x$get_limits()
          p.y <- layer_scales(p)$y$get_limits()

          p1 <- p +
          geom_point(data = data.frame(x = p.x, y = p.y) %>% tidyr::complete(x, y),
          aes(x = x, y = y),
          size = 2, stroke = 1, color = "purple")

          p1 + ggtitle("Step 1: Get plot limits")


          step 1



          Take note of the values for the x-axis limits (still in purple):



          p2 <- p1 +
          annotate(geom = "text", x = p.x, y = min(p.y), label = c("x[0]", "x[1]"),
          vjust = -1, parse = TRUE, color = "purple", size = 4)

          p2 +
          ggtitle("Step 2: Note x-axis coordinates of limits") +
          annotate(geom = "segment",
          x = p.x[1] + diff(p.x),
          xend = p.x[2] - diff(p.x),
          y = min(p.y), yend = min(p.y),
          color = "purple", linetype = "dashed", size = 1,
          arrow = arrow(ends = "both")) +
          annotate(geom = "text", x = mean(p.x), y = min(p.y), label = "x[1] - x[0]",
          vjust = -1, parse = TRUE, color = "purple", size = 4)


          step 2



          We want to construct a polygon (a parallelogram, to be precise) with corners far beyond the original plot's range, so that none of it is visible within the plot. One way to achieve this is to take the existing plot's x-axis limits & shifting them outwards by the same amount as the existing plot's x-axis range: the resulting positions (in black) are pretty far out:



          p3 <- p2 +
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)), y = min(p.y),
          shape = 4, size = 1, stroke = 2) +
          annotate(geom = "text",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)), y = min(p.y),
          label = c("x[0] - (x[1] - x[0])", "x[1] + (x[1] - x[0])"),
          vjust = -1, parse = TRUE, size = 5, hjust = c(0, 1))

          p3 +
          ggtitle("Calculate x-axis coordinates of two points far beyond the limits") +
          annotate(geom = "segment",
          x = p.x,
          xend = p.x + c(-diff(p.x), diff(p.x)),
          y = min(p.y), yend = min(p.y),
          linetype = "dashed", size = 0.5,
          arrow = arrow(ends = "both", length = unit(0.1, "inches")))


          step 3



          We can derive the corresponding y values associated with the x-axis positions, for each geom_abline (in red / blue), using the standard y = a + b * x formula:



          p4 <- p3 + 
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          y = val_intcpt[2] + ss * c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          shape = 8, size = 2, stroke = 2, col = "red") +
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          y = val_intcpt[1] + ss * c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          shape = 8, size = 2, stroke = 2, col = "blue")

          p4 +
          ggtitle("Calculate the corresponding y coordinates for both ab-lines") +
          annotate(geom = "text",
          x = p.x[1] - diff(p.x),
          y = val_intcpt + ss * (p.x[1] - diff(p.x)),
          label = c("y == a[1] + b * (x[0] - (x[1] - x[0]))",
          "y == a[2] + b * (x[0] - (x[1] - x[0]))"),
          hjust = -0.2, parse = TRUE,
          color = c("blue", "red")) +
          annotate(geom = "text",
          x = p.x[2] + diff(p.x),
          y = val_intcpt + ss * (p.x[2] + diff(p.x)),
          label = c("y == a[1] + b * (x[1] + (x[1] - x[0]))",
          "y == a[2] + b * (x[1] + (x[1] - x[0]))"),
          hjust = 1.2, parse = TRUE,
          color = c("blue", "red"))


          step 4



          Now that we have the x / y coordinates for the corners, constructing the polygon is a simple matter of joining them together:



          p5 <- p4 +
          annotate(geom = "polygon",
          x = rep(c(p.x[1] - diff(p.x),
          p.x[2] + diff(p.x)),
          each = 2),
          y = c(val_intcpt + ss * (p.x[1] - diff(p.x)),
          rev(val_intcpt) + ss * (p.x[2] + diff(p.x))),
          fill = "yellow", alpha = 0.4)

          p5 +
          ggtitle("Step 5: Draw polygon based on calculated coordinates") +
          annotate(geom = "label",
          x = rep(c(p.x[1] - diff(p.x),
          p.x[2] + diff(p.x)),
          each = 2),
          y = c(val_intcpt + ss * (p.x[1] - diff(p.x)),
          rev(val_intcpt) + ss * (p.x[2] + diff(p.x))),
          label = c("list(x[0] - (x[1] - x[0]), a[1] + b*(x[0] - (x[1] - x[0])))",
          "list(x[0] - (x[1] - x[0]), a[2] + b*(x[0] - (x[1] - x[0])))",
          "list(x[1] + (x[1] - x[0]), a[2] + b*(x[1] + (x[1] - x[0])))",
          "list(x[1] + (x[1] - x[0]), a[1] + b*(x[1] + (x[1] - x[0])))"),
          parse = TRUE, hjust = rep(c(0, 1), each = 2))


          step 5



          Apply the original plot range, & we have a polygon pretending to be a filled ribbon, with corners safely hidden out of the way beyond view:



          p5 +
          ggtitle("Step 6: Reset plot range to original range") +
          coord_fixed(ratio = 1.5, xlim = p.x, ylim = p.y)


          step 6



          (Note: There's a lot of unnecessary code here, to label & colour intermediate steps for illustration purpose. For actual use, as per my original solution, none of that is necessary. But as far as explanation goes, it's either this or sketch + scan in my crappy handwriting...)






          share|improve this answer















          Plot a polygon, perhaps?



          # let ss be the slope for geom_abline
          ss <- 1

          p <- ggplot() +
          geom_point(data = iris, mapping = aes(x = Petal.Length, y = Sepal.Width)) +
          geom_abline(intercept = 0, slope = ss, linetype = 'dashed') +
          geom_abline(intercept = val_intcpt, slope = ss, linetype = 'dotted')

          # get plot limits
          p.x <- layer_scales(p)$x$get_limits()
          p.y <- layer_scales(p)$y$get_limits()

          # create polygon coordinates, setting x positions somewhere
          # beyond the current plot limits
          df <- data.frame(
          x = rep(c(p.x[1] - (p.x[2] - p.x[1]),
          p.x[2] + (p.x[2] - p.x[1])), each = 2),
          intcpt = c(val_intcpt, rev(val_intcpt))
          ) %>%
          mutate(y = intcpt + ss * x)

          # add polygon layer, & constrain to previous plot limits
          p +
          annotate(geom = "polygon",
          x = df$x,
          y = df$y,
          alpha = 0.2) +
          coord_cartesian(xlim = p.x, ylim = p.y)


          plot



          Explanation for why it works



          Let's consider a normal plot:



          ss <- 0.75 # this doubles up as illustration for different slope values

          p <- ggplot() +
          geom_point(data = iris, aes(x = Petal.Length, y = Sepal.Width), color = "grey75") +
          geom_abline(intercept = val_intcpt, slope = ss, linetype = 'dashed',
          color = c("blue", "red"), size = 1) +
          annotate(geom = "text", x = c(6, 3), y = c(2.3, 4), color = c("blue", "red"), size = 4,
          label = c("y == a[1] + b*x", "y == a[2] + b*x"), parse = TRUE)
          coord_fixed(ratio = 1.5) +
          theme_classic()

          p + ggtitle("Step 0: Construct plot")


          step 0



          Get the limits p.x / p.y from the p, & take a look at the corresponding locations in the plot itself (in purple):



          p.x <- layer_scales(p)$x$get_limits()
          p.y <- layer_scales(p)$y$get_limits()

          p1 <- p +
          geom_point(data = data.frame(x = p.x, y = p.y) %>% tidyr::complete(x, y),
          aes(x = x, y = y),
          size = 2, stroke = 1, color = "purple")

          p1 + ggtitle("Step 1: Get plot limits")


          step 1



          Take note of the values for the x-axis limits (still in purple):



          p2 <- p1 +
          annotate(geom = "text", x = p.x, y = min(p.y), label = c("x[0]", "x[1]"),
          vjust = -1, parse = TRUE, color = "purple", size = 4)

          p2 +
          ggtitle("Step 2: Note x-axis coordinates of limits") +
          annotate(geom = "segment",
          x = p.x[1] + diff(p.x),
          xend = p.x[2] - diff(p.x),
          y = min(p.y), yend = min(p.y),
          color = "purple", linetype = "dashed", size = 1,
          arrow = arrow(ends = "both")) +
          annotate(geom = "text", x = mean(p.x), y = min(p.y), label = "x[1] - x[0]",
          vjust = -1, parse = TRUE, color = "purple", size = 4)


          step 2



          We want to construct a polygon (a parallelogram, to be precise) with corners far beyond the original plot's range, so that none of it is visible within the plot. One way to achieve this is to take the existing plot's x-axis limits & shifting them outwards by the same amount as the existing plot's x-axis range: the resulting positions (in black) are pretty far out:



          p3 <- p2 +
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)), y = min(p.y),
          shape = 4, size = 1, stroke = 2) +
          annotate(geom = "text",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)), y = min(p.y),
          label = c("x[0] - (x[1] - x[0])", "x[1] + (x[1] - x[0])"),
          vjust = -1, parse = TRUE, size = 5, hjust = c(0, 1))

          p3 +
          ggtitle("Calculate x-axis coordinates of two points far beyond the limits") +
          annotate(geom = "segment",
          x = p.x,
          xend = p.x + c(-diff(p.x), diff(p.x)),
          y = min(p.y), yend = min(p.y),
          linetype = "dashed", size = 0.5,
          arrow = arrow(ends = "both", length = unit(0.1, "inches")))


          step 3



          We can derive the corresponding y values associated with the x-axis positions, for each geom_abline (in red / blue), using the standard y = a + b * x formula:



          p4 <- p3 + 
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          y = val_intcpt[2] + ss * c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          shape = 8, size = 2, stroke = 2, col = "red") +
          annotate(geom = "point",
          x = c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          y = val_intcpt[1] + ss * c(p.x[1] - diff(p.x), p.x[2] + diff(p.x)),
          shape = 8, size = 2, stroke = 2, col = "blue")

          p4 +
          ggtitle("Calculate the corresponding y coordinates for both ab-lines") +
          annotate(geom = "text",
          x = p.x[1] - diff(p.x),
          y = val_intcpt + ss * (p.x[1] - diff(p.x)),
          label = c("y == a[1] + b * (x[0] - (x[1] - x[0]))",
          "y == a[2] + b * (x[0] - (x[1] - x[0]))"),
          hjust = -0.2, parse = TRUE,
          color = c("blue", "red")) +
          annotate(geom = "text",
          x = p.x[2] + diff(p.x),
          y = val_intcpt + ss * (p.x[2] + diff(p.x)),
          label = c("y == a[1] + b * (x[1] + (x[1] - x[0]))",
          "y == a[2] + b * (x[1] + (x[1] - x[0]))"),
          hjust = 1.2, parse = TRUE,
          color = c("blue", "red"))


          step 4



          Now that we have the x / y coordinates for the corners, constructing the polygon is a simple matter of joining them together:



          p5 <- p4 +
          annotate(geom = "polygon",
          x = rep(c(p.x[1] - diff(p.x),
          p.x[2] + diff(p.x)),
          each = 2),
          y = c(val_intcpt + ss * (p.x[1] - diff(p.x)),
          rev(val_intcpt) + ss * (p.x[2] + diff(p.x))),
          fill = "yellow", alpha = 0.4)

          p5 +
          ggtitle("Step 5: Draw polygon based on calculated coordinates") +
          annotate(geom = "label",
          x = rep(c(p.x[1] - diff(p.x),
          p.x[2] + diff(p.x)),
          each = 2),
          y = c(val_intcpt + ss * (p.x[1] - diff(p.x)),
          rev(val_intcpt) + ss * (p.x[2] + diff(p.x))),
          label = c("list(x[0] - (x[1] - x[0]), a[1] + b*(x[0] - (x[1] - x[0])))",
          "list(x[0] - (x[1] - x[0]), a[2] + b*(x[0] - (x[1] - x[0])))",
          "list(x[1] + (x[1] - x[0]), a[2] + b*(x[1] + (x[1] - x[0])))",
          "list(x[1] + (x[1] - x[0]), a[1] + b*(x[1] + (x[1] - x[0])))"),
          parse = TRUE, hjust = rep(c(0, 1), each = 2))


          step 5



          Apply the original plot range, & we have a polygon pretending to be a filled ribbon, with corners safely hidden out of the way beyond view:



          p5 +
          ggtitle("Step 6: Reset plot range to original range") +
          coord_fixed(ratio = 1.5, xlim = p.x, ylim = p.y)


          step 6



          (Note: There's a lot of unnecessary code here, to label & colour intermediate steps for illustration purpose. For actual use, as per my original solution, none of that is necessary. But as far as explanation goes, it's either this or sketch + scan in my crappy handwriting...)







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 15 hours ago

























          answered Oct 22 '18 at 15:33









          Z.LinZ.Lin

          12.3k22138




          12.3k22138












          • yeah That is a nice hack :) I didn't know layer_scales. Again, I learned a lot from you :) I will wait a tiny bit with accepting the answer though, there might be other suggestions out there

            – Tjebo
            Oct 22 '18 at 15:40











          • The solution is great for my example (and also for my requirements) but would not work for different slopes. Do you suggest editing the question to make it more general or ask a new question? Happy to do both

            – Tjebo
            Oct 22 '18 at 15:53











          • (Sorry, I feel very stupid). I admit I just do not manage to understand why your solution works at all. Why does using the coordinates of the plot limits result in the correct polygon?? That is beyond my ken

            – Tjebo
            Oct 22 '18 at 16:02






          • 1





            @Tjebo I just saw your questions & now I feel really bad. >_< Will update my answer to incorporate different slopes.

            – Z.Lin
            17 hours ago






          • 1





            @Tjebo I've updated my answer.

            – Z.Lin
            15 hours ago

















          • yeah That is a nice hack :) I didn't know layer_scales. Again, I learned a lot from you :) I will wait a tiny bit with accepting the answer though, there might be other suggestions out there

            – Tjebo
            Oct 22 '18 at 15:40











          • The solution is great for my example (and also for my requirements) but would not work for different slopes. Do you suggest editing the question to make it more general or ask a new question? Happy to do both

            – Tjebo
            Oct 22 '18 at 15:53











          • (Sorry, I feel very stupid). I admit I just do not manage to understand why your solution works at all. Why does using the coordinates of the plot limits result in the correct polygon?? That is beyond my ken

            – Tjebo
            Oct 22 '18 at 16:02






          • 1





            @Tjebo I just saw your questions & now I feel really bad. >_< Will update my answer to incorporate different slopes.

            – Z.Lin
            17 hours ago






          • 1





            @Tjebo I've updated my answer.

            – Z.Lin
            15 hours ago
















          yeah That is a nice hack :) I didn't know layer_scales. Again, I learned a lot from you :) I will wait a tiny bit with accepting the answer though, there might be other suggestions out there

          – Tjebo
          Oct 22 '18 at 15:40





          yeah That is a nice hack :) I didn't know layer_scales. Again, I learned a lot from you :) I will wait a tiny bit with accepting the answer though, there might be other suggestions out there

          – Tjebo
          Oct 22 '18 at 15:40













          The solution is great for my example (and also for my requirements) but would not work for different slopes. Do you suggest editing the question to make it more general or ask a new question? Happy to do both

          – Tjebo
          Oct 22 '18 at 15:53





          The solution is great for my example (and also for my requirements) but would not work for different slopes. Do you suggest editing the question to make it more general or ask a new question? Happy to do both

          – Tjebo
          Oct 22 '18 at 15:53













          (Sorry, I feel very stupid). I admit I just do not manage to understand why your solution works at all. Why does using the coordinates of the plot limits result in the correct polygon?? That is beyond my ken

          – Tjebo
          Oct 22 '18 at 16:02





          (Sorry, I feel very stupid). I admit I just do not manage to understand why your solution works at all. Why does using the coordinates of the plot limits result in the correct polygon?? That is beyond my ken

          – Tjebo
          Oct 22 '18 at 16:02




          1




          1





          @Tjebo I just saw your questions & now I feel really bad. >_< Will update my answer to incorporate different slopes.

          – Z.Lin
          17 hours ago





          @Tjebo I just saw your questions & now I feel really bad. >_< Will update my answer to incorporate different slopes.

          – Z.Lin
          17 hours ago




          1




          1





          @Tjebo I've updated my answer.

          – Z.Lin
          15 hours ago





          @Tjebo I've updated my answer.

          – Z.Lin
          15 hours ago



















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52932253%2fplot-ribbon-between-lines-created-with-geom-abline%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

          Save data to MySQL database using ExtJS and PHP [closed]2019 Community Moderator ElectionHow can I prevent SQL injection in PHP?Which MySQL data type to use for storing boolean valuesPHP: Delete an element from an arrayHow do I connect to a MySQL Database in Python?Should I use the datetime or timestamp data type in MySQL?How to get a list of MySQL user accountsHow Do You Parse and Process HTML/XML in PHP?Reference — What does this symbol mean in PHP?How does PHP 'foreach' actually work?Why shouldn't I use mysql_* functions in PHP?

          Compiling GNU Global with universal-ctags support Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Tags for Emacs: Relationship between etags, ebrowse, cscope, GNU Global and exuberant ctagsVim and Ctags tips and trickscscope or ctags why choose one over the other?scons and ctagsctags cannot open option file “.ctags”Adding tag scopes in universal-ctagsShould I use Universal-ctags?Universal ctags on WindowsHow do I install GNU Global with universal ctags support using Homebrew?Universal ctags with emacsHow to highlight ctags generated by Universal Ctags in Vim?

          Add ONERROR event to image from jsp tldHow to add an image to a JPanel?Saving image from PHP URLHTML img scalingCheck if an image is loaded (no errors) with jQueryHow to force an <img> to take up width, even if the image is not loadedHow do I populate hidden form field with a value set in Spring ControllerStyling Raw elements Generated from JSP tagds with Jquery MobileLimit resizing of images with explicitly set width and height attributeserror TLD use in a jsp fileJsp tld files cannot be resolved