37

I want to make a 2D plot where the x-axis is flipped so the higher numbers are on the right and lower numbers are on the left.

I've managed to do it by flipping the data and making new Ticks but this solution is manually and requires manipulating the data. I was hoping there was a better way.

For the normal plot:

data = Table[{x, x^2}, {x, 20, 100}];
ListLinePlot[data]

Mathematica graphics

And for the flipped data and the new plot:

data = Table[{100 - x + 20, x^2}, {x, 20, 100}];
ticks = Table[{x, 100 - x + 20}, {x, 20, 100, 10}]
ListLinePlot[data, Ticks -> {ticks, Automatic}]

Mathematica graphics

I couldn't seem to find any options like ReverseAxis.

s0rce
  • 9,632
  • 4
  • 45
  • 78

6 Answers6

45

@Mr. Wizard pointed to a thread that mentioned the option ScalingFunctions which works for BarChart and Histogram according to the documentation and supports a Reverse option.

I simply tried this with ListLinePlot and although the ScalingFunctions appears in red, it works!

ListLinePlot[data, ScalingFunctions -> {"Reverse", Identity}]

Mathematica graphics

Thanks @Mr. Wizard and undocumented magic functions!

s0rce
  • 9,632
  • 4
  • 45
  • 78
16

Here is a bit different solution

d = Transpose@data;
ListLinePlot[ Transpose@{Reverse@d[[1]], d[[2]]}, 
              Ticks -> {Transpose@{Range[20, 100, 10], Range[100, 20, -10]}, Automatic}]

enter image description here

If we don't like to specify in advance ranges of ticks, here is another, more general approach :

ListLinePlot[ Transpose @ { Reverse@ d[[1]], d[[2]]}, 
              Ticks -> {Transpose @ { Range[ Min[#], Max[#], 
                                     10^(Ceiling@Log[10, (Max[#] - Min[#])] - 1)] &@d[[1]], 
                                     Range[Max[#], Min[#], 
                                     -10^(Ceiling@Log[10, (Max[#] - Min[#])] - 1)] & @ d[[1]]},
                                      Automatic}]
Artes
  • 57,212
  • 12
  • 157
  • 245
  • @belisarius I was mislead by two different definitions of data in the OP question. So I had to update my earlier answer. – Artes May 18 '12 at 18:05
  • I imagined that, and posted my comment so that you could come with a different answer. Well done +1 – Dr. belisarius May 18 '12 at 22:40
  • @belisarius Thanks for an upvote. I don't understand your approach. The plot in your post seems to be ok, but when I applied your solution to the first definition of data in the OP question the ticks on the x axes are not reversed. How do I get what the OP wanted ? – Artes May 18 '12 at 22:58
  • Something got tangled (probably some neurons) when I pasted the code here. Thanks for the warning! Try the code now – Dr. belisarius May 18 '12 at 23:24
  • @belisarius Now it works +1. – Artes May 18 '12 at 23:27
9

For flipping the axes I use the following function:

Options[flippeAchsen] = Union[{Achsen -> 1}, Options[Graphics]];
flippeAchsen[pp_Graphics, opts : OptionsPattern[]] := 
 Module[{tx, ty, labx, laby, GAPx, GAPy, qq, xyRule, x, y, achs, 
   TICKS, ticks, gropts, frame, FTall}, achs = OptionValue[Achsen];
  If[achs > 3, FTall = True; achs = Mod[achs, 3, 1], FTall = False];
  frame = OptionValue[Frame];
  TICKS = If[frame === True, FrameTicks, Ticks];
  gropts = Sequence @@ FilterRules[Flatten[{opts}], Options[Graphics]];
  tx = AbsoluteOptions[pp, TICKS][[1, 2, 1]];
  ty = AbsoluteOptions[pp, TICKS][[1, 2, 2]];
  labx = Select[Flatten[Cases[tx, {n_, l_, rest__}]], NumericQ];
  laby = Select[Flatten[Cases[ty, {n_, l_, rest__}]], NumericQ];
  GAPx = Max[labx] - Min[labx];
  GAPy = Max[laby] - Min[laby];
  Which[achs == 1,(*x Achse*)
   xyRule = {x_?NumericQ, y_?NumericQ} -> {GAPx - x, y};
   ticks = {Map[{GAPx - First[#], Sequence @@ Rest[#]} &, tx], ty}, 
   achs == 2,(*y Achse*)
   xyRule = {x_?NumericQ, y_?NumericQ} -> {x, GAPy - y};
   ticks = {tx, Map[{GAPy - First[#], Sequence @@ Rest[#]} &, ty]}, 
   achs == 3,(*beide Achsen*)
   xyRule = {x_?NumericQ, y_?NumericQ} -> {GAPx - x, GAPy - y};
   ticks = {Map[{GAPx - First[#], Sequence @@ Rest[#]} &, tx], 
     Map[{GAPy - First[#], Sequence @@ Rest[#]} &, ty]}];
  ticks = 
   If[frame === True, 
    If[FTall === 
      True, {{ticks[[2]], ticks[[2]]}, {ticks[[1]], 
       ticks[[1]]}}, {{ticks[[2]], None}, {ticks[[1]], None}}], ticks];
  Show[pp /. xyRule, Evaluate[gropts], Axes -> True, PlotRange -> All,
    AxesOrigin -> AbsoluteOptions[pp, AxesOrigin][[1, 2]] /. xyRule, 
   TICKS -> ticks]]

The option Achsen choses the axes to flip:

Achsen->1 reverts the first (x-axis)
Achsen->2 reverts the second (y-axis
Achsen->3 reverts both

If you use FrameTicks you must pass this option to flippeAchsen too.
In frames the ticks are drawn bottom and left by default. If one want the Ticks on all four sides, just add 3 to the option Achsen.

Call is: flippeAchsen[plot, Achsen->number]

Peter Breitfeld
  • 5,182
  • 1
  • 24
  • 32
  • Thanks it works, however, when I run flippeAchsen[ListLinePlot[data, AxesOrigin -> {100, 0}], Achsen -> 1] I get a few errors OptionValue::nodef: Unknown option Achsen for flippeAchsen. >> – s0rce May 18 '12 at 13:29
  • 1
    @s0rce For me it works. Did you copy the first Line of the code Options[flippeAchsen]=Union... ? – Peter Breitfeld May 18 '12 at 13:38
  • nope, I missed it. Thanks, it works now! – s0rce May 18 '12 at 13:50
9

Mike Honeychurch wrote a package ReverseListPlot that does this; it's available on MathSource.

Verbeia
  • 34,233
  • 9
  • 109
  • 224
4

Probably can be simplified:

k1 = Transpose@({Reverse[#[[1]]], #[[2]]} &@Transpose@data);
ListLinePlot[k1, 
 Ticks -> ({Transpose[({#[[1]], Reverse@#[[2]], #[[3]], #[[4]]} &@
           Transpose[Sort@#[[1, 2, 1]]])], #[[1, 2, 2]]} &@
                                                    AbsoluteOptions[ListLinePlot@k1, Ticks])]

enter image description here

Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
1

You may use the following commands:

g = Plot[x^2, {x, 20, 100}]

Mathematica graphics

Show[g /. x_Line :> Reverse[x, 3], PlotRange -> Automatic]

Mathematica graphics

Öskå
  • 8,587
  • 4
  • 30
  • 49
user14592
  • 29
  • 1