Ggplot2: Fill Color Behaviour of Geom_Ribbon

ggplot2: fill color behaviour of geom_ribbon

An option that doesn't require manually creating another column would be to do the logic within aes(fill = itself;

## fill dependent on level > level2
h +
geom_ribbon(aes(ymin = level, ymax = level2, fill = level > level2)) +
geom_line(aes(y = level)) + geom_line(aes(y=level2)) +
scale_fill_manual(values=c("red", "green"), name="fill")

filled conditional on level > level2

Or, if you only want to fill based on that condition being true,

## fill dependent on level > level2, no fill otherwise
h +
geom_ribbon(aes(ymin = level, ymax = level2, fill = ifelse(level > level2, TRUE, NA))) +
geom_line(aes(y = level)) + geom_line(aes(y=level2)) +
scale_fill_manual(values=c("green"), name="fill")

filled conditional on level > level2, not otherwise

I assume the lack of interpolated fill seems to have something to do with the ggplot2 version, as I get the same thing happening with @beetroot's code

## @beetroot's answer
huron$id <- 1:nrow(huron)
huron$group <- ifelse(huron$id <= 50, "A", "B")

h <- ggplot(huron, aes(year))
h +
geom_ribbon(aes(ymin = level, ymax = level2, fill = group)) +
geom_line(aes(y = level)) + geom_line(aes(y = level2))

@beetroot's answer

I get @ManuK's image output when running that code without logic in aes(fill =.

Custom colours for geom_ribbon fill based for categorical data

Try adding scale_fill_manual using the same colors defined in you scale_color_manual argument.

ggplot(data, aes(num, value, colour=category, fill=category)) + 
scale_colour_manual(values = c("A"="black", "B"="red", "C"="magenta", "D"="green")) +
geom_smooth(method="loess", se=FALSE) +
geom_ribbon(aes(x=num, ymax=upperLoess, ymin=lowerLoess, fill=category),
alpha=0.2) +
scale_fill_manual(values = c("A"="black", "B"="red", "C"="magenta", "D"="green"))

matching colors

geom_ribbon: create a rule for colour changes using fill

When you specify something in the original ggplot() it will be inherited by subsequent layers. Don't put group = 1 up there globally. If you need it for the line layer, put group = 1 just in geom_line. Similarly, don't put fill=factor(groups) in the base ggplot() call because you don't want it being used in the point layer, the second ribbon layer, etc. You only need it in the first ribbon layer, so only put it there. (And you need to put it inside aes() since it references a column name!)

pred_avg$DATE = as.Date(pred_avg$DATE)

# Create the plot
ggplot(pred_avg, aes(x = DATE, y = canopycover)) +
geom_point () +
geom_line(group = 1) +
geom_ribbon(
data = pred_avg,
aes(
ymin = canopycoverSDmin,
ymax = canopycoverSDmax,
fill = groups),
alpha = 0.1
) +
scale_fill_manual(values = c("red", "green"), name = "fill") +
geom_ribbon(aes(ymin = covermin, ymax = covermax), alpha = 0.1) +
scale_x_date(breaks = "1 week") +
theme_bw() + theme(
panel.border = element_blank(),
panel.grid.major = element_blank(),
axis.text = element_text(size = 10),
axis.title = element_text(size = 12),
plot.title = element_text(size = 14, face = "bold"),
legend.title = element_blank(),
axis.text.x = element_text(angle = 90, hjust = 1),
panel.grid.minor = element_blank(),
axis.line = element_line(colour = "black")
)

Sample Image

wrong color in geom_ribbon?

As AntoniosK said, you can use the function scale_fill_manual(), but a second option is to put the parameter fill = 'blue' outside of the function aes() (same thing for the parameter alpha).
Like this :

testdf %>% 
ggplot(., aes(x = time)) +
geom_line(aes(y = coef)) +
geom_ribbon(aes(ymin = low_ci, ymax = high_ci), alpha = 0.3, fill = 'blue')

Sample Image

Colouring geom_ribbon in ggplot2 & R

You can use scale_fill_manual() to change fill colors. First argument is your data level and second argument is actual color.

  +scale_fill_manual(values=c("green"="green","red"="red"))

Colour area above y-lim in geom_ribbon

There's really not a direct way to do this in ggplot2 as far as I know. If you didn't want the transparency, then it would be pretty easy just to draw a rectangle in the background and then draw the ribbon on top.

ggplot(df, aes(x = Variable, y = value)) +
geom_rect(aes(xmin=min(Variable), xmax=max(Variable), ymin=0, ymax=1), fill="green") +
geom_ribbon(aes(ymin=pmin(value,1), ymax=0), fill="red", col="red") +
geom_hline(aes(yintercept=0), color="black") +
theme_bw(base_size = 16) +
geom_point()

Sample Image

But if you need the transparency, you're going to need to calculate the bounds of that region which is messy because the points where the line crosses the axis are not in your data, you would need to calculate those. Here's a function that finds the places where the region crosses the axis and keeps track of the top points

crosses <- function(x, y) {
outx <- x[1]
outy <- max(y[1],0)
for(i in 2:length(x)) {
if (sign(y[i-1]) != sign(y[i])) {
outx <- c(outx, -y[i-1]*(x[i]-x[i-1])/(y[i]-y[i-1])+x[i-1])
outy <- c(outy, 0)
}
if (y[i]>0) {
outx <- c(outx, x[i])
outy <- c(outy, y[i])
}
}
if (y[length(y)]<0) {
outx <- c(outx, x[length(x)])
outy <- c(outy, 0)
}
data.frame(x=outx, y=outy)
}

Basically it's just doing some two-point line formula stuff to calculate the intersection.

Then use this to create a new data frame of points for the top ribbon

top_ribbon <- with(df, crosses(Variable, value))

And plot it

ggplot(df, aes(x = Variable, y = value)) +
geom_ribbon(aes(ymin=pmin(value,1), ymax=0), fill="red", col="red", alpha=0.5) +
geom_ribbon(aes(ymin=y, ymax=1, x=x), fill="green", col="green", alpha=0.5, data=top_ribbon) +
geom_hline(aes(yintercept=0), color="black") +
theme_bw(base_size = 16) +
geom_point()

Sample Image

Change colors of a single geom_ribbon() depending on variable

Since in ggplot you cannot have more than one color per line, we can expand the data into multiple lines that connect to each other so they appear to be one line. Then we can assign each section a color.

To make sure they appear connected, we have to expand the data so that the start of the next group and the end of the previous group have the same x and y coordinates, but different groups:

library(zoo)
library(data.table)
df$group <- rleid(df$type)
df_plot <- head(do.call(rbind, by(df, df$group, rbind, NA)), -1)
df_plot[,c("group","type")] <- lapply(df_plot[,c("group","type")], na.locf)
df_plot[] <- lapply(df_plot, na.locf, fromLast = TRUE)

ggplot(df_plot, aes(x = year)) +
geom_ribbon(aes(ymin = lower, ymax = upper, fill = type, group = group))

Sample Image


Compare this to the original, uncolored line:

ggplot(df, aes(x = year)) +
geom_ribbon(aes(ymin = lower, ymax = upper))

Sample Image

One note - I lapply with the na.locf so the type doesnt get changed on me. I am aware you can do na.locf(df_plot).



Related Topics



Leave a reply



Submit