I cannot seem to change the legend title without the legend splitting my shape and color into two separate legends. How can i change the combined legend title? The image is what the graph looks like.
ggplot(data = df, aes (x = factor(dminp,c("-3 to -1", "-1 to 1")), y = sum_diff,col = factor(dmin), shape = factor(dmin), group = factor(dmin)))+
xlab("Range of Difficulty Parameters for Screen Items") + ylab("Bias Due to Skip-Logic") +
stat_summary(geom = "point",fun.y = "mean",size = 8, aes(shape = factor(dmin)))+
stat_summary(geom = "point",fun.y = "mean",size = 8, aes(col = factor(dmin)))+
scale_shape_manual(values = c(8,5)) + theme_bw() + scale_colour_manual(values = c("orange","purple"))+
theme(panel.grid.major.x = element_blank(),
panel.grid.major = element_line(colour = "black",size=0.25))+ theme(legend.justification = "top")
I have tried using labs(col = "what i want it to be named") but this adds a 2nd legend and splits shape/color.
How about trying:
... +
scale_shape_manual(name="X",values = c(8,5)) +
scale_colour_manual(name="X",values = c("orange","purple"))+
..
Here's an example:
ggplot(iris,aes(x=Sepal.Width,y=Sepal.Length,shape=Species,col=Species)) +
geom_point()+
scale_color_manual(name="X",values=c("Blue","Orange","Red")) +
scale_shape_manual(name="X",values=c(17,18,19))
Related
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())
I am trying to make a combo chart using ggplot2. However i want to add a text box sort outside my plot body. I am unable to place it at the desired location
I have used grid pack to create grob and include that in annotation in the ggplot code. Additionally i have also put the same text in geom_text. How do i ensure the text comes say below the legend. Following is my code
m <- ggplot() +
geom_area(data= (ly_vol_ntwk %>%
mutate(Wk_end_d = as.factor(Wk_end_d))%>%
filter(!is.na(value_new))),
aes(x = Wk_end_d, y = value_new ,group = variable,fill=variable))+
geom_bar(data = (fcst_act_vol_ntwk %>%
mutate(Wk_end_d = as.factor(Wk_end_d))%>%
filter(!is.na(value_new))),
aes(x = Wk_end_d, y = value_new, group = variable, fill = variable),
stat = "identity",position = "dodge", width =0.5)+
geom_line(data = (var_vol_ntwk %>%
mutate(Wk_end_d = as.factor(Wk_end_d))%>%
filter(!is.na(value_new))),
aes(x = Wk_end_d, y = value_new,
group = variable, fill= variable), size = 0.8)+
scale_y_continuous(sec.axis = sec_axis(trans = ~./100000,
name = "Variance", breaks = waiver(),
labels=function(x) paste0(x,"%")))+
theme_set(theme_bw())+
theme(axis.text.x = element_text(angle=65, vjust=0.5,face = "plain"),
text = element_text(size=9), legend.position = "bottom", legend.title = element_blank())+
labs(title= "Inbound - Network", x= "Week end date", y = " ")+
scale_fill_manual(values = c("#C5E0B4","#7030A0", "#D9D9D9","#ED7D31","black"))+
geom_text(label = "LW Variance",
aes(x = 19, y = -1960000),
check_overlap = TRUE) #annotation_custom(grob = textGrob("LW Variance"), xmin = 18, xmax = 18, ymin = -1030000, ymax = -1030000)+ coord_cartesian(clip = 'off')
I need to get the text box with a border outside the area of the ggplot. Can you please help me?
You can place text below plot area with labs(caption = "text"), but you can't place captions on top of the plot. However, you could use subtitles labs(subtitle = "text") to produce a similar visual of captions on the top.
To further control the aspect of both options use theme(plot.caption = element_text(...), plot.subtitle = element_text(...)). Type ?element_text in your console to get all the options for text formatting.
For example:
library(ggplot2)
df <- data.frame(x = rnorm(50), y = rnorm(50))
ggplot(df, aes(x, y)) +
geom_point() +
labs(subtitle = "Your text here", caption = "Your text here") +
theme(plot.caption = element_text(colour = "red", hjust = 0, angle = 15),
plot.subtitle = element_text(size = 18, face = "bold", hjust = 0.8))
If you want it below your current legend, you can always add a dummy legend and put your text as its name. An example:
ggplot(mtcars, aes(mpg, wt, color = gear,fill = "a")) +
geom_point() +
scale_fill_discrete(name = "Your custom caption\ngoes here", labels = "") +
theme(legend.key = element_rect(fill = "white")) +
guides(color = guide_legend(order = 1),
fill = guide_legend(order = 2, override.aes = list(linetype = 0, shape=NA))) # setting the order parameter in guide_legend will help place it below your existing legend(s)
I am trying to change the labels of a legend on a ggplot where I have legends for 2 aes.
With scale_file_manual, it works, but for one of the two legends only. I guess I should use "guides" that I already used to remove the titles and also remove legend for a 3rd aes, but I do not manage to do it.
Do you have a solution?
Here is my code :
p <- ggplot(data, aes(x = Nb))
p + geom_ribbon(aes(ymin = Sandwich.min, ymax = Sandwich.max, fill = 'grey70',alpha=0.8)) +
geom_ribbon(aes(ymin = Assiette.min, ymax = Assiette.max, fill = '#6495ED80',alpha=0.8)) +
geom_line(aes(y = Pizza, col = '#FF7F24')) +
geom_line(aes(y = Sushis, col = '#228B22')) +
labs(title = "Business lunch cost by number of participants",
x = "Number of participants",
y = "Price (Euros)") +
scale_x_continuous(breaks=seq(1,20,1)) +
scale_y_continuous(breaks = seq(0,300,50)) +
theme_light() +
theme(plot.title = element_text(size = 12, hjust = 0.5)) +
guides(alpha = FALSE, colour = guide_legend(" "), fill = guide_legend(" ")) +
scale_fill_manual(
values=c('#6495ED80','grey70'),
labels=c("Assiettes","Sandwiches"))
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:
I want to build a ggplot graph for a given data.frame with one x-axis and multiple y.curves. Also, I want to do it within a customized function so i could call this function anytime I want to plot something with various dataframes.
The script I'm trying to develop is:
graph.date <- function(data, y.axis1, y.axis2, y.axis3, y.axis4, y.axis5, y.axis6, y.axis7, x.axis, y.lab, title, ...){
ggplot(data, aes_string(x = x.axis)) +
ylab(label = y.lab) + xlab(label = "Date") +
ggtitle(label = title) +
scale_x_date(breaks = "1 month", labels = date_format("%d-%b-%Y")) +
geom_line(aes(y = y.axis1, colour = y.axis1), size = 1) +
geom_line(aes(y = y.axis2, colour = y.axis2), size = 1) +
geom_line(aes(y = y.axis3, colour = y.axis3), size = 1) +
geom_line(aes(y = y.axis4, colour = y.axis4), size = 1) +
geom_line(aes(y = y.axis5, colour = y.axis5), size = 1) +
geom_line(aes(y = y.axis6, colour = y.axis6), size = 1) +
geom_line(aes(y = y.axis7, colour = y.axis7), size = 1) +
scale_fill_discrete() + scale_color_manual(values = c(brewer.pal(9, "Set1"), brewer.pal(9, "Set1"))) +
labs(colour = "") + theme(plot.title = element_text(size = rel(1.76))) +
guides(colour = guide_legend(override.aes = list(size=3))) +
theme(text = element_text(size=20), axis.title=element_text(size=34,face="bold"), axis.text.x = element_text(face="bold",
color="black", size=24, angle=25), axis.text.y = element_text(face="bold", color="black", size=24, angle=0))
}
Then I am calling the function:
graph.date(data = BelgiumMerged, y.axis1 = "Gen1", y.axis2 = "Gen2", y.axis3 = "Gen3",
x.axis = "Date", y.lab = "Capacity", title = "title")
The error I get is :
Error in eval(expr, envir, enclos) : object 'y.axis1' not found
The error you get is that df does not have a column called y.axis1. The easiest way to refer to the column that have the name that is stored in the variable y.axis1 is to use aes_string() instead of aes(). Also don't set the color in the call to aes()
So change all
geom_line(aes(y = y.axis1, colour = y.axis1), size = 1)
to
geom_line(aes_string(y = y.axis1), size = 1,color="red") # Or whatever color you want
However a better way to solve the problem is to reshape the dataframe to long formating so that all x coordinates lays in one column all y coordinates in one column and the grouping of these in a third column. Your function could then be defined as
graph.date <- function(df,y.axes,x.axis){
index <- which(names(df) %in% y.axes)
plotDF <- gather(df,y.type,y.data,index)
ggplot(plotDF,aes_string(x.axis)) +
geom_line(mapping=aes(y=y.data,color=y.type))
}
Here you will pass a vector of y axes instead of having one parameter for each y axis
Thanks a lot Nist - you're a RockStar
My final script looks as follows:
graph.date <- function(data,y.axes,x.axis, y.lab, x.lab, title){
index <- which(names(data) %in% y.axes)
plotDF <- gather(data,y.type,y.data,index)
ggplot(plotDF,aes_string(x.axis)) + ggtitle(label = title) + ylab("Capacity [MW]") + xlab("Date") +
geom_line(mapping=aes(y=y.data,color=y.type))+
scale_fill_discrete() + scale_x_date(breaks = "1 month", labels = date_format("%d-%b-%Y")) +
scale_color_manual(values = c(brewer.pal(9, "Set1"), brewer.pal(9, "Set1"))) +
labs(colour = "LegendTitle") + theme(plot.title = element_text(size = rel(1.76))) +
guides(colour = guide_legend(override.aes = list(size=3))) +
theme(text = element_text(size=20), axis.title=element_text(size=34,face="bold"),
axis.text.x = element_text(face="bold", color="black", size=24, angle=25),
axis.text.y = element_text(face="bold", color="black", size=24, angle=0))
}
#Calling the function
graph.date(df, y.axes = c("Gen1", "Gen2", "Gen3"), x.axis = "Date", title = "title")