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]