plotTree = function (dat) { # settings width = 500 # pixel plt = c(5, 98) / 100 asp = 1.25 # ratio (y / x) circle = 20 # ratio to par('cin')[1] text = 0.25 # ratio to circle lwd = 0.5 # line width bgcolor = 'whiteSmoke' xlm = c(1, 2 ^ floor(log2(nrow(dat)))) xpd = diff(xlm) / 18 * c(-1, 1) ypd = xpd / asp xlm = xlm + xpd ylm = range(dat$y) + ypd height1 = width * (plt[2] - plt[1]) * diff(ylm) * asp / diff(xlm) height2 = width * plt[1] + height1 + width * (1 - plt[2]) plt[3] = width * plt[1] / height2 plt[4] = (width * plt[1] + height1) / height2 svg('.test.svg', width=width/96, height=height2/96) par(bg=bgcolor, plt = plt, xpd=NA) cexCircle = par('cin')[1] * circle cexText = cexCircle * text plot(asp=asp, axes=F, type='n', x=xlm, y=ylm, xlab='', ylab='', xaxs='i', yaxs='i') for (i in 2:nrow(dat)) lines(dat[c(i, floor(i / 2)),], col='red') points(dat, cex=cexCircle, pch=21, bg='white', lwd=lwd) text(dat, label=dat$val, cex=cexText) par(cex=cexText, tck=0.03) xat = seq(1, xlm[2] - 1, by=2) yat = unique(dat$y) for (i in 1:2) { if (i == 1) { at = xat } else { at = yat } axis(i, at=at, col=NA, col.ticks=1, labels=NA, lwd=lwd) } usr = par('usr') xlbAt = usr[1] - diff(usr[1:2]) / diff(plt[1:2]) * (plt[1] / 4) ylbAt = usr[3] - diff(usr[3:4]) / diff(plt[3:4]) * (plt[3] / 2) text(label=xat, x=xat, y=ylbAt) text(adj=1, label=yat, x=xlbAt, y=yat) box(lwd=lwd) graphics.off() } plotTree(dat)