Vary the Color Gradient on a Scatter Plot Created with Ggplot2

Vary the color gradient on a scatter plot created with ggplot2

you can do that by preparing color by yourself before calling ggplot2.

Here is an example:

data$sdt <- rescale(as.numeric(as.Date(data$dt)))  # data scaled [0, 1]
cols <- c("red", "blue") # colour of gradients for each group

# here the color for each value are calculated
data$col <- ddply(data, .(grp), function(x)
data.frame(col=apply(colorRamp(c("white", cols[as.numeric(x$grp)[1]]))(x$sdt),
1,function(x)rgb(x[1],x[2],x[3], max=255)))
)$col

p <- ggplot(data, aes(x,y, shape=grp, colour=col)) +
geom_jitter(size=4, alpha=0.75) +
scale_colour_identity() + # use identity colour scale
scale_shape_discrete(name="") +
opts(legend.position="none")
print(p)

How can a color gradient based on date be applied to a ggplot2 scatter plot?

the dt is factor variable, and probably scale_*_gradient is not available with discrete variable by nature.

you can convert the dt into Date and then into integer that is continuous variable.

Here is an example:

ggplot(data, aes(x,y, colour=as.integer(as.Date(data$dt)))) + 
geom_point() +
scale_colour_gradient(limits=as.integer(as.Date(c("2010-01-29","2010-12-31"))),
low="white", high="blue") +
opts(legend.position="none")

R color scatter plot with more color gradiant

You can play with a customized color palette and scale_colour_gradientn like this:

library(RColorBrewer)
library(ggplot2)
#Data
df <- read.delim(file='test.txt',stringsAsFactors = F)
#Palette
myPalette <- colorRampPalette(rev(brewer.pal(11, "Spectral")))
sc <- scale_colour_gradientn(colours = myPalette(100))
#Plot
ggplot(df, aes(log(data1), log(data2)),cex=1.9)+
geom_point(aes(color =data3)) + sc +
theme(legend.position = "top")+
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"))+
theme(text = element_text(size = 20, face="bold"))

Output:

Sample Image

If you want more color try this:

#Palette 2
sc2 <- scale_colour_gradientn(colours = rainbow(7))
#Plot
ggplot(df, aes(log(data1), log(data2)),cex=1.9)+
geom_point(aes(color =data3)) + sc2 +
theme(legend.position = "top")+
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"))+
theme(text = element_text(size = 20, face="bold"))

Output:

Sample Image

Update2: With breaks you can define limits for the color scale:

#Plot 3
ggplot(df, aes(log(data1), log(data2),color=data3),cex=1.9)+
geom_point() +
scale_colour_gradientn(colours = rainbow(25),breaks = seq(0,100,by=5))+
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"))+
theme(text = element_text(size = 12, face="bold"),
legend.text = element_text(size = 7, face="bold"))

Output:

Sample Image

Update 3: If you want to have different colors you can mix different palettes like this:

#Plot
ggplot(df, aes(log(data1), log(data2),color=data3),cex=1.9)+
geom_point() +
scale_colour_gradientn(colours = c(viridis::inferno(5),
viridis::plasma(5),
viridis::magma(5),
viridis::viridis(5),
rainbow(5)),breaks = seq(0,100,by=5))+
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"))+
theme(text = element_text(size = 12, face="bold"),
legend.text = element_text(size = 7, face="bold"))

Output:

Sample Image

Varying gradient using ggplot2 in R

Here's an option for doing it using a hue calculated from x and y:

df$hue <- pmax(pmin((df$x + pi)/pi/3 + (2 - df$y) / 12, 1), 0)
ggplot(df, aes(x=x, y=y, group = 1, colour = hsv(hue, 1, 1))) + geom_path() +
scale_colour_identity()

Note because the lines are quite long vertically so the effect isn't fully seen. Here's a version using approx to interpolate:

adf <- as.data.frame(approx(df, xout = seq(-pi, max(df$x), 0.001)))
adf$hue <- pmax(pmin((adf$x + pi)/pi/3 + (2 - adf$y) / 12, 1), 0)
ggplot(adf, aes(x=x, y=y, group = 1, colour = hsv(hue, 1, 1))) + geom_path() +
scale_colour_identity()

hue plot

In both cases, it's the hue that's dependent on both x and y, with value held constant. That fits your proposed example, if not your original description. Clearly it could be tailored to vary hue and value separately. It's also worth noting that there needs to be a group set. Otherwise ggplot2 tries to join together all the points of the same colour.

Color code a scatter plot by group with a gradient

Using scales::colour_ramp you can create the colours yourself with a quick function. I'm not sure how else to get different gradients happening within each group. Note I'm using df$score = df$x + df$y here to make the mapping more obvious.

make_colour_gradient = function(x, brewer_palette = "Greens") {
min_x = min(x)
max_x = max(x)
range_x = max_x - min_x
x_scaled = (x - min_x) / range_x

# Chopping out first colour as it's too light to work well as a
# point colour
colours = scales::brewer_pal("seq", brewer_palette)(5)[2:5]

colour_vals = scales::colour_ramp(colours)(x_scaled)
colour_vals
}

df$score = df$x + df$y

df = df %>%
# Assign a different gradient to each group, these are the names
# of different palettes in scales::brewer_pal
mutate(group_colour = case_when(
group == "A" ~ "Greens",
group == "B" ~ "Oranges",
group == "C" ~ "Purples"
)) %>%
group_by(group) %>%
mutate(point_colour = make_colour_gradient(score, first(group_colour)))

plot_ly(marker=list(size=10),type='scatter',mode="markers",
x=~df$x,y=~df$y,color=~ I(df$point_colour)) %>%
hide_colorbar() %>%
layout(xaxis=list(title="X",zeroline=F,showticklabels=F),
yaxis=list(title="Y",zeroline=F,showticklabels=F))

Result:

Scatter plot with colours per group

This does bring up error messages but they don't seem to be important? Adding a legend to this would probably be tricky.

How to add gradient color to line plot based on its corresponding y value using ggplot

ggforce package includes geoms that can have interpolated aesthetics, like a gradient:

df %>%
mutate(row = row_number()) %>%
ggplot(aes(row, Global, color = Global)) +
ggforce::geom_link2() +
scale_color_gradient(low = "red", high = "white") +
# theme_dark() # built-in theme, dark gray
ggdark::dark_theme_minimal() # add-on black theme

Sample Image

R ggplot2 Specify separate color gradients by group

My coworker found a solution in another post that requires an additional package called ggnewscale. I still don't know if this can be done only with ggplot2, but this works. I'm still open to alternative plotting suggestions though. The purpose is to detect any trends in day of completion across and within users. Across users is where I expect to see more of a trend, but within could be informative too.

How merge two different scale color gradient with ggplot

library(ggnewscale)

dat1 <- test_data %>% filter(task_group == 1)
dat2 <- test_data %>% filter(task_group == 2)
dat3 <- test_data %>% filter(task_group == 3)

ggplot(mapping = aes(x = days_completion, y = user)) +
geom_point(data = dat1, aes(color = task_order)) +
scale_color_gradientn(colors = c('#99000d', '#fee5d9')) +
new_scale_color() +
geom_point(data = dat2, aes(color = task_order)) +
scale_color_gradientn(colors = c('#084594', '#4292c6')) +
new_scale_color() +
geom_point(data = dat3, aes(color = task_order)) +
scale_color_gradientn(colors = c('#238b45'))

Example draft plot



Related Topics



Leave a reply



Submit