Punchcard plot in R - r

Can anyone help me out on how can I create a punchcard plot in R (without using ggplot)?
Just like this one that was made in python:

The black border looks good on the original figure. It can be reproduced with symbols(). sqrt((pctable$value / max(pctable$value)) / pi) added in order to make sure that values are proportional to the symbols' surface rather than to their radius.
pctable <- data.frame(expand.grid(weekday=c("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"),
day=1:22), value=abs(rnorm(nrow(pctable), 20, 30)))
par(list(las=1, mar=c(6,6,1,1), mgp=c(4.5,1,0)))
bubble.size <- sqrt((pctable$value / max(pctable$value)) / pi)
symbols(pctable$day, pctable$weekday, circles=bubble.size,
inches=.2, fg="black", bg="blue", yaxt="n", xaxt="n", xlab="Day", ylab="Weekday")
axis(1, at=1:22, labels=c(1:22))
axis(2, at=1:7,labels=rev(c("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday")), cex.axis=0.7)

How about this?
pctable<-data.frame(expand.grid(c("monday","tuesday","wednesday","thursday","friday","saturday","sunday"),1:22))
colnames(pctable)<-c("weekday","day")
pctable$value=rnorm(nrow(pctable),15,8)
plot(pctable$day,pctable$weekday,cex=pctable$value/(max(pctable$value)/5), col=rgb(0,0,1), pch=19, yaxt="n", xaxt="n")
axis(1, at=1:22, labels=c(1:22))
axis(2, at=1:7, labels=c("monday","tuesday","wednesday","thursday","friday","saturday","sunday"), cex.axis=0.7)
You will need to probably have a function to return the correct cex='?' value for your scale, it won't resize.
Out of interest, why not ggplot?

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.

minor.tick() position in R

I've extensively searched for a solution without luck. I'd like to plot functions in the usual way (axes cross at (0,0)) using the default R plotting facilities.
Setting the axes position to 0 as in the example below solve partially the problem. However when adding minor ticks the default position is retained resulting in the weird plot below.
plot.new()
x <- seq(-10,10, 0.1)
f <- ((x+2)*(x-5))/((x-3)*(x+1))
plot.window(xlim=c(-10,10), ylim=c(-30,30))
axis(side=1, at=seq(-10,10,2), pos=0, las=0)
axis(2)
library(Hmisc)
minor.tick(nx=5, ny=10, tick.ratio=0.5)
One solution would be to still use the axis function, and just specify the locations and size (tck) of the minor ticks.
plot.new()
x <- seq(-10,10, 0.1)
f <- ((x+2)*(x-5))/((x-3)*(x+1))
plot.window(xlim=c(-10,10), ylim=c(-30,30))
axis(side=1, at=seq(-10,10,2), pos=0, las=0)
axis(side=1, at=seq(-10,10,0.5), pos=0, las=0, tck=-0.01, labels=FALSE)
axis(2)
This allows you to retain complete control over the plot.

Set zero axes in R

How can one force the visualisation of the zero axes y=0, x=0 in R, removing the external ones siding the plot? I want to obtain the same effect that one can have for example in Gnuplot with set xzeroaxis, set yzeroaxis.
You can do this using by suppressing the default axes by using axes=FALSE and then using axis to draw horizontal and vertical lines to represent the axes.
# example plot
plot(-2:2, -2:2, axes=FALSE)
# add yaxis at position zero and rotate labels 45deg
axis(side=2, pos=0, las=1, lty="dashed")
# x axis
axis(side=1, at=c(-2,-1,1,2), pos=0, lty="dashed")
This produces
Actually, I have solved my own question as follows:
f<-function(x) x^3-2*x
# take the axes off first
plot(f,-2,2, axes=FALSE)
# re-set the axes at a given point (pos=0)
axis(1, pos=0, at=c(-2,-1,0,1,2))
axis(2, pos=0, at=c(-4,-2,2,4))
produces the below, which is what I had in mind (labels and the rest can be then adjusted at will).

Changing x-Axis in r

I would like to change x-axis of a plot in r. For example:
r<-c(1:10)
plot(r)
axis(1,at=10/(1:10),labels=NULL)
but I see the old values on the x-axis too. I want to have only new values on x-axis.What should I do to?
You should use axes argument in plot function and frame.plot argument if you want your plot to have a border, for example:
r<-c(1:10)
plot(r, axes=FALSE, frame.plot=TRUE)
axis(1, at=10/(1:10), labels=NULL)
axis(2, at=axTicks(2), axTicks(2))

Multiple axis/scales on a XY-plot in R

How can I plot a second line in a XY-plot, using plot(), to a different scale like this example (purple line)?
My R code for the first (red) line is something like:
p <- sqlQuery(ch,"SELECT wl,param1 FROM qryPlot ORDER BY wl")
plot(p$wl,p$param1,axes=T,xlim=c(400,800),ylim=c(0,100),type="l",col="red")
Here is the general idea:
plot(1:10)
par(new=T)
plot(1:10, rep(50, 10), type='l', axes=F, xlab=NA, ylab=NA)
axis(4)
I slightly extended the answer by #johncolby to this:
x<-1:20
y1<-sqrt(x)
y2<-sqrt(x)*x
plot(x,y1,ylim=c(0,25),col="blue")
par(new=TRUE)
plot(x,y2,ylim=c(0,100),col="red",axes=FALSE)
axis(4)
(axes=FALSE in second plot() command = to prevent labels second axis printed on the left side)
With this result:
Little problem to solve: labels both y-axes are printed to the left side.

Resources