I'd like to make a geom_area plot with the fill colour based on the y (or any other) value, similar to the geom_density_ridges_gradient function of the ggridges package. I could achieve this with multiple geom_cols but I want to have the nice smooth geom_area style. Do you have any idea?
This code illustrates what I want to do:
data <- data.frame(x = 1:100,
y = rnorm(100, 20,3))
#I'd like to have an area plot with the fill colour based on the y values
ggplot(data = data, aes(x = x, y = y))+
geom_area(aes(fill = y))
#As in a bar plot, but with a smooth area, not a composite of rectangles
ggplot(data = data, aes(x = x, y = y))+
geom_col(aes(fill = y))
Thanks a lot!
You can use approx to get a huge number of interpolated values and plot them as very thin vertical geom_segments
data2 <- as.data.frame(approx(data$x, data$y, seq(1, 100, len = 5000)))
ggplot(data = data2, aes(x = x, y = y))+
geom_segment(aes(xend = x, yend = 0, colour = y), linewidth = 0.1) +
geom_area(fill = NA, color = "black") +
scale_color_viridis_c() +
theme_minimal(base_size = 20)
Related
When trying to plot some data in ggplot2 using geom_line(), I noticed that the legend items become empty if I use alpha < 1. How can I fix this and why is this happening?
# dummy data
data <- data.frame(
x = rep(1:10, 10),
y = 1:100 + c(runif(50,0,5), runif(50,0,10)),
grp = c(rep("A", 50), rep("B", 50)))
# using alpha on defaul = 1
ggplot(data, aes(x = x, y = y, col = grp)) +
geom_line()
When I plot the same graph, but with alpha < 1, the lines in the legend completely disappear:
# using alpha < 1
ggplot(data, aes(x = x, y = y, col = grp)) +
geom_line(alpha = 0.9)
(versions: R 4.1.3, ggplot2 3.3.5)
Edit: Updating R and restarting RStudio did not help. This also occurs when using R directly without RStudio.
I ran into the same problem. When saving the plots to PDF/PNG the lines do appear in the legend.
Another workaround I found is adding geom_point() so that way at least you have the colors in the legend:
ggplot(data, aes(x = x, y = y, col = grp)) +
geom_line(alpha = 0.4) +
geom_point(alpha = 0.4, size = 0.1) +
guides(colour = guide_legend(override.aes = list(size=4)))
Legend take the same aes() than plot, you can override this by override.aes.
This should work
ggplot(data, aes(x = x, y = y, col = grp)) +
geom_line(alpha = 0.2) + # using alpha = 0.2 to have it more evident
guides(col = guide_legend(override.aes = list(alpha = 1)))
The same can be used for example to change shape or color of legend elements, respect to aes() mapping in plot
Example data frame (if there's a better/more idiomatic way to do this, let me know):
n <- 10
group <- rep(c("A","B","C"),each = n)
x <- rep(seq(0,1,length = n),3)
y <- ifelse(group == "A",1+x,ifelse(group == "B",2+2*x,3+3*x))
df <- data.frame(group,x,y)
xd <- 0.5
des <- data.frame(xd)
I want to plot create point-line plots for the data in df, add a vertical curve at the x location indicated by xd, and get readable legends for both. I tried the following:
p <- ggplot(data = df, aes(x = x, y = y, color = group)) + geom_point() + geom_line(aes(linetype=group))
p <- p + geom_vline(data = des, aes(xintercept = xd), color = "blue")
p
Not quite what I had in mind, there's no legend for the vertical line.
A small modification (I don't understand why geom_vline is one of the few geometries with a show.legend parameter, which moreover defaults to FALSE!):
p <- ggplot(data = df, aes(x = x, y = y, color = group)) + geom_point() + geom_line(aes(linetype=group))
p <- p + geom_vline(data = des, aes(xintercept = xd), color = "blue", show.legend = TRUE)
p
At least now the vertical bar is showing in the legend, but I don't want it to go in the same "category" (?) as group. I would like another legend entry, titled Design, and containing only the vertical line. How can I achieve this?
A possible approach is to add an extra dummy aesthetic like fill =, which we'll subsequently use to create the second legend in combination with scale_fill_manual() :
ggplot(data = df, aes(x = x, y = y, color = group)) +
geom_point() +
geom_line(aes(linetype=group), show.legend = TRUE) +
geom_vline(data = des,
aes(xintercept = xd, fill = "Vertical Line"), # add dummy fill
colour = "blue") +
scale_fill_manual(values = 1, "Design", # customize second legend
guide = guide_legend(override.aes = list(colour = c("blue"))))
I'm producing a facet wrapped forest plot and I'd like to manually set the y-axis labels.
Here's my example data:
set.seed(1)
df <- data.frame(x=rnorm(10),y=c(1:5,1:3,1:2),
group=c(rep("a",5),rep("b",3),rep("c",2)),
name=c(paste("a",1:5,sep=""),paste("b",1:3,sep=""),paste("c",1:2,sep="")))
df$xmin <- df$x-runif(10,0.5,0.7)
df$xmax <- df$x+runif(10,0.5,0.7)
And here's the code I'm trying:
library(ggplot2)
p <- ggplot(df,aes(y = y, x = x))+
geom_point()+
scale_y_discrete(limits = df$name, expand = c(.1,0))+
facet_wrap(~group,ncol=3,scales="free")+
geom_segment(aes(x = xmin, xend = xmax, y = y, yend = y))+
geom_vline(lty=2, aes(xintercept=0), colour = 'red')
Which produces this figure:
As you can see the y-axis tick labels of the middle and right most facets are not consistent with df$name.
ggplot(df,aes(y = name, x = x)) +
geom_point() +
facet_wrap(~group,ncol=3,scales="free") +
geom_segment(aes(x = xmin, xend = xmax, y = name, yend = name)) +
geom_vline(lty=2, aes(xintercept=0), colour = 'red')
If you look at this
ggplot(mtcars,aes(x=disp,y=mpg,colour=mpg))+geom_line()
you will see that the line colour varies according to the corresponding y value, which is what I want, but only section-by-section. I would like the colour to vary continuously according to the y value. Any easy way?
One possibility which comes to mind would be to use interpolation to create more x- and y-values, and thereby make the colours more continuous. I use approx to " linearly interpolate given data points". Here's an example on a simpler data set:
# original data and corresponding plot
df <- data.frame(x = 1:3, y = c(3, 1, 4))
library(ggplot2)
ggplot(data = df, aes(x = x, y = y, colour = y)) +
geom_line(size = 3)
# interpolation to make 'more values' and a smoother colour gradient
vals <- approx(x = df$x, y = df$y)
df2 <- data.frame(x = vals$x, y = vals$y)
ggplot(data = df2, aes(x = x, y = y, colour = y)) +
geom_line(size = 3)
If you wish the gradient to be even smoother, you may use the n argument in approx to adjust the number of points to be created ("interpolation takes place at n equally spaced points spanning the interval [min(x), max(x)]"). With a larger number of values, perhaps geom_point gives a smoother appearance:
vals <- approx(x = df$x, y = df$y, n = 500)
df2 <- data.frame(x = vals$x, y = vals$y)
ggplot(data = df2, aes(x = x, y = y, colour = y)) +
geom_point(size = 3)
Since ggplot2 v0.8.5 one can use geom_line or geom_path with different lineend options (right now there are three options: round, butt and square). Selection depends on the nature of the data.
round would work on sharp edges (like in given OPs data):
library(ggplot2)
ggplot(mtcars, aes(disp, mpg, color = mpg)) +
geom_line(size = 3, lineend = "round")
square would work on a more continuous variable:
df <- data.frame(x = seq(0, 100, 10), y = seq(0, 100, 10) ^ 2)
ggplot(data = df, aes(x = x, y = y, colour = y)) +
geom_path(size = 3, lineend = "square")
Maybe this will work for you:
library(dplyr)
library(ggplot2)
my_mtcars <-
mtcars %>%
mutate(my_colors = cut(disp, breaks = c(0, 130, 200, 400, Inf)))
ggplot(my_mtcars, aes(x = disp, y = mpg, col = mpg)) +
geom_line() + facet_wrap(~ my_colors, scales = 'free_x')
Is it possible to create great number of different kinds of "red" color. For better understanding I am expecting following, but instead of grey I desire to have "red" or "red-black".
mypalette <- rev(grey.colors(10000, start = 0.1, end = 0.5, gamma = 4))
plot(1:length(mypalette),1:length(mypalette), col=mypalette, pch=16)
The color packages I know have limited range of colors. Any idea will be appreciated.
If I understand what you want, try colorRampPalette. It returns a function that outputs the requested number of colours between the two you specified.
reds <- colorRampPalette(c("black","red"))
reds(5)
[1] "#000000" "#3F0000" "#7F0000" "#BF0000" "#FF0000"
Here are some ggplot alternatives
library(ggplot2)
df <- data.frame(x = rnorm(100), y = rnorm(100), z = rnorm(100), z2 = factor(1:5))
# colour set by continuous variable
ggplot(data = df, aes(x = x, y = y, colour = z)) +
geom_point() +
scale_colour_gradient(low = "red", high = "white")
library(RColorBrewer)
ggplot(data = df, aes(x = x, y = y, colour = z)) +
geom_point() +
scale_colour_gradientn(colours = brewer.pal(5, "Reds"))
# colour set by discrete variable
ggplot(data = df, aes(x = x, y = y, colour = z2)) +
geom_point() +
scale_colour_brewer(palette = "Reds")