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:
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:
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.
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):
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.
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))