user2840286
user2840286

Reputation: 601

Problems when using ggplot aes_string, group, and linetype

Let's say I have this data set:

x <- rnorm(1000)
y <- rnorm(1000, 2, 5)
line.color <- sample(rep(1:4, 250))
line.type <- as.factor(sample(rep(1:5, 200)))

data <- data.frame(x, y, line.color, line.type)

I'm trying to plot the x and y variables group by the interaction of line.type and line.color. In addition I want to specify the linetype using line.type and the color using line.color. If I write this:

ggplot(data, aes(x = x, y = y, group = interaction(line.type, line.color), colour = line.color, linetype = line.type)) + geom_line()

It works but If I try to use aes_string like this:

interact <- c("line.color", "line.type")
inter <- paste0("interaction(", paste0('"', interact, '"', collapse = ", "), ")")

ggplot(data, aes_string(x = "x", y = "y", group = inter, colour = "line.color", linetype = "line.type")) + geom_line()

I get the error:

Error: geom_path: If you are using dotted or dashed lines, colour, size and linetype must be constant over the line

What am I doing wrong? I need to use aes_string because I have a lot of variables to plot.

Upvotes: 3

Views: 5287

Answers (2)

mnel
mnel

Reputation: 115392

You were almost there defining

inter <- paste0("interaction(", paste0('"', interact, '"', collapse = ", "), ")")

However, for aes_string to work, you need pass a character string of what would work if it you were calling aes, that is you don't need to have the arguments within interaction as strings. You want to create a string "interaction(line.color, line.type)". Therefore

 inter <- paste0('interaction(', paste0(interact, collapse = ', ' ),')')
 # or
 # inter <- sprintf('interaction(%s), paste0(interact, collapse = ', '))
 # the result being
 inter
 ## [1] "interaction(line.color, line.type)"

 # and the following works
 ggplot(data, aes_string(x = "x", y = "y", 
    group = inter, colour = "line.color", linetype = "line.type")) + 
    geom_line()

Upvotes: 2

joran
joran

Reputation: 173567

Turns out I was mistaken on several counts in my comments above. This appears to work:

data$inter <- interaction(data$line.type,data$line.color)
ggplot(data, aes_string(x = "x", y = "y", group = "inter",colour = "line.color",linetype = "line.type")) + geom_line()

(I was completely wrong about the graph specifying varying colour, etc within a single dashed/dotted line.)

I take this as a slight vindication, though, that relying on parsing of the interaction code inside aes_string() is a generally bad idea. My guess is that there is simply a small bug in ggplot's attempt to parse what you're giving aes_string() in complex cases that's causing it to evaluate things in an order that makes it look like you're asking for varying aesthetics over dashed/dotted lines.

Upvotes: 3

Related Questions