[R] lattice: wireframe "eats up" points; how to make points on wireframe visible?

Marius Hofert m_hofert at web.de
Fri Apr 1 07:33:23 CEST 2011


okay, I found a solution:

library(lattice)

f <- function(x) 1/((1-x[1])*(1-x[2])+1)

u <- seq(0, 1, length.out=20)
grid <- expand.grid(x=u, y=u)
x <- grid[,1]
y <- grid[,2]
z <- apply(grid, 1, f)

pt.x <- c(0.4, 0.7)
pt.y <- c(0.6, 0.8)
eps <- 0.4
pts <- rbind(c(pt.x, f(pt.x)-eps), c(pt.y, f(pt.y))) # points to add to the wireframe

trellis.device("pdf", onefile=FALSE, paper="special", width=5.4, height=5.4)
wireframe(z~x*y, pts=pts, aspect=1, scales=list(col=1, arrows=FALSE),
        zlim=c(0,1), 
        panel.3d.wireframe = function(x,y,z,xlim,ylim,zlim,xlim.scaled,
        ylim.scaled,zlim.scaled,pts,drape=drape,...){
            panel.3dwire(x=x, y=y, z=z, xlim=xlim, ylim=ylim, zlim=zlim,
                         xlim.scaled=xlim.scaled, ylim.scaled=ylim.scaled,
                         zlim.scaled=zlim.scaled,drape=TRUE,...)
            panel.3dscatter(x=pts[,1], y=pts[,2], z=pts[,3],
                            xlim=xlim, ylim=ylim, zlim=zlim, 
                            xlim.scaled=xlim.scaled, ylim.scaled=ylim.scaled,
                            zlim.scaled=zlim.scaled, type="p", col=c(2,3),
                            cex=1.8, pch=c(3,4), .scale=TRUE, ...)
        })
dev.off()

On 2011-03-30, at 23:56 , Marius Hofert wrote:

> Dear Deepayan,
> 
> thanks for answering. It's never too late to be useful.
> 
> I see your point in the minimal example. I checked the z-axis limits in my
> original problem for the point to be inside and it wasn't there. I can't easily
> reproduce it from the minimal example though. I'll get back to you if I run into 
> this problem again.
> 
> In the example below, both points are shown. Although one lies clearly below/under
> the surface, it looks as if it lies above. One would probably have to plot this 
> point first so that the wire frame is above the point. But still, this is 
> misleading since the eye believes that the wireframe is *not* transparent. This
> happens because the lines connecting (0,1,0)--(1,1,0)--(1,0,0) [dashed ones] are
> not completely visible [also not the one from (1,1,0) to (1,1,1)]. How can I make
> them visible even if they lie behind/under the wireframe? I tried to work with 
> col="transparent" and with alpha=... but neither did work as I expected. 
> My goal is to make the small "rectangles" between the wire transparent.
> I also use these plots in posters with a certain gradient-like background color
> and so it's a bit annoying that the "rectangles" are filled with white color. 
> 
> Cheers and many thanks for helping [as usual],
> 
> Marius
> 
> library(lattice)
> 
> f <- function(x) 1/((1-x[1])*(1-x[2])+1)
> 
> u <- seq(0, 1, length.out=20)
> grid <- expand.grid(x=u, y=u)
> x <- grid[,1]
> y <- grid[,2]
> z <- apply(grid, 1, f)
> 
> pt.x <- c(0.4, 0.7)
> pt.y <- c(0.6, 0.8)
> eps <- 0.4
> pts <- rbind(c(pt.x, f(pt.x)-eps), c(pt.y, f(pt.y))) # points to add to the wireframe
> 
> trellis.device("pdf", onefile=FALSE, paper="special", width=5.4, height=5.4)
> wireframe(z~x*y, pts=pts, aspect=1, scales=list(col=1, arrows=FALSE),
>         zlim=c(0,1), 
>         panel.3d.wireframe = function(x,y,z,xlim,ylim,zlim,xlim.scaled,
>         ylim.scaled,zlim.scaled,pts,...){
>             panel.3dwire(x=x, y=y, z=z, xlim=xlim, ylim=ylim, zlim=zlim,
>                          xlim.scaled=xlim.scaled, ylim.scaled=ylim.scaled,
>                          zlim.scaled=zlim.scaled,...)
>             panel.3dscatter(x=pts[,1], y=pts[,2], z=pts[,3],
>                             xlim=xlim, ylim=ylim, zlim=zlim, 
>                             xlim.scaled=xlim.scaled, ylim.scaled=ylim.scaled,
>                             zlim.scaled=zlim.scaled, type="p", col=c(2,3),
>                             cex=1.8, pch=c(3,4), .scale=TRUE, ...)
>         })
> dev.off()
> 
> On 2011-03-30, at 10:52 , Deepayan Sarkar wrote:
> 
>> On Fri, Mar 4, 2011 at 1:47 PM, Marius Hofert <m_hofert at web.de> wrote:
>>> Dear expeRts,
>>> 
>>> I would like to add two points to a wireframe plot. The points have (x,y,z) coordinates
>>> where z is determined to be on the wireframe [same z-value]. Now something strange
>>> happens. One point is perfectly plotted, the other isn't shown at all. It only
>>> appears if I move it upwards in z-direction by adding a positive number. So somehow
>>> it disappears in the wireframe-surface *although* the plot symbol [the cross] has
>>> a positive length in each dimension [I also chose cex=5 to make it large enough so
>>> that it should (theoretically) be visible].
>>> 
>>> My wireframe plot is a complicated function which I cannot post here. Below is a minimal
>>> example, however, it didn't show the same problem [the surface is too nice I guess].
>>> I therefore *artifically* create the problem in the example below so that you know
>>> what I mean. For one of the points, I subtract an epsilon [=0.25] in z-direction and
>>> suddenly the point completely disappears. The strange thing is that the point is
>>> not even "under" the surface [use the screen-argument to rotate the wireframe plot to check this],
>>> it's simply gone, eaten up by the surface.
>>> 
>>> How can I make the two points visible?
>>> I also tried to use the alpha-argument to make the wireframe transparent, but I couldn't
>>> solve the problem.
>>> 
>>> Cheers,
>>> 
>>> Marius
>>> 
>>> PS: One also faces this problem for example if one wants to make points visible that are on "opposite sides" of the wireframe.
>>> 
>>> library(lattice)
>>> 
>>> f <- function(x) 1/((1-x[1])*(1-x[2])+1)
>>> 
>>> u <- seq(0, 1, length.out=20)
>>> grid <- expand.grid(x=u, y=u)
>>> x <- grid[,1]
>>> y <- grid[,2]
>>> z <- apply(grid, 1, f)
>>> 
>>> pt.x <- c(0.2, 0.5)
>>> pt.y <- c(0.6, 0.8)
>>> eps <- 0.25
>>> pts <- rbind(c(pt.x, f(pt.x)-eps), c(pt.y, f(pt.y))) # points to add to the wireframe
>> 
>> The reason in this case is fairly obvious: you have
>> 
>>> pts
>>    [,1] [,2]      [,3]
>> [1,]  0.2  0.5 0.4642857
>> [2,]  0.6  0.8 0.9259259
>> 
>> So the z-value for Point 1 is 0.4642857, which is less than 0.5, the
>> minimum of the z-axis.panel.3dscatter() "clips" any points outside the
>> range of the bounding box, so this point is not plotted.
>> 
>> I can't say what the problem was in your original example without
>> looking at it, but I would guess it's caused by something similar.
>> 
>> Hope this is not too late to be useful.
>> 
>> -Deepayan
>> 
>> 
>> 
>>> 
>>> wireframe(z~x*y, pts=pts, aspect=1, scales=list(col=1, arrows=FALSE),
>>>         panel.3d.wireframe = function(x,y,z,xlim,ylim,zlim,xlim.scaled,
>>>         ylim.scaled,zlim.scaled,pts,...){
>>>             panel.3dwire(x=x, y=y, z=z, xlim=xlim, ylim=ylim, zlim=zlim,
>>>                          xlim.scaled=xlim.scaled, ylim.scaled=ylim.scaled,
>>>                          zlim.scaled=zlim.scaled, ...)
>>>             panel.3dscatter(x=pts[,1], y=pts[,2], z=pts[,3],
>>>                             xlim=xlim, ylim=ylim, zlim=zlim,
>>>                             xlim.scaled=xlim.scaled, ylim.scaled=ylim.scaled,
>>>                             zlim.scaled=zlim.scaled, type="p", col=c(2,3),
>>>                             cex=1.8, .scale=TRUE, ...)
>>>         }, key=list(x=0.5, y=0.95, points=list(col=c(2,3)),
>>>            text=list(c("Point 1", "Point 2")),
>>>            cex=1, align=TRUE, transparent=TRUE))
>>> 
>>> ______________________________________________
>>> 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.
>>> 
> 



More information about the R-help mailing list