I would like to fill the background of a ggplot in R
with a specific color.
The dataframe contains 3 columns: time
, value
, and color
.
df <- data.frame(time = seq(1, 100, 1),
value = c(runif(n = 45, min = 1, max= 10), runif(10, 40, 50), runif(45, 70, 90)),
color = c(rep("green", 45), rep("orange", 10), rep("red", 45)))
I am able to fill background of the plot in the following manner:
library(tidyverse)
ggplot(df) +
geom_line(aes(x = time, y = value)) +
annotate("rect", xmin=-Inf, xmax= 45, ymin = -Inf, ymax = Inf, alpha = 0.2, fill = "green") +
annotate("rect", xmin=45, xmax= 55, ymin = -Inf, ymax = Inf, alpha = 0.2, fill = "orange") +
annotate("rect", xmin=55, xmax= Inf, ymin = -Inf, ymax = Inf, alpha = 0.2, fill = "red")
Question
In the example above, the background fill
is 'hard coded'. Is there a more convenient/automated way to find the xmin
and xmax
values of the borders between the color transitions?
You can layer a tile plot with just one row behind and use cut
to assign a color to each point.
For your data, I could use a simple cut
. But I doubt that it will always play out as nicely as with the example data:
ggplot(df) +
geom_tile(aes(x=time,y=50,fill=cut(value,3)),height=100,alpha=0.2) +
geom_line(aes(x=time,y=value))
Then it is even simpler:
ggplot(df) +
geom_tile(aes(x=time,y=50,fill=color),height=100,alpha=0.2) +
geom_line(aes(x=time,y=value)) +
scale_fill_manual("Important aspect", values=c("green","orange","red"))
library(tidyverse)
# create a summary table to use for plotting positions
d = df %>%
group_by(color) %>%
summarise(maxtime = max(time))
# plot using you dataset (for the line)
# and the summary table for the color areas
ggplot(df) +
geom_line(aes(x = time, y = value))+
geom_rect(data = data.frame(d$maxtime),
xmin = lag(d$maxtime, default = -Inf),
xmax = d$maxtime,
ymin = rep(-Inf, nrow(d)),
ymax = rep(Inf, nrow(d)),
fill = d$color,
alpha = 0.2)
Your summary table d
shows you the x-axis positions where your color should change and what color that is. And it looks like:
# # A tibble: 3 x 2
# color maxtime
# <fct> <dbl>
# 1 green 45
# 2 orange 55
# 3 red 100
Then you have to find a way to use d
and pass the appropriate info to function geom_rect
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With