Side-By-Side ggplots within rMarkdown using grid.arrange() - r

I want to display two plots (ggplot) side-by-side in an html report. Most resources suggest grid.arrange() from the package gridExtra is the simplest way to accomplish this. However, grid.arrange() is changing the proportions of my plots (squishing them along the x-axis). I want to maintain axis proportions. I've played with widths= and heights= options but nothing has worked.
If this isn't easily resolved with grid.arrange(), are there other alternatives for displaying images side-by-side?
P.S. I did see altering height of rows produced by grid.arrange when nrow=1, but the solution did not work for me.
Thanks!
{r Images, echo=FALSE}
p1 <- ggplot(pcaData, aes(PC1, PC2, color=By_Experiment, shape=Date)) +
geom_point(size=3) +
xlab(paste0("PC1: ",percentVar[1],"% Variance")) +
ylab(paste0("PC2: ",percentVar[2],"% Variance")) +
labs(title="PCA of Gene Counts (rLog Transformed)") +
theme(axis.line = element_line(color = "black"))
p2 <- ggplot(pcaData, aes(PC1, PC2, color=By_Experiment, shape=Calcium_TP)) +
geom_point(size=3) +
xlab(paste0("PC1: ",percentVar[1],"% Variance")) +
ylab(paste0("PC2: ",percentVar[2],"% Variance")) +
labs(title="PCA of Gene Counts (rLog Transformed)") +
theme(axis.line = element_line(color = "black"))
p1
p2
grid.arrange(p1, p2, ncol=2)

You can control the dimensions of the plots produced in an HTML report by including fig.width and fig.height in the beginning of the code chunk. Try to include {r, fig.width=12, fig.height=4} and see if the plots looks less squashed.

Related

R: Partially overlapping ggplots

I'm graphing 21 channels of time-series data together in a plot. See image below. As you can see the waveforms are quite flat because they're limited to their respective graphs. Is there some way to allow the graphs to partially overlap with the graphs above and below? Or to allow the lines to exceed their graphs and 'spill over' above or below?
My graph currently looks as follows:
Code:
png("spectral_all_channels.png", units="in", width=16, height=12, res=300)
mdf <- melt(data=EEG, id="X")
ggplot(data=mdf, mapping=aes(x=X, y=value)) +
coord_cartesian(ylim=c(min(mdf["value"]), max(mdf["value"]))) +
theme(axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
axis.title.y=element_blank(),
strip.text.y.left=element_text(angle = 0),
text = element_text(size = 26) +
labs(x="Time (s)") +
geom_line() +
facet_grid(variable ~ .,
switch = "y") +
scale_x_continuous(breaks=seq(start_s*256, end_s*256, 2560), labels=seq(start_s, end_s, 10))
dev.off()
An example of the desired effect:
There are couple of way you might attempt this. One is use something like patchwork to set up your plots in a grid that overlaps with one another.
The other option is to use a different kind of plot like a ridgeplot. See ggridges. But as #TarJae said w/o knowing what your endgoal is and some dummy data it's kinda hard to give working example

Knitting plots to word, sizing of plots is squashed

I am trying to create 4 bar plots that simply present number of responses split by various demographics.
Thus I have the following chunk of code
{r, echo = FALSE, fig.height=20, fig.width=40} <-this is has the proper start but stackoverflow wont let me post it
a <- ggplot(data=Data, aes(x=Gender, fill=Gender))+
geom_bar(stat="count")+
scale_x_discrete(labels = wrap_format(10))+
ylab("Number of respondents")
b <- ggplot(data=Data, aes(x=Condition, fill=Condition))+
geom_bar(stat="count")+
scale_x_discrete(labels = wrap_format(10))+
ylab("Number of respondents")+
xlab("Employment type")
c <- ggplot(data=Data, aes(x=Schedule, fill=Schedule))+
geom_bar(stat="count")+
scale_x_discrete(labels = wrap_format(10))+
ylab("Number of respondents")
d <- ggplot(data=Data, aes(x=Region, fill=Region))+
geom_bar(stat="count")+
scale_x_discrete(labels = wrap_format(10))+
ylab("Number of respondents")
plot_grid(a,b,c,d)
This presents the plots in a nice grid. However the graphs are unreadably small unless one zooms in a lot.
However, messing with the fig.height and fig.width either make the graphs incredibly tiny or larger but then all the data in each graph is so squashed.
How can one simply resize the graph appropriately while maintaining readability?

x-axis is pressed together

I'd like to create a markdown document out of my R script. I managed it to display different barplots, piecharts, a leaflet map and so on.
But it doesn't work with ggplot.
{r, eval=TRUE, echo=TRUE, warning=FALSE, message=FALSE}
p <- qplot() +
theme_classic() +
ggtitle("Title") +
coord_fixed(ratio = 1) +
xlab("wrong") +
ylab("super") +
geom_polygon(data=fortify(data1),
aes(x=long, y=lat, group=group), alpha=0.1, fill=NA, col="black", size=0.1) +
geom_point(data = as.data.frame(data2),
aes(x = coords.x1, y = coords.x2, color = pal1), shape=4, alpha=1)
p + theme(legend.position="right")
The plot looks totally fine if i export it with ggsave, but in the markdown the x axis is pressed together.
Without a reproducible example, it is difficult to work out your problems. However, you could try to change a few lines (each at a time) to see if it makes a difference. Particularly, I would remove the line coord_fixed(ratio = 1) + to see what happens. You could also try different ratio numbers as well to get what you want.
If this does not fix your problem, please provide a reproducible example data.

Draw box around a grid of plots in R

I have arranged eight ggplots underneath each other in two columns with plot_grid. How can I draw a box around the entire grid?
If I understand your question correctly you can use the function panel_border as described in the following link:
https://www.rdocumentation.org/packages/cowplot/versions/1.0.0/topics/panel_border
Which adds an outer border to figures. I could not test that because you didn't added any piece of code that reproduce your result or a similar one.
EDIT:
as Matt said, the function panel_border is per plot, and not the entire plot image as desired. a solution with a dummy example is:
library(ggplot2)
library(cowplot)
p1 <- ggplot(mtcars, aes(disp, mpg)) +
geom_point()
p2 <- ggplot(mtcars, aes(qsec, mpg)) +
geom_point()
plot_grid(p1, p2, labels = c('A', 'B'))+
theme(panel.border = element_rect(colour = "black", fill=NA, size=5))
Is to use theme combined with its attribute panel.border the results is:
As can be seen the border is on the entire plot and not per graph.

Add a footnote citation outside of plot area in R?

I'd like to add a footnote citation to my 3-panel facet grid plot produced in R. It's a footnote to credit the data source. I'd ideally like to have it below and external to all three axes---preferably in the lower left.
I'm using ggplot2 and also ggsave(). This means I can't use grid.text()-based solutions, because that only draws on the x11() window, and can't be added to the ggplot object.
Using instead png() ...code... dev.off() does not appear to be an option because I need ggsave's resizing parameters, and find this command produces better, clearer prints (that are also much faster, because I'm not printing to the screen).
Here's my basic code:
p1 <- ggplot(data, aes(date, value))
facet_grid(variable ~ .) + geom_point(aes(y =value), size=1) +
theme_bw() +
opts(title=mytitle)
print(p1)
ggsave("FILE.png",width=mywidth, height=myheight, p1, dpi=90)
I've tried:
p1 <- ggplot(data, aes(date, value))
facet_grid(variable ~ .) + geom_point(aes(y =value), size=1) +
theme_bw() +
opts(title=mytitle)
print(p1)
grid.text(unit(0.1,"npc"),0.025,label = "Data courtesy of Me")
grid.gedit("GRID.text", gp=gpar(fontsize=7))
ggsave("FILE.png",width=mywidth, height=myheight, p1, dpi=90)
This appropriately puts the footnote in the lower left corner on the x11() display, external to the plots, but unfortunately, since it isn't applied to the p1 object, it isn't saved by the ggsave command.
I've also tried:
p1 <- ggplot(data, aes(date, value))
facet_grid(variable ~ .) + geom_point(aes(y =value), size=1) +
theme_bw() +
opts(title=mytitle) +
annotate("text", label = "Footnote", x = 0, y = 10, size = 5, colour = "black") +
print(p1)
ggsave("FILE.png",width=mywidth, height=myheight, p1, dpi=90)
This successfully prints using ggsave, however it has the following problems:
It is repeated 3 times, in each of the 3 facets, rather than 1 time.
It is contained within the plots, rather than external to them.
Text is difficult to place---seems to be using plot units (my x-axis is date, so 0 puts it around 1970).
The text size doesn't seem to change despite my size parameter.
A couple of related links from when I explored this...
ggplot2 footnote
(doesn't work with ggsave)
How to label the barplot in ggplot with the labels in another test result?
(is inside the plot, not external/below plot)
Different font faces and sizes within label text entries in ggplot2
(doesn't work with ggsave)
problem saving pdf file in R with ggplot2
ggplot2 now has this ability natively with no need for additional packages. ... + labs(caption = "footnote", ...)
library(ggplot2)
ggplot(diamonds, aes(carat, price, color = clarity)) +
geom_point() +
labs(title = "Diamonds are forever...",
subtitle = "Carat weight by Price",
caption = "H. Wickham. ggplot2: Elegant Graphics for Data Analysis Springer-Verlag New York, 2009.")
library(gridExtra)
library(grid)
library(ggplot2)
g <- grid.arrange(qplot(1:10, 1:10, colour=1:10) + labs(caption="ggplot2 caption"),
bottom = textGrob("grid caption", x = 1,
hjust = 1, gp = gpar(fontface = 3L, fontsize = 9)))
ggsave("plot.pdf", g)
Edit: note that this solution is somewhat complementary to the recent caption argument added to ggplot2, since the textGrob can here be aligned with respect to the whole figure, not just the plot panel.
Adding to the answer of Brandon Bertelsen: if you want to have the caption in the left corner, add
theme(plot.caption = element_text(hjust = 0))

Resources