17
votes

I'm trying to draw a plot with several curves in it. The x-axis are not numerical values, but Strings.

This works fine (like in how to plot all the columns of a data frame in R):

require(ggplot2)
df_ok <- rbind(data.frame(x=4:1,y=rnorm(4),d="d1"),data.frame(x=3:1,y=rnorm(3),d="d2"))
ggplot(df_ok, aes(x,y)) + geom_line(aes(colour=d))

But my data looks like this:

require(ggplot2)
df_nok <- rbind(data.frame(x=c("four","three","two","one"),y=rnorm(4),d="d1"),data.frame(x=c("three","two","one"),y=rnorm(3),d="d2"))
ggplot(df_nok, aes(x,y)) + geom_line(aes(colour=d))

I get the error geom_path: Each group consist of only one observation. Do you need to adjust the group aesthetic?. Even though the graph lines do not appear, the axis are plotted, and the x-Axis contains the correct Labels - but also in wrong order.

Any idea how to plot this as easy as possible? (Also note the missing x-values for some series).

3

3 Answers

20
votes

Your problem is that the x variable is a factor. So, change your data frame and make x a double:

df = rbind(data.frame(x=4:1,y=rnorm(4),d="d1"), 
           data.frame(x=3:1,y=rnorm(3),d="d2"))

Plot as normal

g = ggplot(df, aes(x,y)) + geom_line(aes(colour=d))

but alter the x-axis scaling explicitly:

g + scale_x_continuous(breaks=1:4, labels=c("one", "two", "three", "four")) 

To rename your variable, try something like:

x1 = factor(df_nok$x, 
            levels=c("one", "two", "three", "four"), 
            labels=1:4)
df$x1 = as.numeric(x1)
7
votes

You can convince ggplot to draw lines by adding a dummy group,

ggplot(df_nok, aes(x,y)) + geom_line(aes(colour=d, group=d))

Also see http://kohske.wordpress.com/2010/12/27/faq-geom_line-doesnt-draw-lines/

3
votes

Add in the group aesthetic (sort of redundant, I know, but much simpler than re-jigging the axis labels).

df_nok <- rbind(data.frame(x=c("four","three","two","one"),y=rnorm(4),d="d1"),data.frame(x=c("three","two","one"),y=rnorm(3),d="d2"))

ggplot(df_nok, aes(x,y, group=d)) + geom_line(aes(colour=d))

It's true your x-axis is still probably not in the order you want. As noted by @csgillespie you can fix this by making it into a factor

df_nok$x <- factor(df_nok$x, 
            levels=c("one", "two", "three", "four"), 
            labels=1:4)