ggplot2: x-axis on top plots with facet_wrap [duplicate] - r

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

Related

How can I keep my facet_wrap() plots from being squished

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

Unable to change color of line and scatter plot R ggplot

I am relatively new to ggplot plot so I think some of the intricacies are lost on me. I have plotted multiple months of data where the data is binned by the hour. Each line is meant to be colored by month where the x-axis is the hour of the day. I am having trouble changing the color of the lines and moved things around in ggplot to try to get it to work but the color of all lines remain black"
Here is an example of some of the data I am plotting: Example data
Here is my code:
p <- ggplot(mtozoneavgk_month, aes(hour, Avgk, group = factor(Date) )) +
geom_point(size = 4) +
geom_line(size = 1)+
scale_color_manual(values = c("#DC143C", "#B22222", "#000080", "#00008B",
"#0000CD", "#0000FF", "#66B2FF", "#FF6347", "#FF0000", "#B22222"),
name = "Month", labels = c("Sept-2019", "Oct-2019", "Nov-2019", "Dec-2019",
"Jan-2020", "Feb-2020", "Mar-2020", "April-2020", "May-2020", "Jun-2020"),
expand = c(0, 0))+
ylab("rate constant (k)")+
scale_y_continuous(label=scientific_10)+
#scale_y_continuous(labels = fancy_scientific)+
theme(axis.ticks.length = unit(0.2, "cm"),
axis.ticks = element_line(size = 2),
axis.text=element_text(size=12, face = 'bold'),
axis.title=element_text(size=14,face="bold"),
axis.text.x = element_text(color = "black", face = "bold", size = 14),
axis.text.y = element_text(color = "black", size = 14),
legend.title=element_text(size=14, face = "bold"),
legend.text = element_text(size = 14, face = "bold"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=3))
p + scale_x_continuous(breaks = c(0,2,4,6,8,10,12,14,16,18,20,22,24),
label = c(0,2,4,6,8,10,12,14,16,18,20,22,24),
expand = c(0, 0))
Any help would be appreciated!
If we simplify your code as follows (letting ggplot2 to take care of colors and labels):
p <- ggplot(mtozoneavgk_month, aes(hour, Avgk, group = factor(Date), color = factor(Date))) +
geom_point(size = 4) +
geom_line(size = 1)+
ylab("rate constant (k)")+
theme(axis.ticks.length = unit(0.2, "cm"),
axis.ticks = element_line(size = 2),
axis.text=element_text(size=12, face = 'bold'),
axis.title=element_text(size=14,face="bold"),
axis.text.x = element_text(color = "black", face = "bold", size = 14),
axis.text.y = element_text(color = "black", size = 14),
legend.title=element_text(size=14, face = "bold"),
legend.text = element_text(size = 14, face = "bold"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=3))
We obtain the following plot:
If you also want to control colors I would suggest to use named vectors:
pcolor <- c("#DC143C", "#B22222", "#000080", "#00008B",
"#0000CD", "#0000FF", "#66B2FF", "#FF6347", "#FF0000")
names(pcolor) <- unique(mtozoneavgk_month$Date)
plabel <- c("Sept-2019", "Oct-2019", "Nov-2019",
"Jan-2020", "Feb-2020", "Mar-2020", "April-2020", "May-2020", "Jun-2020")
names(plabel) <- unique(mtozoneavgk_month$Date)
p <- ggplot(mtozoneavgk_month, aes(hour, Avgk, group = factor(Date), color = factor(Date))) +
geom_point(size = 4) +
geom_line(size = 1)+
scale_color_manual(values = pcolor,
name = "Month",
labels = plabel,
expand = c(0, 0))+
ylab("rate constant (k)")+
theme(axis.ticks.length = unit(0.2, "cm"),
axis.ticks = element_line(size = 2),
axis.text=element_text(size=12, face = 'bold'),
axis.title=element_text(size=14,face="bold"),
axis.text.x = element_text(color = "black", face = "bold", size = 14),
axis.text.y = element_text(color = "black", size = 14),
legend.title=element_text(size=14, face = "bold"),
legend.text = element_text(size = 14, face = "bold"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=3))
Which results in:
Remark: I do not know if it was because of the sample you gave us but December 2019 is missing so tweaked a little bit your code. Be aware of it when you make your own

How can I resize the plot in order to be used in R Markdown?

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

Adjusting white space between titles and the edge of the plot

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

Aligning two ggplots with grid.arrange

I would like to have two ggplots aligned and the same x axis length. Somehow it does not work. Here is my code:
#5cm_Four Treatments different color
d1<-ggplot(MyDataMoistWinkler[550:10000,], aes(x=betterDate)) +
geom_line(aes(y=VerticalTillHigh5cm, color="Vertical Till High Disturbance 5cm"))+
geom_line(aes(y=VerticalTillLow5cm, color="Vertical Till Low Disturbance 5cm"))+
geom_line(aes(y=StripST5cm, color="Strip Till in row"))+
geom_line(aes(y=StripNT5cm, color="Strip Till between row"))+
geom_line(aes(y=Disc5cm, color="Double Disc"))+
xlab("Date")+
ylab("Volumetric Water Content [m3/m3]")+
scale_y_continuous(limits = c(0, NA))+
theme(text = element_text(size = 11, colour = "black"))+
theme(legend.title=element_blank())+
#theme(panel.background = element_blank(), panel.grid = element_line( size=.5, colour="black" ) )+
theme(axis.text = element_text(size = 15, colour = "grey"))+# changes axis labels
theme(axis.title = element_text(size = 15))+ # change axis titles
theme(text = element_text(size = 15, colour = "black"))+ # this will change all text size # (except geom_text)
theme(strip.text.x = element_text(size = 15, colour = "black", angle =NULL))+
ggtitle("Moisture in 5cm, in Winkler MB")
d2<-ggplot(MyDataMoistWinkler[550:10000,], aes(x=betterDate, y=AccumulatedRainfall)) +
geom_line(aes(y=AccumulatedRainfall, color="Accumulated Rainfall"))+
xlab("Date ")+
ylab("Accumulated Rainfall [mm]")+
scale_y_continuous(limits = c(0, NA))+
theme(text = element_text(size = 11, colour = "black"))+
theme(legend.title=element_blank())+
#theme(panel.background = element_blank(), panel.grid = element_line( size=.5, colour="black" ) )+
theme(axis.text = element_text(size = 15, colour = "grey"))+# changes axis labels
theme(axis.title = element_text(size = 15))+ # change axis titles
theme(text = element_text(size = 15, colour = "black"))+ # this will change all text size # (except geom_text)
theme(strip.text.x = element_text(size = 15, colour = "black", angle =NULL))+
ggtitle("Precipitation in mm, in Winkler MB")
1st Option: If you want to arrange them next to each other
require(gridExtra)
grid.arrange(d1, d2, ncol=1)
library(grid)
grid.draw(rbind(ggplotGrob(d1), ggplotGrob(d2)))
might work

Resources