R YaleToolkit: How to change the font size of tick labels on the sparklines?

Ben picture Ben · Dec 1, 2011 · Viewed 7.8k times · Source

I'm using this function for some quick and easy sparklines with R but I can't seem to work out how to change the font size to avoid ugly overlaps of the y-axis tick labels. Here's my code (see below for a reproducible example):

sparklines(gamma.df, sub=c(1:23),outer.margin = unit(c(2, 2, 2, 2), "cm"))

and the resulting plot:

enter image description here

I seem to be able to completely suppress the y-axis with

sparklines(gamma.df, sub=c(1:23),yaxis=FALSE,outer.margin = unit(c(2, 2, 2, 2), "cm"))

But what I really want is just shrink the numbers at the tick marks (and add grey fill under the line, but it looks like I'd have to draw polygons on the screen which is probably enough trouble to deserve a separate question... and a different package).

The documentation suggests that gpar might be relevant: 'In all the cases where a list of graphics parameters is needed, the valid parameter names are the same as would be valid when passed to gpar in the appropriate call.' But I need a bit of help to make sense of that as none of my attempts seem to get anywhere (ditto for cex.axis and axis()). Any experts on R's grid graphics out there? Links to a well-documented completely different approach (ggplot2?) that gives better quality sparkline-style output are welcome also.

Here's some example data and code that replicates my problem:

x <- data.frame(V = rnorm(1000), W = rnorm(1000), X = rnorm(1000), Y = rnorm(1000), Z = rnorm(10))
sparklines(x,outer.margin = unit(c(2, 2, 2, 2), "cm")) 

And here's the resulting example data plot with ugly overlapping numbers at the y-axis tickmarks:

enter image description here

UPDATE: Using the very helpful plot code from @geek-on-acid and some code from the Tufte forum (see below) I've come up with an alternative sparkline method that doesn't use the YaleToolkit package and looks alright... Here's a reproducible example (really just two lines, but annotated here for my education):

     x <- data.frame(V = rnorm(1000), W = rnorm(1000), X = rnorm(1000), Y = rnorm(1000), 
     Z = rnorm(1000)) # get a bit of data

    par(mfrow=c(ncol(x),1), #sets number of rows in space to number of cols in data frame x
    mar=c(1,0,0,0), #sets margin size for the figures
    oma=c(4,5,4,4)) #sets outer margin

    for (i in 1:ncol(x)){ # setup for statement to loops over all elements in a list or vector
        plot(x[,i], #use col data, not rows from data frame x
        col="grey",lwd=0.5, #make the line grey and thin
        axes=F,ylab="",xlab="",main="",type="l"); #suppress axes lines, set as line plot
        axis(2,yaxp=c(min(x[,i]),max(x[,i]),2), # y-axis: only show tickmarks for max and min values of col
        cex.axis=1.1,las=1, # shrink fontsize slightly, make text horizontal for easy reading
        at=c(round(min(x[,i]),3),round(max(x[,i]),3))); #specify where tickmark numbers go and round them to keep it tidy
        axis(2,yaxp=c(min(x[,i]),max(x[,i]),2),col="white",tcl=0,labels=FALSE)  #y-axis: put a 2nd white axis line over the 1st y-axis to make it invisible
        ymin<-min(x[,i]); tmin<-which.min(x[,i]);ymax<-max(x[,i]);tmax<-which.max(x[,i]); # see the code from Jason below for what these do 
        points(x=c(tmin,tmax),y=c(ymin,ymax),pch=19,col=c("red","blue"),cex=1) # add coloured points at max and min
        }
        axis(1,pos=c(-5)) # places horizontal axis at the bottom of it all. 

Here's the resulting image, which is basically the solution to my problem. The y-axis tick marks try to be elegant by showing only the max and min values of the data and having no vertical line. Thanks again to @geek-on-acid for the tip on how to I get a single x-axis along the bottom of them all.

enter image description here

Finally, for completeness I include some code for sparklines closer to Tufte's style by Jason Dieterle that I found on the Tufte forum. They look much nicer than mine, but the code only does one plot at a time. Here's the original post:

#Here is a simple R implementation of sparklines. Running sparkline() will generate a random sparkline; running sparkline(yourdata) will generate a sparkline using the data in yourdata. As an example, here is Google's stock price for the last year.

#R sparklines
sparkline<-function(ydata=rnorm(100,500,50),width=1.5,height=0.5,sigfigs=4) {

# ydata = vector of data to be plotted
# width = width of sparlkline in inches, including text
# height = height of sparkline in inches
# sigfigs = number of significant figures to round min, max, and last values to

    temppar<-par(no.readonly = TRUE) # store default graphics parameters
    par(mai=c(0.10,0.05,0.10,0.05),fin=c(width,height)) # adjust graphics parameters for sparklines
    len<-length(ydata) # determine the length of the data set
    ymin<-min(ydata) # determine the minimum
    tmin<-which.min(ydata) # and its index
    ymax<-max(ydata) # determine the maximum
    tmax<-which.max(ydata) # and its index
    yfin<-signif(ydata[len],sigfigs) #determine most recent data point
    plotrange=c(ymin-0.3*(ymax-ymin),ymax+0.3*(ymax-ymin)) # define plot range to leave enough room for min and max circles and text
    plot(x=1:len,y=ydata,type="l",xlim=c(1,len*1.5),ylim=plotrange,col="gray",lwd=0.5,ann=FALSE,axes=FALSE) # plot sparkline
    points(x=c(tmin,tmax),y=c(ymin,ymax),pch=19,col=c("red","blue"),cex=0.5) # plot min and max points
    text(x=len,y=ymin,labels=signif(ymin,sigfigs),cex=0.5,pos=4,col="red") # show minimum value
    text(x=len,y=ymax,labels=signif(ymax,sigfigs),cex=0.5,pos=4,col="blue") # show maximum value
    text(x=len,y=(ymin+ymax)/2,labels=yfin,cex=0.5,pos=4) # show most recent value
    par(temppar) # restore graphics defaults
}
#-- Jason Dieterle (email), January 28, 2008

and here's what his output looks like (enlarged a little):

enter image description here

In addition to the YaleToolkit package, there is the sparkTable package which I learnt of at stats.stackexchange but have not tried. R-forge has an entry for another package to make sparklines, but this one appears not to have be active or useful.

Answer

Geek On Acid picture Geek On Acid · Dec 1, 2011

Well, sparklines are heavily dependant on grid package, so you need to dig deep to search for those font size parameters. Playing with viewpoint will probably get you there. For an easy (but VERY 'raw') solution, just use simple plotting options using par - this way you can manipulate almost every parameter very easily:

 x <- data.frame(V = rnorm(1000), W = rnorm(1000), X = rnorm(1000),
      Y = rnorm(1000), Z = rnorm(10))
 par(mfrow=c(5,1),mar=c(1,0,0,0),oma=c(4,5,4,4))
 plot(x$V,axes=F,ylab="",xlab="",main="",type="l");axis(2,cex.axis=0.7)
 plot(x$W,axes=F,ylab="",xlab="",main="",type="l");axis(2,cex.axis=0.7)
 plot(x$X,axes=F,ylab="",xlab="",main="",type="l");axis(2,cex.axis=0.7)
 plot(x$Y,axes=F,ylab="",xlab="",main="",type="l");axis(2,cex.axis=0.7)
 plot(x$Z,axes=F,ylab="",xlab="",main="",type="l");axis(2,cex.axis=0.7)
 axis(1,pos=c(-2))

enter image description here