Smooth colors in geom_line - r

Using ggplot2, I would like color lines "smoothly" in a plot where I have only few datapoints. As is, the scales I tried (e.g. scale_color_gradient2) do not seem to interpolate colors, but instead color segments monochromatically.
Code example:
ggplot(data.frame(x=1:5)) + geom_line(aes(x=x, y=x, color=x), size=3) +
scale_color_gradient2()

You could increase the amount of points between 1 and 5:
df <- data.frame(x=seq(1,5,0.001))
ggplot(df) + geom_line(aes(x=x, y=x, color=x), size=3) +
scale_color_gradient2()

Related

ggplot2 z order of multiple geoms (background to foreground)

I am trying to plot multiple lines with surrounding area, using ggplot2, with geom_ribbon for the are, and a centerline with geom_line. The values are overlapping, but I'd like each ribbon/line combination to be either bottom or top as a combination.
Here's a reproducible example:
library(ggplot2)
x <- 1:10
y <- c(1+x/100, 2-x, .1*x^2)
data <- data.frame(x=rep(x,3), y=y, lower=y-1, upper=y+1, color=rep(c('green', 'blue', 'yellow'), each=10))
In the example I can get the plot I want by using this code:
ggplot() +
geom_ribbon(data=data[data$color=='green',],aes(x=x, ymin=lower, ymax=upper, fill=paste0('light',color))) +
geom_line(data=data[data$color=='green',],aes(x=x, y=y, col=color)) +
geom_ribbon(data=data[data$color=='blue',],aes(x=x, ymin=lower, ymax=upper, fill=paste0('light',color))) +
geom_line(data=data[data$color=='blue',],aes(x=x, y=y, col=color)) +
geom_ribbon(data=data[data$color=='yellow',],aes(x=x, ymin=lower, ymax=upper, fill=paste0('light',color))) +
geom_line(data=data[data$color=='yellow',],aes(x=x, y=y, col=color)) +
scale_color_identity() +
scale_fill_identity()
But when I keep it simple and us this this code
plot <- ggplot(data=data) +
geom_ribbon(aes(x=x, ymin=lower, ymax=upper, fill=paste0('light',color))) +
geom_line(aes(x=x, y=y, col=color)) +
scale_color_identity() +
scale_fill_identity()
the lines of the background data go over the 'top' ribbons, or if I switch the geom_line and geom_ribbon, my middle-lines are no longer visible.
For this example, the lengthy call works, but in my real data, I have a lot more lines, and I'd like to be able to switch lines from background to foreground dynamically.
Is there any way that I can tell ggplot2 that there is an ordering that has to switch between my different geoms?
P.S. I can't post images yet, sorry if my question seems unclear.
You could save some typing with a loop
ggplot(data=data) +
purrr::map(.x = split(data, f = data$color),
.f = function(d){
list(geom_ribbon(data=d,aes(x=x, ymin=lower, ymax=upper), fill=paste0('light',unique(d$color))),
geom_line(data=d,aes(x=x, y=y), col=unique(d$color)))
})

Edit 2 stat_hex_bin geoms separately ggplot2

I start by giving you my example code:
x <- runif(1000,0, 5)
y <- c(runif(500, 0, 2), runif(500, 3,5))
A <- data.frame("X"=x,"Y"=y[1:500])
B <- data.frame("X"=x,"Y"=y[501:1000])
ggplot() +
stat_bin_hex(data=A, aes(x=X, y=Y), bins=10) +
stat_bin_hex(data=B, aes(x=X, y=Y), bins=10) +
scale_fill_continuous(low="red4", high="#ED1A3A")
It produces the following plot:
Now I want the lower hexagons to follow a different scale. Namely ranging from a dark green to a lighter green. How can I achieve that?
Update:
As you can see from the answers so far, I am asking myself whether there is a solution without using alpha scales. Also, using two plots with no margin or something similar is not an option for my specific application. Though they both are legitimate answers :)
Rather than trying to get two different fill scales in one plot you could alter the colours of the lower values, after the plot has been built. The basic idea is have two plots with the differing fill scales and then copy accross certain details from one plot to the other.
# Base plot
p <- ggplot() +
stat_bin_hex(data=A, aes(x=X, y=Y), bins=10) +
stat_bin_hex(data=B, aes(x=X, y=Y), bins=10)
# Produce two plots with different fill colours
p1 <- p + scale_fill_continuous(low="red4", high="#ED1A3A")
p2 <- p + scale_fill_continuous(low="darkgreen", high="lightgreen")
# Get fill colours for second plot and overwrite the corresponding
# values in the first plot
g1 <- ggplot_build(p1)
g2 <- ggplot_build(p2)
g1$data[[1]][,"fill"] <- g2$data[[1]][,"fill"]
# You can draw this now but there is only one legend
grid.draw(ggplot_gtable(g1))
To have two legends you can join the legends from the two plots together
# Bind the legends from the two plots together
g1 <- ggplot_gtable(g1)
g2 <- ggplot_gtable(g2)
g1$grobs[[grep("guide", g1$layout$name )]] <-
rbind(g1$grobs[[grep("guide", g1$layout$name )]],
g2$grobs[[grep("guide", g2$layout$name )]] )
grid.newpage()
grid.draw(g1)
Giving (from set.seed(10) prior to data generation)
This should provide more or less what you want
ggplot() +
stat_bin_hex(data=A, aes(x=X, y=Y, alpha=..count..), bins=10,fill="green") +
stat_bin_hex(data=B, aes(x=X, y=Y, alpha=..count..), bins=10,fill="red")
To avoid that the grey is disturbing due to the alpha one could underlay the plot with another white plot at the same location and darken the colours a bit, as suggested by the TO in the comments
#just the red to show the impact due to scale_alpha
ggplot() +scale_alpha_continuous(range=c(0.5,1))+ stat_bin_hex(data=A, aes(x=X, y=Y), bins=10,fill="white",show.legend = TRUE) +
+ stat_bin_hex(data=A, aes(x=X, y=Y, alpha=..count..), bins=10,fill="red",show.legend = TRUE) +
+ stat_bin_hex(data=B, aes(x=X, y=Y, alpha=..count..), bins=10,fill="green", show.legend=TRUE)+guides(fill=FALSE, alpha=FALSE)
An alternative, if you want more options to play with the colours, just create two plots and remove all the space between the two plots when combined with grid.arrange().
p1 <- ggplot() + stat_bin_hex(data=B, aes(x=X, y=Y), bins=10) +
scale_fill_continuous(low="red4", high="#ED1A3A") + xlab("") + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(), plot.margin=unit(c(1,1,-0.5,1), "cm")) + scale_y_continuous(limits = c(2.5, 5.5))
p2 <- ggplot() + stat_bin_hex(data=A, aes(x=X, y=Y), bins=10) + scale_fill_continuous(low="darkgreen", high="green") + theme(plot.margin=unit(c(-0.5,1,1,1), "cm")) + scale_y_continuous(limits = c(-0.5, 2.5))
grid.arrange(p1,p2)

How to combine 2 plots (ggplot) into one plot?

By using R, is it possible to place 2 ggplot together (i.e., on the same plot)? I wish to show a trend from 2 different data frames and instead of putting them one next to the other, I'd like to integrate them together in one plot and only to change the color of one of them (the black dot).
To be more specific, I have the following 2 visuals:
ggplot(visual1, aes(ISSUE_DATE,COUNTED)) + geom_point() + geom_smooth(fill="blue", colour="darkblue", size=1)
and
ggplot(visual2, aes(ISSUE_DATE,COUNTED)) + geom_point() + geom_smooth(fill="red", colour="red", size=1)
They look like this (both have black dots and I'll need to change one of them to something different):
and
Creating a single combined plot with your current data set up would look something like this
p <- ggplot() +
# blue plot
geom_point(data=visual1, aes(x=ISSUE_DATE, y=COUNTED)) +
geom_smooth(data=visual1, aes(x=ISSUE_DATE, y=COUNTED), fill="blue",
colour="darkblue", size=1) +
# red plot
geom_point(data=visual2, aes(x=ISSUE_DATE, y=COUNTED)) +
geom_smooth(data=visual2, aes(x=ISSUE_DATE, y=COUNTED), fill="red",
colour="red", size=1)
however if you could combine the data sets before plotting then ggplot will
automatically give you a legend, and in general the code looks a bit cleaner
visual1$group <- 1
visual2$group <- 2
visual12 <- rbind(visual1, visual2)
p <- ggplot(visual12, aes(x=ISSUE_DATE, y=COUNTED, group=group, col=group, fill=group)) +
geom_point() +
geom_smooth(size=1)
Dummy data (you should supply this for us)
visual1 = data.frame(ISSUE_DATE=runif(100,2006,2008),COUNTED=runif(100,0,50))
visual2 = data.frame(ISSUE_DATE=runif(100,2006,2008),COUNTED=runif(100,0,50))
combine:
visuals = rbind(visual1,visual2)
visuals$vis=c(rep("visual1",100),rep("visual2",100)) # 100 points of each flavour
Now do:
ggplot(visuals, aes(ISSUE_DATE,COUNTED,group=vis,col=vis)) +
geom_point() + geom_smooth()
and adjust colours etc to taste.
Just combine them. I think this should work but it's untested:
p <- ggplot(visual1, aes(ISSUE_DATE,COUNTED)) + geom_point() +
geom_smooth(fill="blue", colour="darkblue", size=1)
p <- p + geom_point(data=visual2, aes(ISSUE_DATE,COUNTED)) +
geom_smooth(data=visual2, fill="red", colour="red", size=1)
print(p)

ggplot2: How to specify multiple fill colors for points that are connected by lines of different colors

I am new to ggplot2. I would like to create a line plot that has points on them where the points are filled with different colors than the lines (see the plot below).
Suppose the dataset I am working with is the one below:
set.seed(100)
data<-data.frame(dv=c(rnorm(30), rnorm(30, mean=1), rnorm(30, mean=2)),
iv=rep(1:30, 3),
group=rep(letters[1:3], each=30))
I tried the following code:
p<-ggplot(data, aes(x=iv, y=dv, group=group, pch=group)) + geom_line() + geom_point()
p + scale_color_manual(values=rep("black",3))+ scale_shape(c(19,20,21)) +
scale_fill_manual(values=c("blue", "red","gray"))
p + scale_shape(c(19,20,21)) + scale_fill_manual(values=c("blue", "red","gray"))
But I do not get what I want.I hope someone can point me to the right direction. Thanks!
scale_fill_manual(), scale_shape_manual() and scale_colour_manual() can be used only if you have set fill=, shape= or colour= inside the aes().
To change colour just for the points you should add colour=group inside geom_point() call.
ggplot(data, aes(x=iv, y=dv, group=group,shape=group)) +
geom_line() + geom_point(aes(colour=group)) +
scale_shape_manual(values=c(19,20,21))+
scale_colour_manual(values=c("blue", "red","gray"))

Seemingly incorrect guide color when geom_line() and geom_segment() are used together

I'm drawing some line segments on top of a plot that uses geom_line(). Surprisingly, the guide (legend) colors for geom_line() are drawn as the color of the last element I add to the plot - even if it is not the geom_line(). This looks like a bug to me, but it could be expected behavior for some reason I don't understand.
#Set up the data
require(ggplot2)
x <- rep(1:10, 2)
y <- c(1:10, 1:10+5)
fac <- gl(2, 10)
df <- data.frame(x=x, y=y, fac=fac)
#Draw the plot with geom_segment second, and the guide is the color of the segment
ggplot(df, aes(x=x, y=y, linetype=fac)) +
geom_line() +
geom_segment(aes(x=2, y=7, xend=7, yend=7), colour="red")
Whereas if I add the geom_segment first, the colors on the guide are black as I would expect:
ggplot(df, aes(x=x, y=y, linetype=fac)) +
geom_segment(aes(x=2, y=7, xend=7, yend=7), colour="red") +
geom_line()
Feature or bug? If the first, can someone explain what's happening?
Feature(ish). The guide that is drawn is a guide for linetype. But, it has to be drawn in some color to be seen. When the color is not specified by an aesthetic mapping, ggplot2 draws it in a color that is consistent with the plot. I'm speculating that the default is whatever last color was used. That is why you are seeing differences when you plot them in a different order.
However, you can control these details of the legend.
ggplot(df, aes(x=x, y=y, linetype=fac)) +
geom_line() +
geom_segment(aes(x=2, y=7, xend=7, yend=7), colour="red") +
scale_linetype_discrete(guide=guide_legend(override.aes=aes(colour="blue")))

Resources