From ligges at statistik.uni-dortmund.de  Fri May 27 11:42:54 2005
From: ligges at statistik.uni-dortmund.de (ligges@statistik.uni-dortmund.de)
Date: Fri May 27 11:43:01 2005
Subject: [Rd] Reversing axis in a log plot (PR#7894)
Message-ID: <20050527094254.7EACF8601@slim.kubism.ku.dk>

This is a multi-part message in MIME format.
--MIMEStream=_0+99651_873538045512443_0843898189
Content-Type: text/plain; charset="us-ascii"; format=flowed
Content-Transfer-Encoding: 7bit

Please find attached my proposal for a bugfix. The experts might to 
better, though.

Uwe Ligges



ligges@statistik.uni-dortmund.de wrote:

> Yes, this one is a bug in CreateAtVector, plot.c.
> It already has the lines:
> 
> 
>      /* Debugging: When does the following happen... ? */
>      if (umin > umax)
>          warning("CreateAtVector \"log\"(from axis()): "
>              "usr[0] = %g > %g = usr[1] !", umin, umax);
> 
> 
> And now we know that it happens if (and only if?????) the logarithmic 
> scale is not very small (i.e. axp[2] > 0, this is equal to R's 
> par("yaxp")[3] in your example) and the axis are reversed (umin > umax).
> 
> I'll try to provide a fix which should be possible by reversing 
> arguments axp and usr in this case and returning a reversed at ...
> 
> Uwe Ligges
> 
> 
> 
> 
> marquardt.christian@gmail.com wrote:
> 
> 
>>Full_Name: Christian Marquardt
>>Version: 2.1.0
>>OS: Linux (Redhat 9)
>>Submission from: (NULL) (151.170.240.10)
>>
>>Following the advice of a reader of R-help, I would now like to submit this as a
>>bug report:
>>
>>Say we have
>>
>>  x = seq(1,3, by = 0.01)
>>  y = exp(x)
>>
>>Plotting and reversing linear axis is fine
>>
>>   plot(x,y)
>>   plot(x,y, ylim = c(30,1))
>>
>>as is a usual log-plot:
>>
>>  plot(x,y, log = "y", ylim = c(1,30))
>>
>>However,
>>
>>  plot(x,y, log = "y", ylim = c(30,1))
>>
>>fails with
>>
>>  Error in axis(2, ...) : log - axis(), 'at' creation, _SMALL_ range:
>>invalid {xy}axp or par;
>>         axp[0]= 10, usr[0:1]=(34.3721,0.872801)
>>  In addition: Warning message:
>>  CreateAtVector "log"(from axis()): usr[0] = 34.3721 > 0.872801 = usr[1] !
>>
>>
>>According to Petr Pikal <petr.pikal -at- precheza.cz>, replacing the ylim
>>argument by ylim = c(30,1.2) helps in the above example; but in my real world
>>applications, it's actually difficult to find a working value for ylim.
>>
>>I hope this is useful,
>>
>>  Christian.
>>
>>______________________________________________
>>R-devel@stat.math.ethz.ch mailing list
>>https://stat.ethz.ch/mailman/listinfo/r-devel
> 
> 
> ______________________________________________
> R-devel@stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel


--MIMEStream=_0+99651_873538045512443_0843898189
Content-Type: text/plain; name="plot.c.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="plot.c.diff"

--- plot.c-orig	2005-05-27 10:38:39.851718400 +0200
+++ plot.c	2005-05-27 11:40:10.118060800 +0200
@@ -778,8 +778,10 @@
  *  The resulting REAL vector must have length >= 1, ideally >= 2
  */
     SEXP at = R_NilValue;/* -Wall*/
-    double umin, umax, dn, rng, small;
+    SEXP atr = R_NilValue;/* for reversed log axis with axp[2]>0 */
+    double umin, umax, dn, rng, small, reversed;
     int i, n, ne;
+    reversed = 0.; /* for reversed log axis with axp[2]>0 */
     if (!logflag || axp[2] < 0) { /* --- linear axis --- Only use axp[] arg. */
     n = fabs(axp[2]) + 0.25;/* >= 0 */
     dn = imax2(1, n);
@@ -799,6 +801,19 @@
        n = 1,2,3.  see switch() below */
     umin = usr[0];
     umax = usr[1];
+
+    if (umin > umax && axp[0] > axp[1]){
+        /* if we have log axis, axp[2]>0 and reversed axis, many following calculations will fail 
+           (assuming umin < umax etc.), hence simply reverse usr and axp at first.
+           At the end reverse output of atr(eversed) back again. */
+        umin = usr[1];
+        umax = usr[0];
+        reversed = axp[0];
+        axp[0] = axp[1];
+        axp[1] = reversed;
+        reversed = 1.;
+    }
+    
     /* Debugging: When does the following happen... ? */
     if (umin > umax)
         warning("CreateAtVector \"log\"(from axis()): "
@@ -899,7 +914,15 @@
           axp[2]);
     }
     }
-    return at;
+    if(reversed == 1.){
+        /* we have to reverse the output back again (reversed log axis with axp[2]>0) */
+        atr = allocVector(REALSXP, n);
+        for (i = 0; i < n; i++)
+            REAL(atr)[i] = REAL(at)[n-i-1];
+        return atr;
+    }
+    else 
+        return at;
 }
 
 static double ComputePAdjValue(double padj, int side, int las)

--MIMEStream=_0+99651_873538045512443_0843898189--


[Rd] Reversing axis in a log plot (PR#7894)
ligges@statistik.uni-dortmund.de