Re: Reversing the axis of a plot
- To: mathgroup at smc.vnet.net
- Subject: [mg15191] Re: Reversing the axis of a plot
- From: Thomas Wachtler <thomas at NOSPAM.salk.edu>
- Date: Fri, 18 Dec 1998 02:11:07 -0500
- Organization: The Scripps Research Institute, La Jolla, CA
- References: <757jb6$cm9$7@dragonfly.wolfram.com>
- Sender: owner-wri-mathgroup at wolfram.com
John,
I had the same problem, and I tried to write a function that
would generate a reversed plot from a given Graphics object.
It turned out to be a pain, without knowing what goes on
inside Show[]. The result (see below) works in many cases, but
would have to be extended to account for all possible Options
you might want to use.
I think the only good solution to this can be to incorporate
this feature as a Graphics Option. I would appreciate comments
from the developers on the list as to whether anything like that
is intended for a future version.
Thomas
(* Code for plots with reversed axis *) (* the basic idea is to map the
coordinate values of the graphics
primitives as well as the Tick marks back to the same interval,
but in reversed order. *)
(* In order to get reversed Tick marks, I found it necessary to
modify the definition of TickFunction *) (* add the lines marked with
(**) to the code in `ExtendGraphics`Ticks *)
Options[ TickFunction] =
{
MajorLength -> {0.00625, 0},
MinorLength -> {0.003125, 0},
MajorStyle -> {Thickness[0.002]},
MinorStyle -> {Thickness[0.001]},
TextFunction -> Automatic,
TickLabels -> Automatic,
TickNumbers -> {8, 32},
(**) Reverse -> False
}
TickFunction[ x0_, x1_, opts___] :=
Block[{maj, min, majlen, minlen, opt, tnums,
majstyle, minstyle, textfun, labs (**) , rev
},
opt = Join[ {opts}, Options[ TickFunction]] ;
majlen = MajorLength /. opt ;
minlen = MinorLength /. opt ;
majstyle = MajorStyle /. opt ;
minstyle = MinorStyle /. opt ;
textfun = TextFunction /. opt ;
labs = TickLabels /. opt ;
(**) rev = Reverse /. opt ;
tnums = CheckNumbers[ TickNumbers /. opt] ;
If[ textfun === Automatic, textfun = TrimDecimal] ;
maj = TickPosition[ x0, x1, First[ tnums]] ;
min = TickPosition[ x0, x1, Last[ tnums]] ;
min = Complement[ min, maj] ;
maj = If[ MatrixQ[ labs],
Map[ {#, ""}&, maj],
Transpose[ {maj, textfun[ maj]}]] ;
maj = Map[ {#[[1]], #[[2]], majlen, majstyle}&, maj] ;
If[ Apply[ Plus, minlen] =!= 0,
min = Map[ {#, "", minlen, minstyle}&, min] ;
maj = Join[ maj, min]] ;
If[ MatrixQ[ labs],
maj = Join[ maj, Map[ Join[#, {{0,0}}]&, labs]]] ; (**)
If[ NumberQ[ rev],
(**) Map[ Join[ {rev - #[[1]]}, Drop[ #, 1]]&, maj ],
maj
(**) ]
]
(* functions to reverse Graphics primitives - extend for other
primitive as needed *)
LineReverseX[ lst_, xr_] := Line[Map[{xr-#[[1]], #[[2]]}&, lst]];
PointReverseX[ {x_,y_}, xr_] := Point[{xr-x,y}];
(* ShowReverseX reverses a plot along the x axis *)
ShowReverseX[ gr_Graphics, opts___] := Module[
{xr,tcks,frmtcks,pltrng,axorig,tckfct,revrule,newgr},
xr = Plus@@{Min[#],Max[#]}&[
Join[Cases[Flatten[ gr[[1]]], _Line], Cases[Flatten[ gr[[1]]],
_Point]] /.
{Line -> ((Transpose[#][[1]])&), Point -> ((#[[1]])&)}];
tckfct[x_] := TickFunction[ #1, #2, Reverse->x ]&;
tcks = Ticks /. Join[{opts}, gr[[2]]];
If[ Length[tcks] < 2, tcks = {tcks,tcks}];
tcks = {tckfct[xr], tcks[[2]]};
pltrng = PlotRange /. Join[{opts}, gr[[2]]];
If[Length[pltrng] == 2, pltrng = { xr-pltrng[[1]], pltrng[[2]] },
Null];
axorig = AxesOrigin /. Join[{opts}, gr[[2]]];
If[Length[axorig] == 2, axorig = {xr, 0} + {-1,1}*axorig, Null];
Return[ Show[ Graphics[ gr[[1]] /.
{ Line -> (LineReverseX[#, xr]&),
Point -> (PointReverseX[#,xr]&) },
Join[{Ticks->tcks, AxesOrigin->axorig,
PlotRange->pltrng},{opts},gr[[2]]]
]]];
];
(* Example: *)
(*
>>I want to reverse the x-axis of the
>>plot of 3x^2+5x+2.
*)
ShowReverseX[ Plot[ 3 x^2 + 5 x + 2, {x,1,5},
DisplayFunction->Identity],
DisplayFunction->$DisplayFunction]