Legend (base graphics) not getting drawn - r

I'm new to R so forgive me if the problem is obvious.
The problem I've got is that my legend just wont get shown
and there're no errors telling me something is wrong. I've been checking
the documentations for legends and I can't see where I've gone wrong.
The legend code looks like this:
legend(1, g_range[2], c("Client0","Client1"), cex=0.8,
col=c("blue","red"), pch=21:22, lty=1:2);
A note, everything in my graph works, just that the legend isn't drawn!
How is the drawingorder in R? What happens if one of the plots / lines crosses the space where the legend is supposed to be?
Will the line/plot be seen through the legend, will the legend overlap the lines/plot, will the plot/lines "hide" the legend?
Here is the whole code:
#Define the two Clients and their Deficencies
Client0 <- c(0,3.14,3.60,3.41,3.7,3.6,3.6)
Client1 <- c(0,1.26,1.7,4,2.82,3.42,4)
# Calculate range from 0 to max value of cars and trucks
g_range <- range(0, Client0, Client1)
# Graph autos using y axis that ranges from 0 to max
# value in cars or trucks vector. Turn off axes and
# annotations (axis labels) so we can specify them ourself
plot(Client0, type="o", col="blue", ylim=g_range,
axes=FALSE, ann=FALSE)
# Make x axis using Mon-Fri labels
axis(1, at=1:7, lab=c("1","2","3","4","5","6","7"))
# Make y axis with horizontal labels that display ticks at
# every 1 marks. 1*0:g_range[2] is equivalent to c(0,1,2,3).
axis(2, las=1, at=1*0:g_range[2])
# Create box around plot
box()
# Graph trucks with red dashed line and square points
lines(Client1, type="o", pch=22, lty=2, col="red")
# Create a title with a red, bold/italic font
title(main="Deficiencies", col.main="red", font.main=4)
# Label the x and y axes with dark green text
title(xlab="Time", col.lab=rgb(0,0.5,0))
title(ylab="Deficiencies", col.lab=rgb(0,0.5,0))
# Create a legend at (1, g_range[2]) that is slightly smaller
# (cex) and uses the same line colors and points used by
# the actual plots
legend(1, g_range[2]-1, c("Client0","Client1"), cex=0.8,
col=c("blue","red"), pch=21:22, lty=1:2);

Related

How to customize base R plots and subplots in detail?

There is this figure in an economics paper:
I want to style my plots just like these -- with invisible top axis, Y-axis values on the right hand side, axis labels on the top of it and aligned horizontally, subplot titles aligned to the left and each subplot taller than wider and thus emphasizing change along Y-axis. I primarily use MATLAB and I tried to fiddle with it to reproduce something like this but in vain. I then reached out to one of the authors of the paper asking if he could tell which application he used for plots and if he could share how to style my plots after theirs. He responded saying he didn't have the code but he thought it was done in R.
I have not seen plots like this being done in R and even after hours of internet trawling, I didn't find anything R-generated which looked even remotely similar. Will appreciate if you folks have any thoughts/advice on whether it is indeed possible to do it in R.
EDIT
Courtesy of inputs by Isabella Ghement and after whuber's comments, I tried plotting one of the 4 by 2 panels in the figure in my question. Here is how it looks:
Ruefully, this is quite different from the panels in the question. Presumably, if I can get one panel right, I can then prepare a figure containing m by n subplots. That said, this figure has only two elements that I want -- invisible top axis and subplot title aligned to the left. But its tick marks are outside, X-axis doesn't meet the two Y-axes and axis labels are still printed vertically beside them. Here's the code that produces the above plot (taken from https://www.statmethods.net/advgraphs/axes.html, thanks Isabella Ghement for the suggestion):
# specify the data
x <- c(1:10); y <- x; z <- 10/x
# create extra margin room on the right for an axis
par(mar=c(5, 4, 4, 8) + 0.1)
# plot x vs. y
plot(x, y,type="b", pch=21, col="red",
yaxt="n", lty=3, xlab="", ylab="", bty="n")
# add x vs. 1/x
lines(x, z, type="b", pch=22, col="blue", lty=2)
# draw an axis on the left
axis(2, at=x,labels=x, col.axis="red", las=2)
# draw an axis on the right, with smaller text and ticks
axis(4, at=z,labels=round(z,digits=2),
col.axis="blue", las=2, cex.axis=0.7)
# add a title for the right axis
mtext("y=1/x", side=4, line=3, cex.lab=1,las=2, col="blue")
# add a main title and bottom and left axis labels
title("(a) Some Variable", xlab="X values",
ylab="Y=X", adj=0)
I was hoping for simple way of generating such plots but seems like it's a lot of handiwork.
FURTHER EDIT
Though one of the authors wrote back saying he thought plots were in done in R, I do suspect at this point, like #iayork, that probably they weren't done in R. I looked at online appendix of another paper in which one of the authors of the paper in this question is a coauthor and that paper too has plots of similar style. Look at this plot for example:
When I looked at file properties of that plot (it's a PDF file that comes with online appendix in a zipped folder but contains no code), I saw this:
After seeing this, I immediately thought it was generated by S-PLUS but after spending hours on end, I didn't come across anything online on S-PLUS site or any other paper which bore any resemblance. And it was then that I thought it might not be that even though it seems like so by looking at file properties. And then as a last resort, I tried to contact the authors but couldn't get anything useful yet.
You've already deactivated the yaxt, so deactivate xaxt as well. In axis we can omit the labels with labels=FALSE. May I then introduce mtext with which you can create labels independently from the axis. Yes the inward ticks are done with tck=-something. To obtain the axes touch each other we start at 0 and end slightly higher as the maximum value, overlap should be hidden automatically. Add legend. Finally it's wise to use png device to obtain desired aspect ratio. I think that's it, in a nutshell?
# specify the data
x <- c(0:10); y <- ((x^2)-20)/100; z <- (100/x-3)/100
# helper variables
t.adj <- .03
y.seq <- c(-.5, seq(0, 1.5, length.out=4))
png("ecn.plot.png", width=400, height=500)
# margins
par(mar=c(4, 4, 4, 5) + 0.1)
# plot x vs. y
plot(x, y,type="l", pch=21, col="red", xlim=c(0, 10), ylim=c(-.42, max(y.seq)),
yaxt="n", xaxt="n", lty=1, xlab="", ylab="", bty="n", lwd=2)
# add x vs. 1/x
lines(x, z, type="l", pch=22, col="blue", lty=2, lwd=2)
# add y-zero line
abline(h=0, lwd=2)
# draw axes
axis(1, at=(-1:6)*2,labels=FALSE, col.axis="black", tck=t.adj, lwd=2)
mtext((0:5)*2, 1, 0, at=(0:5)*2,col.axis="black", font=2)
axis(2, at=y.seq, labels=FALSE, col.axis="red", las=2, tck=t.adj, lwd=2)
axis(4, at=y.seq, labels=FALSE, col.axis="red", las=2, tck=t.adj, lwd=2)
mtext(formatC(sort(c(0, y.seq)), digits=1, format="f"), 4, 2,
at=sort(c(0, y.seq)), col="black", las=2, font=2, adj=1)
mtext("pct.", 4, 0, at=max(y.seq)+.15, las=2, adj=1, font=2, cex=.9)
# add title
mtext("(a) Some Variable", padj=-2, adj=0, cex=1.2, font=2)
# add legend
legend(x[2], max(y.seq), c("Home", "Foreign"), lty=c(1, 2),
col=c("red", "blue"), bty="n", cex=.8)
dev.off()
Result
Ah, for the arranging of multiple plots you may want to look at this answer.

R: combine mtext() with points() - correct way to specify coordinates?

I want to combine a text I place in the margins with mtext() with a graphics object that I create either using points() or polygon(). The following example roughly works for me with the default plot settings:
plot(1)
mtext("This is a red dot:", side=1, line=2, cex=0.8)
par(xpd=T)
points(1.08, 0.512, pch=15, cex=1.5, col="red")
However, using plot(1:10) instead or prefixing it with windows(8,8) puts the dot in the wrong position, as points() takes user coordinates. Is there a way to get my dot placed correctly independent of plot limits or device size?
I think I have found an answer that works based on the suggestions of #koekenbakker. To make it look pretty, some minor adjustments are still necessary to get the dot in line with the text, but it seems to work well independent of plot size and axis limits (but you cannot resize the plot once created). To do the adjustments on the exact position of the point, I would recommend using fractions of strheight("O", cex=0.8) and strheight("O", cex=0.8) for this example (which uses cex=0.8 for demonstration).
plot(1)
mtext("This is a red dot:", side=1, line=2, cex=0.8, col="green") ## place sample text at bottom of figure
par(xpd=T) ## enable plotting outside plot region
textXPos <- mean(par("usr")[1:2]) ## x position is middle of plot
textYPos <- par("usr")[3] - strheight("O") * 4 ## y position is below bottom of plot (line 2 = 4 * height of letter O)
text(textXPos, textYPos, "This is a red dot:", cex=0.8, col="red", adj=c(0.5, 0)) ## this text overlaps - y position is correct
pointXPos <- textXPos + 0.5 * strwidth("This is a red dot:", cex=0.8) ## text is centred, so need to move half of the text width to the right
points(pointXPos, textYPos, pch=16, col="red") ## still needs minor adjustments to x and y position to make it look nice

Overlay custom axes to a plot created by symbols

Struggling with this one. I have 25 data items that I want plotted with bubbles in 5 columns.
The plot can be re-created thus:
xcord <- c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5)
ycord <- c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5)
zsize <- c(2,1,2,3,6,8,9,1,4,5,5,6,7,8,8,9,5,5,5,5,1,8,1,1,12)
Save the parameters before I change them:
op <- par()
dev.off()
Change the parameters:
par (mfrow=c(1,0), mar=c(2,2,2,2), oma=c(2,2,2,2))
Plot using symbols:
symbols(xcord, ycord, zsize, inches=0.3, fg="white", bg="red", xlab="Events", ylab="Diagnoses", tck=0, xaxt="n", yaxt="n")
mtext("Rheumatic diagnoses by cerebrovasular events", line=2, font=2, cex=1.2)
I am happy with the above plot and deliberately used tck=0, xaxt="n", yaxt="n" to clear the axes. I want to manually overlay custom text, controlled with custom co-ordinates (which work with the sysmbols plot), but have not been able to do it. I have tried some of the par arguments and the axes function.
I also tried leaving the axes on:
symbols(xcord, ycord, zsize, inches=0.3, fg="white", bg="red", xlab="Events", ylab="Diagnoses")
but do not know how to change the output (1,2,3,4,5) to my own custom axes labels.
Thank you.
You are looking for the axis function (see ?axis for details), e.g. to replace the 1:5 with A, B, C, D, E:
axis(side=1, at=1:5, labels=LETTERS[1:5])

X axis labels begin at the middle and do not match data points

I either seem to be running in circles or there is something wrong with my data. I want to plot some data and use ?axisto modify the labels on the X axis.
I have two issues however:
The axis labels begin in the center of the x-axis instead of at the beginning
The axis labels do not match the data points in the plot
I would like to have X axis labels ranging from 10 to 90 by 5.
This is the code that I use and came up with so far:
values <- cbind(1:180,1)
l <- list(1:10,11:20,21:30,31:40,41:50,51:60,61:70,71:80,81:90,91:100,101:110,111:120,121:130,131:140,141:150,151:160,161:170,171:180)
# compute mean across the intervals in l
meanqual <- sapply(l, function(x) mean(values[x,1]))
meanqual
plot <- plot(meanqual, type="o", xlab="% Size of Wave", ylab="Values",xaxt='n', lty=1)
legend('bottomright', c("Values"),pch=21, lty=1, cex=1)
axis(side=1, at= seq(10,90,5))
If you only give one numeric vector to plot it "assumes" you meant to use the position or index of the values in that vector as the x values, so the plot call plotted meanqual against 1:length(meanqual). If you wanted to plot against the seq() argument you latter used in the axis call you should supply it (or rather something similar in scale with the same length as meanqual) to plot:
plot <- plot(x=seq(5,90,5), y=meanqual, type="o",
xlab="% Size of Wave", ylab="Values",xaxt='n', lty=1)
legend('bottomright', c("Values"),pch=21, lty=1, cex=1)
axis(side=1, at= seq(10,90,5), labels=seq(10,90,5))

R: Two axis chart adjustments

I am trying to plot a chat with two axis, here is the code and attached is the plot,
I have to do two adjustments to it.
I want to plot a line with dots and dots should be middle of the bars
Adjusting right side axis(i.e axis(4)) tick marks should align with left side axix(i.e axis(2))
Code:
Region=c("North","South","East","West")
Sales=sample(500:1000,4)
Change=sample(1:10,4)/10
names(Sales)=Region
names(Change)=Region
barplot(Sales,ylim=c(0,1000))
par(new=T)
plot(Change,type="b",axes=F,ylim=c(0,1))
axis(4)
box()
Regards,
Sivaji
First, save your barplot as some object. So you will get coordinates of the middle points. Then to add line you can use also function lines() and just multiply Change values with 1000.
Then for axis() function supply at= values and labels= the same as at=, just divided by 1000.
x<-barplot(Sales,ylim=c(0,1000))
lines(x,Change*1000,type="b")
axis(4,at=seq(0,800,200),labels=seq(0,800,200)/1000)
You need to play to set the same x-axis in the second plot, you get this info from par("usr").
The xaxs="i" is to set the xlim exactly, by default R increase the xlim a bit to make it better looking.
par(mar=c(5,5,2,5)) # change margins
x = barplot(Sales, ylim=c(0,1000)) # barplot, keep middle points of bars
mtext("Sales", 2, line=3) # first y-axis label
xlim = par("usr")[1:2] # get xlim from plot
par(new=TRUE)
plot.new() # new plot
plot.window(xlim=xlim, ylim=c(0,1), xaxs="i", yaxs="i") # new plot area, same xlim
lines(x,Change,type="b") # the lines in the middle points
axis(4) # secondary y-axis
mtext("Change", 4, line=3) # secondary y-axis label
box()

Resources