I would like to achieve a different colour gradient every time I add another a geom_line() to my main plot, each time with 'colour' as the scale.
Here is a data frame just as an example:
df <- data.frame("letter"=c(rep("a",5),rep("b",5)),"x"=rep(seq(1,5),2),"y1"=c(seq(6,10),seq(6,10)/2),"y2"=c(seq(1,5),seq(1,5)/2),"y3"=c(seq(3,7),seq(3,7)/2))
For which I first plot:
y1 <- ggplot(df,aes(x=x,y=y1,colour=letter))+geom_line()
y1
I then would like to add y1 and y2, which I can do as follows:
y2 <- geom_line(data=df,aes(x=x,y=y2,colour=letter))
y3 <- geom_line(data=df,aes(x=x,y=y3,colour=letter))
y1+y2+y3
But I would like the colour gradient (or hue) to be different for y1, y2 and y3!
Is it possible to assign something like scale_colour_hue() to each geom_line, or is this only possible for the ggplot?
Thanks!
As I outlined above, here are some options:
df <- data.frame("letter"=c(rep("a",5),rep("b",5)),
"x"=rep(seq(1,5),2),
"y1"=c(seq(6,10),seq(6,10)/2),
"y2"=c(seq(1,5),seq(1,5)/2),
"y3"=c(seq(3,7),seq(3,7)/2))
# melt your data and create a grouping variable
library(plyr)
df_m <- melt(df,id.vars = 1:2)
df_m$grp <- with(df_m,interaction(letter,variable))
# Option 1
ggplot(df_m,aes(x = x, y = value)) +
facet_wrap(~variable) +
geom_line(aes(group = letter,colour = letter))
# Option 2
ggplot(df_m,aes(x = x, y = value)) +
geom_line(aes(group = grp,colour = letter,linetype = variable))
Related
I have a csv file which looks like the following:
Name,Count1,Count2,Count3
application_name1,x1,x2,x3
application_name2,x4,x5,x6
The x variables represent numbers and the applications_name variables represent names of different applications.
Now I would like to make a barplot for each row by using ggplot2. The barplot should have the application_name as title. The x axis should show Count1, Count2, Count3 and the y axis should show the corresponding values (x1, x2, x3).
I would like to have a single barplot for each row, because I have to store the different plots in different files. So I guess I cannot use "melt".
I would like to have something like:
for each row in rows {
print barplot in file
}
Thanks for your help.
You can use melt to rearrange your data and then use either facet_wrap or facet_grid to get a separate plot for each application name
library(ggplot2)
library(reshape2)
# example data
mydf <- data.frame(name = paste0("name",1:4), replicate(5,rpois(4,30)))
names(mydf)[2:6] <- paste0("count",1:5)
# rearrange data
m <- melt(mydf)
# if you are wanting to export each plot separately
# I used facet_wrap as a quick way to add the application name as a plot title
for(i in levels(m$name)) {
p <- ggplot(subset(m, name==i), aes(variable, value, fill = variable)) +
facet_wrap(~ name) +
geom_bar(stat="identity", show_guide=FALSE)
ggsave(paste0("figure_",i,".pdf"), p)
}
# or all plots in one window
ggplot(m, aes(variable, value, fill = variable)) +
facet_wrap(~ name) +
geom_bar(stat="identity", show_guide=FALSE)
I didn't see #user20650's nice answer before preparing this. It's almost identical, except that I use plyr::d_ply to save things instead of a loop. I believe dplyr::do() is another good option (you'd group_by(Name) first).
yourData <- data.frame(Name = sample(letters, 10),
Count1 = rpois(10, 20),
Count2 = rpois(10, 10),
Count3 = rpois(10, 8))
library(reshape2)
yourMelt <- melt(yourData, id.vars = "Name")
library(ggplot2)
# Test a function on one piece to develope graph
ggplot(subset(yourMelt, Name == "a"), aes(x = variable, y = value)) +
geom_bar(stat = "identity") +
labs(title = subset(yourMelt, Name == 'a')$Name)
# Wrap it up, with saving to file
bp <- function(dat) {
myPlot <- ggplot(dat, aes(x = variable, y = value)) +
geom_bar(stat = "identity") +
labs(title = dat$Name)
ggsave(filname = paste0("path/to/save/", dat$Name, "_plot.pdf"),
myPlot)
}
library(plyr)
d_ply(yourMelt, .variables = "Name", .fun = bp)
I mocked up the following code to provide context. The functions, sequence intervals, names, and colors are all arbitrary.
library(ggplot2)
function1 <- function(input) {
input * 3
}
function2 <- function(input) {
2 * input + 1
}
function3 <- function(input) {
input + 4
}
x1 <- seq(1, 10, 0.1)
x2 <- seq(1, 10, 0.2)
x3 <- seq(1, 10, 0.5)
y1 <- sapply(x1, function1)
y2 <- sapply(x2, function2)
y3 <- sapply(x3, function3)
data1 <- data.frame(x1, y1)
data2 <- data.frame(x2, y2)
data3 <- data.frame(x3, y3)
ggplot() +
geom_point(data = data1, aes(x1, y1, color = "B")) +
geom_point(data = data2, aes(x2, y2, color = "C")) +
geom_point(data = data3, aes(x3, y3, color = "A")) +
scale_color_manual(name = "Functions",
values = c("B" = "Green", "C" = "Red",
"A" = "Blue")) +
xlab("X") +
ylab("Y")
Here is a screenshot of the resulting plot:
There are a few previously answered questions that address similar issues with legend ordering, such as this one, but none seem to deal with multilayer plots. This question addresses ordering of legends for version 0.9.2, but ggplot2 is currently
on version 2.2.1. Additionally, it seems to address only ascending or descending orders.
I'd like to know if there's any way to customize the order of the values in the legend. For example, in the legend, is it possible to display it as B, C, A instead of A, B, C?
The "ggplot2 way" would be to reshape your data to long format (or create it in long format in the first place). Then you need only one call to geom_point and you can create a factor column to order the functions:
dat = data.frame(X=c(x1,x2,x3),
Y=c(y1,y2,y3),
Functions=rep(LETTERS[1:3], sapply(list(x1,x2,x3), length)))
dat$Functions = factor(dat$Functions, levels=c("B","C","A"))
ggplot(dat, aes(X, Y, colour=Functions)) +
geom_point() +
scale_color_manual(values=c(B="green", C="red", A="blue"))
UPDATE: In response to the comment, if you want to add an abline, you can use the code below. However, this will not only add a new key value to the colour legend, it will also add a diagonal line to the other three pre-existing legend keys.
ggplot(dat, aes(X, Y, colour=Functions)) +
geom_point() +
scale_color_manual(values=c(B="green", C="red", A="blue", `My Abline`="black")) +
geom_abline(aes(intercept=0, slope=1, colour="My Abline"))
If you want a separate legend for the abline, then you could use a fill aesthetic for the points and reserve the colour legend only for the abline. To do this, use a filled point marker (point marker shapes 21 through 25). In the code below, stroke=0 is to remove the border around the filled points.
ggplot(dat, aes(X, Y, fill=Functions)) +
geom_point(shape=21, size=2, stroke=0) +
geom_abline(aes(intercept=0, slope=1, colour="My Abline")) +
scale_fill_manual(values=c(B="green", C="red", A="blue")) +
scale_colour_manual(values="black") +
labs(colour="")
I'm analyzing a series that varies around zero. And to see where there are parts of the series with a tendency to be mostly positive or mostly negative I'm plotting a geom_smooth. I was wondering if it is possible to have the color of the smooth line be dependent on whether or not it is above or below 0. Below is some code that produces a graph much like what I am trying to create.
set.seed(5)
r <- runif(22, max = 5, min = -5)
t <- rep(-5:5,2)
df <- data.frame(r+t,1:22)
colnames(df) <- c("x1","x2")
ggplot(df, aes(x = x2, y = x1)) + geom_hline() + geom_line() + geom_smooth()
I considered calculating the smoothed values, adding them to the df and then using a scale_color_gradient, but I was wondering if there is a way to achieve this in ggplot directly.
You may use the n argument in geom_smooth to increase "number of points to evaluate smoother at" in order to create some more y values close to zero. Then use ggplot_build to grab the smoothed values from the ggplot object. These values are used in a geom_line, which is added on top of the original plot. Last we overplot the y = 0 values with the geom_hline.
# basic plot with a larger number of smoothed values
p <- ggplot(df, aes(x = x2, y = x1)) +
geom_line() +
geom_smooth(linetype = "blank", n = 10000)
# grab smoothed values
df2 <- ggplot_build(p)[[1]][[2]][ , c("x", "y")]
# add smoothed values with conditional color
p +
geom_line(data = df2, aes(x = x, y = y, color = y > 0)) +
geom_hline(yintercept = 0)
Something like this:
# loess data
res <- loess.smooth(df$x2, df$x1)
res <- data.frame(do.call(cbind, res))
res$posY <- ifelse(res$y >= 0, res$y, NA)
res$negY <- ifelse(res$y < 0, res$y, NA)
# plot
ggplot(df, aes(x = x2, y = x1)) +
geom_hline() +
geom_line() +
geom_line(data=res, aes(x = x, y = posY, col = "green")) +
geom_line(data=res, aes(x = x, y = negY, col = "red")) +
scale_color_identity()
I have this dataset: https://dl.dropboxusercontent.com/u/73950/data.csv
The dataset contains 3 variables.
Here's how I visualize the data right now:
library(ggplot2)
library(reshape2)
library(RColorBrewer)
dat = read.csv("data.csv", header = FALSE)
myPalette <- colorRampPalette(rev(brewer.pal(11, "Spectral")))
sc <- scale_colour_gradientn(colours = myPalette(100))
ggplot(dat, aes(x=V1, y=V3, colour = V2))+ geom_point(alpha = .2,size = 3) + sc
Instead of just one figure, I'd like to facet the figure to display 3 different ways to attribute variables to each axis and color. As such:
x = V1, y = V2, color = V3
x = V1, y = V3, color = V2
x = V2, y = V3, color = V1
How to do this kind of things with ggplot2's faceting?
You can get this by putting the data in the format ggplot likes. In this case, a column that can be used to split the data into facets (called var below). To do that, I just repeated the data three times, choosing the appropriate x and y variables for each 2-way combo, and using the variable left out of each combination as the coloring variable.
## Rearrange the data by 2-way combinations, the coloring is the remaining column
res <- do.call(rbind, combn(1:3, 2, function(ii)
cbind(setNames(dat[,c(ii, setdiff(1:3, ii))], c("x", "y", "color")),
var=paste(ii, collapse=".")), simplify=F))
ggplot(res, aes(x=x, y=y, color=color))+ geom_point(alpha = .2,size = 3) +
facet_wrap(~ var, scales="free") + sc
I have a data.frame df with columns T ,V1,V2,V3,V4
I would like to make a ggplot containing two plots with T as the common the x axis
The first plot contains V1
The second plot contains V2,V3,V4
I tried:
m1 <- melt(df, id = "T")
chart1<-qplot(T, value, data = m1, geom = "line", group = variable) +
stat_smooth() +
facet_grid(variable ~ ., scale = "free_y")
But this gives me four common plots whereas I just want two.
Is there a way to do this?
library(ggplot2)
library("reshape")
df <- data.frame(T,V1,V2,V3,V4)
m1 <- melt(df, id = "T")
m1$sepfac <- (m1$variable=="V1")
chart1<-qplot(T, value, data = m1, geom = "line", group = variable) +
stat_smooth() +
facet_grid(sepfac~., scale = "free_y")