1

Question/problem

Well, I am almost there, but there is still one or two things I want to solve/understand.

I am trying to plot a series of geom_smooth()'s by data.table's column PlotCat specifying two distinct linetypes by another variable, PlotLine.

I am struggling with a neat solution with linetypes visible on the legend.

Setup

library(data.table)
library(ggplot2)
library(RColorBrewer)


dataT <- data.table(
  X = c(13.24, 22.8, 29.79, 32.13, 35.02, 40.8, 48.05, 59.89, 7.24, 18.33, 25.86, 29.74, 38.5, 48.5, 55.99, 6.71, 12.36, 22.8, 27.99, 41.11, 53.88, 61.34, 7.83, 23.85, 31.89, 37.38, 48.35, 59.62, 60.28, 5.8, 10.12, 18.12, 22.5, 32.98, 44.58, 51.39, 13.61, 19.41, 23.77, 27.5, 34.66, 39.63, 51.63, 1.06, 14.39, 20.2, 23.34, 31.56, 36.96, 50.94, 14.38, 26.85, 34.49, 39.33, 51.74, 60.11, 64.83),
  Y = c(0.02, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0, 0, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0.03, 0.03, 0.03, 0.03, 0.03, 0.04, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0, 0.02, 0.02, 0.02, 0.01, 0.02, 0.01, 0, 0, 0, 0, 0, 0, 0.01),
  PlotCat = c("Control 0", "Control 0", "Control 0", "Control 0", "Control 0", "Control 0", "Control 0", "Control 0", "Control 1", "Control 1", "Control 1", "Control 1", "Control 1", "Control 1", "Control 1", "Model Cat 1", "Model Cat 1", "Model Cat 1", "Model Cat 1", "Model Cat 1", "Model Cat 1", "Model Cat 1", "Model Cat 2", "Model Cat 2", "Model Cat 2", "Model Cat 2", "Model Cat 2", "Model Cat 2", "Model Cat 2", "Model Cat 3", "Model Cat 3", "Model Cat 3", "Model Cat 3", "Model Cat 3", "Model Cat 3", "Model Cat 3", "Model Cat 4", "Model Cat 4", "Model Cat 4", "Model Cat 4", "Model Cat 4", "Model Cat 4", "Model Cat 4", "Model Cat 5", "Model Cat 5", "Model Cat 5", "Model Cat 5", "Model Cat 5", "Model Cat 5", "Model Cat 5", "Model Cat 6", "Model Cat 6", "Model Cat 6", "Model Cat 6", "Model Cat 6", "Model Cat 6", "Model Cat 6"),
  PlotLine = c("dashed", "dashed", "dashed", "dashed", "dashed", "dashed", "dashed", "dashed", "dashed", "dashed", "dashed", "dashed", "dashed", "dashed", "dashed", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid", "solid"))

# Sample of rows:
#         X    Y     PlotCat PlotLine
#  1: 13.24 0.02   Control 0   dashed
# 11: 25.86 0.01   Control 1   dashed
# 22: 61.34 0.04 Model Cat 1    solid
# 28: 59.62 0.02 Model Cat 2    solid
# 34: 32.98 0.01 Model Cat 3    solid
# 46: 20.20 0.02 Model Cat 5    solid

Desired plot

Based on accepted answer from this question, but manual specification of linetype values is ugly.

g1 <- ggplot(data.frame(dataT),
             aes(x = X,
                 y = Y,
                 colour = PlotCat,
                 linetype = PlotCat)) +
  geom_point() +
  geom_smooth(level = 0.5, fill = NA) +
  theme_minimal() +
  coord_cartesian(ylim = c(0, 0.05)) +
  scale_linetype_manual(values = c(rep("dashed", dataT[PlotLine == "dashed", length(unique(PlotCat))]),
                                   rep("solid", dataT[PlotLine == "solid", length(unique(PlotCat))]))) + 
  ggtitle("Desired plot")
g1

Desired plot

Closest I can get without manually specifying values

dataT[, PlotLine := factor(PlotLine, levels = c("solid", "dashed"))]

g2 <- ggplot(data.frame(dataT),
             aes(x = X,
                 y = Y,
                 colour = PlotCat,
                 linetype = PlotLine)) +
  geom_point() +
  geom_smooth(level = 0.5, fill = NA) +
  theme_minimal() +
  coord_cartesian(ylim = c(0, 0.05)) +
  scale_linetype(guide = FALSE) + 
  ggtitle("Almost there...")
g2

Almost there...

Issues I want to solve/understand

  1. Somehow indicate linetype on the legend of Almost there... (see Control 0 and Control 1 on the Desired plot);
  2. Get the same linetype of Control 0 and Control 1 on Desired plot and Almost there... - this is probably related to the levels of the factor(PlotLine), I tried to add more of them to "push" "dashed" into higher levels, but got no visible changes on the plots.

Any hints?

5
  • @jf328, it will circle through all linetypes, I just want two - solid and dashed (and be able to change them easily). Commented Apr 22, 2016 at 12:45
  • 1. I don't know if you can combine them. You can however have another legend if you don't specify guide=FALSE 2. You are right. ggplot uses factor level. You can reorder the levels however you want and get type you want dataT[, PlotLine2 := reorder(PlotLine, PlotLine == 'dashed')] Commented Apr 22, 2016 at 12:54
  • @jf328, ad 1: I have used guide=FALSE to not print two legends, so clearly I am looking for another answer than just getting it back. Ad 2: reordering PlotLine unfortunately gives exactly same plot. Commented Apr 22, 2016 at 14:53
  • Then try reorder(PlotLine, PlotLine == 'solid'), one will work :) Commented Apr 22, 2016 at 16:14
  • @jf328, looks like using a factor is not an answer here, as it still gives line type showed on the second plot (i.e. slightly narrower dashed), so it does not change anything - I still had to use scale_linetype_manual(values = c("solid", "dashed"), guide = FALSE) to get the line type matching the first plot. It is a bit confusing, I will try to dig more into it. Thanks for your time! Commented Apr 24, 2016 at 21:07

1 Answer 1

2

I don't think it is possible to combine two scales without using scale_*_manual. However, there's a generic solution unsing only information form PlotCat:

dataT$PlotCat = factor(dataT$PlotCat)

ggplot(data.frame(dataT), aes(x=X, y=Y, colour=PlotCat, linetype=PlotCat)) +
  geom_point() +
  geom_smooth(level = 0.5, fill = NA) +
  scale_linetype_manual(values=as.numeric(grepl("Control", levels(dataT$PlotCat)))+1)
Sign up to request clarification or add additional context in comments.

3 Comments

This is slightly limited (imagine writing those ifelse's for more groups...), but definitely better than replicating the linetype values, thank you. Lets wait a bit more for other solutions.
You can use the numeric representation of the factor levels (see the edited solution). That way it's independent of the number of groups.
How would you add other groups to your solution? Let's say we want to plot "Control 0" with dashed, "Control 1" with dotted and all the "Model Cat X" with solid line. I have "patched" sapply, grepl and max together, but the solution is long, ugly and there must be something better than that: dataT$PlotCat = factor(dataT$PlotCat); keys <- c("Model", "Control 1", "Control 0"); cats <- levels(dataT$PlotCat); linetypes <- sapply(1:length(keys), function(i) { as.numeric(grepl(keys[i], cats, ignore.case=TRUE)) * i }) %>% t() %>% data.frame() %>% summarise_each(funs(max(., na.rm = TRUE))) %>% t()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.