Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shade region between two lines with ggplot

Tags:

r

ggplot2

fill

I produce the folowing two lines with ggplot and would like to shade a specific region between the two lines i.e. where y=x² is greater than y=2x, where 2 <= x <= 3.

# create data #

x<-as.data.frame(c(1,2,3,4))
colnames(x)<-"x"
x$twox<-2*x$x
x$x2<-x$x^2

# Set colours #

blue<-rgb(0.8, 0.8, 1, alpha=0.25)
clear<-rgb(1, 0, 0, alpha=0.0001)

# Define region to fill #

x$fill <- "no fill"
x$fill[(x$x2 > x$twox) & (x$x <= 3 & x$x >= 2)] <- "fill"

# Plot #

ggplot(x, aes(x=x, y=twox)) + 
  geom_line(aes(y = twox)) + 
  geom_line(aes(y = x2)) +
  geom_area(aes(fill=fill)) +
  scale_y_continuous(expand = c(0, 0), limits=c(0,20)) +
  scale_x_continuous(expand = c(0, 0), limits=c(0,5)) + 
  scale_fill_manual(values=c(clear,blue))

The result is the following which just shades the region under the line y=2x, and this no matter what the x-value - why?

enter image description here

like image 811
user2568648 Avatar asked Feb 18 '15 14:02

user2568648


People also ask

What is %>% in Ggplot?

%>% is a pipe operator reexported from the magrittr package. Start by reading the vignette. Introducing magrittr. Adding things to a ggplot changes the object that gets created. The print method of ggplot draws an appropriate plot depending upon the contents of the variable.

Can you filter within Ggplot?

ggplot2 allows you to do data manipulation, such as filtering or slicing, within the data argument.

How do I add a legend in ggplot2?

Adding a legend If you want to add a legend to a ggplot2 chart you will need to pass a categorical (or numerical) variable to color , fill , shape or alpha inside aes . Depending on which argument you use to pass the data and your specific case the output will be different.


2 Answers

How about using geom_ribbon instead

ggplot(x, aes(x=x, y=twox)) + 
    geom_line(aes(y = twox)) + 
    geom_line(aes(y = x2)) +
    geom_ribbon(data=subset(x, 2 <= x & x <= 3), 
          aes(ymin=twox,ymax=x2), fill="blue", alpha=0.5) +
    scale_y_continuous(expand = c(0, 0), limits=c(0,20)) +
    scale_x_continuous(expand = c(0, 0), limits=c(0,5)) + 
    scale_fill_manual(values=c(clear,blue))

plot

like image 120
Tobias Madsen Avatar answered Sep 29 '22 16:09

Tobias Madsen


I think that geom_ribbon is the way to go. There are 2 steps to go:

  1. Data Manipulation: You should manipulate data to define ymin & ymax for arguments in geom_ribbon
  2. Draw plot with geom_ribbon.

Let's see my example:

#Data 
library(gcookbook) 
# Data Manipulation
cb <-subset(climate,Source=="Berkeley")
cb$valence[cb$Anomaly10y >= 0.3] <- "pos"
cb$valence[cb$Anomaly10y < 0.3]  <- "neg"
cb$min <- ifelse(cb$Anomaly10y >= 0.3, 0.3, cb$Anomaly10y)
cb$max <- ifelse(cb$Anomaly10y >= 0.3, cb$Anomaly10y, 0.3)

#Drawing plot
ggplot(cb,aes(x=Year,y=Anomaly10y)) +
geom_ribbon(aes(ymin = min, ymax = max, fill = valence), alpha = 0.75) +
scale_fill_manual(values = c("blue", "orange")) +
geom_line(aes(col = valence), size = 1) +
scale_color_manual(values = c("blue", "orange")) +
geom_hline(yintercept=0.3, col = "blue") +
theme_bw()
like image 24
user3119765 Avatar answered Sep 29 '22 17:09

user3119765