Skip to content

How to shade area between lines in ggplot2

10 messages · Luigi Marongiu, Rui Barradas, PIKAL Petr

#
Hello,
I am running SVM and showing the results with ggplot2. The results
include the decision boundaries, which are two dashed lines parallel
to a solid line. I would like to remove the dashed lines and use a
shaded area instead. How can I do that?
Here is the code I wrote..
```
library(e1071)
library(ggplot2)

set.seed(100)
x1 = rnorm(100, mean = 0.2, sd = 0.1)
y1 = rnorm(100, mean = 0.7, sd = 0.1)
y2 = rnorm(100, mean = 0.2, sd = 0.1)
x2 = rnorm(100, mean = 0.75, sd = 0.1)
df = data.frame(x = c(x1,x2), y=c(y1,y2),
                z=c(rep(0, length(x1)), rep(1, length(x2))))
df$z = factor(c(rep(0, length(x1)), rep(1, length(x2))))
df[, "train"] <- ifelse(runif(nrow(df)) < 0.8, 1, 0)
trainset <- df[df$train == 1, ]
testset <- df[df$train == 0, ]
trainColNum <- grep("train", names(df))
trainset <- trainset[, -trainColNum]
testset <- testset[, -trainColNum]
head(trainset); str(df)

svm_model<- svm(z ~ .,
                data = trainset,
                type = "C-classification",
                kernel = "linear",
                scale = FALSE)

#! plot
p = ggplot(data = trainset, aes(x=x, y=y, color=z)) +
  geom_point() + scale_color_manual(values = c("red", "blue"))
# show decision boundaries
w = t(svm_model$coefs) %*% svm_model$SV  # %*% = matrix multiplication
slope_1 = -w[1]/w[2]
intercept_1 = svm_model$rho / w[2]
p = p + geom_abline(slope = slope_1, intercept = intercept_1)
### here we go: can I use a shaded area between these two lines? ###
p = p + geom_abline(slope = slope_1, intercept = intercept_1 - 1/w[2],
                    linetype = "dashed") +
  geom_abline(slope = slope_1, intercept = intercept_1 + 1/w[2],
              linetype = "dashed")
print(p)

```

Thank you
#
Hi

Did you try google? I got several answers using your question

e.g.
https://stackoverflow.com/questions/54687321/fill-area-between-lines-using-g
gplot-in-r

Cheers
Petr
line. I
factor(c(rep(0,
< 0.8, 1, 0)
<-
testset[,
go:
#
I don't know if I can find a case similar to my need.
I tried with:
```
p = p + geom_abline(slope = slope_1, intercept = intercept_1, col =
"royalblue4")
p = p + geom_line() +
  geom_hline(yintercept = 5) +
  theme_classic() +
  geom_ribbon(aes(ymin=intercept_1 - 1/w[2],ymax=intercept_1 +
1/w[2]), fill="blue")
```
but did not work.
Thanks anyway
On Fri, Oct 23, 2020 at 10:26 AM PIKAL Petr <petr.pikal at precheza.cz> wrote:

  
    
#
I tried from this website
https://community.rstudio.com/t/fill-area-between-lines-using-ggplot-in-r/35355/2
it looked promising but did not work for me:
```
#! plot
p = ggplot(data = trainset, aes(x=x, y=y, color=z)) +
  geom_point() + scale_color_manual(values = c("red", "blue"))
# show support vectors
df_sv = trainset[svm_model$index, ]
p = p + geom_point(data = df_sv, aes(x=x, y=y),
                   color="purple", size=4, alpha=0.5)
# show hyperplane (decision boundaries are off set by 1/w[2])
w = t(svm_model$coefs) %*% svm_model$SV  # %*% = matrix multiplication
slope_1 = -w[1]/w[2]
intercept_1 = svm_model$rho / w[2]
p = p + geom_abline(slope = slope_1, intercept = intercept_1, col =
"royalblue4")
p = p + geom_ribbon(aes(ymin = intercept_1 - 1/w[2],
                        ymax = intercept_1 + 1/w[2]), fill = "grey70")
```
On Fri, Oct 23, 2020 at 10:26 AM PIKAL Petr <petr.pikal at precheza.cz> wrote:

  
    
#
also from this site: https://plotly.com/ggplot2/geom_ribbon/
I get the answer is geom_ribbon but I am still missing something
```
#! plot
p = ggplot(data = trainset, aes(x=x, y=y, color=z)) +
  geom_point() + scale_color_manual(values = c("red", "blue"))
# show support vectors
df_sv = trainset[svm_model$index, ]
p = p + geom_point(data = df_sv, aes(x=x, y=y),
                   color="purple", size=4, alpha=0.5)
# show hyperplane (decision boundaries are off set by 1/w[2])
w = t(svm_model$coefs) %*% svm_model$SV  # %*% = matrix multiplication
slope_1 = -w[1]/w[2]
intercept_1 = svm_model$rho / w[2]
p = p + geom_abline(slope = slope_1, intercept = intercept_1, col =
"royalblue4")
p = p +     geom_ribbon(aes(ymin=intercept_1 - 1/w[2],
                            ymax=intercept_1 + 1/w[2],
                            x=x, fill = "band"), alpha = 0.3) +
  scale_fill_manual("",values="grey12")
```
On Fri, Oct 23, 2020 at 10:26 AM PIKAL Petr <petr.pikal at precheza.cz> wrote:

  
    
#
Hi

What about something like

p+geom_ribbon(aes(ymin = slope_1*x + intercept_1 - 1/w[2],
ymax = slope_1*x + intercept_1 + 1/w[2], fill = "grey70", alpha=0.1))

Cheers
Petr
#
Thank you, but this split the area into two and distorts the shape of
the plot. (compared to
```
p + geom_abline(slope = slope_1, intercept = intercept_1 - 1/w[2],
                    linetype = "dashed", col = "royalblue") +
  geom_abline(slope = slope_1, intercept = intercept_1 + 1/w[2],
              linetype = "dashed", col = "royalblue")
```

Why there is a hole in the middle of the ribbon? and the color is not grey...
On Fri, Oct 23, 2020 at 2:35 PM PIKAL Petr <petr.pikal at precheza.cz> wrote:

  
    
#
Hello,

What about this?


straightline <- function(x, slope, intercept) slope*x + intercept

p <- ggplot(data = trainset, aes(x=x, y=y, color=z)) +
   geom_point() +
   geom_ribbon(aes(ymin = straightline(x, slope_1, intercept_1 + 1/w[2]),
                   ymax = straightline(x, slope_1, intercept_1 - 1/w[2])),
               color = NA, fill = "grey", alpha = 0.5) +
   geom_abline(slope = slope_1, intercept = intercept_1) +
   scale_color_manual(values = c("red", "blue"))

p


Note that now the middle line is drawn last. Otherwise it will be greyed 
by the ribbon.

Hope this helps,

Rui Barradas

?s 08:58 de 23/10/20, Luigi Marongiu escreveu:
2 days later
#
Hi

Put fill outside aes

p+geom_ribbon(aes(ymin = slope_1*x + intercept_1 - 1/w[2],
ymax = slope_1*x + intercept_1 + 1/w[2]), fill = "blue", alpha=0.1)

The "hole" is because you have two levels of data (red and blue). To get rid 
of this you should put new data in ribbon call.
Something like

newdat <- trainset
newdat$z <- factor(0)
p+geom_ribbon(data=newdat, aes(ymin = slope_1*x + intercept_1 - 1/w[2],
ymax = slope_1*x + intercept_1 + 1/w[2]), fill = "yellow", alpha=0.1)

Cheers
Petr
1 day later
#
Thank you!
On Mon, Oct 26, 2020 at 7:30 AM PIKAL Petr <petr.pikal at precheza.cz> wrote: