How to change x-axis labels when using facet-grid? - r

I would like to rename the x-axis labels on this plot using the labels mentioned in "mylabels", but it does not work (it only uses the first label for all the ticks). I guess the problem comes from the 'facet_grid" function as I can rename labels properly when I do not use this function. Any idea how to solve this issue?
mylabels <- c("MRA2x3","MRA2x4","MRB2x3","MRB2x4","whole milk")
ggplot(file, aes(x=as.factor(diet),y=ADG, fill= as.factor(farm))) +
geom_boxplot(width=1,alpha=0.5) +
scale_fill_viridis(discrete = TRUE, alpha=0.6,guide = guide_legend(title = "Farm")) +
labs(y="Average daily gain", x = "Diet") +
scale_y_continuous(breaks=seq(0, max(file$ADG), by=0.2)) +
scale_x_discrete(labels = mylabels) +
theme(text = element_text(size = 18),
panel.grid.minor.x = element_blank(),
panel.grid.major.x = element_blank(),
plot.title = element_text(hjust = 0.5),
strip.text.x = element_blank()) +
facet_grid(~ diet, scales = "free_x")

You can add a vector of new names to the facet_grid() statement in stead of the scale_x_discrete (delete that):
facet_grid(~ diet,
scales = "free_x",
labeller = labeller(diet = mylabels))
I remember the vector in labeller has to be a named vector : c("old name1" = "new_name1", "old_name2" = "new_name2", etc) so it maps the old names to the new names.

Related

Adjust the length of facet_wrap so that each facet reflect number of samples?

I have a plot that looks like below. However as you can see facet 4 only has 1 sample but the vertical size is equal to facet 6 which has 4 samples; this makes the plot look really weird since it becomes really thick. I can't use face_grid (facet_grid( cyl~. , scales = "free", space="free" )) at the moment because because then the labels goes to the side but what I really want is to put the labels on top like with facet_wrap as illustrated below. Is there anyway around this? thanks.
temp = head ( mtcars )
temp$car = row.names ( temp )
ggplot( temp , aes(x=car , y=hp, fill=vs )) +
geom_bar(stat = 'identity', position = 'stack') +
theme_bw() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"))+
coord_flip() +
scale_y_continuous(expand = expansion(mult = c(0, .1))) +
facet_wrap( ~cyl , ncol=1, scales = "free" )
Not sure if you want this. If so, you can use facet_col from the package ggforce, which allows you to have facet in a single column and also drop the facet ratio (space argument).
library(tidyverse)
library(ggforce)
temp = head (mtcars)
temp$car = row.names(temp)
ggplot(temp, aes(x = car , y = hp, fill = vs)) +
geom_bar(stat = 'identity', position = 'stack') +
theme_bw() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"))+
coord_flip() +
scale_y_continuous(expand = expansion(mult = c(0, .1))) +
ggforce::facet_col(cyl ~ ., scales = "free", space = "free")

How to create a plot by two subgroups using interaction() in ggplot (combination of several plots)

I am trying to create plots by two subgroups, just like in the picture below (ggplot2 multiple sub groups of a bar chart). However, I would like to do that for a combination of plots.
When I tried to do that, instead of having the categories clearly separated (like in the example with Irrigated/Dry and Variety1/Variety 2), my variables "growth" and "year" are being collapsed together.
I am having trouble incorporating into my code this tiny modification. I would like for my variable year to be just like "Irrigated/Dry", and the variable growth as "Variety1/Variety2" Right now, this is how the plot looks like:
Here is my code:
library(ggplot2)
#Creates the data
d <- expand.grid(c(.3, .8), c(.3, 0.8), c(0, 0.5), c(1, 2), c("Oregon"," California"), c("2010","2011"))
colnames(d) <- c("gamma1", "gamma2", "growth", "store", "state", "year")
d$sells <- rnorm(64)
d$gamma_plot <- as.factor(paste(d$gamma1, d$gamma2, sep = "_"))
d$store <- as.factor(d$store)
d$growth <- factor(d$growth)
d$gamma_plot = factor(d$gamma_plot,
labels=c(expression(paste(gamma[1],"=", gamma[2]," = 0.3")),
expression(paste(gamma[1], " = 0.3 ", gamma[2], " = 0.8")),
expression(paste(gamma[1], " = 0.8 ", gamma[2], " = 0.3")),
expression(paste(gamma[1],"=", gamma[2]," = 0.8"))
)
)
d$store = factor(d$store,
labels = c(expression(paste(store[1], " = 1")),
expression(paste(store[2], " = 2"))
)
)
#Creates the plot
p = ggplot(data=d, aes(x=interaction(year, growth), y=sells, fill=state)) +
geom_col(position="dodge") +
theme_bw() +
facet_grid(store ~ gamma_plot, labeller = label_parsed) +
theme(legend.title = element_blank(), legend.position="bottom",
panel.grid.major = element_blank(),
legend.key.size = unit(0.10, "cm"),
legend.key.width = unit(0.15,"cm")) +
guides(fill = guide_legend(nrow = 1)) +
labs(x=expression(growth), y = "Sells")
EDITED:
The two solutions given to my question were great and I really appreciate it.
I have decided to alter the plot a little and have an interaction between gamma_plot and growth instead. I could not make R understand that gamma_plot was an expression. Any ideas?
#Creates the plot using teunbrand's code :)
ggplot(data=d, aes(x=interaction(growth, gamma_plot, sep = "&"), y=sells, fill=year)) +
geom_col(position="dodge") +
theme_bw() +
facet_grid(store ~ state, labeller = label_parsed) +
theme(legend.title = element_blank(), legend.position="bottom",
panel.grid.major = element_blank(),
legend.key.size = unit(0.10, "cm"),
legend.key.width = unit(0.15,"cm"),
axis.text.x = element_text(margin = margin(2,2,2,2))) +
scale_x_discrete(guide = guide_axis_nested(delim = "&")) +
guides(fill = guide_legend(nrow = 1)) +
labs(x=expression(growth), y = "Sells")
How about this option:
library(ggplot2)
ggplot(data=d, aes(x = interaction(year, growth), y=sells, fill = state)) +
geom_col(position="dodge") +
scale_x_discrete(labels = unique(interaction(d$year, factor(d$growth), sep = "\n")))+
theme_bw() +
facet_grid(store ~ gamma_plot, labeller = label_parsed) +
theme(legend.title = element_blank(), legend.position="bottom",
panel.grid.major = element_blank(),
legend.key.size = unit(0.10, "cm"),
legend.key.width = unit(0.15,"cm")) +
guides(fill = guide_legend(nrow = 1)) +
labs(x = expression(Year~growth), y = "Sells")
Created on 2020-07-10 by the reprex package (v0.3.0)
As far as I'm aware there is no axis hierarchy in ggplot2. Normally, one would use facets to seperate the year from growth, but it seems like you're already using the facets to seperate out something else.
Example how one would use facets in this case:
ggplot(data=d, aes(x=interaction(growth), y=sells, fill=state)) +
geom_col(position="dodge") +
theme_bw() +
facet_grid(store ~ gamma_plot + year, labeller = label_parsed, switch = "x") +
theme(legend.title = element_blank(), legend.position="bottom",
panel.grid.major = element_blank(),
strip.placement = "outside",
legend.key.size = unit(0.10, "cm"),
legend.key.width = unit(0.15,"cm")) +
guides(fill = guide_legend(nrow = 1)) +
labs(x=expression(growth), y = "Sells")
Seeing as the above is not really a good option, I recommend looking for extention packages that offer what you seek. If you'll allow me to be so bold, there is a function in a github package I wrote that formats axes in a nested fashion. Example below:
library(ggh4x)
ggplot(data=d, aes(x=interaction(growth, year, sep = "&"), y=sells, fill=state)) +
geom_col(position="dodge") +
theme_bw() +
facet_grid(store ~ gamma_plot, labeller = label_parsed) +
theme(legend.title = element_blank(), legend.position="bottom",
panel.grid.major = element_blank(),
legend.key.size = unit(0.10, "cm"),
legend.key.width = unit(0.15,"cm"),
axis.text.x = element_text(margin = margin(2,2,2,2))) +
scale_x_discrete(guide = guide_axis_nested(delim = "&")) +
guides(fill = guide_legend(nrow = 1)) +
labs(x=expression(growth), y = "Sells")
Edit:
With regards to the follow up question about the spacing between years; I can't think of an elegant solution but the following would get the job done. It converts the discrete axis to a continuous one.
# Precalculate interaction
d$interaction <- interaction(d$growth, d$year, sep = "&")
nudge <- 1 # How much you want to nudge
# Use ifelse to nudge position and use factor as integer
ggplot(data=d, aes(x=ifelse(as.numeric(interaction) > 2,
as.numeric(interaction) + nudge,
as.numeric(interaction)),
y=sells, fill=state)) +
geom_col(position="dodge") +
theme_bw() +
facet_grid(store ~ gamma_plot, labeller = label_parsed) +
theme(legend.title = element_blank(), legend.position="bottom",
panel.grid.major = element_blank(),
legend.key.size = unit(0.10, "cm"),
legend.key.width = unit(0.15,"cm"),
axis.text.x = element_text(margin = margin(2,2,2,2))) +
# Using a continuous axis here
scale_x_continuous(breaks = c(1,2,3 + nudge, 4 + nudge),
labels = levels(d$interaction),
guide = guide_axis_nested(delim = "&")) +
guides(fill = guide_legend(nrow = 1)) +
labs(x=expression(growth), y = "Sells")

How to add superscripts to facet labels

I am trying to plot three variables and want the units in the axes labels but can't find a way to label them properly in facets with the superscripts.
I've tried as_labeller, label_bquote, expression/paste and changing the original data.
p <- ggplot(data = LST, aes(x = Date, y = Measurements)) +
geom_point((aes(color = parameter)))
p + facet_grid(parameter ~ ., scales = "free_y",
switch="y",labeller=as_labeller(DO~(mg~L^{-1}), Temperature~(°C), Light~
(µmol~m^{-2}~s^{-1}))) +
theme_bw()+ theme(strip.background = element_blank(),
legend.title = element_blank(), strip.placement = "outside",
panel.grid.minor = element_blank()) +
scale_x_datetime()+ ylab(NULL) +ggtitle("Spring 2018") +
scale_colour_manual(values=c('royalblue1', 'springgreen4', 'darkblue')) +
theme(legend.position="none")+
theme(strip.text=element_text(size=10))
Everything I try either labels all facets the same or doesn't place the superscripts. I'm pretty new at ggplot2 so am unsure if what I'm trying will help.
You want labeller = label_parsed. Here's a simple example
mt = mtcars
mt$facets = factor(mt$cyl, labels = c(
"DO~(mg~L^{-1})",
"Temperature~('°C')",
"Light~(µmol~m^{-2}~s^{-1})"))
ggplot(mt, aes(mpg,cyl)) +
geom_point() +
facet_grid(~facets, labeller = label_parsed)

Labelling and theme of ggalluvial plot in R

For the past hours I have tried to understand the whole design/theme/labelling concept around ggalluvial, but I failed.
Within minutes I was able to produce the kind of graph I want (thanks to the package ggalluvial), but I can't figure how to produce the correct labelling/theme I'd like to have.
This is where I am currently:
This is where I was initially:
To get you to understand where I am, here's a reproducible example
I used the following code:
library(ggalluvial)
ds <- as.data.frame(Titanic)
ggplot(ds,
aes(weight = Freq, axis1 = Sex, axis2 = Class)) +
geom_alluvium(aes(fill = Sex), width = 1/12) +
geom_stratum(width = 1/4, fill = "black", color = "grey") +
scale_x_continuous(breaks = 1:2, labels = c("Sex", "Class")) +
scale_fill_manual(name = "", values=c("#A0A0A0", "#494949")) +
ggtitle("Titanic Survival") +
theme_bw() +
geom_text(stat = "stratum", color="white",label.strata = TRUE,
angle=c(90,90,0,0,0,0) , size=6,
nudge_y=c(1,2,3,4,5,0)) +
theme(legend.position = "bottom",
title = element_text(size = 20),
legend.text = element_text(size = 20),
axis.text.y = element_blank(),
axis.text.x = element_text(size=20))
What I would like to change:
turn labels on the left vertically
done
make labels on the right not overlap (not visible with the Titanic data)
I tried nudging. But it may be more useful to place these legends outside the graph, maybe like on an axis?
remove y-axis labels
done
Understand with what command I can change each of the text elements size (title, legend, labels, axis labels)
dome
I am very happy for any help on this. Thank you.
You can try:
ggplot(ds,
aes(weight = Freq, axis1 = Sex, axis2 = Class)) +
geom_alluvium(aes(fill = Sex), width = 1/12) +
geom_stratum(width = 1/16, fill = "black", color = "grey") +
scale_x_continuous(breaks = 1:2, labels = c("Sex", "Class")) +
scale_fill_manual(name = "", values=c("#A0A0A0", "#494949")) +
ggtitle("Titanic Survival") +
theme_bw() +
geom_text(stat = "stratum", color="red",label.strata = TRUE, angle=c(0,0,45,45,45,45),size=5) +
theme(legend.position = "bottom",
title = element_text(size = 20),
legend.text = element_text(size = 20),
axis.text.y = element_blank(),
axis.text.x = element_text(size=20))
add a vector with the same length of labels like angle=c(0,0,45,45,45,45)
add axis.text.y = element_blank() in theme()
pending
Sizes via theme
via theme() such as x-axis labels
text in plot via size=5 in geom_text()

Overlay different datasets in same facetted plot in ggplot2

I need to gather two facet columns into one column with ggplot2.
In the following example, I need to overlay the content of the two columns DEG and RAN into one, while giving different colours to DEG and RAN data (small points and smooth line) and provide the corresponding legend (so I can distinguish them as they are overlayed).
I feel my code is not too, too far from what I need, but the relative complexity of the dataset blocks me. How to go about achieving this in ggplot2?
Here's my code so far:
require(reshape2)
library(ggplot2)
library(RColorBrewer)
fileName = paste("./4.csv", sep = "") # csv file available here: https://www.dropbox.com/s/bm9hd0t5ak74k89/4.csv?dl=0
mydata = read.csv(fileName,sep=",", header=TRUE)
dataM = melt(mydata,c("id"))
dataM = cbind(dataM,colsplit(dataM$variable,pattern = "_",names = c("NM", "ORD", "CAT")))
dataM$variable <- NULL
dataM <- dcast(dataM, ... ~ CAT, value.var = "value")
my_palette <- colorRampPalette(rev(brewer.pal(11, "Spectral")))
ggplot(dataM, aes(x=NR ,y= ASPL)) +
geom_point(size = .4,alpha = .5) +
stat_smooth(se = FALSE, size = .5) +
theme_bw() +
theme(plot.background = element_blank(),
axis.line = element_blank(),
legend.key = element_blank(),
legend.title = element_blank()) +
scale_y_continuous("ASPL", expand=c(0,0), limits = c(1, 7)) +
scale_x_continuous("NR", expand=c(0,0), limits = c(0, 100)) +
theme(legend.position="bottom") +
theme(axis.title.x = element_text(vjust=-0.3, face="bold", size=12)) +
theme(axis.title.y = element_text(vjust=1.5, face="bold", size=12)) +
ggtitle("Title") + theme(plot.title = element_text(lineheight=.8, face="bold")) +
theme(title = element_text(vjust=2)) +
facet_grid(NM ~ ORD)
Here's what it gives me right now:
Extra question: how come DEG/SF doesn't show a smooth line?
You can use the group aesthetic to define that data points with the same value of ORD belong together. You can also map aesthetics shape and color to this variable. You can also use . to specify that the facets are not split along a specific dimension.
I have made the changes to your code below after transforming NR and ASPL to numeric variables:
dataM$NR <- as.integer(dataM$NR)
dataM$ASPL <- as.numeric(dataM$ASPL)
ggplot(dataM, aes(x=NR ,y= ASPL, group=ORD, color=ORD)) +
geom_point(size = .7,alpha = .5, aes(shape=ORD)) + ## increased size
stat_smooth(se = FALSE, size = .5) +
theme_bw() +
theme(plot.background = element_blank(),
axis.line = element_blank(),
legend.key = element_blank(),
legend.title = element_blank()) +
scale_y_continuous("ASPL", expand=c(0,0), limits = c(1, 7)) +
scale_x_continuous("NR", expand=c(0,0), limits = c(0, 100)) +
theme(legend.position="bottom") +
theme(axis.title.x = element_text(vjust=-0.3, face="bold", size=12)) +
theme(axis.title.y = element_text(vjust=1.5, face="bold", size=12)) +
ggtitle("Title") + theme(plot.title = element_text(lineheight=.8, face="bold")) +
theme(title = element_text(vjust=2)) +
facet_grid(NM ~.)

Resources