How to draw an empty ggplot with just the legend? - r

My question is very similar to this question, but it's not the same.
I am looking for a way to create an empty ggplot with just the legend. However, in contrast to the autohor of the question I linked at the top, I actually need to create just the legend with no plot area included in the image.
I tried the following code:
ggplot(NULL, aes(color = ""))+
geom_blank()+
scale_color_manual(values = "black", labels = "Something")+
guides(color = guide_legend())+
theme(legend.box.background = element_rect(color = "black"))
But I'm getting the opposite of what I want - I am getting an empty plot area with no legend, like this:
And I would like my end result to look like this (I drew this in Paint):
Any help would be appreciated!

You can make a normal plot, then play with theme to achieve the desired result.
library(ggplot2)
ggplot(data.frame(x = 1, y = 1, colour = 'Something'), aes(x, y, fill = colour))+
geom_point(alpha=0, shape = 0)+ # completely transparent rectangular point
scale_fill_manual(values='black', drop=FALSE) +
guides(fill = guide_legend(override.aes = list(alpha=1, size = 40)))+ # showing the point in the legend
theme(axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
legend.position = c(0.5, 0.5), # move the legend to the center
legend.title = element_blank(),
legend.text = element_text(size = 40),
legend.key = element_rect(fill='NA'),
panel.grid = element_blank(),
panel.border = element_rect(colour = "black", fill='white', size=1)
)

Get the legend how you want it to look, then extract it with cowplot::get_legend:
library(grid)
library(cowplot)
library(ggplot2)
grid.newpage()
grid.draw(get_legend(
ggplot(data.frame(x = 1, y = 1), aes(x, y, fill = "Something")) +
geom_col(size = 20)+
scale_fill_manual(values = "white", labels = "Something", name = "") +
theme_bw() +
theme(legend.box.background = element_rect(color = "black"),
legend.title = element_text(size = 30),
legend.key.size = unit(60, "points"),
legend.text = element_text(size = 24),
legend.key = element_rect(colour = "black"),
legend.box.margin = margin(20, 20, 20, 20))))

Related

How can I completely remove legend.key from ggplot2 legend?

I'm plotting a graph and I need to completely remove the legend.key from my ggplot legend. Why I need to do this? The legend starts with a number that reference the X axis breaks, and the label its too large and I don't want to keep it in the X axis. So, in the X axis i put breaks=1:15, and in legend the label starts with this numbers.
In resume, I just want to remove the legend.key from my graph. Is it possible? I have tried legend.key=element_blank(), but without sucess.
Obs.: In the code is it possible to see that I don't want the fill=legto change the colors of each bar. Everything is set to be gray and I just want to remove de legend.key.
ggplot(IC_QS, aes(x=ind,y=values))+
geom_boxplot(aes(fill=leg),color="black", outlier.colour = "red")+
labs(title = "XXXXXXXXXX",
subtitle = "XXXXXXXXXXX",
caption = "XXXXXXXXXXXXX")+
scale_x_discrete(name = "", labels=1:15)+
scale_y_continuous(name = "XXX", breaks = seq(0,10,1), expand = c(0,0.08*max(IC_QS$values)))+
scale_fill_manual(name="Sectors", values = rep("gray", 15), labels=str_wrap(IC_QS_leg,25))+
theme(legend.position = "right", legend.background = element_blank(),
legend.key = element_blank(),legend.text = element_text(face = "bold", size = 8,),
panel.background = element_blank(), panel.grid.major = element_line(colour = "gray", linetype = "dashed"),
axis.title.x = element_text(face = "bold",vjust = -1), axis.title.y = element_text(face="bold", vjust = +1.5),
axis.text = element_text(colour="black", face = "bold"), title = element_text(face = "bold"))
Obviously we don't have your data, but here's an idea using the iris built-in data set
ggplot(iris, aes(Species, Petal.Width, fill = Species)) +
geom_boxplot() +
scale_x_discrete(labels = seq(length(levels(iris$Species)))) +
scale_fill_manual(values = rep("grey", length(levels(iris$Species))),
labels = paste(seq(length(levels(iris$Species))),
levels(iris$Species), sep = " - ")) +
guides(fill = guide_legend(override.aes = list(color = NA, fill = NA))) +
theme_light(base_size = 16) +
theme(legend.key.width = unit(0, "mm"))

ggplot2 - draw line and annotate text outside of graph area

I have the following data:
fixed <- as.data.frame(rep(0.125,8))
fixed[,2] <- c("1","2","3","4","5","6","7","8")
colnames(fixed) <- c("Percentage", "Test")
and produced the following graph:
Now I would like to achive something like this. However, I have not found a way to draw outside of the graph area and write separate axis labels. Is that possible?
The code for my plot is here:
p <- ggplot(fixed,aes(x=Test ,y=Percentage,fill=Test))+
geom_boxplot()+
stat_summary(fun.data = function(y)
data.frame(y=0.6, label = paste(round(mean(y),2))), geom="text",size=3) +
geom_hline(yintercept=0.55, linetype="dashed", color = "black")+
theme(legend.position="none")+
scale_y_continuous(limits = c(0, 0.6),breaks=seq(0,0.6,0.1),
labels= c("0%","10%","20%","30%","40%","50%","Mean"))+
theme_bw()+
labs(title = "Title")+
xlab("Test")+
ylab("Percetage")+
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_rect(fill = "grey90", colour = NA),
plot.background = element_rect(fill = "grey90", colour = NA),
legend.position="none",plot.title = element_text(size= 12, hjust=0.5),
plot.margin = unit(c(1,1,1,1), "cm"))+
scale_fill_manual(values=c("#00441b","#006d2c","#238b45","#41ab5d","#74c476",
"#a1d99b","#c7e9c0","#e5f5e0"))
p

Set y limits in Bar Chart ggplot2

I have created a bar chart which shows the sales of products in a particular category. This is the bar chart. As you can see it is not very clear so I am trying to set limits for the Y axis.
I create the bar chart with the following line:
bakerySales <- ggplot(sales_bakery, aes(ProductName, ProductSales))+
stat_summary(fun.y=sum,geom="bar",colour="red",fill="red",show.legend =
FALSE)
I then go on to apply a theme to the bar chart using:
bakerySales <- bakerySales +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.x = element_text(colour = "black", size = 14, angle = 60,
hjust = 1),
axis.text.y = element_text(colour = "black", size = 14),
panel.background = element_rect(fill = "white"),
panel.grid.minor = element_blank(),
panel.grid.major = element_blank(),
axis.line = element_line(colour = "black", size = 1),
legend.position = "none",
plot.title = element_text(lineheight = 8, face = "bold"))
I have tried to set the limits for the y axis using:
bakerySales <- bakerySales + ylim(5000,10000)
When I do this I lose the content of the bar chart, It looks like this.
Can someone please tell me where I am going wrong.
Thanks
If you want to zoom in on specifix ylimits, you could use the coord_cartesian function. I do not have the bakerysales dataset, this is an example using mtcars data:
ggplot(mtcars, aes(x = gear, y = qsec)) +
stat_summary(fun.y=sum,geom="bar",colour="red",fill="red",show.legend = FALSE) +
coord_cartesian(ylim = c(200, 300))
Maybe you want
+ coord_cartesian(ylim = c(5000,10000))
df <- data.frame(x = c("a","b"), y = c(1000, 2000))
ggplot(df, aes(x=x,y=y)) +
geom_bar(stat="identity") +
coord_cartesian(ylim = c(500,3000))

How to add two (same) legends in ggplot and change legend title and labels?

I would like to add two (same) legends in ggplot and also want to change legend title and labels. I have tried this:
library(ggplot2)
ggplot(ToothGrowth, aes(x = len, color=factor(dose), fill= factor(dose))) +
geom_density(alpha=0.4) +
theme(panel.background = element_rect(fill = "khaki1", colour = "darkorchid3", size = 2, linetype = "solid"),
panel.grid.major = element_line(size = 0.5, linetype = 'solid', colour = "white"),
panel.grid.minor = element_line(size = 0.25, linetype = 'solid', colour = "white"),
plot.background = element_rect(fill = "bisque2"),
text = element_text(colour="blue4"), axis.title = element_text(size = rel(1.25)), axis.text = element_text(colour="blue4", size = 12),
legend.position=c(.90,.85), legend.background =
element_rect(fill="lightsalmon", colour = "tomato3", size = 1.25),
legend.title = element_text(colour="navy", face="bold"),
legend.text = element_text( colour="midnightblue", face="bold"), strip.background = element_rect(fill="olivedrab1", colour = "darkorchid3", size = 2, linetype = "solid"),
strip.text = element_text(colour="coral4", size=12, angle=0, face="bold")) +
scale_fill_discrete(name = "Dose", labels = c("A", "B", "C")) +
facet_wrap(~supp)
but I got this plot:
I want this plot:
Can somebody help me? Thank you.
As #erocoar and others have suggested, grid.arrange from gridExtra is useful here. Borrowing heavily from from the linked question:
library(gridExtra)
out <- by(data = ToothGrowth, INDICES = ToothGrowth$supp, FUN = function(m) {
m <- droplevels(m)
m <- ggplot(m, aes(x = len, fill= factor(dose)), color=factor(dose)) +
geom_density(alpha=0.4) +
theme(panel.background = element_rect(fill = "khaki1", colour = "darkorchid3",
size = 2, linetype = "solid"),
panel.grid.major = element_line(size = 0.5, linetype = 'solid',
colour = "white"),
panel.grid.minor = element_line(size = 0.25, linetype = 'solid',
colour = "white"),
plot.background = element_rect(fill = "bisque2"),
text = element_text(colour="blue4"),
axis.title = element_text(size = rel(1.25)),
axis.text = element_text(colour="blue4", size = 12),
legend.position=c(.90,.85),
legend.background = element_rect(fill="lightsalmon",
colour = "tomato3", size = 1.25),
legend.title = element_text(colour="navy", face="bold"),
legend.text = element_text( colour="midnightblue", face="bold"),
strip.background = element_rect(fill="olivedrab1",
colour = "darkorchid3", size = 2,
linetype = "solid"),
strip.text = element_text(colour="coral4", size=12, angle=0,
face="bold")) +
scale_fill_discrete(name = "Dose", labels = c("A", "B", "C")) +
xlim(0,35) +
ylim(0,0.2) +
ggtitle(m$supp)
})
do.call(grid.arrange, list(grobs = out, ncol = 2))
Some things to note.
I moved the color argument outside of the aes() call and this removed the extra legend.
I manually set the x and y limits for a consistent look.
I needed to add a title.
To get the plots side by side I had to add a second argument to do.call(). When supplying more than one argument it needs to be in a list.
I hope this helps.

Add legend to ggplot object (why two legends?)

I created a ggplot2 object:
a <- replicate(8,rnorm(100))
colnames(a) <- letters[1:8]
b < -melt(a,id.vars=1:1)
colnames(b) <- c("c","variable","value")
ggplot(b,aes(x = c,y = value, colour = variable, linetype = variable)) +
geom_line()+
geom_point(aes(shape = factor(variable)), size = 1.7) +
scale_x_continuous(limits = c(-1, 1),
breaks = seq(-1, 1, 0.1),
expand=c(0.01, 0.01)) +
scale_y_continuous(limits = c(-1, 1),
breaks = seq(-1, 1, 0.1),
expand = c(0.01, 0.01))+
theme_bw(base_size = 12, base_family = "Helvetica") +
theme(axis.text=element_text(size = 10),
axis.title=element_text(size = 10),
text = element_text(size = 10),
axis.line = element_line(size = 0.25),
axis.ticks=element_line(size = 0.25),
panel.grid.major = element_blank(),
#panel.grid.minor = element_blank(),
panel.border = element_rect(colour = "black", fill = NA, size = 0.5),
panel.background = element_blank(),
legend.position = "top" ,
legend.direction = "vertical",
legend.title = element_blank(),
legend.text = element_text(size = 13),
legend.background = element_blank(),
legend.key = element_blank()) +
labs(x = '', y = '', title = "") +
theme(plot.title = element_text(size=10)) +
theme(strip.text.x = element_text(size = 8,color="black"),
strip.background = element_blank()) +
theme(strip.text.x = element_text(size = 8, colour = "black"))
My problem is the following:
when I create the legend, there is a separate legend for the colors and a separate one for the points.
How can I create a single legend for each of the 8 variables?
Let me minimise your code and focus on the legend issue. This is what you have now.
ggplot(b,aes(x = c, y = value, colour = variable, linetype = variable)) +
geom_line() +
geom_point(aes(shape = factor(variable)),size=1.7)
Your data frame, b has variable as factor. You use this in two ways here; variable and factor(variable). You can simply use variable for shape in geom_point; make all variable identical.
ggplot(b,aes(x = c, y = value, colour = variable, linetype = variable)) +
geom_line()+
geom_point(aes(shape = variable),size = 1.7)
I saw some warning messages related to colours and other things. You may want to take care of them. But, for legend, this is one way to go.
Take from the ideas on this page: http://www.cookbook-r.com/Graphs/Legends_(ggplot2)/#modifying-the-text-of-legend-titles-and-labels
I edited your code to make the data visible (you had problems with your x-axis limits. Note the final three lines. These commands tell ggplot to create only one legend.
a<-replicate(6,rnorm(100))
colnames(a)<-letters[1:6]
b<-melt(a,id.vars=1:1)
colnames(b)<-c("c","variable","value")
ggplot(b,aes(x=c,y=value,colour=variable,linetype=variable)) +
geom_line() + geom_point(aes(shape=factor(variable)),size=1.7)+
scale_x_continuous(limits=c(0,100))+
scale_y_continuous(limits=c(-2,2),breaks=seq(-2,2,0.1),expand=c(0.01,0.01))+
theme_bw(base_size=12, base_family="Helvetica") +
theme(axis.text=element_text(size=10),
axis.title=element_text(size=10),
text = element_text(size=10),
axis.line = element_line(size=0.25),
axis.ticks=element_line(size=0.25),
panel.grid.major = element_blank(),
#panel.grid.minor = element_blank(),
panel.border = element_rect(colour="black",fill=NA,size=0.5),
panel.background = element_blank(),
legend.position="top" ,
legend.direction="vertical",
legend.title=element_blank(),
legend.text=element_text(size=13),
legend.background=element_blank(),
legend.key=element_blank())+
labs(x='', y='',title="")+
theme(plot.title=element_text(size=10))+
theme(strip.text.x = element_text(size = 8,color="black"),strip.background=element_blank())+
theme(strip.text.x = element_text(size = 8,color="black"))+
scale_colour_discrete(name ="Factor")+
scale_linetype_discrete(name ="Factor") +
scale_shape_discrete(name ="Factor")

Resources