Continuous colour of geom_line according to y value - r

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')

Related

geom_area with fill colour based on value

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)

How to plot stat_mean for scatterplot in R ggplot2?

For each treatment tmt, I want to plot the means using stat_summary in ggplot2 with different colour size. I find that the there are mulitple means being plotted over the current points. Not sure how to rectify it.
df <- data.frame(x = rnorm(12, 4,1), y = rnorm(12, 6,4), tmt = rep(c("A","B","C"), each = 4))
ggplot(aes(x = x, y = y, fill = tmt), data = df) +
geom_point(shape=21, size=5, alpha = 0.6) +
scale_fill_manual(values=c("pink","blue", "purple")) +
stat_summary(aes(fill = tmt), fun = 'mean', geom = 'point', size = 5) +
scale_fill_manual(values=c("pink","blue", "purple"))
Plot without the last two lines of code
Plot with the entire code
Using stat_summary you compute the mean of y for each pair of x and tmt. If you want the mean of x and the mean of y per tmt I would suggest to manually compute the means outside of ggplot and use a second geom_point to plot the means. In my code below I increased the size and used rectangles for the means:
df <- data.frame(x = rnorm(12, 4,1), y = rnorm(12, 6,4), tmt = rep(c("A","B","C"), each = 4))
library(ggplot2)
library(dplyr)
df_mean <- df |>
group_by(tmt) |>
summarise(across(c(x, y), mean))
ggplot(aes(x = x, y = y, fill = tmt), data = df) +
geom_point(shape=21, size=5, alpha = 0.6) +
geom_point(data = df_mean, shape=22, size=8, alpha = 0.6) +
scale_fill_manual(values=c("pink","blue", "purple"))

ggplot2: continuous and discrete scale in facet

I am trying to create a plot where I show two measures for the same set of points, one with a discrete scale and one with a continuous scale. I want to show the plots side-by-side, and getting them into facets would be great. Unfortunately, I can't figure out how to have one color scale in one facet and a different color scale in another.
library(tidyverse)
disc <- tibble(x = rnorm(100), y = rnorm(100), color = sample(1:3, 100, replace = TRUE), model = "discrete")
cont <- tibble(x = rnorm(100), y = rnorm(100), color = rnorm(100, 10), model = "continuous")
# want this to be discrete
ggplot(disc, aes(x = x, y = y, color = factor(color))) +
geom_point() + scale_color_discrete()
# want this to be continuous
ggplot(cont, aes(x = x, y = y, color = color)) +
geom_point() + scale_color_viridis_c()
# This would be prettier!
bind_rows( disc, cont ) %>%
ggplot(aes(x = x, y = y, color = color)) +
geom_point() +
facet_wrap(~model)
Created on 2021-10-16 by the reprex package (v2.0.0)
I realize that this is probably outside the intended use of facet. But I'm having a harder time getting the maps to print side-by-side in a coherent way and thought this could be a more sustainable shortcut.
Just learned about ggnewscale in my searching, and it seems to be easy enough! :
library(tidyverse)
library(ggnewscale)
disc <- tibble(x = rnorm(100), y = rnorm(100), color = sample(letters[1:3], 100, replace = TRUE), model = "discrete")
cont <- tibble(x = rnorm(100), y = rnorm(100), color = rnorm(100, 10), model = "continuous")
ggplot(mapping = aes(x = x, y = y)) +
geom_point(data = disc, aes(color = color)) +
scale_color_discrete("discrete") +
new_scale_color() +
geom_point(data = cont, aes(color = color)) +
scale_color_viridis_c("continuous") +
facet_wrap(~model)
Created on 2021-10-16 by the reprex package (v2.0.0)

R: How to combine grouping and colour aesteric in ggplot line plot

I am trying to create a line plot with 2 types of measurements, but my data is missing some x values. In Line break when no data in ggplot2 I have found how to create plot that will make a break when there is now data, but id does not allow to plot 2 lines (one for each Type).
1) When I try
ggplot(Data, aes(x = x, y = y, group = grp)) + geom_line()
it makes only one line, but with break when there is no data
2) When I try
ggplot(Data, aes(x = x, y = y, col = Type)) +
geom_line()
it makes 2 lines, but with break when there is no data
3) When I try
ggplot(Data, aes(x = x, y = y, col = Type, group = grp)) +
geom_line()
it makes unreadyble chart
4) of course I could combine the Type and grp to make new variable, but then the legend is not nice, and I get 4 groups (and colours) insted of 2.
5) also I could make something like that, but it dose not produce a legend, and in my real dataset i have way to many Types to do that
ggplot() +
geom_line(data = Data[Data$Type == "A",], aes(x = x, y = y, group = grp), col = "red") +
geom_line(data = Data[Data$Type == "B",], aes(x = x, y = y, group = grp), col = "blue")
Data sample:
Data <- data.frame(x = c(1:100, 201:300), y = rep(c(1, 2), 100), Type = rep(c("A", "B"), 100), grp = rep(c(1, 2), each = 100))
One way is to use interaction() to specify a grouping of multiple columns:
library(ggplot2)
Data <- data.frame(x = c(1:100, 201:300), y = rep(c(1, 2), 100), Type = rep(c("A", "B"), 100), grp = rep(c(1, 2), each = 100))
ggplot(Data, aes(x = x, y = y, col = Type, group = interaction(grp,Type))) +
geom_line()

Wide Range of the same Color in R

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")

Resources