geom_hline ignoring colour aes for some reason - r

line_data <- data.frame(value = c(1,2), color = as.factor(c("blue", "green"))
plot1 <- plot1 +
geom_hline(aes(yintercept = value, colour = color), line_data, linetype = "dashed", size = 0.5)
The above is a snippet of my code. No matter what I assign to color column, it will be ignored. I can assign integers or continuous numbers. it will be ignored.
EDITED:
The reason is because plot1 already has a scale_color_manual added to it. Now the challenge becomes how to make it work without having to remove the scale_color_manual?

Please post reproducible code to help us answer your question. We don't know what plot1 is.
Use scale_colour_identity to tell ggplot2 to interpret the variable directly as a color:
line_data <- data.frame(value = c(1,2), color = as.factor(c("blue", "green")))
ggplot(line_data) +
geom_hline(aes(yintercept = value, colour = color), line_data, linetype = "dashed", size = 0.5) +
scale_colour_identity()
EDIT: To make a new color legend compatible with an existing one, re-specify scale_colour_manual. You will still get the warning Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale., but it works:
library(ggplot2)
# example plot1 with manual scale
plot1data = data.frame(x=c(1,2,3,4),
y=c(1,2,3,4),
color=factor(c(1,1,1,2)))
plot1 = ggplot(plot1data, aes(x=x, y=y, colour=color)) +
geom_point() +
scale_colour_manual(values=c('1'='green','2'='red'))
# data you want to add to the plot
line_data <- data.frame(value = c(1,2), color = as.factor(c("blue", "green")))
# assume you have the plot1 object but no access to the code that generated it
# extract colors from plot1
ggdata = ggplot_build(plot1)$data[[1]]
plot1_colours = ggdata$colour
names(plot1_colours) = ggdata$group
# use the values originally specified for plot1 (plot_colours); add additional custom values
plot1 +
geom_hline(aes(yintercept = value, colour = color), data = line_data, linetype = "dashed", size = 0.5) +
scale_colour_manual(values=c(plot1_colours, 'blue'='blue', 'green'='green'))
Specify breaks if you want to remove some values from the legend:
plot1 +
geom_hline(aes(yintercept = value, colour = color), data = line_data, linetype = "dashed", size = 0.5) +
scale_colour_manual(values=c(plot1_colours, 'blue'='blue', 'green'='green'), breaks = names(plot1_colours))

Related

scale_fill_discrete with breaks and custom color scale?

I have an issue choosing the custom colouring of my plot, I am trying to add my own values to the plot but I can's seem to understand where should I put the custom color vector:
col <- c("#004d8d", "#cc2701", "#e5b400")
This is the plot code right now:
p1 <- ggplot(data = densdf1, mapping = aes(x = x, y = y)) +
geom_area(data = densdf1[densdf1$CI,],
aes(fill = Electrode, color = Electrode),
outline.type = "full", alpha = 0.3, size = 1) +
geom_line(aes(color = Electrode), size = 1) +
scale_fill_discrete(breaks=c("Fz","Cz","Pz")) +
guides(colour = "none") +
geom_vline(xintercept = 0) +
lims(x = c(-3, 2), y = c(0, 2.25)) +
labs(title="INTERVAL 225-275ms", x="VALUES", y="DENSITY") +
theme_bw() +
theme(axis.text=element_text(size=10),
axis.title=element_text(size=12),
plot.title=element_text(size=14))
This is the plot with default colours and it looks perfectly fine, but I'd like to customise the colours.
As you can see there is a contour line and the area from the density that need to be coloured.
I tried changing the aesthetics but I think I am not understanding the logic. I tried also using scale_manual_fill(values = col) removing scale_fill_discrete(breaks=c("Fz","Cz","Pz")) but it only works with the area inside.
Can any ggplot2 expert give me a hint? Thanks!
in the aes(...) section you define scales, and the color must be adjusted for each scale. In your case it would be the "fill" and the "color" scale, hence the following two lines must be added to adjust both scales:
scale_color_manual(values = col, breaks = c("Fz", "Cz", "Pz")) +
scale_fill_manual(values = col, breaks = c("Fz", "Cz", "Pz")) +
If you want to make sure, that a certain category gets a certain color, you have to specify the breaks, and the order the vector corresponds to the order of the color vector.

Adding legend for combo bar and line graph -- ggplot ignoring commands

I am trying to make a bar chart with line plots as well. The graph has created fine but the legend does not want to add the line plots to the legend.
I have tried so many different ways of adding these to the legend including:
ggplot Legend Bar and Line in Same Graph
None of which have worked. show.legend also seems to have been ignored in the geom_line aes.
My code to create the graph is as follows:
ggplot(first_q, aes(fill = Segments)) +
geom_bar(aes(x= Segments, y= number_of_new_customers), stat =
"identity") + theme(axis.text.x = element_blank()) +
scale_y_continuous(expand = c(0, 0), limits = c(0,3000)) +
ylab('Number of Customers') + xlab('Segments') +
ggtitle('Number Customers in Q1 by Segments') +theme(plot.title =
element_text(hjust = 0.5)) +
geom_line(aes(x= Segments, y=count) ,stat="identity",
group = 1, size = 1.5, colour = "darkred", alpha = 0.9, show.legend =
TRUE) +
geom_line(aes(x= Segments, y=bond_count)
,stat="identity", group = 1, size = 1.5, colour = "blue", alpha =
0.9) +
geom_line(aes(x= Segments, y=variable_count)
,stat="identity", group = 1, size = 1.5, colour = "darkgreen",
alpha = 0.9) +
geom_line(aes(x= Segments, y=children_count)
,stat="identity", group = 1, size = 1.5, colour = "orange", alpha
= 0.9) +
guides(fill=guide_legend(title="Segments")) +
scale_color_discrete(name = "Prod", labels = c("count", "bond_count", "variable_count", "children_count)))
I am fairly new to R so if any further information is required or if this question could be better represented then please let me know.
Any help is greatly appreciated.
Alright, you need to remove a little bit of your stuff. I used the mtcars dataset, since you did not provide yours. I tried to keep your variable names and reduced the plot to necessary parts. The code is as follows:
first_q <- mtcars
first_q$Segments <- mtcars$mpg
first_q$val <- seq(1,nrow(mtcars))
first_q$number_of_new_costumers <- mtcars$hp
first_q$type <- "Line"
ggplot(first_q) +
geom_bar(aes(x= Segments, y= number_of_new_costumers, fill = "Bar"), stat =
"identity") + theme(axis.text.x = element_blank()) +
scale_y_continuous(expand = c(0, 0), limits = c(0,3000)) +
geom_line(aes(x=Segments,y=val, linetype="Line"))+
geom_line(aes(x=Segments,y=disp, linetype="next line"))
The answer you linked already gave the answer, but i try to explain. You want to plot the legend by using different properties of your data. So if you want to use different lines, you can declare this in your aes. This is what get's shown in your legend. So i used two different geom_lines here. Since the aes is both linetype, both get shown at the legend linetype.
the plot:
You can adapt this easily to your use. Make sure you using known keywords for the aesthetic if you want to solve it this way. Also you can change the title names afterwards by using:
labs(fill = "costum name")
If you want to add colours and the same line types, you can do customizing by using scale_linetype_manual like follows (i did not use fill for the bars this time):
library(ggplot2)
first_q <- mtcars
first_q$Segments <- mtcars$mpg
first_q$val <- seq(1,nrow(mtcars))
first_q$number_of_new_costumers <- mtcars$hp
first_q$type <- "Line"
cols = c("red", "green")
ggplot(first_q) +
geom_bar(aes(x= Segments, y= number_of_new_costumers), stat =
"identity") + theme(axis.text.x = element_blank()) +
scale_y_continuous(expand = c(0, 0), limits = c(0,3000)) +
geom_line(aes(x=Segments,y=val, linetype="solid"), color = "red", alpha = 0.4)+
geom_line(aes(x=Segments,y=disp, linetype="second"), color ="green", alpha = 0.5)+
scale_linetype_manual(values = c("solid","solid"),
guide = guide_legend(override.aes = list(colour = cols)))

How do I add a legend to identify vertical lines in ggplot?

I have a chart that shows mobile usage by operating system. I'd like to add vertical lines to identify when those operating systems were released. I'll go through the chart and then the code.
The chart -
The code -
dev %>%
group_by(os) %>%
mutate(monthly_change = prop - lag(prop)) %>%
ggplot(aes(month, monthly_change, color = os)) +
geom_line() +
geom_vline(xintercept = as.numeric(ymd("2013-10-01"))) +
geom_text(label = "KitKat", x = as.numeric(ymd("2013-10-01")) + 80, y = -.5)
Instead of adding the text in the plot, I'd like to create a legend to identify each of the lines. I'd like to give each of them its own color and then have a legend to identify each. Something like this -
Can I make my own custom legend like that?
1) Define a data frame that contains the line data and then use geom_vline with it. Note that BOD is a data frame that comes with R.
line.data <- data.frame(xintercept = c(2, 4), Lines = c("lower", "upper"),
color = c("red", "blue"), stringsAsFactors = FALSE)
ggplot(BOD, aes( Time, demand ) ) +
geom_point() +
geom_vline(aes(xintercept = xintercept, color = Lines), line.data, size = 1) +
scale_colour_manual(values = line.data$color)
2) Alternately put the labels right on the plot itself to avoid an extra legend. Using the line.data frame above. This also has the advantage of avoiding possible multiple legends with the same aesthetic.
ggplot(BOD, aes( Time, demand ) ) +
geom_point() +
annotate("text", line.data$xintercept, max(BOD$demand), hjust = -.25,
label = line.data$Lines) +
geom_vline(aes(xintercept = xintercept), line.data, size = 1)
3) If the real problem is that you want two color legends then there are two packages that can help.
3a) ggnewscale Any color geom that appears after invoking new_scale_color will get its own scale.
library(ggnewscale)
BOD$g <- gl(2, 3, labels = c("group1", "group2"))
line.data <- data.frame(xintercept = c(2, 4), Lines = c("lower", "upper"),
color = c("red", "blue"), stringsAsFactors = FALSE)
ggplot(BOD, aes( Time, demand ) ) +
geom_point(aes(colour = g)) +
scale_colour_manual(values = c("red", "orange")) +
new_scale_color() +
geom_vline(aes(xintercept = xintercept, colour = line.data$color), line.data,
size = 1) +
scale_colour_manual(values = line.data$color)
3b) relayer The experimental relayer package (only on github) allows one to define two color aethetics, color and color2, say, and then have separate scales for each one.
library(dplyr)
library(relayer)
BOD$g <- gl(2, 3, labels = c("group1", "group2"))
ggplot(BOD, aes( Time, demand ) ) +
geom_point(aes(colour = g)) +
geom_vline(aes(xintercept = xintercept, colour2 = line.data$color), line.data,
size = 1) %>% rename_geom_aes(new_aes = c("colour" = "colour2")) +
scale_colour_manual(aesthetics = "colour", values = c("red", "orange")) +
scale_colour_manual(aesthetics = "colour2", values = line.data$color)
You can definitely make your own custom legend, but it is a bit complicated, so I'll take you through it step-by-step with some fake data.
The fake data contained 100 samples from a normal distribution (monthly_change for your data), 5 groupings (similar to the os variable in your data) and a sequence of dates from a random starting point.
library(tidyverse)
library(lubridate)
y <- rnorm(100)
df <- tibble(y) %>%
mutate(os = factor(rep_len(1:5, 100)),
date = seq(from = ymd('2013-01-01'), by = 1, length.out = 100))
You already use the colour aes for your call to geom_line, so you will need to choose a different aes to map onto the calls to geom_vline. Here, I use linetype and a call to scale_linetype_manual to manually edit the linetype legend to how I want it.
ggplot(df, aes(x = date, y = y, colour = os)) +
geom_line() +
# set `xintercept` to your date and `linetype` to the name of the os which starts
# at that date in your `aes` call; set colour outside of the `aes`
geom_vline(aes(xintercept = min(date),
linetype = 'os 1'), colour = 'red') +
geom_vline(aes(xintercept = median(date),
linetype = 'os 2'), colour = 'blue') +
# in the call to `scale_linetype_manual`, `name` will be the legend title;
# set `values` to 1 for each os to force a solid vertical line;
# use `guide_legend` and `override.aes` to change the colour of the lines in the
# legend to match the colours in the calls to `geom_vline`
scale_linetype_manual(name = 'lines',
values = c('os 1' = 1,
'os 2' = 1),
guide = guide_legend(override.aes = list(colour = c('red',
'blue'))))
And there you go, a nice custom legend. Please do remember next time that if you can provide your data, or a minimally reproducible example, we can better answer your question without having to generate fake data.

ggplot generating two legends when only one is wanted

In R I'm trying to generate a plot where I want to apply unique colors, line types, transparencies, and line thicknesses by case grouping. As currently implemented two legend plots are generated instead of one. The second legend plot is the only one that I can change the legend title. Presumably I've made a mistake any help would be greatly appreciated.
Ultimately I want to generate a single legend and have the style changes and labeling changes take effect.
library(ggplot2)
temp_df <- data.frame(year = integer(50), value = numeric(50), case = character(50))
temp_df$year <- 1:50
temp_df$value <- runif(50)
temp_df$case <- "A"
df <- temp_df
temp_df$value <- runif(50)
temp_df$case <- "B"
df <- rbind(df, temp_df)
LineTypes <- c("solid", "dotted")
colors <- c("red", "black")
linealphas <- c(1, .8)
linesizes <- c(1, 2)
Plot <- ggplot(df, aes(x = year, y = value, group = case))+
geom_line(aes(linetype = case, color = case, size = case, alpha = case))+
scale_linetype_manual(values = LineTypes)+
scale_color_manual(values = colors)+
scale_y_continuous(limits = c(0, 1), labels = scales::percent)+
scale_alpha_manual(values = linealphas)+
scale_size_manual(values = linesizes)+
xlab("Year")+
ylab("Percentage%")+
labs(color = "Scenario")+
theme_minimal()
Plot
If you want ggplot to merge the legends then they all have to have the same title. You can specify the legend title with the name argument in the scales:
ggplot(df, aes(x = year, y = value, group = case))+
geom_line(aes(linetype = case, color = case, size = case, alpha = case)) +
scale_linetype_manual(values = LineTypes, name = "Scenario")+
scale_color_manual(values = colors, name = "Scenario")+
scale_y_continuous(limits = c(0, 1), labels = scales::percent)+
scale_alpha_manual(values = linealphas, name = "Scenario")+
scale_size_manual(values = linesizes, name = "Scenario")+
xlab("Year")+
ylab("Percentage%")+
theme_minimal()
A coworker pointed out a resolution to me the key was to remove the guides so that only one of styles that I had defined was being used for the legend.
guides(size = FALSE)+
guides(alpha = FALSE)+
guides(linetype = FALSE)+
His explanation for this was that R doesn't recognize that the vector of factors defining the properties of the plot are necessarily related. As a result it will generate multiple legends when only one is desired.
library(ggplot2)
temp_df<-data.frame(year=integer(50),value=numeric(50),case=character(50))
temp_df$year<-1:50
temp_df$value<-runif(50)
temp_df$case<-"A"
df<-temp_df
temp_df$value<-runif(50)
temp_df$case<-"B"
df<-rbind(df,temp_df)
LineTypes<-c("solid","dotted")
colors<-c("red","black")
linealphas<-c(1,.8)
linesizes<-c(1,2)
Plot<-ggplot(df,aes(x=year,y=value,group=case))+
geom_line(aes(linetype=case, color=case, size=case, alpha =case))+
scale_linetype_manual(values=LineTypes)+
scale_color_manual(values=colors)+
scale_y_continuous(limits=c(0,1),labels = scales::percent)+
scale_alpha_manual(values=linealphas)+
scale_size_manual(values=linesizes)+
xlab("Year")+
ylab("Percentage%")+
labs(color = "Scenario")+
guides(size = FALSE)+
guides(alpha = FALSE)+
guides(linetype = FALSE)+
theme_minimal()
Plot
Can't you just remove the line "labs(color = "Scenario")"?
This is the plot that gets generated. Not sure if it's missing anything that you need.
The result seems fine to me:

Change transparency, shape and size of a categorical variables

I am trying to plot using ggplot and trying to set the transparency, size and shape for geom_point using a binary variable in my dataset.
For example, if binary_variable == 1 then set the size to 1, shape = triangle, transparency = 0.2, if binary_variable == 0 set the size to 0.5 etc.
I have been able to make the colour change as follows:
library(ggplot2)
df <- data.frame(variable1 = 1:5,
variable2 = 1:5,
binary = c(0,0,0,1,1))
ggplot(df, aes(x = variable1, y = variable2, colour = as.factor(binary))) +
geom_point(size = 2, alpha = 0.3) +
scale_colour_manual(values = c("grey", "black"), labels = c("cat1", "cat2")) +
theme_bw()
You can control shape, colour and aesthetics in the same way using the scale_X_manual functions. See the help page for all the different ways these can be controlled.
The key part to make this work though is to make sure that you added the variable you want to control to the aes part of the ggplot function.
Here is an example:
df$binary <- as.factor(df$binary)
ggplot(df, aes(x = variable1, y = variable2, colour = binary, shape = binary, alpha = binary)) +
geom_point(size = 2) +
scale_colour_manual(values = c("blue", "red")) +
scale_shape_manual(values=c(16,17)) +
scale_alpha_manual(values=c(1, 0.5)) +
theme_bw()

Resources