Adding ggplot code chunk to RMarkdown breaks HTML tabset - r

Newish R programmer here and new to SO...
I have an RMarkdown doc where I've created tabs.
For some reason, when I try to knit, the chunks with ggplot seem to break the tabset code, because when I omit those chunks, the doc appears as it should.
When the ggplot code include = FALSE, the tabs are included, but the below code appears to break the tabs. Any ideas for workarounds? Is this a bug, or my novice-ness? Thanks in advance...
## Options {.tabset .tabset-pills}
```{r Barplot, include=TRUE,echo=FALSE}
barplot_group_count <- ggplot(data=group_count, aes(x=Group, y=n)) +
geom_bar(stat = "identity") +
labs(title = "Count of Groups According to PSA Attributes") +
coord_flip()
barplot_group_count
```

I found that if I wrapped the call to ggplotly(), the graphs are displayed.
barplot_group_count <- ggplot(data=group_count, aes(x=Group, y=n)) +
geom_bar(stat = "identity") +
labs(title = "Count of Groups According to PSA Attributes") +
theme(plot.margin=unit(c(2, 1.5, 1.5, 1.5),"cm"))+
coord_flip()
ggplotly(barplot_group_count)

Related

Best way to export ggplot2 graphs to a Word document?

I have created some awesome graphs that I want to export to my Word document. Yea, should write in Markdown but... you know... someday!
However, how do I resize the graphs to the right dimensions while labels stay "within" the perimeter? See the following examples (code is at the end of the document).
I want to insert the following graph into my word document:
Looks great! Not when I insert it into the document:
Labels are two tiny, and I would love to stretch it vertically, so the width is greater than the height. So I managed to produce this:
And this is were I am stuck. How do I keep the labels within the perimeters? And is there a better way to "fit" the word document than guessing correct dimensions?
Thanks!
This is the code:
library(ggplot2)
df <- mpg # Load sample data
# First test graph
ggplot(data = df, mapping = aes(cyl, hwy)) +
geom_smooth() +
geom_point() +
geom_point() +
labs(y = "This is just one very long label to prove a point ..... 1234",
x = "Cyl") +
theme_classic() +
theme(legend.title = element_blank())
ggsave("test1.png")
# Modified test graph to add fit the Word document
ggplot(data = df, mapping = aes(cyl, hwy)) +
geom_smooth() +
geom_point() +
geom_point() +
labs(y = "This is just one very long label to prove a point ..... 1234",
x = "Cyl") +
theme_classic(base_size = 12) + # SIZE CHANGED
theme(legend.title = element_blank())
ggsave("test2.png", width = 8, height = 4) # DIMENSIONS DEFINED
A solution I tend to use involves the officer package as mentioned above. This used to be able export graphs as vector objects to docx so you could change sizes and text in the graph when it's in the document. This seems to have been suspended in recent versions, but still works for powerpoint. The following code puts the graph as a grouped shape in a powerpoint slide where you can tweak it before copying into word:
library(ggplot2)
library(officer)
library(tidyverse)
df <- mpg # Load sample data
# First test graph
plot2 <- ggplot(data = df, mapping = aes(cyl, hwy)) +
geom_smooth() +
geom_point() +
geom_point() +
labs(y = "This is just one very long label to prove a point ..... 1234",
x = "Cyl") +
theme_classic(base_size = 12) + # SIZE CHANGED
theme(legend.title = element_blank())
pptx <- read_pptx()
pptx %>%
add_slide() %>%
# This first line puts it in as a static png image for comparison
ph_with(plot2, location = ph_location_type(type = "body")) %>%
add_slide() %>%
# This line puts in a shape object, which can be ungrouped and edited
ph_with(rvg::dml(ggobj = plot2),
width = 8,
height = 4,
location = ph_location_type(type = "body"))
#> pptx document with 2 slide(s)
print(pptx, "test_graph.pptx")
Created on 2020-12-08 by the reprex package (v0.3.0)
That's a sort of tweaky solution which at least allows you visual control over sizes. This used to be more easily provided through the export package (available on GitHub), but it's not on CRAN anymore and behind the scenes used the now defunct parts of officer to put vector graphics in docx documents.
Edit: See this issue on GitHub for an explanation of why vector graphics to docx is no longer an option through officer.

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.

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

grid.layout in ggplot

I'm using the following code to create three sets of plots in the amazing package ggplot2:
w<-rnorm(100)
x<-rnorm(100)
y<-rnorm(100)
z<-rnorm(100)
g<-rep(factor(LETTERS[1:4]), 25)
d<-data.frame(g,w,x,y,z)
library(ggplot2)
pw<-ggplot(d, aes(w, y))
px<-ggplot(d, aes(x, y))
pz<-ggplot(d, aes(z, y))
pw+geom_point()+facet_grid(.~g, scales='fixed')+coord_equal()+stat_smooth(method='lm')
px+geom_point()+facet_grid(.~g, scales='fixed')+coord_equal()+stat_smooth(method='lm')
pz+geom_point()+facet_grid(.~g, scales='fixed')+coord_equal()+stat_smooth(method='lm')
I would make a PDF file that has each of these three sets of plots printed on the same page. My understanding is thatsplit.screen(c(3,1))andpar(mfrow=c(3,1))won't work with ggplot2 graphics, but thatgrid.layout()from the grid package would work so I tried:
pdf(file="test.pdf")
pushViewport(viewport(layout=grid.layout(3,1)))
print(pw+geom_point()+facet_grid(.~g, scales='fixed')+coord_equal()+stat_smooth(method='lm'))
print(px+geom_point()+facet_grid(.~g, scales='fixed')+coord_equal()+stat_smooth(method='lm'))
print(pz+geom_point()+facet_grid(.~g, scales='fixed')+coord_equal()+stat_smooth(method='lm'))
dev.off()
but this ends up being a four page PDF file with the first page being blank and each set of figures following one per page and the x-axis label way down at the bottom. Is there a way to make a PDF file with all the sets of figures on the same page (and without a blank page leading!)?
You'll probably have a better time using grid.arrange(), from the gridExtra package:
p1 <- pw + geom_point() + facet_grid(.~g, scales='fixed') + coord_equal() +
stat_smooth(method='lm')
p2 <- px + geom_point() + facet_grid(.~g, scales='fixed') + coord_equal() +
stat_smooth(method='lm')
p3 <- pz + geom_point() + facet_grid(.~g, scales='fixed') + coord_equal() +
stat_smooth(method='lm')
grid.arrange(p1, p2, p3, ncol=1)
You can also use the multiplot() function, which could be customized to suite your needs: http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)/
If you use markdown, use fig.height in each code chunk for each plot:
```{r pw, fig.height = 2.66, echo = F}
pw
```
```{r px, fig.height = 2.66, echo = F}
px
```
```{r pz, fig.height = 2.66, echo = F}
pz
```

Resources