Adjust ggplot legend - r

I am trying to make the following changes to the ggplot below (partly illustrated in the picture provided):
change shading legend to show economic cycle (shaded is a recession, no shade is an expansion)
add additional legend to show economic variables (green is 'CLI' and red is 'Inflation Expectations")
The code so far looks like this:
A <- ggplot(Alldata, aes(Date)) +
geom_tile(aes(alpha = Recession, y = 1),
fill = "grey", height = Inf) +
scale_alpha_continuous(range = c(0, 1), breaks = c(0, 1))+
geom_line(aes(y = stdINFEX), col = 'blue', size = .8)+
ylab('')+
theme( axis.text.y=element_blank(), #remove y axis labels
axis.ticks.y=element_blank() #remove y axis ticks
)
A
B <- A + geom_line(aes(y = CLI), col = 'green', size = .8)
B

Maybe this is what you are looking for:
You could set the labels for legend entries via the labels argument of the scale, e.g. using a named vector you could assign a label Expansion to the value "0"
To get a legend for your lines you have to map on aesthetics, i.e. move color=... inside of aes(). Note that using color names inside aes() is meaningless. Therefore I would suggest to use meaningful labels. You could then set your desired colors via scale_color_manual.
Finally, to set the labels for your legends you could make use of labs()
As you provided no example data (see how to make a minimal reproducible example) I make use of the ggplot2::economics dataset as example data:
library(ggplot2)
set.seed(123)
economics$Recession <- 0
economics$Recession[sample(1:nrow(economics), 100)] <- 1
ggplot(economics, aes(date)) +
geom_tile(aes(alpha = Recession, y = 1),
fill = "grey", height = Inf
) +
scale_alpha_continuous(range = c(0, 1),
breaks = c(0, 1),
labels = c("0" = "Expansion", "1" = "Recession")) +
geom_line(aes(y = psavert, color = "psavert"), size = .8) +
geom_line(aes(y = uempmed, color = "uempmed"), size = .8) +
scale_color_manual(values = c(psavert = "blue", uempmed = "green")) +
labs(y = NULL, alpha = "Economic Cycle", color = "Economic Variable") +
theme(
axis.text.y = element_blank(),
axis.ticks.y = element_blank()
)

Related

adding custom ggplot legend to dashed lines and confidence bands

I'm having trouble setting a custom legend for confidence bands and dashed lines. This is my graph so far.
di<-matrix(ncol = 3,nrow = 5) %>% as.data.frame()
colnames(di)<-c('group','estimate','SE')
di<-di %>% mutate(group=1:5,
estimate=c(0.5,9.6,13,15,23.1),
SE=14)
ggplot(di, aes(x=group, y=estimate)) +
geom_point() +
geom_errorbar(width=.5, aes(ymin=estimate-(1.647*SE), ymax=estimate+(1.647*SE)), colour="black") +
xlab('Group') +
ylab('Treatment Effect') +
labs(title="GATE with confidence bands",
subtitle="Point estimates and confidence bands are derived using median of all splits") +
geom_hline(yintercept=c(7.83,22.55),
linetype="longdash",
col='darkred') +
geom_hline(yintercept=15.19,
linetype="longdash",
col='blue')
It looks like this:
However what I want it to look like is something like this, with the exact same legend:
Any advice on this?
This could be achieved like so:
As a general rule: If you want to have a legend you have to map something on aesthetics, e.g. move color=... into aes() for all four geoms
The desired color values can then be set via scale_color_manual
For the geom_hline we also have to pass yintercept as an aes() too. To this end these get something helper data frames with the desired values.
To fix the lines and shapes in the legend I make use of guide_legend's overide.aes to remove the undesired points in the legend as well as removing the line for the point. Additionally I set the number of rows for the legend to 2.
The labels and the order of the layers can be set via the labels and the breaks argument of scale_color_manual
Move the legend in the topleft and get rid of the background fill for the legend and the keys via theme options.
library(ggplot2)
di <- data.frame(
group = 1:5,
estimate = c(0.5, 9.6, 13, 15, 23.1),
SE = 14
)
labels <- c(point = "Point", error = "Error", blue = "Blue", darkred = "Red")
breaks <- c("blue", "darkred", "point", "error")
ggplot(di, aes(x = group, y = estimate)) +
geom_point(aes(color = "point"), size = 3) +
geom_errorbar(width = .5, aes(
ymin = estimate - (1.647 * SE),
ymax = estimate + (1.647 * SE),
color = "error"
)) +
scale_color_manual(values = c(
point = "black",
error = "black",
blue = "blue",
darkred = "darkred"
), labels = labels, breaks = breaks) +
labs(
title = "GATE with confidence bands",
subtitle = "Point estimates and confidence bands are derived using median of all splits",
x = "Group",
y = "Treatment Effect",
color = NULL, linetype = NULL, shape = NULL
) +
geom_hline(
data = data.frame(yintercept = c(7.83, 22.55)),
aes(yintercept = yintercept, color = "darkred"), linetype = "longdash"
) +
geom_hline(
data = data.frame(yintercept = 15.19),
aes(yintercept = yintercept, color = "blue"), linetype = "longdash"
) +
guides(color = guide_legend(override.aes = list(
shape = c(NA, NA, 16, NA),
linetype = c("longdash", "longdash", "blank", "solid")
), nrow = 2, byrow = TRUE)) +
theme(legend.position = c(0, 1),
legend.justification = c(0, 1),
legend.background = element_rect(fill = NA),
legend.key = element_rect(fill = NA))

Combine legend for fill and colour ggplot to give only single legend

I am plotting a smooth to my data using geom_smooth and using geom_ribbon to plot shaded confidence intervals for this smooth. No matter what I try I cannot get a single legend that represents both the smooth and the ribbon correctly, i.e I am wanting a single legend that has the correct colours and labels for both the smooth and the ribbon. I have tried using + guides(fill = FALSE), guides(colour = FALSE), I also read that giving both colour and fill the same label inside labs() should produce a single unified legend.
Any help would be much appreciated.
Note that I have also tried to reset the legend labels and colours using scale_colour_manual()
The below code produces the below figure. Note that there are two curves here that are essentially overlapping. The relabelling and setting couours has worked for the geom_smooth legend but not the geom_ribbon legend and I still have two legends showing which is not what I want.
ggplot(pred.dat, aes(x = age.x, y = fit, colour = tagged)) +
geom_smooth(size = 1.2) +
geom_ribbon(aes(ymin = lci, ymax = uci, fill = tagged), alpha = 0.2, colour = NA) +
theme_classic() +
labs(x = "Age (days since hatch)", y = "Body mass (g)", colour = "", fill = "") +
scale_colour_manual(labels = c("Untagged", "Tagged"), values = c("#3399FF", "#FF0033")) +
theme(axis.title.x = element_text(face = "bold", size = 14),
axis.title.y = element_text(face = "bold", size = 14),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12),
legend.text = element_text(size = 12))
The problem is that you provide new labels for the color-aesthetic but not for the fill-aesthetic. Consequently ggplot shows two legends because the labels are different.
You can either also provide the same labels for the fill-aesthetic (code option #1 below) or you can set the labels for the levels of your grouping variable ("tagged") before calling ggplot (code option #2).
library(ggplot2)
#make some data
x = seq(0,2*pi, by = 0.01)
pred.dat <- data.frame(x = c(x,x),
y = c(sin(x), cos(x)) + rnorm(length(x) * 2, 0, 1),
tag = rep(0:1, each = length(x)))
pred.dat$lci <- c(sin(x), cos(x)) - 0.4
pred.dat$uci <- c(sin(x), cos(x)) + 0.4
#option 1: set labels within ggplot call
pred.dat$tagged <- as.factor(pred.dat$tag)
ggplot(pred.dat, aes(x = x, y = y, color = tagged, fill = tagged)) +
geom_smooth(size = 1.2) +
geom_ribbon(aes(ymin = lci, ymax = uci), alpha = 0.2, color = NA) +
scale_color_manual(labels = c("untagged", "tagged"), values = c("#F8766D", "#00BFC4")) +
scale_fill_manual(labels = c("untagged", "tagged"), values = c("#F8766D", "#00BFC4")) +
theme_classic() + theme(legend.title = element_blank())
#option 2: set labels before ggplot call
pred.dat$tagged <- factor(pred.dat$tag, levels = 0:1, labels = c("untagged", "tagged"))
ggplot(pred.dat, aes(x = x, y = y, color = tagged, fill = tagged)) +
geom_smooth(size = 1.2) +
geom_ribbon(aes(ymin = lci, ymax = uci), alpha = 0.2, color = NA) +
theme_classic() + theme(legend.title = element_blank())

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

Create legend with manual shapes and colours

I use bars and line to create my plot. The demo code is:
timestamp <- seq(as.Date('2010-01-01'),as.Date('2011-12-01'),by="1 mon")
data1 <- rnorm(length(timestamp), 3000, 30)
data2 <- rnorm(length(timestamp), 30, 3)
df <- data.frame(timestamp, data1, data2)
p <- ggplot()
p <- p + geom_histogram(data=df,aes(timestamp,data1),colour="black",stat="Identity",bindwidth=10)
p <- p + geom_line(data=df,aes(timestamp,y=data2*150),colour="red")
p <- p + scale_y_continuous(sec.axis = sec_axis(~./150, name = "data2"))
p <- p + scale_colour_manual(name="Parameter", labels=c("data1", "data2"), values = c('black', 'red'))
p <- p+ scale_shape_manual(name="Parameter", labels=c("data1", "data2"), values = c(15,95))
p
This results in a plot like this:
This figure does not have a legend. I followed this answer to create a customized legend but it is not working in my case. I want a square and line shape in my legend corresponding to bars and line. How can we get it?
I want legend as shown in below image:
For the type of data you want to display, geom_bar is a better fit then geom_histogram. When you to manipulate the appaerance of the legend(s), you need to place the colour = ... parts inside the aes. To get the desired result it probably best to use different types of legend for the line and the bars. In that way you are better able to change the appearance of the legends with guide_legend and override.aes.
A proposal for your problem:
ggplot(data = df) +
geom_bar(aes(x = timestamp, y = data1, colour = "black"),
stat = "Identity", fill = NA) +
geom_line(aes(x = timestamp, y = data2*150, linetype = "red"), colour = "red", size = 1) +
scale_y_continuous(sec.axis = sec_axis(~./150, name = "data2")) +
scale_linetype_manual(labels = "data2", values = "solid") +
scale_colour_manual(name = "Parameter\n", labels = "data1", values = "black") +
guides(colour = guide_legend(override.aes = list(colour = "black", size = 1),
order = 1),
linetype = guide_legend(title = NULL,
override.aes = list(linetype = "solid",
colour = "red",
size = 1),
order = 2)) +
theme_minimal() +
theme(legend.key = element_rect(fill = "white", colour = NA),
legend.spacing = unit(0, "lines"))
which gives:

ggplot2: How to have a different color of geom_vline()

I have this five (5) geom_vline() in my plot and I want them to have a different colors. Is there a way to do that?
Here's my codes,
library(ggplot2)
x <- seq(-7, 8, length = 90)
tvalues <- dt(x,15)
qplot(x, tvalues) + geom_polygon(fill = "purple", colour = "purple", alpha = 0.5) +
geom_point(fill = "purple", colour = "purple", alpha = 0.2, pch = 21) +
geom_vline(xintercept = c(a <- c(-2.27685371, 0.01661155,
0.33598194, 1.92426022), mean(a)), linetype = "dashed", colour = "red") + theme_bw() + xlab(bquote(bold('Average Tensile Strength (lb/in'^'2'*')'))) +
ylab(expression(bold(P(x)))) +
opts(title = expression(bold("Student t Distribution")), plot.title = theme_text(size = 20, colour = "darkblue"),
panel.border = theme_rect(size = 2, colour = "red"))
And here is the output,
Notice the five vertical lines in the plot, I want each of those line to have a different color,
I tried this
library(colorRamps)
geom_vline(xintercept = c(a <- c(-2.27685371, 0.01661155,
0.33598194, 1.92426022), mean(a)), linetype = "dashed", colour = matlab.like(5))
but didn't work, Another attempt
geom_vline(xintercept = c(a <- c(-2.27685371, 0.01661155,
0.33598194, 1.92426022), mean(a)), linetype = "dashed", colour = c("red","blue","green","yellow","orange"))
and still unsuccessful.
Thanks in advance!
So you're sort of missing the fundamental idea behind ggplot2, which is that you always put all your data into a data.frame and every aesthetic that you map corresponds to a variable in your data frame.
You could get 5 vertical lines, each of a different color with five separate calls to geom_vline but that misses the point of the entire package. Instead, you create a data frame:
a <- c(-2.27685371,0.01661155,0.33598194,1.92426022)
vlines <- data.frame(xint = c(a,mean(a)),grp = letters[1:5])
I've explicitly created a grouping variable grp to map to colour. Then we add the layer and map the aesthetics to these variables using aes:
qplot(x, tvalues) +
geom_polygon(fill = "purple", colour = "purple", alpha = 0.5) +
geom_point(fill = "purple", colour = "purple", alpha = 0.2, pch = 21) +
geom_vline(data = vlines,aes(xintercept = xint,colour = grp), linetype = "dashed") +
theme_bw() +
xlab(bquote(bold('Average Tensile Strength (lb/in'^'2'*')'))) +
ylab(expression(bold(P(x)))) +
opts(title = expression(bold("Student t Distribution")),
plot.title = theme_text(size = 20, colour = "darkblue"),
panel.border = theme_rect(size = 2, colour = "red"))
(The colors will be hard to distinguish because they're dashed lines, and two of them are nearly on top of each other.)
You will get much more out of ggplot2 if you transition away from qplot towards ggplot() and start putting your data into data frames rather than vectors.
If you just want to put one line, adding the following geom would add a vertical line at x=1 in red colour and dashed.
+ geom_vline(aes(xintercept=1), colour="#BB0000", linetype="dashed")

Resources