Greetings all! I'm wanting to plot contours of a function, and I don't want to evaluate it at a dense grid of points (i.e. I don't want a huge array of values). Say I have a vector of x-values such as x <- 0.1*c(1:10), and the same for y <- 0.1*(0:10). I then evaluate a 10*10 matrix z of values of z = f(x,y). so I can then do CL <- contourLines(x,y,z) and get a list of contour-lines, each list containing the x and y coordinates. When I look at the plot from contour(x,y,z), I see that the lines are (as expected) made up of straight-line segments. But the break-points between the segments seem to either have x-coords on the x-values in x, or have y-coords on the y-values in y. In other words, the breaks occur on the sides of the squares of the grid defined by x and y. So quite often the straight-line segments are quite long, and the resulting contours do not look at all smooth. An example of what I'm talking about can be seen from the following code: n2 <- function(x,y){ dnorm(x,0.25,0.3)*dnorm(y,0.25,0.3) + dnorm(x,0.75,0.3)*dnorm(y,0.75,0.3) } x <- y <- 0.1*(0:10) z <- matrix(numeric(121),nrow=11) for(i in (0:11)){ for(j in (1:11)){ z[i,j]<-n2(x[i],y[j]) } } contour(x,y,z,nlevels=10) for(i in (1:11)) lines(c(x[i],x[i]),c(0,1)) for(i in (1:11)) lines(c(0,1),c(y[i],y[i])) I could get whatever minute difference between contour-levels I like by setting the nlevels or levels parameter. But there doesn't seem to be any way of achieving finer resolution in where the break-points occur. It is just as coarse, and always breaks on the grid-lines. Looking at the plot, it seems that this is due to an algorithm which linearly interpolates along the sides of the grid squares, and joins the resulting points by line segments. It seems that contourLines() generates the same breakpoints as occur in the plot from contour(). I would be happy with the relatively few contour lines and the fairly coarse spacing between contour levels shown in the above plot, but would like to have smoother contours without having to use denser grid spacing such as x <- y <- 0.005*(0:200) z <- matrix(numeric(40401),nrow=201) #etc Is there a function which, perhaps, produces contours by non-linear interpolation, and curved smoothing between interpolated points, to a specified resolution between break-points? I have had a poke under "functions" in the R-Site Help and Archive Search at http://finzi.psych.upenn.edu, searching on "contour", but nothing has leapt obviously to the eye amongst the 494 hits. With thanks, Ted. -------------------------------------------------------------------- E-Mail: (Ted Harding) <Ted.Harding at manchester.ac.uk> Fax-to-email: +44 (0)870 094 0861 Date: 13-Sep-09 Time: 23:49:06 ------------------------------ XFMail ------------------------------
Have you looked at lowess? That is the function that Harrell's perimeter function calls for that purpose. -- David On Sep 13, 2009, at 6:54 PM, (Ted Harding) wrote:> Greetings all! > I'm wanting to plot contours of a function, and I don't > want to evaluate it at a dense grid of points (i.e. I don't > want a huge array of values). > > Say I have a vector of x-values such as x <- 0.1*c(1:10), > and the same for y <- 0.1*(0:10). > > I then evaluate a 10*10 matrix z of values of z = f(x,y). > > so I can then do > > CL <- contourLines(x,y,z) > > and get a list of contour-lines, each list containing the > x and y coordinates. > > When I look at the plot from contour(x,y,z), I see that the > lines are (as expected) made up of straight-line segments. > But the break-points between the segments seem to either have > x-coords on the x-values in x, or have y-coords on the y-values > in y. In other words, the breaks occur on the sides of the > squares of the grid defined by x and y. > > So quite often the straight-line segments are quite long, and > the resulting contours do not look at all smooth. > > An example of what I'm talking about can be seen from the > following code: > > n2 <- function(x,y){ > dnorm(x,0.25,0.3)*dnorm(y,0.25,0.3) + > dnorm(x,0.75,0.3)*dnorm(y,0.75,0.3) > } > > x <- y <- 0.1*(0:10) > z <- matrix(numeric(121),nrow=11) > for(i in (0:11)){ for(j in (1:11)){ z[i,j]<-n2(x[i],y[j]) } } > > contour(x,y,z,nlevels=10) > for(i in (1:11)) lines(c(x[i],x[i]),c(0,1)) > for(i in (1:11)) lines(c(0,1),c(y[i],y[i])) > > I could get whatever minute difference between contour-levels > I like by setting the nlevels or levels parameter. But there > doesn't seem to be any way of achieving finer resolution in > where the break-points occur. It is just as coarse, and always > breaks on the grid-lines. > > Looking at the plot, it seems that this is due to an algorithm > which linearly interpolates along the sides of the grid squares, > and joins the resulting points by line segments. > > It seems that contourLines() generates the same breakpoints as > occur in the plot from contour(). > > I would be happy with the relatively few contour lines and the > fairly coarse spacing between contour levels shown in the above > plot, but would like to have smoother contours without having to > use denser grid spacing such as > > x <- y <- 0.005*(0:200) > z <- matrix(numeric(40401),nrow=201) > #etc > > Is there a function which, perhaps, produces contours by non-linear > interpolation, and curved smoothing between interpolated points, > to a specified resolution between break-points? > > I have had a poke under "functions" in the R-Site Help and Archive > Search at http://finzi.psych.upenn.edu, searching on "contour", > but nothing has leapt obviously to the eye amongst the 494 hits. > > With thanks, > Ted. > > -------------------------------------------------------------------- > E-Mail: (Ted Harding) <Ted.Harding at manchester.ac.uk> > Fax-to-email: +44 (0)870 094 0861 > Date: 13-Sep-09 Time: 23:49:06 > ------------------------------ XFMail ------------------------------ > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.David Winsemius, MD Heritage Laboratories West Hartford, CT
On Sep 13, 2009, at 6:54 PM, (Ted Harding) wrote:> Greetings all! > I'm wanting to plot contours of a function, and I don't > want to evaluate it at a dense grid of points (i.e. I don't > want a huge array of values). > > Say I have a vector of x-values such as x <- 0.1*c(1:10), > and the same for y <- 0.1*(0:10). > > I then evaluate a 10*10 matrix z of values of z = f(x,y). > > so I can then do > > CL <- contourLines(x,y,z) > > and get a list of contour-lines, each list containing the > x and y coordinates. > > When I look at the plot from contour(x,y,z), I see that the > lines are (as expected) made up of straight-line segments. > But the break-points between the segments seem to either have > x-coords on the x-values in x, or have y-coords on the y-values > in y. In other words, the breaks occur on the sides of the > squares of the grid defined by x and y. > > So quite often the straight-line segments are quite long, and > the resulting contours do not look at all smooth. > > An example of what I'm talking about can be seen from the > following code: > > n2 <- function(x,y){ > dnorm(x,0.25,0.3)*dnorm(y,0.25,0.3) + > dnorm(x,0.75,0.3)*dnorm(y,0.75,0.3) > } > > x <- y <- 0.1*(0:10) > z <- matrix(numeric(121),nrow=11) > for(i in (0:11)){ for(j in (1:11)){ z[i,j]<-n2(x[i],y[j]) } } > > contour(x,y,z,nlevels=10)Also, consider this Thin plate spline solution from Bill Dunlap earlier this year: library(fields) xy<-as.matrix(expand.grid(x=x,y=y)) contour(predict.surface(Tps(as.matrix(expand.grid(x=x, y=y)), as.vector(z) ))) -- David Winsemius> for(i in (1:11)) lines(c(x[i],x[i]),c(0,1)) > for(i in (1:11)) lines(c(0,1),c(y[i],y[i])) > > I could get whatever minute difference between contour-levels > I like by setting the nlevels or levels parameter. But there > doesn't seem to be any way of achieving finer resolution in > where the break-points occur. It is just as coarse, and always > breaks on the grid-lines. > > Looking at the plot, it seems that this is due to an algorithm > which linearly interpolates along the sides of the grid squares, > and joins the resulting points by line segments. > > It seems that contourLines() generates the same breakpoints as > occur in the plot from contour(). > > I would be happy with the relatively few contour lines and the > fairly coarse spacing between contour levels shown in the above > plot, but would like to have smoother contours without having to > use denser grid spacing such as > > x <- y <- 0.005*(0:200) > z <- matrix(numeric(40401),nrow=201) > #etc > > Is there a function which, perhaps, produces contours by non-linear > interpolation, and curved smoothing between interpolated points, > to a specified resolution between break-points? > > I have had a poke under "functions" in the R-Site Help and Archive > Search at http://finzi.psych.upenn.edu, searching on "contour", > but nothing has leapt obviously to the eye amongst the 494 hits. > > With thanks, > Ted. > > -------------------------------------------------------------------- > E-Mail: (Ted Harding) <Ted.Harding at manchester.ac.uk> > Fax-to-email: +44 (0)870 094 0861 > Date: 13-Sep-09 Time: 23:49:06 > ------------------------------ XFMail -------------------------------- David Winsemius, MD Heritage Laboratories West Hartford, CT