I have several images in a Sweave report that look like this:
They are created by a function with a code akin to this:
<<fig = T>>=
barplot(prop.table(table(x, y), margin = 2) * 100,
border = F, xlab = '', ylab = '', las = 2)
#
I want to compress the y-axis, so my plot looks something like this (without the label distortion):
The only way I was able to get this was by using png() with a custom height parameter and then using the image file on LaTeX, but that kind of ruins the whole purpose of Sweave. How can I achieve this within barplot() (or with par() or some other elegant solution)?
Sweave has chunk options width and height for the dimensions of the images. It won't control how big the plot is in the final rendered PDF as that is something LaTeX controls, but it does control the creation of the figures themselves.
From the Sweave Manual [pdf]:
Attention: One thing that gets easily confused are the width/height parameters of the R
graphics devices and the corresponding arguments to the LaTeX \includegraphics command.
The Sweave options width and height are passed to the R graphics devices, and hence affect
the default size of the produced EPS and PDF files. They do not affect the size of figures in the document, by default they will always be 80% of the current text width. Use \setkeys{Gin} to modify figure sizes or use explicit \includegraphics commands in combination with Sweave option include=FALSE.
Also read
require("utils")
?RweaveLatex
which also has details.
For your quoted example, width and height are both 6, the default. So you could do something like
<<fig=TRUE, width=8, height=5>>=
barplot(prop.table(table(x, y), margin = 2) * 100,
border = FALSE, xlab = '', ylab = '', las = 2)
#
To get the desired proportions.
[Please don't use F and T - you are asking for trouble!]
However, do note what the Manual or ?RweaveLatex say. Once in LaTeX by default the image will be included with a width equal to 0.8\textwidth. Hence you might also wish to set the width for each chunk explicitly to the size of the figure created, e.g.
\setkeys{Gin}{width=8in}
<<fig=TRUE, width=8, height=5>>=
barplot(prop.table(table(x, y), margin = 2) * 100,
border = FALSE, xlab = '', ylab = '', las = 2)
#
%% reset if you want
\setkeys{Gin}{width=0.8\textwidth}
So you have to manage the two settings:
The sweave chunk options width and height control creation of the EPS or PDF file (or both)
\setkeys{Gin} controls the width of the included figure when processed using LaTeX.
Related
I am trying to have multiple histogram plots rendered from a for loop fill up the entire page on my R Markdown pdf output.
My histogram plots are rendered from the following code
mclogins<-c("sacfreq","logsacfreq","meanvel","logmeanvel", "meanvelx","logmeanvelx", "meanvely","logmeanvely","meanacc","logmeanacc", "meanaccx", "logmeanaccx", "meanaccy","logmeanaccy", "meanamp", "logmeanamp", "meanampx","logmeanampx", "meanampy","logmeanampy")
# dev.off()
par(mar=c(5.1 ,4.1, 4.1 ,2.1),mfrow=c(3,2))
for( i in mclogins){
hist(df.1log[,i],
xlab = i,
main = paste("Histogram of",i),
col = "lightblue")
}
Where df.1log is the dataset containing values for all variables in mclogins
Right now, my output looks like this:
And as you can see, there is much empty space at the bottom of the page.
I have tried the following suggestions:
R:plot : fitting multiple plots properly on one A4 pdf page
R pdf set margin
But it ends up causing the plots to disappear or nothing changes and the blank space is still there.
Thank you so much!
You can set fig.height and fig.width to suite your preferences, but a reasonable starting point could be to add the following to the top of the chunk where you make your visualizations.
{r, echo = FALSE, fig.height = 28, fig.width = 20}
I want to export charts to a PPT and am using the officer package to achieve the same. However, the default resolution of the charts is low and I would like to change that. I am currently using the following call
ph_with_gg(p1,type = "chart",res = 1200)
where p1 is a ggplot object. On running this, I get the following error:
Error in png(filename = file, width = width, height = height, units =
"in", :
formal argument "res" matched by multiple actual arguments
Would really appreciate the help around this
Rather than using png, for high-resolution plots in PPT you should be using vector graphics.
See under extensions:
Vector graphics with package rvg
The package rvg brings an API to
produce nice vector graphics that can be embedded in PowerPoint
documents or Excel workbooks with officer.
This package provides functions dml() and ph_with() corresponding method to export ggplots to .pptx as vector graphics.
Example:
library(ggplot2)
library(officer)
library(rvg)
library(magrittr)
data(iris)
read_pptx() %>%
add_slide(layout='Title and Content',master='Office Theme') %>%
ph_with('Iris Sepal Dimensions', location = ph_location_type(type="title")) %>%
ph_with(dml( ggobj=
ggplot(iris, aes(x=Sepal.Length,y=Sepal.Width,col=Species)) +
geom_point()), location = ph_location_type(type="body")) %>%
print('iris_presentation.pptx')
As an additional benefit, you will be able to edit the charts in PowerPoint. For example, if you decided to capitalize the names of the 3 species, you could just edit the chart instead of editing the data and regenerating the slides. (You can also make the plots non-editable, but editable is the default.)
Is it important that the plot is saved to a presentation in the code?
Otherwise using:
ggsave(filename = file, p1, width = width, height = height, dpi = dpi)
will give you a png of any resolution you need..
(provided that filename ends with .png and you set width, height and dpi to appropriate values)
I have made a beautiful plot in R to be used in a scientific journal. According to the journal's specifications, I need an eps file format with embedded fonts. Since R does not export eps files with embedded fonts, I am using the base graphics call embedFonts() to convert it. However, this call is changing the bounding box of my figure. In this simple example below, the white space is cropped. In my OCD-adjusted publication-quality plot, white space is added because I've already adjusted it perfectly to the edges.
I want the fonts to be embedded, but everything else to stay the same!
Here is an example:
setEPS()
postscript(file = "~/Desktop/test.eps", family = "Helvetica", colormodel = "srgb", width = 5, height = 3)
plot(x = 1:10, y = 1:10, col = "red", main = "Keep everything the same but embed my fonts!")
dev.off()
embedFonts(file = "/Users/athena/Desktop/test.eps", format = "eps2write", outfile = "/Users/athena/Desktop/stupid.eps")
So far I have:
- installed ghostscript using homebrew: $ brew install ghostscript
- learned that embedFonts needs FULL paths, no tilda's allowed
- specified the format as "eps2write" because the default "ps2write" changes it to a postscript
I spent so much effort on "reproducible research" with open data, open code, open journal, bla bla bla... I really don't want to have to make my final figures using illustrator conversion or something :(
The reason this happens is because embedFonts internally calls Ghostscript which in turn tries to act smart by fitting an "optimal" bounding box by trimming out some of the surrounding white space.
We can prevent that by drawing an invisible box around the perimeter of our 5inx3in drawing area in R. Just add one more line to your code snippet:
setEPS()
postscript(file = "~/Desktop/test.eps", family = "Helvetica", colormodel = "srgb", width = 5, height = 3)
plot(x = 1:10, y = 1:10, col = "red", main = "Keep everything the same but embed my fonts!")
box(which="outer", col="white")
dev.off()
embedFonts(file = "/Users/athena/Desktop/test.eps", format = "eps2write", outfile = "/Users/athena/Desktop/stupid.eps")
Another way to go about this is Jonathan's answer here which basically uses sed to read in Bounding Box info from the input file and writes it to the output file: http://r.789695.n4.nabble.com/eps-file-with-embedded-font-td903387.html as pointed out by #neilfws in a comment above.
I'm trying to make a png in R where I can vary the resolution without changing the apparent height of the text and it is not working.
Here is my code
drawbox <- function(res, ps=12, textcex=1) {
png(file="test.png",width=6,height=3, units="in", res=res, bg="transparent", pointsize=ps)
plot(x=c(0,1),y=c(0,1),type="n",xaxs = 'i',yaxs = 'i',axes=FALSE)
text(x=0.5, y=0.5, adj=c(0.5,0.5), labels="Some text", cex=textcex*6)
dev.off()
}
then this makes a very different size of text
drawbox(res=300, ps=12, textcex=1)
than this
drawbox(res=100, ps=12, textcex=1)
but isn't that the point of the pointsize argument, that this doesn't happen?
Note: I need base graphics here, other packages lack the flexibility to allow me to make what I want to make.
If I mess around with that textcex parameter I can get things to work, but that's annoying.
I am trying to get figures ready for publication, where the journal requires the figures to be a certain width and height and the font size to be 10.
This is my basic structure:
cairo_ps(file = "plot.eps", width = 6.85, height = 9.213)
dotplot(...)
dev.off()
I've tried to force the font size using trellis.par.set, trellis.device and setting it with pointsize in the device itself, but no luck. I can't get to change the font size to be anything than it defaults to. Any ideas?
You could use Cairo instead. This solution can, however, yield some unexpected results as it seems, for example when changing the dpi argument when calling Cairo.
There seems to be some coding problems involved. For example, I have to re-run the code after changing the font size for changes to take effect. Be warned! You might have to tweak it a bit to get the font size you want.
Contrary to the built-in graphics devices, however, this seems to react to changes made by trellis.par.set. Here is a example with PNG, the same works for me with PDF:
dat <- data.frame(a=1:3, b=1:3)
Cairo(file = "plot.png", type="png", units="in", width = 6, height = 3, dpi=100)
xyplot(b~a, dat)
trellis.par.set("fontsize", list(text=12, points=8))
dev.off()
Compare to:
Cairo(file = "plot.png", type="png", units="in", width = 6, height = 3, dpi=100)
xyplot(b~a, dat)
trellis.par.set("fontsize", list(text=18, points=8))
dev.off()