I don't think it's got the slope exactly right - you'll see this if you go to a really extreme aspect ratio by changing the shape of a window to be long and thin before you call your code. To fix this:
- use "usr" rather than "xaxp" and "yaxp" to get the limits of the plot region in user coordinates; those two refer to the ticks, not the whole plot region as "usr" does. - "fin" is the whole figure region, not just the plot region; you need to use "plt" to modify it to find the plot region within it. So I think the aspect ratio should really be done as pars <- par("fin", "plt") asp.ratio <- (diff(pars$plt)[1]*pars$fin[1]) / (diff(pars$plt)[3]*pars$fin[2]) Some other suggestions: - split the function into two: one that determines a slope from the data, and one that converts a slope to an angle suitable for "srt". (I think the latter would have pretty wide use; the former is pretty specialized for data the way you're using it). - use the fact that defaults in a function call can be local variables in the function, so that you only need one call to par() instead of 4. (The 4 calls probably take a negigible amount of time, but it just looks wasteful to make them.) Duncan Murdoch On 2/4/2006 5:19 PM, ivo welch wrote: > Thank you, Duncan. This led me to the info I needed. Here is a > simple utility function that does what I needed---maybe it will come > in helpful for others. > > ################################################################ > #### native.slope computes a suitable srt from a function around > #### a point on a function. This is useful until text() gets > #### an srt parameter that is relative to the coordinate system. > #### (Ideally, R would be able to slope along a function.) > ################################################################ > > native.slope <- function( x, y, where.i, > xlim = par()$xaxp, ylim= par()$yaxp, > asp.ratio = (par()$fin)[1]/(par()$fin)[2] ) { > if (where.i<=1) { return(0); } > if (where.i>=length(y)) { return(0); } > if (length(x)!=length(y)) { > stop("native.slope: Sorry, but x and y must have equal dimensions, > not ", length(x), " and ", length(y), "\n"); } > > # native slope in a 1:1 coordinate system > d= ( (y[where.i-1]-y[where.i+1])/(x[where.i-1]-x[where.i+1]) ); > if (is.na(d)) return(0); # we do not know how to handle an undefined > spot at a function! > > d.m= (ylim[2]-ylim[1])/(xlim[2]-xlim[1]); # now adjust by the axis scale > if (is.na(d)) stop("native.slope: internal error, I do not have > sensible axis dimensions (", xlim, ylim, ")\n"); > > if (is.na(asp.ratio)) stop("native.slope: internal error, I do not > have a reasonable drawing aspect ratio"); > > net.slope= d/asp.ratio/d.m; > return(slope = atan(net.slope)/pi*180.0 ) > } > > > # some test code > x<- seq(-10,20,by=0.1) > y<- x*x; > > plot( x, y, type="l" ); > > display= ((1:length(y))%%40 == 0) > > for (i in 1:(length(y))) { > if (display[i]) { > points(x[i],y[i], pch=19); > srt= native.slope( x, y, i ); > text( x[i], y[i], paste(i,"=",x[i],"=",srt), srt=srt, cex=0.9 ); > } > } > > > > On 2/4/06, Duncan Murdoch <[EMAIL PROTECTED]> wrote: >> On 2/4/2006 3:50 PM, ivo welch wrote: >>> [resent, plus small addition; I do not understand why gmail sent a >>> weird charset.] >>> >>> Dear R wizards: >>> >>> I would love to write a general function that matches the slope of a plotted >>> line in an xy-plot at a particular x,y location. something like >>> >>> x<- (1:10)^2; y<- 40:50; >>> plot( x,y, type="l", xlim=c(0,90) ) >>> srt.at5 = text.at.current.plot.with.slope( x, y, 5); >>> text( x[5],y[5], pos=3, srt=srt.at.5); >>> >>> to do this, I first need to compute the function slope around x[5], which is >>> an easy task. alas, the harder task is that I need to scale this by the >>> plot aspect ratio and the axes. How can a function read this from the >>> current plot? >> I haven't done this, but you can presumably work it out from the >> conversions implied by the "fig", "fin", "plt", and/or "usr" values. >>> (Has someone written such a function, perhaps more embellished, to save me >>> the debugging effort?) >>> >>> Or, is there an alternative to srt, which slopes the text relative to the >>> existing scale? >>> >>> *** come to think of it, what I would really like is the ability of >>> text to 'snake' itself along the line itself. I doubt that this is >>> easily possible, but I just wanted to ask. >> Using strsplit and strwidth you should be able to do it, but it will >> probably look quite ugly. >> >> Duncan Murdoch >> ______________________________________________ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html