Inconsistencies in device_Raster when axes are reflected

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Inconsistencies in device_Raster when axes are reflected

Sharpie
I noticed some undocumented and inconsistent behavior in device_Raster when a plot is produced with reflected axes such as:

    image(volcano, xlim = c(1,0), useRaster = TRUE)
    image(volcano, ylim = c(1,0), useRaster = TRUE)

The `pdf` device will perform horizontal and vertical reflections, while `quartz` will ignore the transformations when plotting to the screen, but when plotting to a file, `quartz(file = 'test.pdf', type = 'pdf')`, it will produce horizontal reflections and ignore vertical ones.

When the `xlim` or `ylim` is reversed, negative widths and heights are passed to the C function `device_Raster`, which is not a behavior documented in `R_ext/GraphicsDevice.h`. Also, the values of `x` and `y` passed to `device_Raster` will be shifted by the width or height of the image such that the coordinates no longer reference the bottom-left corner of the image as `R_ext/GraphicsDevice.h` says they should.

Given the inconsistencies in documentation and behavior, I am wondering what the intended behavior of `device_Raster` is in this situation.

Thanks!

-Charlie
Charlie Sharpsteen
Undergraduate-- Environmental Resources Engineering
Humboldt State University
Reply | Threaded
Open this post in threaded view
|

Re: Inconsistencies in device_Raster when axes are reflected

Paul Murrell
Hi

On 12/01/2012 7:11 a.m., Sharpie wrote:

> I noticed some undocumented and inconsistent behavior in device_Raster when a
> plot is produced with reflected axes such as:
>
>      image(volcano, xlim = c(1,0), useRaster = TRUE)
>      image(volcano, ylim = c(1,0), useRaster = TRUE)
>
> The `pdf` device will perform horizontal and vertical reflections, while
> `quartz` will ignore the transformations when plotting to the screen, but
> when plotting to a file, `quartz(file = 'test.pdf', type = 'pdf')`, it will
> produce horizontal reflections and ignore vertical ones.
>
> When the `xlim` or `ylim` is reversed, negative widths and heights are
> passed to the C function `device_Raster`, which is not a behavior documented
> in `R_ext/GraphicsDevice.h`. Also, the values of `x` and `y` passed to
> `device_Raster` will be shifted by the width or height of the image such
> that the coordinates no longer reference the bottom-left corner of the image
> as `R_ext/GraphicsDevice.h` says they should.
>
> Given the inconsistencies in documentation and behavior, I am wondering what
> the intended behavior of `device_Raster` is in this situation.

I think the problem is that I just failed to anticipate this situation
(i.e., the current documentation and behaviour both assume xlim[1] <
xlim[2] and ylim[1] < ylim[2]).

Will take a look at where to apply a fix (EITHER allow the API to be
more flexible [allow negative 'width' and 'height' and 'x' and 'y' to be
other than left-bottom], which will require complicating the code in
some devices OR keep the API fixed and complicate the graphics engine
code instead).  The rotation argument adds an interesting twist ...

Thanks for the report!

Paul

> Thanks!
>
> -Charlie
>
> -----
> Charlie Sharpsteen
> Undergraduate-- Environmental Resources Engineering
> Humboldt State University
> --
> View this message in context: http://r.789695.n4.nabble.com/Inconsistencies-in-device-Raster-when-axes-are-reflected-tp4286320p4286320.html
> Sent from the R devel mailing list archive at Nabble.com.
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

--
Dr Paul Murrell
Department of Statistics
The University of Auckland
Private Bag 92019
Auckland
New Zealand
64 9 3737599 x85392
[hidden email]
http://www.stat.auckland.ac.nz/~paul/

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: Inconsistencies in device_Raster when axes are reflected

Sharpie
Paul Murrell wrote
I think the problem is that I just failed to anticipate this situation
(i.e., the current documentation and behaviour both assume xlim[1] <
xlim[2] and ylim[1] < ylim[2]).

Will take a look at where to apply a fix (EITHER allow the API to be
more flexible [allow negative 'width' and 'height' and 'x' and 'y' to be
other than left-bottom], which will require complicating the code in
some devices OR keep the API fixed and complicate the graphics engine
code instead).  The rotation argument adds an interesting twist ...

Thanks for the report!

Paul
Thanks for the reply Paul!

This isn't too hard to handle at the device level. For example, all I had to do to the tikzDevice was add a loop and some logic that re-ordered the raster vector and re-positioned the coordinate anchor:


int i, j, index, target, row_offset = 0, col_offset = 0, row_trans = 1, col_trans = 1;
  if ( height < 0 ) {
    /* Using these parameters, one can cause a loop to "count backwards" */
    row_trans = -1;
    row_offset = h - 1;
    /*
     * If a dimension is negative, the (x,y) coordinate no longer references
     * the lower left corner of the image. We correct for this and then make
     * sure the dimension is positive.
     */
    y += height;
    height = fabs(height);
  }

  if ( width < 0 ) {
    col_trans = -1;
    col_offset = w - 1;
    x += width;
    width = fabs(width);
  }

  for ( i = 0; i < h; ++i ) {
    for ( j = 0; j < w; ++j ) {
      target = i*w + j;
      index = (row_trans*i + row_offset)*w + (col_trans*j + col_offset);

      INTEGER(red_vec)[target] = R_RED(raster[index]);
      INTEGER(green_vec)[target] = R_BLUE(raster[index]);
      INTEGER(blue_vec)[target] = R_GREEN(raster[index]);
      INTEGER(alpha_vec)[target] = R_ALPHA(raster[index]);
    }
  }


This gives the device the same behavior as the PDF device. So, the behavior isn't too difficult to correct on the device end---I was just concerned by the difference between documentation and behavior and wanted to make sure the graphics engine was not expecting something different.


-Charlie
Charlie Sharpsteen
Undergraduate-- Environmental Resources Engineering
Humboldt State University