This is my first time posting a question here so I'm nervous, but this has been bugging me forever: when using facet_wrap() in ggplot, is there a way to keep your plots from getting all squished when you have a lot of them? (see example below)
There is too much range in the data so I have to free the scales, otherwise I would set the y-axis breaks and probably have fewer labels to that from crowding. But the biggest thing is that the plots are so squished they become hard to see. When I put space in between the plots it just squishes them more as though it is working with a limited amount of space. I also tried adjusting font sizes, getting rid of the title, and even the legend. Removing the legend makes more room but obviously, that's sort of an important thing to have in there!
Is there a way to fix this or is this just something that goes with trying to facet a lot of plots?
Here is my code:
lu_acres_plot <- ggplot(data = land_use_acres, aes(x = land_use, y = acres)) +
geom_col(aes(fill = land_use)) +
facet_wrap(~i_desclu, scales = "free_y") +
labs(title = "Land Use Change",
y = "Change in Acreage") +
theme_minimal() +
geom_hline(aes(yintercept=0)) +
scale_fill_manual(values = lu_pallette) +
theme(
axis.title.x = element_blank(),
axis.text.x = element_blank(),
text = element_text(family = "Times"),
axis.text = element_text(size = 12),
axis.title = element_text(size = 14, face = "bold"),
plot.title = element_text(size = 16, face = "bold"),
legend.position = "bottom",
legend.title = element_text(size = 14, face = "bold"),
legend.title.align = 0.5,
strip.background = element_rect(color = "grey40", fill = "grey30"),
strip.text = element_text(size = 9, color = "white", face = "bold"),
panel.border = element_rect(color = "grey40", fill = NA)
) +
guides(fill = guide_legend(title = "Land Use",
title.position = "top",
nrow = 2))
lu_acres_plot
Related
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"))
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))))
I've created the attached plot using the mentioned code, however, the height of the whole plot looks a bit large and the blank area between the plot and the legend does not seem suitable.
I want to resize the plot in order to use it later in R Markdown presentation. I've seen some posts about resizing the plots but they have all been about resizing the plot for saving purposes. I want to get a plot that looks similar to the one created by Urban Institute Style Guide.
ggplot(top_five, aes(x= Year, y = Production, fill = Country)) +
geom_bar(stat = "identity", position = "dodge") +
theme_minimal() +
scale_fill_manual(values = c("#375E97", "#FB6542", "#FFBB00", "#3F681C", "#98DBC6")) +
scale_y_continuous(limits = c(0,30000), breaks = c(0, 2000, 4000, 6000, 8000, 10000, 12000, 14000), labels = scales::comma) +
theme(axis.title.x = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
legend.title = element_blank(),
axis.text.y = element_text(size = 12, colour = "black"),
axis.text.x = element_text(size = 12, colour = "black"),
axis.title.y = element_blank(),
legend.position = "top",
legend.key.height = unit(0.8, "lines"),
legend.key.width = unit(0.8, "lines"),
legend.text = element_text(size = 12, colour = "black", face = "bold")) +
labs(title= "Top Five Oil-Producing Countries (2012-2017)", subtitle = "Thousand Barrels Daily",
caption = "Source: BP Statistical Review") +
theme(title = element_text(size = 12)) +
theme(legend.position=c(0,1),
legend.direction="horizontal",
legend.justification=c(0, 1))
My Plot
Urban Institute's Plot
This question already has answers here:
Add x and y axis to all facet_wrap
(6 answers)
ggplot add ticks to each plot in a facet_wrap
(1 answer)
Closed 4 years ago.
I'm making a multi-plot figure for publishing with ggplot2 using facet_wrap(). The x-axis labels only show on the bottom plots, which is perfectly fine, but there's not even an axis on the top plots. This reduces the readability imo and I'm pretty sure most publishers will not like this.
How do I get an x-axis there without labels?
My figure (with some quick example code):
The code:
library(ggplot2)
# theme settings (just to get the exact same example plot)
theme_set(theme_bw())
font <- "serif"
theme_update(axis.line = element_line(colour = "black"),
axis.title.x = element_text(size = 16, colour = 'black', family = font),
axis.title.y = element_text(size = 16, colour = 'black', family = font, angle = 90),
axis.text.x = element_text(size = 14, colour = 'black', family = font),
axis.text.y = element_text(size = 14, colour = 'black', family = font),
legend.text = element_text(size = 12, colour = 'black', family = font),
legend.title = element_blank(),
legend.position = c(0.95,0.9),
legend.box = "vertical",
strip.text.x = element_text(size = 14, colour = 'black', family = font),
strip.text.y = element_text(size = 14, colour = 'black', family = font, angle = -90),
strip.text = element_text(hjust = 1),
strip.background = element_blank(),
panel.background = element_rect(fill = "white"),
panel.grid.minor = element_blank(),
panel.grid.major = element_blank(),
panel.border = element_blank(),
plot.title = element_text(size = 15, face = "bold", family = font, vjust = 1, hjust = 0.5))
# example data
count <- c(10,5,6,9,2,4,8,3,1,12,5,3)
stage <- rep(c("AD","NY"),6)
treat <- rep(c("A","B","C","D"),3)
days <- c(0,7,14,21,28,35,42,49,56,63,70,77)
df1 <- data.frame(count,stage,treat,days)
# example plot
ggplot(data=df1, aes(days,count,fill=stage)) +
facet_wrap(~treat) +
geom_col(position = "dodge",color="black") +
#expand = put 0 on intersection
scale_y_continuous(expand = c(0,0), limits = c(0,15)) +
scale_x_continuous(expand = c(0,0), limits = c(0,80)) +
ylab("# per plant") +
xlab("Days after release")
I want to create space between the titles (the axis title and the plot title) and the edge of the plot. I tried vjust on axis.title and plot.title with no luck. Nothing really changed in the plot when I tried various values for vjust. I also tried plot.margin, but nothing seemed to happen with it either.
Data:
data = data.frame(Category = c(0,1), value = c(40000, 120000))
data$Category = factor(data$Category, levels = c(0,1), labels = c("One-time", "Repeat"))
Plot:
p = ggplot(data, aes(Category, Value)) +
geom_bar(stat = "identity", width = 0.5, position=position_dodge(width=0.9)) +
geom_text(aes(label=Value), position=position_dodge(width=0.9), family = "mono", vjust=-0.5) +
ggtitle("Title") +
scale_y_continuous(expand = c(0,0), limits = c(0,150000)) +
scale_x_discrete(expand = c(0,0), limits = c("One-time", "Repeat")) +
xlab("X axis Title") +
ylab("Y axis Title")
Theme:
p + theme(
panel.grid.major = element_line(linetype = "blank"),
panel.grid.minor = element_line(linetype = "blank"),
axis.title = element_text(family = "sans", size = 15),
axis.text = element_text(family = "mono", size = 12),
plot.title = element_text(family = "sans", size = 18),
panel.background = element_rect(fill = NA)
)
You want to do this using margin
p + theme(
panel.grid.major = element_line(linetype = "blank"),
panel.grid.minor = element_line(linetype = "blank"),
axis.title.x = element_text(family = "sans", size = 15, margin=margin(30,0,0,0)),
axis.title.y = element_text(family = "sans", size = 15, margin=margin(0,30,0,0)),
axis.text = element_text(family = "mono", size = 12),
plot.title = element_text(family = "sans", size = 18, margin=margin(0,0,30,0)),
panel.background = element_rect(fill = NA)
)
Note that margin requires a four inputs and they specify the space in the order top,right,bottom,left. Also note I'm using the developmental ggplot2 version so my title default is left justified. 'hjust' and 'vjust' worked in older versions of ggplot2.
You can also give a "-ve" value to margin argument to pull the title closer to the plot.
gg_1 +
theme(plot.title = element_text(size = 12,
hjust = 0.5,
family = fam_3,
face = "bold",
margin = margin(0,0,-10,0))