plotting multiple data frame columns??

4,637 views
Skip to first unread message

Mike

unread,
May 26, 2010, 7:10:40 PM5/26/10
to ggplot2
All,

I looked through manuals & did a brief search in this group, I
seem to be missing how to do something simple with ggplot / qplot.
Can someone help me with how I could graph 2 different columns of a
data frame? E.g.:

df <- data.frame(x=c(1:10), y1=c(10:1), y2=c(1:10))

qplot(df$x, df$y1, df$y2, geom="line")

I know this isn't right, and it doesn't work. But I don't know what
info I add to say that I have, in essence, two sets of y data. I also
know that I could put it all into 1 longer column & create a
categorical column "y1" & "y2". For reasons that aren't worth
deliberating upon here, that is not particularly easy to do with the
data set that I have.

How do I write something like the code above where I would have 2
separate lines, one that is a straight line with slope = -1 (y1) and
another with slope = +1 (y2).

Much obliged!!
Mike Williamson


Ben Bolker

unread,
May 26, 2010, 10:54:38 PM5/26/10
to Mike, ggplot2

I only ever use ggplot() because I can't keep qplot() straight
(strange but true).

ggplot(df,aes(x=x)) + geom_line(aes(y=y1)) + geom_line(aes(y=y2))

appears to work.

--
Ben Bolker
Associate professor, Biology Dep't, Univ. of Florida
*** NEW E-MAIL ADDRESSES:
*** bbo...@gmail.com , bol...@math.mcmaster.ca
bol...@ufl.edu / people.biology.ufl.edu/bolker
GPG key: people.biology.ufl.edu/bolker/benbolker-publickey.asc

signature.asc

Andrie de Vries

unread,
May 27, 2010, 7:03:13 AM5/27/10
to ggplot2
I also tend to use ggplot() rather than qplot(), for the same reason
as Ben. However, there are two ways to achieve your objective using
qplot().

The first to add a new layer for each additional column in your
data.frame.

df <- data.frame(x=c(1:10), y1=c(10:1), y2=c(1:10))

qplot(df$x, df$y1, geom="line") + geom_line(aes(y=df$y2))


The second way is to reshape your data into a long dataframe, as
opposed to a wide dataframe, and then using the group= parameter in
qplot:

library(reshape)


df <- data.frame(x=c(1:10), y1=c(10:1), y2=c(1:10))

mdf <- melt(df, id.vars="x")
qplot(x, value, group=variable, data=mdf, geom="line")

Andrie

Mike

unread,
May 27, 2010, 1:08:33 PM5/27/10
to ggplot2
Thanks kindly to Dennis, Andrie & Ben! I keep forgetting about
melt(), which I know is quite handy. And as folks said above, simply
using the geom_line() twice works great. Thanks!

Now if I may follow up with another question: I usually stay away
from ggplot (as opposed to qplot) because it seems less forgiving in
that it forces you to use a data frame more often. As I show above, I
like to call the "x" column df$x and provide it as a vector instead of
as just the data frame column name. There are 2 reasons why I
currently prefer qplot:

(1) It allows for more flexibility: I don't have to have all of my
columns of interest in the same data frame (or in a data frame at all)

(2) More importantly, it allows me to put the plot into a loop more
easily, which I am ALWAYS doing. E.g., I can write:

qplot(x=df$time, y=df[,i],...)

and put this in a loop through several of the columns that I want to
plot, for instance

But I cannot seem to get this to function well in ggplot, because I
need to provide the data frame & then put the NAME of the column in
the aes. Is there any way around this? If so, I will always use
ggplot, like the others above. E.g., is there any way to write:

ggplot(df, aes(x=time, y=eval(i))

or even better:

ggplot(aes(x=df$time, y=df[,i])) (ignoring the required dataframe
somehow)

I know that "eval" is not the right function for my call above. But
is there something that exists to fix this? I really like the ggplot2
package, it is amazing. But this reliance upon data frames &
especially upon column names is a serious Achilles' heel.

Thanks again!
Mike

On May 27, 4:03 am, Andrie de Vries <apdevr...@gmail.com> wrote:
> I also tend to use ggplot() rather than qplot(), for the same reason
> as Ben. However, there are two ways to achieve your objective using
> qplot().
>
> The first to add a new layer for each additional column in your
> data.frame.
>
> df <- data.frame(x=c(1:10), y1=c(10:1), y2=c(1:10))
> qplot(df$x, df$y1, geom="line") + geom_line(aes(y=df$y2))
>
> The second way is to reshape your data into a long datafram

Hadley Wickham

unread,
May 27, 2010, 1:30:20 PM5/27/10
to Mike, ggplot2
Hi Mike,

Have a look at aes_string.

Hadley

> --
> You received this message because you are subscribed to the ggplot2 mailing list.
> Please provide a reproducible example: http://gist.github.com/270442
>
> To post: email ggp...@googlegroups.com
> To unsubscribe: email ggplot2+u...@googlegroups.com
> More options: http://groups.google.com/group/ggplot2
>

--
Assistant Professor / Dobelman Family Junior Chair
Department of Statistics / Rice University
http://had.co.nz/

Mike

unread,
May 27, 2010, 1:39:53 PM5/27/10
to ggplot2
Hi Hadley,

Thanks, it worked! I had tried aes_string in the past & had
trouble with it, then I forgot it over time. Maybe it was my mistake
back then...

Regards,
Mike

baptiste auguie

unread,
May 27, 2010, 1:42:41 PM5/27/10
to Mike, ggplot2
Hi,


Using ggplot in a loop is quite easy with aes_string, or subsetting,
or a melted data.frame. Consider this example where we want to plot n
data.frames, n=1, 2, 3, and for each one we want to plot the n+1-th
column against x. Below are three solutions:

l <- replicate(3, data.frame(x = 1:10,
y1 = rnorm(10),
y2 = rnorm(10),
y3 = rnorm(10)), simplify=FALSE)

library(ggplot2)

p <- list()
for( ii in seq_along(l)){

yname <- names(l[[ii]])[ii+1]
p[[ii]] <- ggplot(l[[ii]]) +
geom_path(aes_string(x="x", y=yname))

}

p2 <- list()
for( ii in seq_along(l)){

tmp <- subset(l[[ii]], select=c(1, ii+1))
names(tmp) <- c("x", "y")
p2[[ii]] <- ggplot(tmp) +
geom_path(aes(x, y))

}

## test
## do.call(arrange, p2)

m <- melt(l, id="x")
p3 <- dlply(subset(m, as.numeric(variable) == L1), .(L1), function(d){
print( str(d))
ggplot(d) +
geom_path(aes(x, value))
})

## test
## do.call(arrange, p3)

HTH,

baptiste

abhij...@factspan.com

unread,
Oct 8, 2014, 10:24:38 AM10/8/14
to ggp...@googlegroups.com, this....@gmail.com
All,

I have used the following code for my problem...Thanks for that but I have one more doubt that y1 and y2 comes in the color format...can you please help for line plot for y1 & y2 in different color.

ggplot(df,aes(x=x)) + geom_line(aes(y=y1)) + geom_line(aes(y=y2))

Ben Bond-Lamberty

unread,
Oct 8, 2014, 12:05:46 PM10/8/14
to ggplot2
The best way to do this in ggplot2 is to structure your data into
'long' (as opposed to 'wide') format. Here's an example:

# Toy data set in 'wide' format - not useful
d_wide <- structure(list(x = c(1, 2), g1 = c(1, 2), g2 = c(3, 4)),
.Names = c("x",
"g1", "g2"), row.names = c(NA, -2L), class = "data.frame")
print(d_wide)

# Same data but in 'long' format
d_long <- structure(list(x = c(1, 2, 1, 2), y = c(1, 2, 3, 4), grp =
structure(c(1L,
1L, 2L, 2L), .Label = c("g1", "g2"), class = "factor")), .Names = c("x",
"y", "grp"), row.names = c(NA, -4L), class = "data.frame")
print(d_long)

# Now it's easy to plot groups in different colors
ggplot(d_long, aes(x,y,color=grp))+geom_line()


Ben
> --
> --
> You received this message because you are subscribed to the ggplot2 mailing
> list.
> Please provide a reproducible example:
> https://github.com/hadley/devtools/wiki/Reproducibility
>
> To post: email ggp...@googlegroups.com
> To unsubscribe: email ggplot2+u...@googlegroups.com
> More options: http://groups.google.com/group/ggplot2
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ggplot2" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ggplot2+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages