Scale for aesthetics used in the plot | ggplot2 - r

I am an absolute beginner in ggplot2. I got frustrated with ggplot2 and started reading Wickham's awesome book. He says that "a scale is required for every aesthetic used on the plot.".
So, I did the following:
Try 1:
huron <- data.frame(year = 1875:1972, level = as.numeric(LakeHuron))
ggplot(huron, aes(year)) +
geom_line(aes(y = level + 5, color = "y+5")) +
scale_color_manual(values = c("orange")) +
geom_line(aes(y = level - 5, color = "y-5")) +
scale_color_manual(values = "blue")
Upon running this, I get an error saying " insufficient value of colors provided."
I googled this and found the following thread on SO : ggplot2 Error: Insufficient values in manual scale. In original post, it makes sense why he/she added extra colors. However, I am not sure why this would be the case in my example because I have two layers, each with its own aesthetic.
Try 2
This code will work: (as in I can see two line plots in two different color and a legend--this is my objective)
ggplot(huron, aes(year)) +
geom_line(aes(y = level + 5, color = "y+5")) +
scale_color_manual(values = c("orange", "blue")) + #Added another color here.
geom_line(aes(y = level - 5, color = "y-5"))
Surprisingly, the above code shows something weird--I have got two aesthetics and only one scale.
Question 1: This is quite surprising because as we can see that there are two geoms but only one scale. Correct? I know Wickham cannot be wrong. So, what am I missing?
Question 2: Also, out of curiosity, if I have multiple geoms each with one aesthetic as in above case, and with one scale tied to each, how will ggplot know which scale ties back to which geom? As in, how would ggplot2 know whether layer1 goes with scale with color = red and layer2 goes with color = blue?
I'd sincerely appreciate your thoughts. Thanks in advance.

To answer the specific question in the comments:
If you want to force specific colors, you need to use scale_color_manual. As the name suggests, this needs some manual work.
library(ggplot2)
#default colors
#http://stackoverflow.com/a/8197703/1412059
gg_color_hue <- function(n) {
hues = seq(15, 375, length = n + 1)
hcl(h = hues, l = 65, c = 100)[1:n]
}
ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(colour = class)) +
geom_smooth(method = "lm", se = FALSE, aes(color = "model")) +
scale_color_manual(values = setNames(c(gg_color_hue(length(unique(mpg$class))), "red"),
c(unique(mpg$class), "model")))
However, I would use an additional aesthetic for the line type.
ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(colour = class)) +
geom_smooth(method = "lm", se = FALSE, aes(linetype = "model"), color = "red")

Related

R, ggplot; Control size of symbols and line thickness independently in legend in ggplot

I have a plot looking principally like this when based on the mpg-dataset:
library(datasets)
plot2 <- ggplot(mapping = aes(
x = cty,
y = hwy,
group = as.factor(cyl),
shape = as.factor(cyl),
linetype = as.factor(cyl)),
data = mpg) +
geom_point() +
geom_smooth(method = lm, se = F, color = "black") +
theme(legend.key.width = unit(4,"cm"))
plot2
I would like to be able to control the size of the symbols in the legend without affecting the thickness of the lines. Trying with the idea of using override.aes from similar threads gives bigger symbols but at the same time thicker lines.
plot2 + guides(shape = guide_legend(override.aes = list(size=5)))
This question is partly described in Modifying legends in ggplot2 with interactions and guides; however, the question in the link adresses changes to Geom_Path and not Geom_Smooth and does not explain how to find the exact definition of the ggproto()-object to change. It would be helpful if someone could supply this information - then I could probably modify the code myself in a similar fashion.

Translating colors to linetypes/symbols in ggplot2

Suppose some R package produces a ggplot object, g, that includes points and/or lines of different colors. But suppose you need to produce this in suitable form for black-and-white reproduction where the colors don't show.
One possibility is to print g + scale_color_grey(). However, different gray-scale values are not easy to discriminate, and even grayscale is not always suitable for some forms of reproduction.
Is there a way to somehow map color groupings to linetype (and also to shape)? I could not figure out how to do this.
For an example to mess with, try
df <- data.frame(x = c(1:3, 1:3), y = c(4, 1, 9, 2, 7, 5),
trt = factor(c(1,1,1, 2,2,2)))
g <- ggplot(df, aes(x, y, group = trt, color = trt)) +
geom_line() + geom_point()
Given g, make a suitable B/W plot with different point shapes and line types. This needs to be done without changing the code that produced g.
Update #aosmith's answer in the comments is most compact:
g +
aes(linetype = trt, shape = trt) +
scale_color_grey(start = 0, end = 0) +
theme_bw()
Original
You can use the linetype and shape arguments in aes(), and remove the color argument in the initial call to ggplot() for b&w.
If you can't change g, use scale_color_manual to set the lines to black, then theme_bw() to create the b&w layout.
g +
geom_line(aes(linetype = trt), size = 1) +
geom_point(aes(shape = trt), size = 3) +
scale_color_manual(values = c("black", "black")) +
theme_bw()

ggplot2 custom legend combining shape and fill

I am trying to combine fill and color in a ggplot2 legend. Because there are several colors for the x axis, it seems logic that ggplot2 do not know which color to pick in the legend.
For exemple:
library(ggplot2)
ggplot(mpg, aes(fl, hwy)) +
geom_point(aes(color = fl, shape = factor(year), fill = fl)) +
scale_shape_manual(values = c("circle filled", "circle open"))
My goal would be to manually edit the factor(year) legend to look like this:
I played around the guides() function without success.
Edit:
Values for shape can be found by running vignette("ggplot2-specs").
you already had the nearly correct answer with the scale_shape_manual. But somehow the "circle filled" argument is invalid. Since i'm not sure where those values can be looked up, i took the values from a table of a similar question (source):
so with value 20 and 79 you can get the desired result.
ggplot(mpg, aes(fl, hwy)) +
geom_point(aes(color = fl, shape = factor(year), fill = fl)) +
scale_shape_manual(values = c(16,79))
output:
Ok, so here is a very roundabout way of making it look like the image above. Maybe someone else can come up with a more intuitive version:
ggplot(mpg, aes(fl, hwy)) +
geom_point(aes(color = fl, shape = factor(year), fill = factor(year))) +
scale_shape_manual(values = c(16,79), guide = FALSE) +
scale_fill_manual("Year", values=c("grey","white"))+
guides(fill = guide_legend(override.aes = list(shape = c(21,21),
color = c("black", "black"))))
Output:

change colors to black in existing ggplots

This is a question about the ggplot2 package (author: Hadley Wickham). I have existing ggplot objects with distinct colors (resp shapes, linetype, fill...) that I would like to map to a single color, e.g. black. What is the recommended approach?
Clarification: I have to work with these ggplot objects: I cannot re-make them
A ggplot with variables grouped as factors: this is the plot object p I need to work with
p <- ggplot(mtcars, aes(x = mpg, y = wt, group = factor(cyl), colour = factor(cyl))) +
geom_point(size = 5)
Several approaches I know of:
1. scale_colour_grey hack
p + scale_colour_grey(start = 0, end = 0) + # gives correct, useless legend
guides(color = FALSE)
The shorter p + scale_colour_grey(0,0) does not work, you have to be explicit about start and end.
2. scale_colour_manual with rep() hack
p + scale_colour_manual(values = rep("black",3)) # gives correct, useless legend
The simpler scale_colour_manual(values = "black") does not work. This was probably the most intuitive approach. Having to specify the length of the vector makes it less attractive an approach.
3. geom_point() recalled
p + geom_point(colour = "black") + # gives incorrect legend
guides(color = FALSE)
It is well documented that the following is not allowed:
p + scale_colour_manual(colour = "black")
Error in discrete_scale(aesthetic, "manual", pal, ...) :
unused argument (colour = "black")
Removing the color mapping directly seems to work:
p_bw = p
p_bw$mapping$colour = NULL
gridExtra::grid.arrange(p, p_bw)
If you just want to set the points to black and get rid of the color legend, I think you can just to this:
p + scale_colour_manual(values=rep("black",length(unique(mtcars$cyl))),
guide=FALSE)

Limit the color variation in R using scale_color_grey

Before I start, allow me to explain my graph: I have two Genotypes (WTB and whd) and each have two conditions (0 and 7), so I have four lines.
Now, I want to make a plot where each variable and its condition is the same color. Anything with whd will be black and anything with WTB will be grey.
I managed to make the graph with the solid/dashed lines correctly, however, I am having trouble with the coloring. I can only make it so that there is a grey gradient. Are there any parameters for scale_color_grey to help me with this?
This is my code (I took out parts of it for easier read):
ggplot(data=df4, aes(x=Day, y=Remain, group=Condition, shape=Condition, colour=Condition) +
theme_bw() +
geom_line(aes(linetype=Condition), size=1) +
geom_point(size=0, fill="#FFFFFF") +
scale_linetype_manual(name="Genotype",
values=c("solid", "dashed", "solid", "dashed")) +
scale_shape_manual(name="Genotype", values=c(1,19,1,19)) +
scale_color_grey(name="Genotype")
I think this code should produce the plot you want. However, without your exact dataset, I had to generate simulated data.
## Generate dummy data and load library
library(ggplot2)
df4 = data.frame(Remain = rep(0:1, times = 4),
Day = rep(1:4, each = 2),
Genotype = rep(c("wtb", "whd"), each = 4),
Condition = rep(c("0", "7"), times = 4 ))
Next, I created a grouping variable:
df4$both = paste0(df4$Genotype, df4$Condition)
And last, I plotted and saved the figure:
example <- ggplot(data=df4, aes(x=Day, y=Remain,
group=both,
color = Genotype,
linetype = Condition)) +
geom_line() +
scale_color_manual(values = c("grey50", "black")) +
scale_linetype_manual(values = c("solid", "dashed")) +
theme_bw()
ggsave("example.jpg", example)
From your code, it was not apparent why you included the geom_point. Also, if you only want one sub-legend, rather than two, this SO question provides details on how to do that.

Resources