Adjusting Plot aspect ratio in R - r

Trying to change the aspect ratio of this plot so that its twice as long as it is tall, here is the code
plot(X,vw,
ylab= "Stress (MPa)",
xlab= "Strain (mm)")
title("Veronda-Westmann")
lines(X,s,col="red")
legend(x=0, y=17, c("Veronda-Westmann", "Experimental"),cex=.8,col=c("black","red"),pch=c(1,NA),lty=c(NA,1))
I used code to try and specify height and width, but this didtn appear to work. New to R so really sorry if this is a stupid Q

Without reproducible data it is a bit hard to exactly reproduce your plot, but you can set asp to your plot which means you can modify the width of the x-axis in any ratio to the y-axis you want. You can use the following code:
X <- c(0,1,2,3,4,5, 6, 7, 8, 9, 10)
vw <- c(0, 0.5, 0.75, 1, 1.5, 3, 5, 8, 10, 15, 22)
s <- c(0, 0.5, 0.75, 1, 1.5, 3, 5, 8, 10, 15, 22)
plot(X,vw,
ylab= "Stress (MPa)",
xlab= "Strain (mm)", asp = 2)
title("Veronda-Westmann")
lines(X,s,col="red")
legend("topleft",
c("Veronda-Westmann", "Experimental"),
cex=.8,col=c("black","red"),
pch=c(1,NA),
lty=c(NA,1))
Output:

Are you looking to export this figure? If so, you can simply specify this on export:
x <- seq(0,5, 0.1)
y <- seq(0,15, 0.3)
Plot 1: native aspect ratio
png("test.png") # or pdf, etc
plot(x, y)
dev.off()
Plot 2: twice as wide:
png("test2.png", width = 1000, height = 500) # random dimensions
plot(x, y)
dev.off()

Related

Log scale for forest plot without changing hazard ratio values or x-axis tick marks

I am trying to use a log scale on my forest plot of hazard ratios. I input the hazard ratio estimates and confidence intervals by hand into my plot, but I need the same values (unchanged) to be on a log scale when plotted. Preferably with the same tick marks as the plot currently has on the arithmetic scale. Is there an easy way to do this?
I tried atransf = exp, which changes all my hazard ratios.
I also tried at = log(c(0.25, 0.5, 1, 2, 4, 6)), which changes all the tick marks drastically. How can I convert to the log scale without changing the numeric tick marks of my axes and the values of my hazards?
Thanks for your help.
#Forest Plot
label1 <- as.character(c("<50", "50 to <60", "60"))
label1 <- factor(label1, levels = unique(label1))
hazards1 <- c(1.42, 1.66, 2.85)
lower1 <- c(1.34, 1.50, 2.59)
upper1 <- c(1.51, 1.85, 3.13)
patient_num1 <- c(240000, 180000, 220000)
event_num1 <- c(2600, 1300, 2900)
forestplot1 <- data.frame(label1, hazards1, lower1, upper1, event_num1, patient_num1)
forestplot1$patient_num1 <- rev(forestplot1$patient_num1)
par(mar=c(4,4,1,2))
pdf(file = "figureex.pdf", width = 15, height = 8.5)
pdf.options(encoding='ISOLatin2.enc')
forest(rev(hazards1), ci.lb = rev(lower1), ci.ub = rev(upper1), slab = rev(label1), xlim = c(-4,0),
xlab = "Adjusted Hazard Ratio for Event",
refline = 1, annotate = T, ylim = c(-1, 29), ilab = cbind(forestplot1$patient_num1, rev(event_num1)),
ilab.xpos=c(-1,-0.25), at = c(0.25, 0.5, 1, 2, 4, 6), rows = c(1:3),
cex = 1, yaxs = "i")
text(-4, 27.29, pos = 4, "Variable")
text(-1.25, 27.67, pos = 4, "No. of \nPatients")
text(-0.45, 27.67, pos = 4, "No. of \nEvents")
text(5.05, 27.69, pos = 4, "Hazard Ratio \n(95% CI)")
dev.off()
It looks like you're using the forest function in the metafor package. The function forestplot in the package forestplot allows you to specify the tick marks with xticks as well as use log scale for the tick marks with xlog.

barplot labels in R: add horizontal lines below the plot region

My code:
x <- c(10, 50, 20, 40)
barplot(x, names.arg=LETTERS[1:4])
What I want is:
I made this figure with the help of R and Adobe Acrobat. I am wondering can I obtain this figure using pure R code?
You can add text with mtext
mtext("E", side = 1, line = 3, adj = 0.375)
mtext("F", side = 1, line = 3, adj = 0.875)
and then draw line with lines but indicating xpd=T
lines(c(0,3.5),c(-10,-10),xpd=TRUE)
lines(c(3.8,4.8),c(-10,-10),xpd=TRUE)
However, you need manually adjust it.
Thanks to Pascal. I got another answer.
x <- c(10, 50, 20, 40)
barplot(x, names.arg=LETTERS[1:4])
mtext("E", side = 1, line = 3, adj = 0.375)
mtext("F", side = 1, line = 3, adj = 0.875)
axis(1, at=c(0.5,1,2,3,3.3), line=2.5, tick=T, labels=rep("",5), lwd=2, lwd.ticks=0)
axis(1, at=4+c(0.1,0.2,0.3,0.4,0.5),line=2.5,tick=T,labels=rep("",5), lwd=2, lwd.ticks=0)

How to rescale label on x axis in log2(n+1) format?

I want to format my x-axis in log2(n+1) format so the x-axis labels correspond to 1, 2, 4, 16 and so on.
Input:
x <- c(1, 2, 3, 11, 15)
y <- c(1.1, 1.2, .4, 2.1, 1.5)
plot(log2(x + 1), y, axes=FALSE)
axis(1, at=(labels=as.character(formatC(x))), cex.axis=0.9)
But plot I get still has the original x-axis values.
How can I make my x-axis powers of 2 (1, 2, 4, 16, etc.)?
I guess this is what you want.
x<-c(1,2,3,11,15)
y<-c(1.1,1.2,.4,2.1,1.5)
lab<-c(1,2,4,16)
plot(log2(x+1),y,xaxt="n",xlab="x")
axis(1,at=log2(lab+1),labels=lab)
It might also be useful to calculate equally spaced labels:
lab<-round(2^seq(min(log2(x+1)),max(log2(x+1)),length.out=4)-1)

R plot: size and resolution

I have stacked into the question: I need to plot the image with DPI=1200 and specific print size.
By default the png looks ok...
png("test.png",width=3.25,height=3.25,units="in",res=1200)
par(mar=c(5,5,2,2),xaxs = "i",yaxs = "i",cex.axis=1.3,cex.lab=1.4)
plot(perf,avg="vertical",spread.estimate="stddev",col="black",lty=3, lwd=3)
dev.off()
But when I apply this code, the image became really terrible it's not scaling (fit) to the size that is needed. What did I miss? How to "fit" the image to the plot?
,
A reproducible example:
the_plot <- function()
{
x <- seq(0, 1, length.out = 100)
y <- pbeta(x, 1, 10)
plot(
x,
y,
xlab = "False Positive Rate",
ylab = "Average true positive rate",
type = "l"
)
}
James's suggestion of using pointsize, in combination with the various cex parameters, can produce reasonable results.
png(
"test.png",
width = 3.25,
height = 3.25,
units = "in",
res = 1200,
pointsize = 4
)
par(
mar = c(5, 5, 2, 2),
xaxs = "i",
yaxs = "i",
cex.axis = 2,
cex.lab = 2
)
the_plot()
dev.off()
Of course the better solution is to abandon this fiddling with base graphics and use a system that will handle the resolution scaling for you. For example,
library(ggplot2)
ggplot_alternative <- function()
{
the_data <- data.frame(
x <- seq(0, 1, length.out = 100),
y = pbeta(x, 1, 10)
)
ggplot(the_data, aes(x, y)) +
geom_line() +
xlab("False Positive Rate") +
ylab("Average true positive rate") +
coord_cartesian(0:1, 0:1)
}
ggsave(
"ggtest.png",
ggplot_alternative(),
width = 3.25,
height = 3.25,
dpi = 1200
)
If you'd like to use base graphics, you may have a look at this. An extract:
You can correct this with the res= argument to png, which specifies the number of pixels per inch. The smaller this number, the larger the plot area in inches, and the smaller the text relative to the graph itself.
An alternate solution to lowering the size of the various components with pointsize and the cex functions is to increase the size of the graph to compensate. This maintains the scale by increasing the size of everything instead of only some components. Your graph will be larger when exported, but will retain the improved resolution if manually decreased in size should you wish to retain the original smaller size.
The png default settings are dpi=72, height=480, width=480. So to maintain the same scale, you need to multiply height and width by the resolution/72. Using your example of width = height = 3.25 inches and a desired resolution dpi of 1200, we will adjust by 1200/72 (equal to 50/3):
reso <- 1200
length <- 3.25*reso/72
png("test.png",units="in",res=reso,height=length,width=length)
par(mar=c(5,5,2,2),xaxs = "i",yaxs = "i",cex.axis=1.3,cex.lab=1.4)
plot(perf,avg="vertical",spread.estimate="stddev",col="black",lty=3, lwd=3)
dev.off()

Grid line consistent with ticks on axis

I am embarrassed to ask this simple question, but has been in kicking my mind for several days whenever I create a plot:
plot (x = 1:10, y = rnorm (10, 5, 2))
grid (10,10, lty = 6, col = "cornsilk2")
I want to position the grids right at where axis are labelled, i.e. at 2, 4, 6, 8, 10 in x axis and similarly 3, 4, 5, 6, 7, 8 in y axis.
I want to automate the process as whenever the plot size changes the default label behaviour changes. See the following plot:
From ?grid description of the nx and ny arguments:
When NULL, as per default, the grid aligns with the tick marks on the
corresponding default axis (i.e., tickmarks as computed by axTicks)
plot (x = 1:10, y = rnorm (10, 5, 2))
grid (NULL,NULL, lty = 6, col = "cornsilk2")
For reference, there is a way to control the grid and axes parameters directly from the plot() command, if we are not defining a custom tick interval:
plot(x = 1:10, y = rnorm(10, 5, 2), xlim=c(1, 10), ylim=c(1, 10), panel.first=grid())
The plot.default() documentation gives more information about these parameters.
When using a custom ticks interval, the easiest is to draw the grid using abline:
plot(x = 1:10, y = rnorm(10, 5, 2), xaxp=c(1, 10, 10), yaxp=c(1, 10, 10), axes=FALSE)
axis(1, 1:10)
axis(2, 1:10)
abline(h=1:10, v=1:10, col="gray", lty=3)
More information about custom tick intervals in this thread and here for grid alignment.
For posterity, here is the long-winded way of doing it manually:
plot (x = 1:10, y = rnorm (10, 5, 2))
grid (lty = 6, col = "cornsilk2")
xaxp <- par("xaxp")
yaxp <- par("yaxp")
abline(v=seq(xaxp[1], xaxp[2], (xaxp[2]-xaxp[1])/xaxp[3]), lty=6, col = "cornsilk2")
abline(h=seq(yaxp[1], yaxp[2], (yaxp[2]-yaxp[1])/yaxp[3]), lty=6, col = "cornsilk2")
The answer provided here is much more straightforward, although you may dislike the lack of "free space" at each end of the axes. In brief,
The problem is that grid is putting nx grid lines in the user space,
but plot is adding 4% extra space on each side. You can take control
of this. Adding xaxs="i", yaxs="i" to your plot will turn off the
extra space. But then your upper right point will be cut off, so you
need to change the xlim and ylim values and change nx to match

Resources