Sorry this example is not entirely reproducible (I do not provide exact input data), but hopefully the example will be clear.
In short, I would like to save three maps in a wide pdf format, so All three maps can be shown with a desired extent + there is an overarching title above (but I don't want it to take up half of the page).
I am really struggling with setting it up properly:
pdf("plots1.pdf",width = 30/2.54,height = 20/2.54)
par(mfrow = c(2,3))
layout(matrix(c(1,1,1,2,3,4), 2, 3, byrow = TRUE))
plot.new()
text(0.5,0.5,"Africa, Params_1",cex=2,font=2)
# plot.new()
# plot.new()
plot(r2_list[[1]], xlim = Region[[g]][1:2], ylim = Region[[g]][3:4],
breaks=cuts, col = plasma(21), main = variable[1],legend=FALSE)
plot(wrld_simpl,add=TRUE)
plot(r2_list[[2]], xlim = Region[[g]][1:2], ylim = Region[[g]][3:4],
breaks=cuts, col = plasma(21), main = variable[2],legend=FALSE)
lines(wrld_simpl)
plot(r2_list[[3]], xlim = Region[[g]][1:2], ylim = Region[[g]][3:4],
breaks=cuts, col = plasma(21), main = variable[3])
lines(wrld_simpl)
dev.off()
I would also like to try to print 6 plots, again - with overarching titles but I fail miserably.
Help will be much appreciated.
Add heights= to your layout call.
layout(matrix(c(1,1,1, 2,3,4), byrow=TRUE, nr=2), heights = c(1, 8))
opar <- par(mar=c(0,0,0,0))
plot.new()
text(0.5,0.5,"Africa, Params_1",cex=2,font=2)
par(opar)
plot(1:20)
plot(3:99)
plot(1:2)
(Blue boundaries below added externally, for reference only.)
Without heights
If I remove the heights= from the code above, I see this:
With heights
(You will want to play with the actual values based on your canvas size, etc.)
Related
When I use the savePlot function I get a graph inside a larger blank graph area. How can I stop this? The beauty of savePlot should be to save a graph for easy insert into Microsoft Word. Now I have to edit the graphs to remove excess. It is like seeing 2 out of 8 business cards placed in positions (1,1) and(2,1) on a page containing eight card places like a 4x2 matrix.
R code:
plot.new()
# set up the graphics
par(mfrow=c(2,1), omi=c(1, 1, 1, 1))
tsplot(soi, col = 4, ylab = "", main = "Southern Oscillation Index")
tsplot(rec, col = 4, ylab = "", main = "Recruitment")
savePlot("soi.emf","emf")
dev.off()
This is a bit of a guess, without seeing your output, or knowing precisely what you want. But can you try:
library(astsa)
if (!require(devEMF)) {
install.packages("devEMF")
}
devEMF::emf("soi.emf")
plot.new()
par(mfrow = c(2, 1)) # set up the graphics
tsplot(soi, col = 4, ylab = "", main = "Southern Oscillation Index")
tsplot(rec, col = 4, ylab = "", main = "Recruitment")
dev.off()
Output:
Edit: Now I realise that the dataset is included with the package, I have included the output. I have also added plot.new() just in case you were overwriting an old plot. Is this your intended output?
I am trying to use layout() to create a pdf with four plots on one page. I created the matrix and give the order of the plots with this line
layout(mat=matrix(c(1,2,3,4), nrow = 4, ncol = 1))
After that, I try to load one of the saved plots in the layout but that does not seem to work. It just loads the plot by itself.
So I tried copying the code of the plot after the layout but I am getting multiple errors starting by a margin Error.
par(mar=c(4, 6, 4, 6) + 0.1,cex.axis=0.8)#START A NEW PLOT FRAME
plot(acms_day$end,acms_day$Org,pty='s',xaxt='n',#CALL THE DESIRED VARIABLES
type = 'b',lty=2,lwd=0.01,
xlim=period,ylim=c(0,max(acms_day$Org,na.rm = T)),#SET LIMITS OF X AND Y AXIS
xlab='', ylab='',
bg=color_pal[14],
col=color_pal[14],
axes=F, main='',
cex=0.5,las=1,pch=21)
axis(2, ylim=c(0,max(acms_day$Org,na.rm = T)),
col='black',lwd=0.2,cex = 0.8,las=1)
mtext(2,text='Org (ug/m3)',line=2.2,
col=color_pal[14],cex = 0.8,las=0)
par(new=T) #START A NEW PLOT OVER THE DAME FRAME
plot(maap_day$date,maap_day$bc,pty='s',xaxt='n',#CALL THE DESIRED VARIABLES
type = 'p',#lty=2,lwd=0.01,
xlim=period,ylim=c(0,max(maap_day$bc,na.rm = T)),#SET LIMITS OF X AND Y AXIS
xlab='', ylab='',
col=color_pal[3], pch=21,
bg=color_pal[3],
main='',cex=0.5,yaxt='n',ann = FALSE,xaxt='n')
axis(4, ylim=c(0,max(maap_day$bc,na.rm = T)),
col='black',lwd=0.2,cex = 0.8,las=1)
mtext(4,text='BC (ug/m3)',line=2.2,
col=color_pal[3],cex = 0.8,las=0)
axis.POSIXct(1,acsm_long$end,at = hours,format = '%H:%M')
rug(hours, ticksize = -0.01, side = 1)#create minor breaks
rug(days,ticksize = -0.02,side=1) #create day breaks
As soon as the first line runs this Error appears Error in plot.new() : figure margins too large.
What am I doing wrong?
I am sure this is not new for the R community, but is new to me and can't find a clear answer.
Assuming this example:
plot(1:10, xlab="", xaxt="n") # supress OX axis
title(xlab="How can I use cm?", line=2.5)
axis(side=1, at=1:10, line=0.2)
Here I used line argument in function title() to place a label at 2,5 lines of text "outwards from the plot edge" (as described in ?title help). Is there any argument that can take cm, or a way to use cm? Also, how can I find out how many cm does a line of text contains (if there is no other way around)?
Would also be great to know/set the margins in cm and not only like par("mar") [lines of text] or par("mai") [inches]. Is there a way to do that?
Using the line2user function from this answer you can convert centimeters to a "line" then convert the line to user coordinates and add things to the plot using xpd = TRUE:
cm2line <- function(x) {
lh <- par('cin')[2] * par('cex') * par('lheight')
inch <- x/2.54
inch/lh
}
par(mai = rep(5/2.54, 4))
plot.new()
box()
mtext("hello", side = 3, line = cm2line(2))
abline(h = line2user(cm2line(1:5), side = 4), xpd = TRUE)
abline(h = line2user(cm2line(1:5), side = 1), xpd = TRUE)
abline(v = line2user(cm2line(1:5), side = 2), xpd = TRUE)
abline(v = line2user(cm2line(1:5), side = 3), xpd = TRUE)
I am essentially replicating this code from UPenn and want to add some styling to the segments, specifically I want to have different colors for whether the slope of the line is positive is negative. Other styling suggestions are welcome.
Thank you, code replicated below:
a <- rnorm(10)
b <- a - rnorm(10)
plot(rep(1,10),a, xlim = c(1,2), ylim = range(a,b) ,xlab = "Back and Forth",ylab = "The values",axes = F)
points(rep(2,10),b)
axis(2)
axis(1,labels = c("Back","Forth"),at = 1:2)
arrows(rep(1,10),a,rep(2,10),b,code = 1)
If you want to change the color of the line, set the col= property.
arrows(rep(1,10),a,rep(2,10),b,code = 1, col=ifelse(a>b,"blue","orange"))
Is there a way to draw the lines in such a way that they would start on the side of the points, or allow the symbols to be in foreground?
My solution was to make the symbols bigger and more visible.
Edit 1: it's for plot {graphics} of the R program.
Edit 2: the code per popular request.
legend(2,.4,bty='n', c('sugar','citrus','none'), pch=c('s','c','u'), pt.bg='white',lty= c(1,2,3), lwd=1.5, title="Condition",pt.cex=c(1.5),cex=1.5)
Edit 3: This is solved for plot(type='b') but somehow not for legend.
Thanks for reading!
The only thing I can come up with is to manually finagle the dash lengths until they end up looking the way you want them. For instance, this:
> plot(1,1)
> legend(c("A", "B"), col = 1:2, x = 1, y = .8, lty="99", pch=1:2)
produces the image below.
The lty parameter allows you to specify the lengths of lines and dashes as hex characters. In this case, it's saying to create a line of length 9 then create a space of length 9 then repeat. It looks like 9 is about the best fit to space around a normal pch symbol.
Note that you'd probably need to adjust this depending on the size of the image, symbol, etc. My advice ultimately would be to export the image from R and touch up the image to meet your needs in graphic editing software.
Going with the suggestion by #JeffAllen, here is a way to get what I think you might want. It requires modifying the legend() function to return the position of the points (these are given by x1 and y1 in body(legend)[[46]]).
legend2 <- legend
body(legend2)[[49]] <- quote(
invisible(list(rect = list(w = w, h = h, left = left, top = top),
text = list(x = xt, y = yt), points = list(x = x1, y = y1)))
)
Make a plot:
plot(-100:100, -100:100, type = "b")
While drawing the legend, draw white circles (pch = 21 with pt.bg = 'white') over the lines, and assign the values invisibly returned by legend2() to an object. Note also the changes to pt.lwd and pt.cex.
myLegend <- legend2(1, .8, bty = 'n', c('sugar','citrus','none'), pch = 21,
pt.bg = 'white', pt.lwd = 0, lty = c(1, 2, 3), lwd = 1.5, title = "Condition",
pt.cex = c(1.8), cex = 1.5)
Finally, draw the characters you'd like to use in the legend using points(), supplying the x and y values from the object myLegend.
points(myLegend$points$x, myLegend$points$y, pch = c('s','c','u'), cex = 1.5)
And this should get you something like:
You could also use the filled points offered by R (pch=21:25) and specify the fill color using pc.bg which gets passed to the points call when creating a legend.
plot(1,1)
legend(c("A", "B"), col = 1:2, x = 1, y = .8, lty=1, pt.bg=1:2, pch=21:22)
generates the following: