ggplot2 custom legend combining shape and fill - r

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:

Related

ggplot2 unable to color legend icons

I'm trying to use ggplot2 to make some sort of timeline using values from a dataframe (df). I've managed to plot the data exactly how I want it (the different colored line segments connecting the x-marks in this exact order, i.e., from left to right: 'early', 'unknown', 'late', 'sub'). The startpoint and endpoint columns in the dataframe are used to define the positions of the points and line segments.
The problem is that the legend doesn't show the color of the 'x' icons, they are just grey. I've tried adding scale_color_manual() and scale_fill_manual() commands but they don't seem to change anything. The legend does display the correct color when I change the shape to shape = 21, however, I really want the shape to be 4 (x icons). I don't care about the shape of the legend though but scale_shape_manual() again didn't change anything about the legend.
I have also tried placing different color arguments inside and outside the aes() argument of ggplot(), geom_segment() and/or geom_point().
How can I make the icons from the legend show the correct color?
Below I added a piece of code to reproduce the problem.
library(ggplot2)
library(RColorBrewer)
## Define dataframe
df <- data.frame(Var = c("sub","late","unknown","early"),
Time = c(10,267,0,1256),
Endpoint = c(1533,1523,1256,1256),
Startpoint = c(1523,1256,1256,0))
colorscheme <- RColorBrewer::brewer.pal(9, "Set1")[c(1,4,2,3)]
## Make plot
ggplot(df, aes(x="", y=Endpoint, fill=Var), color =colorscheme) +
geom_segment( aes(x="", xend="", y=Startpoint, yend=Endpoint), color = colorscheme) +
geom_point(aes(x="", y=Endpoint),size=5, shape=4 , color = colorscheme) +
coord_flip()
Thanks in advance for any suggestions!
You should use color instead of fill. To remove the line from the legend, use guides(color = guide_legend(override.aes = list(linetype = 0))) or use show.legend = F in geom_segment.
Also, arguments passed in ggplot need not to be repeated afterward.
ggplot(df, aes(x="", y=Endpoint, color=Var), colorscheme) +
geom_segment(aes(xend="", y=Startpoint, yend=Endpoint)) +
geom_point(size=5, shape=4) +
coord_flip() +
guides(color = guide_legend(override.aes = list(linetype = 0)))
#or
ggplot(df, aes(x="", y=Endpoint, color=Var), colorscheme) +
geom_segment(aes(xend="", y=Startpoint, yend=Endpoint)) +
geom_point(size=5, shape=4) +
coord_flip()
Try this:
ggplot(df, aes(x = "", y = Endpoint, color = Var), colorscheme) +
geom_segment(aes(x = "", xend = "", y = Startpoint, yend = Endpoint), show.legend = FALSE) +
geom_point(aes(x = "", y = Endpoint), size = 5, shape = 4) +
coord_flip()
In this way legend will show only X

R ggplot2 scale alpha discrete to display in legend

I'm trying to make a plot across two factors (strain and sex) and use the alpha value to communicate sex. Here is my code and the resulting plot:
ggplot(subset(df.zfish.data.overall.long, day=='day_01' & measure=='distance.from.bottom'), aes(x=Fish.name, y=value*100)) +
geom_boxplot(aes(alpha=Sex, fill=Fish.name), outlier.shape=NA) +
scale_alpha_discrete(range=c(0.3,0.9)) +
scale_fill_brewer(palette='Set1') +
coord_cartesian(ylim=c(0,10)) +
ylab('Distance From Bottom (cm)') +
xlab('Strain') +
scale_x_discrete(breaks = c('WT(AB)', 'WT(TL)', 'WT(TU)', 'WT(WIK)'), labels=c('AB', 'TL', 'TU', 'WIK')) +
guides(color=guide_legend('Fish.name'), fill=FALSE) +
theme_classic(base_size=10)
I'd like for the legend to reflect the alpha value in the plot (i.e. alpha value F = 0.3, alpha value M=0.9) as greyscale/black as I think that will be intuitive.
I've tried altering the scale_alpha_discrete, but cannot figure out how to send it a single color for the legend. I've also tried playing with 'guides()' without much luck. I suspect there's a simple solution, but I cannot see it.
One option to achieve your desired result would be to set the fill color for the alpha legend via the override.aes argument of guide_legend.
Making use of mtcars as example data:
library(ggplot2)
ggplot(mtcars, aes(x = cyl, y = mpg)) +
geom_boxplot(aes(fill = factor(cyl), alpha = factor(am))) +
scale_alpha_discrete(range = c(0.3, 0.9), guide = guide_legend(override.aes = list(fill = "black"))) +
scale_fill_brewer(palette='Set1') +
theme_classic(base_size=10) +
guides(fill = "none")
#> Warning: Using alpha for a discrete variable is not advised.

How to change colour of histograms with facet_grid and the position of the text?

How can I change the colour for the two histograms plot made with facet_grid?
I would like to have the histogram of "Active" in green and "Failed" in red.
And also, how can I change the position of the text of the line in order to have it a bit more down?
Here is my code:
df %>%
ggplot(aes(x = `Banks/turnover%Last avail. yr`)) +
geom_histogram(
bins = nclass.Sturges(`Banks/turnover%Last avail. yr`),colour = "black")+
geom_vline(data = status_means, aes(xintercept = avg), color="red", linetype="dashed")+
geom_text(data = status_means , aes(x = avg, label = avg), y= Inf )+
theme(legend.position="None")+
facet_grid(~general_status)
You need to add a factor to the fill parameter. Here, I just use active-failed as I'm not sure how you have that distinguished in your data.
ggplot(df_all,
aes(x = `Banks/turnover%Last avail. yr`, fill = as.factor(active-failed)))
Then, you can add a line to define the colors:
scale_fill_manual(values = c("green", "red"))
As #teunbrand said, you can just use vjust to move the text so that it is not cut off.
Remember to give a good reproducible example, it is helpful to provide some of your data via dput(head(df)).

Scale for aesthetics used in the plot | ggplot2

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")

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)

Resources