Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
Hi Gabor Grothendieck wrote: On 6/6/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: On 6/2/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Thanks. I have mucked around in vpTree structures and discovered its actually quite easy to specify children so I have changed my example so that instead of naming the children of 'layout' and then remembering coordinates linked to the names of the children of 'layout' in the 'coords' structure (which really just duplicates state information already available in grid) it simply follows the order of the children of 'layout' directly. This permits elimination of 'coords' and the two naming functions. Using the depth approach you advocate, 'with' also becomes shorter and I think I have it to the point where it works with both vpPath and viewport classes. Once Deepayan implements the use.viewport= argument to print, 'with' can be eliminated too. No questions this time but I thought I would post the latest version for completeness. Regards. Ok. I can see this working ... for now. The disadvantage with this approach is that it makes use of the undocumented, internal structure of a viewport tree to grab a list of child viewports. A worse example of the same thing is that the with() methods make use of a happy coincidence that both viewport objects and viewport path objects share a component called name (and an even happier coincidence that they contain the same information). I think it would be cleaner and better practice, despite requiring longer code, to make use of the documented interface which requires specifying viewport names and viewport paths. The internal structure of objects is not guaranteed to be stable. Perhaps accessor functions could be provided that allow one to retrieve the name of a viewport and the name of a vpPath in a safe way. These could be as simple as: names.viewport - names.vpPath - function(x) x$name Fair enough. If I say use the API, I should provide a useful API :) This is a reasonable request for viewports; the name component of a viewport is a sensible thing to want. OTOH, it is not necessarily reasonable for a viewport path; not all components of an object should necessarily have accessors. The name component of a viewport path is the last element in the path. Perhaps an API should be supplied for extracting parts of a viewport path, but it should probably be something along the lines of car()/cdr() or head()/tail() or explode() to get different bits of the path. Accessing the children of a viewport is subtly problematic too. Directly accessing the children slot and using the order of the children in that slot is dangerous because there is no claim made by the system as to how the children are internally ordered. Again, it works currently, but it makes incorrect assumptions about what the system is doing internally so is vulnerable to future changes. So again, the recommended approach is to use the API provided; you provide the naming scheme for viewports and you control the order in which viewports are used. Paul Similarly an accessor function to safely retrieve the children would be nice.Again, it should ideally be possible to have a generic with methods for various grid classes. Then the relevant line in the code concerning name could be written in a safe way like this: depth - if (data$name == ROOT) 0 else downViewport(names(data)) and similarly for the children. Paul [pushLayout is same as before except there are no names on the children of 'layout' and the rest is new] library(grid) library(lattice) pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j)) upViewport() } } upViewport() } with.vpPath - with.viewport - function(data, expr, ...) { # if data is a vpPath it cannot be ROOT since NULL will never dispatch here depth - if (data$name == ROOT) 0 else downViewport(data$name) result - eval.parent(substitute(expr)) upViewport(depth) invisible(result) } grid.newpage() # specify number of cells to fill and number of rows n - 5; nr - 3 nc - ceiling(n/nr) downViewport(pushLayout(nr, nc)) vpt - current.vpTree(all = FALSE) for(k in 1:n) with(vpt$children[[k]], print( xyplot(v ~ v, list(v = 1:k)), newpage = FALSE ) ) -- Dr Paul Murrell Department of Statistics The University of Auckland Private Bag 92019 Auckland New Zealand 64 9 3737599 x85392 [EMAIL PROTECTED] http://www.stat.auckland.ac.nz/~paul/ -- Dr Paul Murrell Department of Statistics The University of Auckland Private Bag 92019 Auckland New Zealand 64 9 3737599 x85392 [EMAIL PROTECTED] http://www.stat.auckland.ac.nz/~paul/ __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
On 6/7/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: On 6/6/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: On 6/2/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Thanks. I have mucked around in vpTree structures and discovered its actually quite easy to specify children so I have changed my example so that instead of naming the children of 'layout' and then remembering coordinates linked to the names of the children of 'layout' in the 'coords' structure (which really just duplicates state information already available in grid) it simply follows the order of the children of 'layout' directly. This permits elimination of 'coords' and the two naming functions. Using the depth approach you advocate, 'with' also becomes shorter and I think I have it to the point where it works with both vpPath and viewport classes. Once Deepayan implements the use.viewport= argument to print, 'with' can be eliminated too. No questions this time but I thought I would post the latest version for completeness. Regards. Ok. I can see this working ... for now. The disadvantage with this approach is that it makes use of the undocumented, internal structure of a viewport tree to grab a list of child viewports. A worse example of the same thing is that the with() methods make use of a happy coincidence that both viewport objects and viewport path objects share a component called name (and an even happier coincidence that they contain the same information). I think it would be cleaner and better practice, despite requiring longer code, to make use of the documented interface which requires specifying viewport names and viewport paths. The internal structure of objects is not guaranteed to be stable. Perhaps accessor functions could be provided that allow one to retrieve the name of a viewport and the name of a vpPath in a safe way. These could be as simple as: names.viewport - names.vpPath - function(x) x$name Fair enough. If I say use the API, I should provide a useful API :) This is a reasonable request for viewports; the name component of a viewport is a sensible thing to want. OTOH, it is not necessarily reasonable for a viewport path; not all components of an object should necessarily have accessors. The name component of a viewport path is the last element in the path. Perhaps an API should be supplied for extracting parts of a viewport path, but it should probably be something along the lines of car()/cdr() or head()/tail() or explode() to get different bits of the path. Accessing the children of a viewport is subtly problematic too. Directly accessing the children slot and using the order of the children in that slot is dangerous because there is no claim made by the system as to how the children are internally ordered. Again, it works currently, but it makes incorrect assumptions about what the system is doing internally so is vulnerable to future changes. That is the point of an accessor. If the internals change then the accessor is modified to hide the change so that the user using the accessor is not impacted. It seems that grid already partly supports this with the childNames function. It could be made generic and a method provided to cover the classes discussed here too. So again, the recommended approach is to use the API provided; you provide the naming scheme for viewports and you control the order in which viewports are used. Paul Similarly an accessor function to safely retrieve the children would be nice.Again, it should ideally be possible to have a generic with methods for various grid classes. Then the relevant line in the code concerning name could be written in a safe way like this: depth - if (data$name == ROOT) 0 else downViewport(names(data)) and similarly for the children. Paul [pushLayout is same as before except there are no names on the children of 'layout' and the rest is new] library(grid) library(lattice) pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j)) upViewport() } } upViewport() } with.vpPath - with.viewport - function(data, expr, ...) { # if data is a vpPath it cannot be ROOT since NULL will never dispatch here depth - if (data$name == ROOT) 0 else downViewport(data$name) result - eval.parent(substitute(expr)) upViewport(depth) invisible(result) } grid.newpage() # specify number of cells to fill and number of rows n - 5; nr - 3 nc - ceiling(n/nr) downViewport(pushLayout(nr, nc)) vpt - current.vpTree(all = FALSE) for(k in 1:n) with(vpt$children[[k]], print( xyplot(v ~ v, list(v = 1:k)), newpage = FALSE ) ) -- Dr Paul
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
Hi Gabor Grothendieck wrote: On 6/7/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: On 6/6/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: On 6/2/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Thanks. I have mucked around in vpTree structures and discovered its actually quite easy to specify children so I have changed my example so that instead of naming the children of 'layout' and then remembering coordinates linked to the names of the children of 'layout' in the 'coords' structure (which really just duplicates state information already available in grid) it simply follows the order of the children of 'layout' directly. This permits elimination of 'coords' and the two naming functions. Using the depth approach you advocate, 'with' also becomes shorter and I think I have it to the point where it works with both vpPath and viewport classes. Once Deepayan implements the use.viewport= argument to print, 'with' can be eliminated too. No questions this time but I thought I would post the latest version for completeness. Regards. Ok. I can see this working ... for now. The disadvantage with this approach is that it makes use of the undocumented, internal structure of a viewport tree to grab a list of child viewports. A worse example of the same thing is that the with() methods make use of a happy coincidence that both viewport objects and viewport path objects share a component called name (and an even happier coincidence that they contain the same information). I think it would be cleaner and better practice, despite requiring longer code, to make use of the documented interface which requires specifying viewport names and viewport paths. The internal structure of objects is not guaranteed to be stable. Perhaps accessor functions could be provided that allow one to retrieve the name of a viewport and the name of a vpPath in a safe way. These could be as simple as: names.viewport - names.vpPath - function(x) x$name Fair enough. If I say use the API, I should provide a useful API :) This is a reasonable request for viewports; the name component of a viewport is a sensible thing to want. OTOH, it is not necessarily reasonable for a viewport path; not all components of an object should necessarily have accessors. The name component of a viewport path is the last element in the path. Perhaps an API should be supplied for extracting parts of a viewport path, but it should probably be something along the lines of car()/cdr() or head()/tail() or explode() to get different bits of the path. Accessing the children of a viewport is subtly problematic too. Directly accessing the children slot and using the order of the children in that slot is dangerous because there is no claim made by the system as to how the children are internally ordered. Again, it works currently, but it makes incorrect assumptions about what the system is doing internally so is vulnerable to future changes. That is the point of an accessor. If the internals change then the accessor is modified to hide the change so that the user using the accessor is not impacted. It seems that grid already partly supports this with the childNames function. It could be made generic and a method provided to cover the classes discussed here too. I agree that a childNames() method for a viewport tree is probably reasonable. The subtle problem is the fact that your code makes use of the *order* of the names that function would return, when in fact there is no claim that they will be in any particular order. Paul So again, the recommended approach is to use the API provided; you provide the naming scheme for viewports and you control the order in which viewports are used. Paul Similarly an accessor function to safely retrieve the children would be nice.Again, it should ideally be possible to have a generic with methods for various grid classes. Then the relevant line in the code concerning name could be written in a safe way like this: depth - if (data$name == ROOT) 0 else downViewport(names(data)) and similarly for the children. Paul [pushLayout is same as before except there are no names on the children of 'layout' and the rest is new] library(grid) library(lattice) pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j)) upViewport() } } upViewport() } with.vpPath - with.viewport - function(data, expr, ...) { # if data is a vpPath it cannot be ROOT since NULL will never dispatch here depth - if (data$name == ROOT) 0 else downViewport(data$name) result - eval.parent(substitute(expr)) upViewport(depth) invisible(result) } grid.newpage() # specify number of cells to fill and number of rows n - 5; nr - 3 nc - ceiling(n/nr) downViewport(pushLayout(nr,
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
Here is the code once again. This time I have supplied two names methods and a getChildren.viewport function to encapsulate the corresponding grid internals. It would be easiest if grid provided these itself but in the absence of that this does encapsulate dependencies on grid internals to a well defined set of functions. Note that names is only used in 'with' and 'with' will be eliminated once Deepayan adds the use.viewport= (or whatever its called) to print. I am not sure from your response whether or not you intend to add these items to the grid API but in any case this provides an intermediate level of safety. library(grid) library(lattice) pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j)) upViewport() } } upViewport() } names.vpPath - names.viewport - function(x) x$name with.vpPath - with.viewport - function(data, expr, ...) { # if data is a vpPath it cannot be ROOT since # NULL will never dispatch here depth - if (data$name == ROOT) 0 else downViewport(names(data)) result - eval.parent(substitute(expr)) upViewport(depth) invisible(result) } getChildren.viewport - function(x) x$children grid.newpage() # specify number of cells to fill and number of rows n - 5; nr - 3 nc - ceiling(n/nr) downViewport(pushLayout(nr, nc)) vpt - current.vpTree(all = FALSE) for(k in 1:n) with(getChildren.viewport(vpt)[[k]], print( xyplot(v ~ v, list(v = 1:k)), newpage = FALSE ) ) __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
Yes, I understand that although such order is convenient for the user as the significant reduction in code size here shows. I wonder if there might be some performance parameter (e.g. hash) to control it. If hash = TRUE then no guarantee is provided. Otherwise order is kept. On 6/7/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: On 6/7/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: On 6/6/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: On 6/2/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Thanks. I have mucked around in vpTree structures and discovered its actually quite easy to specify children so I have changed my example so that instead of naming the children of 'layout' and then remembering coordinates linked to the names of the children of 'layout' in the 'coords' structure (which really just duplicates state information already available in grid) it simply follows the order of the children of 'layout' directly. This permits elimination of 'coords' and the two naming functions. Using the depth approach you advocate, 'with' also becomes shorter and I think I have it to the point where it works with both vpPath and viewport classes. Once Deepayan implements the use.viewport= argument to print, 'with' can be eliminated too. No questions this time but I thought I would post the latest version for completeness. Regards. Ok. I can see this working ... for now. The disadvantage with this approach is that it makes use of the undocumented, internal structure of a viewport tree to grab a list of child viewports. A worse example of the same thing is that the with() methods make use of a happy coincidence that both viewport objects and viewport path objects share a component called name (and an even happier coincidence that they contain the same information). I think it would be cleaner and better practice, despite requiring longer code, to make use of the documented interface which requires specifying viewport names and viewport paths. The internal structure of objects is not guaranteed to be stable. Perhaps accessor functions could be provided that allow one to retrieve the name of a viewport and the name of a vpPath in a safe way. These could be as simple as: names.viewport - names.vpPath - function(x) x$name Fair enough. If I say use the API, I should provide a useful API :) This is a reasonable request for viewports; the name component of a viewport is a sensible thing to want. OTOH, it is not necessarily reasonable for a viewport path; not all components of an object should necessarily have accessors. The name component of a viewport path is the last element in the path. Perhaps an API should be supplied for extracting parts of a viewport path, but it should probably be something along the lines of car()/cdr() or head()/tail() or explode() to get different bits of the path. Accessing the children of a viewport is subtly problematic too. Directly accessing the children slot and using the order of the children in that slot is dangerous because there is no claim made by the system as to how the children are internally ordered. Again, it works currently, but it makes incorrect assumptions about what the system is doing internally so is vulnerable to future changes. That is the point of an accessor. If the internals change then the accessor is modified to hide the change so that the user using the accessor is not impacted. It seems that grid already partly supports this with the childNames function. It could be made generic and a method provided to cover the classes discussed here too. I agree that a childNames() method for a viewport tree is probably reasonable. The subtle problem is the fact that your code makes use of the *order* of the names that function would return, when in fact there is no claim that they will be in any particular order. Paul So again, the recommended approach is to use the API provided; you provide the naming scheme for viewports and you control the order in which viewports are used. Paul Similarly an accessor function to safely retrieve the children would be nice.Again, it should ideally be possible to have a generic with methods for various grid classes. Then the relevant line in the code concerning name could be written in a safe way like this: depth - if (data$name == ROOT) 0 else downViewport(names(data)) and similarly for the children. Paul [pushLayout is same as before except there are no names on the children of 'layout' and the rest is new] library(grid) library(lattice) pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j))
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
Hi Gabor Grothendieck wrote: Here is the code once again. This time I have supplied two names methods and a getChildren.viewport function to encapsulate the corresponding grid internals. It would be easiest if grid provided these itself but in the absence of that this does encapsulate dependencies on grid internals to a well defined set of functions. Note that names is only used in 'with' and 'with' will be eliminated once Deepayan adds the use.viewport= (or whatever its called) to print. I am not sure from your response whether or not you intend to add these items to the grid API but in any case this provides an intermediate level of safety. Yep, I've made a note to look at adding these to the grid API. Thanks. Paul library(grid) library(lattice) pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j)) upViewport() } } upViewport() } names.vpPath - names.viewport - function(x) x$name with.vpPath - with.viewport - function(data, expr, ...) { # if data is a vpPath it cannot be ROOT since # NULL will never dispatch here depth - if (data$name == ROOT) 0 else downViewport(names(data)) result - eval.parent(substitute(expr)) upViewport(depth) invisible(result) } getChildren.viewport - function(x) x$children grid.newpage() # specify number of cells to fill and number of rows n - 5; nr - 3 nc - ceiling(n/nr) downViewport(pushLayout(nr, nc)) vpt - current.vpTree(all = FALSE) for(k in 1:n) with(getChildren.viewport(vpt)[[k]], print( xyplot(v ~ v, list(v = 1:k)), newpage = FALSE ) ) -- Dr Paul Murrell Department of Statistics The University of Auckland Private Bag 92019 Auckland New Zealand 64 9 3737599 x85392 [EMAIL PROTECTED] http://www.stat.auckland.ac.nz/~paul/ __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
Thanks. Yet one other comment to consider when thinking about this. Even if its not possible or advisable to guarantee order, even without the hash= idea, it may be possible to guarantee that default names are generated in some order that can be used by getChildren to ensure that it returns the children in the same order they are created or perhaps even some sort of timestamp can be attached to objects to facilitate later traversal. On 6/7/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: Here is the code once again. This time I have supplied two names methods and a getChildren.viewport function to encapsulate the corresponding grid internals. It would be easiest if grid provided these itself but in the absence of that this does encapsulate dependencies on grid internals to a well defined set of functions. Note that names is only used in 'with' and 'with' will be eliminated once Deepayan adds the use.viewport= (or whatever its called) to print. I am not sure from your response whether or not you intend to add these items to the grid API but in any case this provides an intermediate level of safety. Yep, I've made a note to look at adding these to the grid API. Thanks. Paul library(grid) library(lattice) pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j)) upViewport() } } upViewport() } names.vpPath - names.viewport - function(x) x$name with.vpPath - with.viewport - function(data, expr, ...) { # if data is a vpPath it cannot be ROOT since # NULL will never dispatch here depth - if (data$name == ROOT) 0 else downViewport(names(data)) result - eval.parent(substitute(expr)) upViewport(depth) invisible(result) } getChildren.viewport - function(x) x$children grid.newpage() # specify number of cells to fill and number of rows n - 5; nr - 3 nc - ceiling(n/nr) downViewport(pushLayout(nr, nc)) vpt - current.vpTree(all = FALSE) for(k in 1:n) with(getChildren.viewport(vpt)[[k]], print( xyplot(v ~ v, list(v = 1:k)), newpage = FALSE ) ) -- Dr Paul Murrell Department of Statistics The University of Auckland Private Bag 92019 Auckland New Zealand 64 9 3737599 x85392 [EMAIL PROTECTED] http://www.stat.auckland.ac.nz/~paul/ __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
Hi Gabor Grothendieck wrote: On 6/2/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Thanks. I have mucked around in vpTree structures and discovered its actually quite easy to specify children so I have changed my example so that instead of naming the children of 'layout' and then remembering coordinates linked to the names of the children of 'layout' in the 'coords' structure (which really just duplicates state information already available in grid) it simply follows the order of the children of 'layout' directly. This permits elimination of 'coords' and the two naming functions. Using the depth approach you advocate, 'with' also becomes shorter and I think I have it to the point where it works with both vpPath and viewport classes. Once Deepayan implements the use.viewport= argument to print, 'with' can be eliminated too. No questions this time but I thought I would post the latest version for completeness. Regards. Ok. I can see this working ... for now. The disadvantage with this approach is that it makes use of the undocumented, internal structure of a viewport tree to grab a list of child viewports. A worse example of the same thing is that the with() methods make use of a happy coincidence that both viewport objects and viewport path objects share a component called name (and an even happier coincidence that they contain the same information). I think it would be cleaner and better practice, despite requiring longer code, to make use of the documented interface which requires specifying viewport names and viewport paths. The internal structure of objects is not guaranteed to be stable. Paul [pushLayout is same as before except there are no names on the children of 'layout' and the rest is new] library(grid) library(lattice) pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j)) upViewport() } } upViewport() } with.vpPath - with.viewport - function(data, expr, ...) { # if data is a vpPath it cannot be ROOT since NULL will never dispatch here depth - if (data$name == ROOT) 0 else downViewport(data$name) result - eval.parent(substitute(expr)) upViewport(depth) invisible(result) } grid.newpage() # specify number of cells to fill and number of rows n - 5; nr - 3 nc - ceiling(n/nr) downViewport(pushLayout(nr, nc)) vpt - current.vpTree(all = FALSE) for(k in 1:n) with(vpt$children[[k]], print( xyplot(v ~ v, list(v = 1:k)), newpage = FALSE ) ) -- Dr Paul Murrell Department of Statistics The University of Auckland Private Bag 92019 Auckland New Zealand 64 9 3737599 x85392 [EMAIL PROTECTED] http://www.stat.auckland.ac.nz/~paul/ __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
On 6/6/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: On 6/2/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Thanks. I have mucked around in vpTree structures and discovered its actually quite easy to specify children so I have changed my example so that instead of naming the children of 'layout' and then remembering coordinates linked to the names of the children of 'layout' in the 'coords' structure (which really just duplicates state information already available in grid) it simply follows the order of the children of 'layout' directly. This permits elimination of 'coords' and the two naming functions. Using the depth approach you advocate, 'with' also becomes shorter and I think I have it to the point where it works with both vpPath and viewport classes. Once Deepayan implements the use.viewport= argument to print, 'with' can be eliminated too. No questions this time but I thought I would post the latest version for completeness. Regards. Ok. I can see this working ... for now. The disadvantage with this approach is that it makes use of the undocumented, internal structure of a viewport tree to grab a list of child viewports. A worse example of the same thing is that the with() methods make use of a happy coincidence that both viewport objects and viewport path objects share a component called name (and an even happier coincidence that they contain the same information). I think it would be cleaner and better practice, despite requiring longer code, to make use of the documented interface which requires specifying viewport names and viewport paths. The internal structure of objects is not guaranteed to be stable. Perhaps accessor functions could be provided that allow one to retrieve the name of a viewport and the name of a vpPath in a safe way. These could be as simple as: names.viewport - names.vpPath - function(x) x$name Similarly an accessor function to safely retrieve the children would be nice.Again, it should ideally be possible to have a generic with methods for various grid classes. Then the relevant line in the code concerning name could be written in a safe way like this: depth - if (data$name == ROOT) 0 else downViewport(names(data)) and similarly for the children. Paul [pushLayout is same as before except there are no names on the children of 'layout' and the rest is new] library(grid) library(lattice) pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j)) upViewport() } } upViewport() } with.vpPath - with.viewport - function(data, expr, ...) { # if data is a vpPath it cannot be ROOT since NULL will never dispatch here depth - if (data$name == ROOT) 0 else downViewport(data$name) result - eval.parent(substitute(expr)) upViewport(depth) invisible(result) } grid.newpage() # specify number of cells to fill and number of rows n - 5; nr - 3 nc - ceiling(n/nr) downViewport(pushLayout(nr, nc)) vpt - current.vpTree(all = FALSE) for(k in 1:n) with(vpt$children[[k]], print( xyplot(v ~ v, list(v = 1:k)), newpage = FALSE ) ) -- Dr Paul Murrell Department of Statistics The University of Auckland Private Bag 92019 Auckland New Zealand 64 9 3737599 x85392 [EMAIL PROTECTED] http://www.stat.auckland.ac.nz/~paul/ __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
On 6/2/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Thanks. I have mucked around in vpTree structures and discovered its actually quite easy to specify children so I have changed my example so that instead of naming the children of 'layout' and then remembering coordinates linked to the names of the children of 'layout' in the 'coords' structure (which really just duplicates state information already available in grid) it simply follows the order of the children of 'layout' directly. This permits elimination of 'coords' and the two naming functions. Using the depth approach you advocate, 'with' also becomes shorter and I think I have it to the point where it works with both vpPath and viewport classes. Once Deepayan implements the use.viewport= argument to print, 'with' can be eliminated too. No questions this time but I thought I would post the latest version for completeness. Regards. [pushLayout is same as before except there are no names on the children of 'layout' and the rest is new] library(grid) library(lattice) pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j)) upViewport() } } upViewport() } with.vpPath - with.viewport - function(data, expr, ...) { # if data is a vpPath it cannot be ROOT since NULL will never dispatch here depth - if (data$name == ROOT) 0 else downViewport(data$name) result - eval.parent(substitute(expr)) upViewport(depth) invisible(result) } grid.newpage() # specify number of cells to fill and number of rows n - 5; nr - 3 nc - ceiling(n/nr) downViewport(pushLayout(nr, nc)) vpt - current.vpTree(all = FALSE) for(k in 1:n) with(vpt$children[[k]], print( xyplot(v ~ v, list(v = 1:k)), newpage = FALSE ) ) __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
On 6/1/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: [moved from r-help to r-devel] On 5/31/05, Paul Murrell [EMAIL PROTECTED] wrote: # mm.row[j] gives the row in the layout of the jth cell # mm.col[j] gives the col in the layout of the jth cell mm - matrix(seq(nr*nc), nr, nc) mm.row - c(row(mm)) mm.col - c(col(mm)) # go to next cell in the array j - j + 1 # increment position pushViewport(viewport(layout.pos.row = mm.row[j], layout.pos.col = mm.col[j])) Is that how to do it or is there some layout/mfcol-like way? That is how to do it. As far as grid is concerned, all viewports are equal and grid has no idea whether a viewport corresponds to a plot region or a margin or whatever, so grid has no concept of which viewport is the next one to use. OK. Thanks. One suggestion. Maybe the cells in a layout could have an order to them and there could be an optional argument that takes a linear index directly allowing easy linear traversals: for(i in seq(nr*nc)) { pushViewport(viewport(i)) # might need different syntax here xyplot(seq(i) ~ seq(i)) popViewport() } I think this sort of thing can easily be built on top rather than into the existing system. For example, here's a function that pushes all of the basic cells in a layout using a simple naming convention: layoutVPname - function(i, j) { paste(layoutViewport, i, ,, j, sep=) } layoutVPpath - function(i, j, name=layout) { vpPath(name, layoutVPname(i, j)) } pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j, name=layoutVPname(i, j))) upViewport() } } upViewport() } And here's a use of the function to push lots of layout cells, then draw lattice plots in different cells using downViewport() to go to the cell with the appropriate name. In this case, we use cells by column, but simply reverse the order of the loops to use cells by row. pushLayout(2, 3) for (i in 1:2) { for (j in 1:3){ depth - downViewport(layoutVPpath(i, j)) print(xyplot(seq(i*j) ~ seq(i*j)), newpage=FALSE) upViewport(depth) } } and taking it one further perhaps 'with' could have a viewport method that automatically pushes the viewport on entry and pops or moves up one level on exit reducing the above to: for(i in seq(nr*nc)) with(viewport(i), xyplot(seq(i) ~ seq(i))) The raw grid functions have a 'vp' argument for this purpose. It would be nice if lattice functions had something similar (or maybe just print.trellis). Here's your example using the 'vp' argument to grid.text() (and using the layout that was pushed above) ... for (i in 1:2) { for (j in 1:3){ grid.text(i*j, vp=layoutVPpath(i, j)) } } The following includes an implementation of 'with.vpPath'. I got some strange results but by trial and error seem to have circumvented them yet I am still not sure that I have the real solution: 1. If I delete the indicated line with the comments which special-cases ROOT then it gives the error also shown in the comments. Why do I have to handle ROOT specially? 2. If I know a viewport how can I find out its vpPath? 3. Will identical code to my with.vpPath work with viewports if I relabel the name to with.viewport? Will seekViewport work with viewport too? The docs say seekViewport takes a name but it seems it at least works on a vpPath too. I would like to be able to hand to 'with' any reasonable grid object (vpPath, name, viewport, any other objects?) and have it work as expected. 4. Given a viewport how can one find its vpPath? its children? its parent? vp - current.viewport() vp$name # this gets name but I want entire vpPath 5. How can I pop everything I have created? Do I have to keep track of every viewport and then visit each one and pop it? Most of the code below is taken from your post to me but 'with.vpPath' onward are new. Thanks. library(lattice) library(grid) layoutVPname - function(i, j) { paste(layoutViewport, i, j, sep= .) } layoutVPpath - function(i, j, name=layout) { vpPath(name, layoutVPname(i, j)) } pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j, name=layoutVPname(i, j))) upViewport() } } upViewport() } with.vpPath - function(data, expr, ...) { # modified from drawInVP cur - current.viewport() seekViewport(data) result - eval.parent(substitute(expr)) # if I comment out next line I get this error: # Error in
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
Hi Gabor Grothendieck wrote: [moved from r-help to r-devel] On 5/31/05, Paul Murrell [EMAIL PROTECTED] wrote: # mm.row[j] gives the row in the layout of the jth cell # mm.col[j] gives the col in the layout of the jth cell mm - matrix(seq(nr*nc), nr, nc) mm.row - c(row(mm)) mm.col - c(col(mm)) # go to next cell in the array j - j + 1 # increment position pushViewport(viewport(layout.pos.row = mm.row[j], layout.pos.col = mm.col[j])) Is that how to do it or is there some layout/mfcol-like way? That is how to do it. As far as grid is concerned, all viewports are equal and grid has no idea whether a viewport corresponds to a plot region or a margin or whatever, so grid has no concept of which viewport is the next one to use. OK. Thanks. One suggestion. Maybe the cells in a layout could have an order to them and there could be an optional argument that takes a linear index directly allowing easy linear traversals: for(i in seq(nr*nc)) { pushViewport(viewport(i)) # might need different syntax here xyplot(seq(i) ~ seq(i)) popViewport() } I think this sort of thing can easily be built on top rather than into the existing system. For example, here's a function that pushes all of the basic cells in a layout using a simple naming convention: layoutVPname - function(i, j) { paste(layoutViewport, i, ,, j, sep=) } layoutVPpath - function(i, j, name=layout) { vpPath(name, layoutVPname(i, j)) } pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j, name=layoutVPname(i, j))) upViewport() } } upViewport() } And here's a use of the function to push lots of layout cells, then draw lattice plots in different cells using downViewport() to go to the cell with the appropriate name. In this case, we use cells by column, but simply reverse the order of the loops to use cells by row. pushLayout(2, 3) for (i in 1:2) { for (j in 1:3){ depth - downViewport(layoutVPpath(i, j)) print(xyplot(seq(i*j) ~ seq(i*j)), newpage=FALSE) upViewport(depth) } } and taking it one further perhaps 'with' could have a viewport method that automatically pushes the viewport on entry and pops or moves up one level on exit reducing the above to: for(i in seq(nr*nc)) with(viewport(i), xyplot(seq(i) ~ seq(i))) The raw grid functions have a 'vp' argument for this purpose. It would be nice if lattice functions had something similar (or maybe just print.trellis). Here's your example using the 'vp' argument to grid.text() (and using the layout that was pushed above) ... for (i in 1:2) { for (j in 1:3){ grid.text(i*j, vp=layoutVPpath(i, j)) } } Paul -- Dr Paul Murrell Department of Statistics The University of Auckland Private Bag 92019 Auckland New Zealand 64 9 3737599 x85392 [EMAIL PROTECTED] http://www.stat.auckland.ac.nz/~paul/ __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Re: [R] Problem going back to a viewport with gridBase
On 6/1/05, Paul Murrell [EMAIL PROTECTED] wrote: Hi Gabor Grothendieck wrote: [moved from r-help to r-devel] On 5/31/05, Paul Murrell [EMAIL PROTECTED] wrote: # mm.row[j] gives the row in the layout of the jth cell # mm.col[j] gives the col in the layout of the jth cell mm - matrix(seq(nr*nc), nr, nc) mm.row - c(row(mm)) mm.col - c(col(mm)) # go to next cell in the array j - j + 1 # increment position pushViewport(viewport(layout.pos.row = mm.row[j], layout.pos.col = mm.col[j])) Is that how to do it or is there some layout/mfcol-like way? That is how to do it. As far as grid is concerned, all viewports are equal and grid has no idea whether a viewport corresponds to a plot region or a margin or whatever, so grid has no concept of which viewport is the next one to use. OK. Thanks. One suggestion. Maybe the cells in a layout could have an order to them and there could be an optional argument that takes a linear index directly allowing easy linear traversals: for(i in seq(nr*nc)) { pushViewport(viewport(i)) # might need different syntax here xyplot(seq(i) ~ seq(i)) popViewport() } I think this sort of thing can easily be built on top rather than into the existing system. For example, here's a function that pushes all of the basic cells in a layout using a simple naming convention: layoutVPname - function(i, j) { paste(layoutViewport, i, ,, j, sep=) } layoutVPpath - function(i, j, name=layout) { vpPath(name, layoutVPname(i, j)) } pushLayout - function(nr, nc, name=layout) { pushViewport(viewport(layout=grid.layout(nr, nc), name=name)) for (i in 1:nr) { for (j in 1:nc) { pushViewport(viewport(layout.pos.row=i, layout.pos.col=j, name=layoutVPname(i, j))) upViewport() } } upViewport() } And here's a use of the function to push lots of layout cells, then draw lattice plots in different cells using downViewport() to go to the cell with the appropriate name. In this case, we use cells by column, but simply reverse the order of the loops to use cells by row. pushLayout(2, 3) for (i in 1:2) { for (j in 1:3){ depth - downViewport(layoutVPpath(i, j)) print(xyplot(seq(i*j) ~ seq(i*j)), newpage=FALSE) upViewport(depth) } } and taking it one further perhaps 'with' could have a viewport method that automatically pushes the viewport on entry and pops or moves up one level on exit reducing the above to: for(i in seq(nr*nc)) with(viewport(i), xyplot(seq(i) ~ seq(i))) The raw grid functions have a 'vp' argument for this purpose. It would be nice if lattice functions had something similar (or maybe just print.trellis). Here's your example using the 'vp' argument to grid.text() (and using the layout that was pushed above) ... for (i in 1:2) { for (j in 1:3){ grid.text(i*j, vp=layoutVPpath(i, j)) } } Thanks, again. I'll try modifying your example to fit my specific application (which requires a linear column-wise traversal ending at the nth cell where n may be less than the number of cells in the matrix). __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel