combine barplot and grid.table - r

# I am trying to combine a horizontal beside barplot with the table
# with the values in it.
# E.g. original table, including sample_ids
df = data.frame(
sample_id=c("s01","s02","s03","s04","s05","s06","s07","s08","s09","s10"),
one=runif(10,0,10),
two=runif(10,0,10),
three=runif(10,0,10),
four=runif(10,0,10)
)
# I created a mydata that I then do barplot as matrix
mydata = data.frame(
one=df$one,
two=df$two,
three=df$three,
four=df$four
)
# Plotted, using rainbow colouring, with a legend in the top right
barplot(as.matrix(mydata),horiz=TRUE,beside=TRUE,col=rainbow(length(df$sample_id)), legend=paste(df$sample_id), args.legend = list(x = "topright", bty = "n"),xlim=c(0,20))
# Now I would like the grid.table to be on the bottom right, ideally with the same order and colouring as the legend
library(gridExtra)
grid.table(df)
# Any ideas?
# EDIT: also tried addtable2plot from plotrix, with no much success
bp = barplot(as.matrix(mydata),horiz=TRUE,beside=TRUE,col=rainbow(length(df$sample_id)), legend=paste(df$sample_id), args.legend = list(x = "topright", bty = "n"),xlim=c(0,20))
library(plotrix)
addtable2plot(bp, y=0, df,cex=0.3)
The other option would be to turn the barplot into a ggplot geom_bar, but I struggled to do it for more than 2 columns.

Here's one way to do it using addtable2plot of plotrix package. It allows you to use the legend positions such as "bottomright"
df = data.frame(
sample_id=c("s01","s02","s03","s04","s05","s06","s07","s08","s09","s10"),
one=runif(10,0,10),
two=runif(10,0,10),
three=runif(10,0,10),
four=runif(10,0,10)
)
mydata = data.frame(
one=df$one,
two=df$two,
three=df$three,
four=df$four
)
library(plotrix)
dev.off()
windows(width = 8, height = 6)
df$one = round(df$one,2)
df$two = round(df$two,2)
df$three = round(df$three,2)
df$four = round(df$four,2)
barplot(as.matrix(mydata),horiz=TRUE,beside=TRUE,col=rainbow(length(df$sample_id)),
legend=paste(df$sample_id),
args.legend = list(x = "topright", bty = "n", cex = 1),
xlim=c(0,20))
addtable2plot("bottomright",table = df, cex = .9, bty = "o",
bg = c("white","grey"), vlines = TRUE, xpad = .25)

If you want to make the barplot in ggplot2, you need to reshape your data into long format. Based on your example data, the following code:
library(ggplot2)
library(gridExtra)
library(reshape2)
bp <- ggplot(melt(df, id.vars = 1),
aes(x = variable, y = value, fill = sample_id)) +
geom_bar(stat = 'identity', position = 'dodge') +
scale_fill_manual(values = rainbow(10)) +
labs(x = NULL, y = NULL) +
coord_flip() +
theme_minimal(base_size = 14)
gt <- tableGrob(df, rows = NULL, theme = ttheme_minimal())
grid.arrange(bp, gt, ncol = 2, widths = c(2.5,2))
which gives the following result:

Related

ggballonplot set limits for axis

To make the plots more comparable, I would like to set the limits of all fill- and symbol size axes to the same size. Is this possible? Also the legends for "size" and "fill" are swapping places in the last two plots, which I would like to prevent as well.
Thanks in advance!!!
ggballonplot chart
Some code as an example
library(ggplot2)
library(ggpubr)
plot4 <- ggballoonplot(data_matrix_comb, x = "Time", y = "Depth",
size = "mean_percentage_of_indivuals",
fill = "mean_variance", facet.by = "Stage",
ggtheme = theme_bw()) + scale_fill_viridis_c(option = "C") +
labs(title "Autumn")
library(gridExtra)
grid.arrange(plot1, plot2, plot3, plot4, ncol=2, nrow = 2)
You can use ggarrange() from ggpubr(),I would suggest a common legend since it doesn't make sense to have it 4 times.
I simulated some data since you did not provide (please do so in the future!).
Also slight variation from what you did, I placed all the data.frames inside a list, and if possible, you should try that so that you don't run the same code multiple times.. (i.e avoid copy-paste code):
library(ggplot2)
library(ggpubr)
library(dplyr)
set.seed(111)
dat = data.frame(Time=rep(c("day","night"),12),
Depth=rep(c("aphotic","euphotic"),each=2,times=6),
Stage = rep(c("adult","juvenil"),each=4),
mean_percentage_of_indivuals=100*runif(24),
mean_variance = rnbinom(24,mu=100,size=0.5))
dat_all = dat %>% group_by(Time,Depth,Stage) %>% summarize_all(mean)
dat_spring = dat[1:8,]
dat_summer = dat[9:16,]
dat_autumn = dat[17:24,]
dat_list = list("All Seasons"=dat_all,"Spring"=dat_spring,
"Summer"=dat_summer,"Autumn"=dat_autumn)
plts = lapply(names(dat_list),function(i){
p <- ggballoonplot(dat_list[[i]], x = "Time", y = "Depth",
size = "mean_percentage_of_indivuals",
fill = "mean_variance", facet.by = "Stage",
ggtheme = theme_bw()) +
scale_fill_viridis_c(option = "C") +
labs(title=i)
return(p)
})
ggarrange(plotlist =plts,ncol=2, nrow=2, common.legend = TRUE)

How to create multiple plots and save as one pdf file using ggplot2 in R? [duplicate]

For the following data set, I would like to plot for each variable and color each 10th observations differently. I can do it using the R base. I want to learn how to do it using the ggplot2?
dput(mydata)
structure(list(beta0_C1 = c(5.90722120539152, 5.89025566996191,
5.88591520258904, 5.86911167649919, 5.93772460437405, 5.92985640353594,
5.89150365752453, 5.99046628686212, 5.91548006074821, 5.91571832976612,
5.88437484241154, 5.92092513223357, 5.98978050584774, 5.91152552752889,
5.91235823292462, 5.87961960044268, 5.84048698713552, 5.85484766204026,
5.94002829943904, 5.8844367778216, 5.90201348639369, 5.91220967575205,
5.90010933186624, 5.9187781795242, 5.85506764080697, 5.90103565341373,
5.88527143992961, 5.90218851192948, 5.90118162849608, 5.93147588185271
), beta1_C1 = c(0.389473200070741, 0.386495525456602, 0.401277295631578,
0.400952009358693, 0.376727640651344, 0.380365338054745, 0.393444927288697,
0.351041363714069, 0.393194356572458, 0.393448101768608, 0.398884551136789,
0.399458966787235, 0.357436746423815, 0.393782316102096, 0.387154169967002,
0.400838223362088, 0.404272252119662, 0.407427775176583, 0.379704250022161,
0.388842664781329, 0.382202010301184, 0.401354531881688, 0.391184010553641,
0.390280828053183, 0.402135923802544, 0.384344141458216, 0.405409447440106,
0.391719398951194, 0.398025625260563, 0.361822915989445), beta2_C1 = c(-0.0214886993465096,
-0.020723519439664, -0.0224612526333316, -0.0218187226687474,
-0.0200324040063121, -0.0208421378685671, -0.0218756660346625,
-0.0182499666400075, -0.0222765863213226, -0.022242845613047,
-0.0222033291270054, -0.0231570312767931, -0.0189429585905841,
-0.0221017468740293, -0.0209327798783444, -0.022409049257, -0.021698958175968,
-0.0225601087054418, -0.020928341508875, -0.0214668830626075,
-0.0205872002686706, -0.0233768022702472, -0.021755967293395,
-0.0218442145294776, -0.0222514480818199, -0.0212195394692002,
-0.0232109717283908, -0.0214814999754984, -0.0225124468437127,
-0.0187033387452614), beta0_C2 = c(6.50537199380546, 6.43626630601952,
6.44460360859128, 6.44788878017196, 6.49678676895955, 6.48474789770674,
6.5459727637079, 6.37593806532098, 6.39492158034295, 6.44497331914909,
6.3888816168562, 6.49660574813212, 6.45922901141938, 6.40080765767324,
6.37918638201668, 6.49354321098856, 6.47057962920788, 6.55699741431025,
6.56617313133218, 6.54271932949381, 6.44608000042182, 6.45333777656105,
6.67458442747556, 6.48420983182487, 6.59919337271637, 6.46645685814734,
6.46171236062657, 6.52625058117578, 6.51177045919728, 6.49897849935538
), beta1_C2 = c(-0.370455826326915, -0.338852275811034, -0.340671118342601,
-0.339888681238265, -0.36934391822867, -0.357194169746804, -0.415966150286963,
-0.349051278947586, -0.358209379291251, -0.371785518417424, -0.349725822847608,
-0.368220986471866, -0.327425879655177, -0.336993142255552, -0.328859493371605,
-0.347764105375218, -0.329761787134926, -0.37935820670654, -0.400211161919931,
-0.408699321227288, -0.357590345066542, -0.376548827126353, -0.44672514669147,
-0.353840422053319, -0.421912098450693, -0.371491468175642, -0.354864346664247,
-0.39139246919467, -0.379006372881295, -0.372492936183765), beta2_C2 = c(0.039728365796445,
0.0368393936404604, 0.0375019672690036, 0.0375019364609944, 0.0403444583999664,
0.0378627636833333, 0.0446717245407897, 0.0377538641609231, 0.039662572899695,
0.0408055348533836, 0.0386737104573771, 0.0397794302159846, 0.0352739962796708,
0.0376756204317514, 0.0370614500426065, 0.0374731659969108, 0.035366001926832,
0.0397165124506166, 0.0414814320660011, 0.0431083057931525, 0.0388672853038453,
0.0403590048367136, 0.0461540000449275, 0.0379315295246309, 0.0440664419193363,
0.0404593732981113, 0.0387390924290065, 0.0417832766420881, 0.0409598003097311,
0.0394548129358408)), row.names = c(NA, 30L), class = "data.frame")
R base code
par(mfrow=c(3,3))
col.set=c("green","blue","purple","deeppink","darkorchid","darkmagenta","black","khaki")
loop.vector=1:ncol(mydata)
for(b in loop.vector) {
x.beta<-mydata[,b]
beta <- substr(sub("^beta", '', names(mydata)[b]),1,1)
Cn <- substr(sub("^beta", '',names(mydata)[b]),3,4)
plot(x.beta, type = "n", ylab="", xlab="",
main=bquote(beta[.(beta)]~.(Cn)),
cex.main=1)
mtext("plots of betas",line=-1.5, cex=1, outer = TRUE)
for (k in 1:3){
beta_k=mydata[((nrow(mydata)/3)*k-((nrow(mydata)/3)-1)):
((nrow(mydata)/3)*k),b]
lines(((nrow(mydata)/3)*k-((nrow(mydata)/3)-1)):
((nrow(mydata)/3)*k),beta_k,
col=col.set[k])
legend("topleft", bg="transparent",inset=0.05,legend=paste0("chain_",1:3),
col=col.set, lty=1,box.lty=0, cex=0.8)
}
}
I want the same main title for each plot and one main titile for all plots.
how can I do it using the ggplot2 package?
ggplot2 works best with a long data frame containing variables for x, y, color, etc. This makes a long data frame:
library(tidyverse)
long_data = my_data %>%
mutate(n=1:nrow(my_data), chain=paste0('Chain ', rep(1:3, each=nrow(my_data)/3))) %>%
pivot_longer(cols=c(-n, -chain)) %>%
mutate(name=str_replace(name, '(\\d)_', '[\\1]~~'))
This makes the plot.
ggplot(long_data, aes(n, value, color=chain)) +
geom_line() +
facet_wrap(~name, scales='free_y', ncol=3, dir='v',
labeller=label_parsed) +
scale_color_manual('', values=c('Chain 1'='green', 'Chain 2'='blue', 'Chain 3'='purple')) +
theme_minimal()
Quite similar to #KentJohnson's answer but adding expression labelling of your facets, centered title and using scale_color_manual function to edit color labeling:
library(ggplot2)
library(dplyr)
library(tidyr)
df %>% mutate(Group = rep(c("A","B","C"), each = 10),
Position = 1:30) %>%
pivot_longer(-c(Group,Position), names_to = "Var",values_to = "val") %>%
mutate(Var = factor(Var, levels = c("beta0_C1","beta1_C1","beta2_C1","beta0_C2","beta1_C2","beta2_C2"),
labels = c(expression(beta[0]*"C1"),
expression(beta[1]*"C1"),
expression(beta[2]*"C1"),
expression(beta[0]*"C2"),
expression(beta[1]*"C2"),
expression(beta[2]*"C2")))) %>%
ggplot(aes(x = Position, y = val, color = Group))+
geom_line()+
facet_wrap(.~Var, scales = "free", labeller = label_parsed)+
labs(x = "", y ="", title = "Plots of Betas", color = "")+
scale_color_manual(values = c("green","blue","purple"), labels = c("Chain 1","Chain 2","Chain 3"))+
theme_minimal()+
theme(plot.title = element_text(hjust = 0.5))

How to set the distance between discrete values in ggplot2?

I am attempting to use grid.arrange to plot several graphs in one column, as the x axis is the same for all graphs. However the different graphs have different number of discrete values, resulting in Samples in the top graph more distanced than the graph below. Is there a way to set the distance between discrete values on an axis so the distance between Sample1 and Sample2 lines is the same for both graphs? Thanks!
Here is an example:
library(reshape2)
library(tidyverse)
library(gridExtra)
#Data frame 1
a <- c(1,2,3,4,5)
b <- c(10,20,30,40,50)
Species <- factor(c("Species1","Species2","Species3","Species4","Species5"))
bubba <- data.frame(Sample1=a,Sample2=b,Species=Species)
bubba$Species=factor(bubba$Species, levels=bubba$Species)
xm=melt(bubba,id.vars = "Species", variable.name="Samples", value.name = "Size")
#Data frame 2
c <- c(1,2,3,4,5)
d <- c(10,20,30,40,50)
e <- c(1,2,3,4,5)
f <- c(10,20,30,40,50)
bubban <- data.frame(Sample1=c,Sample2=d,Sample3=e,Sample4=f,Species=Species)
xn=melt(bubban,id.vars = "Species", variable.name="Samples", value.name = "Size")
#Not related, but part of my original script i am using
shrink_10s_trans = trans_new("shrink_10s",
transform = function(y){
yt = ifelse(y >= 10, y*0.1, y)
return(yt)
},
inverse = function(yt){
return(yt) # Not 1-to-1 function, picking one possibility
}
)
#Make plot 1
p1=ggplot(xm,aes(x= Species,y= fct_rev(Samples), fill = Size < 10))+
geom_point(aes(size=Size), shape = 21)+
scale_size_area(trans = shrink_10s_trans, max_size = 10,
breaks = c(1,3,5,10,20,30,40,50),
labels = c(1,3,5,10,20,30,40,50)) +
scale_fill_manual(values = c(rgb(136,93,100, maxColorValue = 255),
rgb(236,160,172, maxColorValue = 255))) +
theme_bw()+theme(axis.text.x = element_text(angle = -45, hjust = 1))+scale_x_discrete(position = "top")
#Make plot 2
p2=ggplot(xn,aes(x= Species,y= fct_rev(Samples), fill = Size < 10))+
geom_point(aes(size=Size), shape = 21)+
scale_size_area(trans = shrink_10s_trans, max_size = 10,
breaks = c(1,3,5,10,20,30,40,50),
labels = c(1,3,5,10,20,30,40,50)) +
scale_fill_manual(values = c(rgb(136,93,100, maxColorValue = 255),
rgb(236,160,172, maxColorValue = 255))) +
theme_bw()+theme(axis.text.x = element_blank())
#arrange the plots
grid.arrange(p1,p2,nrow=2)
Instead of using grid.extra use ggpubr::ggarrange function. It lets you specify heights of each plot and set shared legend.
# Using plots generated with OPs code
ggpubr::ggarrange(p1, p2, nrow = 2, heights = c(1.3, 2),
common.legend = TRUE, legend = "right")
With argument heights you can set relative heights of each provided plot.

Nonstandard breaks in plot for yaxis

I would like to create a simple plot but with nonstandard breaks.
That's the code for my data:
> dput(dt1)
c(15.9540654816514, 37.5416557213931, 143.317585514018, 317.329051086954,
736.342269565211, 611.759999999995, 1145.49376842104, 3287.57274999997
)
> dput(dt2)
c(7.74957214839424, 17.5499521829522, 47.8167516932271, 72.1468924428822,
131.457629238329, 119.135097468354, 193.812365333332, 339.109355072461
)
> dput(dt3)
c(3.43850794565666, 11.4081262121212, 24.6747108504399, 54.7253625128734,
85.7360432084306, 89.7801271317832, 117.764457806452, 152.859368367347
)
and I would like to achieve something like that:
Just ignore red point on that graph.
That's the code which I have written so far. However, approach of changing the y breaks doesn't work.
plot(dt1,col="blue",cex = 1.8,xlim=c(0,10), ylim = c(1,5000), yaxt = "n", bty="n",xlab="",ylab="")
axis(side = 2, at = C(10,100,1000,5000)
points(dt2,col="green",cex = 1.8)
points(dt3,col="red",cex = 1.8)
Is it possible ? I would like to create identical xlabel like on the attached picture. I can change it as well in other software so do not focus mostly on that.
This is the closest I can think of using ggplot2.
library(data.table)
library(dplyr)
library(ggplot2)
theme_set(theme_bw())
dat <- rbindlist(list(
data.table(dt = "dt1",
y = c(15.9540654816514, 37.5416557213931, 143.317585514018, 317.329051086954,
736.342269565211, 611.759999999995, 1145.49376842104, 3287.57274999997)),
data.table(dt = "dt2",
y = c(7.74957214839424, 17.5499521829522, 47.8167516932271, 72.1468924428822,
131.457629238329, 119.135097468354, 193.812365333332, 339.109355072461)),
data.table(dt = "dt3",
y = c(3.43850794565666, 11.4081262121212, 24.6747108504399, 54.7253625128734,
85.7360432084306, 89.7801271317832, 117.764457806452, 152.859368367347))))
## generate lables
labs <- paste(rep(1:4, c(2,3,2,1)), rep(c(1,2,3,4,3,4), c(1,2,1,1,1,2)), sep = '\n-\n')
## create x variable
dat[, x := rep(1:8, 3) %>% factor(labels = labs)]
## plot
ggplot(dat, aes(x = x, y = y, colour = dt)) +
geom_point() +
scale_y_log10(limits = c(1, 10000),
breaks = 10^(0:4)) +
xlab("") + ylab("")
ggsave('temp.png', width = 4, height = 3)
The output looks like this:

Draw vegan graph on ggplot

I am fairly new to vegan and ggplot, I have drawn a species diversity plot in vegan. Ggplot has better graph so I was wondering if these codes could be modified to ggplot code.
Any help would be greatly appreciated. I am using bray in vegan.
library(vegan)
library(mass)
data <- read.table("data.txt", header = T)
attach(data)
rownames(data) <- c("TCI1", "TCI2", "TCI3", "TCII1", "TCII2", "TCII3", "TCIII1", "TCIII2", "TCIII3", "TCIV1", "TCIV2", "TCIV3",
"NCI1", "NCI2", "NCI3", "NCII1", "NCII2", "NCII3", "NCIII1", "NCIII2", "NCIII3", "NCIV1", "NCIV2", "NCIV3","TFI1", "TFI2", "TFI3", "TFII1", "TFII2", "TFII3", "TFIII1", "TFIII2", "TFIII3", "TFIV1", "TFIV2", "TFIV3",
"NFI1", "NFI2", "NFI3", "NFII1", "NFII2", "NFII3", "NFIII1", "NFIII2", "NFIII3", "NFIV1", "NFIV2", "NFIV3")
bcdist <- vegdist(data, "bray")
bcmds <- isoMDS(bcdist, k = 2)
plot(bcmds$points, type = "n", xlab = "", ylab = "")
text(bcmds$points, dimnames(data)[[1]])
You can indeed create a plot that looks like the imgur image. First I created some made-up data for your weeds. Then I called ggplot2 and put the weed names at the points, but made the points transparent.
x <- seq(from = -1, to = 1, .025)
df <- data.frame(valuesX = sample(x, size = 48, replace = TRUE),
valuesY = sample(x, size = 48, replace = TRUE),
seeds = c("TCI1", "TCI2", "TCI3", "TCII1", "TCII2", "TCII3", "TCIII1", "TCIII2", "TCIII3", "TCIV1", "TCIV2", "TCIV3",
"NCI1", "NCI2", "NCI3", "NCII1", "NCII2", "NCII3", "NCIII1", "NCIII2", "NCIII3", "NCIV1", "NCIV2", "NCIV3","TFI1", "TFI2", "TFI3", "TFII1", "TFII2", "TFII3", "TFIII1", "TFIII2", "TFIII3", "TFIV1", "TFIV2", "TFIV3",
"NFI1", "NFI2", "NFI3", "NFII1", "NFII2", "NFII3", "NFIII1", "NFIII2", "NFIII3", "NFIV1", "NFIV2", "NFIV3")
)
ggplot(df, aes(x = valuesX, y = valuesY)) +
geom_point(colour = "transparent") +
geom_text(data = df, aes(label = seeds), hjust = 1.5) +
theme_bw() +
labs(x = "Your axis label", y = "", title = "Weed Distribution") +
theme(axis.ticks= element_blank()) +
theme(plot.title = element_text(face = "bold", size = 12))
You can adjust all the elements of the plot as you see fit.

Resources