Flipping axis on a plot

35

12

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

Posted 2012-05-18T12:53:06.873

Reputation: 9 292

1You've flipped the curve (and that is easily done indeed), but I don't see any difference in the ticks between your first and second image... are you sure that's what you intended? – J. M.'s ennui – 2012-05-18T12:55:34.083

@J.M. fixed, thanks. – s0rce – 2012-05-18T13:00:24.197

2

Strongly related: http://stackoverflow.com/q/5655224/618728

– Mr.Wizard – 2012-05-18T13:50:26.637

Answers

42

@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

Posted 2012-05-18T12:53:06.873

Reputation: 9 292

1It is of note that this does not work in version 7. Good find for v8 users! – Mr.Wizard – 2012-05-18T14:34:25.397

3Unfortunately this does not work with DateListPlot, but it does work with ListPlot/ListLinePlot. As well as "Reverse", "Log" and "Log10" seem to work. – Verbeia – 2012-05-23T03:44:57.843

@Mr.Wizard Does this work in version 9? – Simon – 2014-09-09T07:29:07.383

This method seems to be very nice. However, if plot with frame, the frame ticks would then be exactly "reversed". For example here the ticks would range from -100 to -20. Any way to improve it? – Mathieu – 2014-10-06T13:45:06.477

Good find! Sometimes you just have to outsmart the manual. – Sjoerd C. de Vries – 2012-06-30T10:02:06.377

This solution prevents graphics primitives from rendering using Epilog (using 10.4). – geordie – 2019-02-02T12:36:00.083

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

Posted 2012-05-18T12:53:06.873

Reputation: 51 831

@belisarius I was mislead by two different definitions of data in the OP question. So I had to update my earlier answer. – Artes – 2012-05-18T18:05:25.110

I imagined that, and posted my comment so that you could come with a different answer. Well done +1 – Dr. belisarius – 2012-05-18T22:40:35.870

@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 – 2012-05-18T22:58:17.417

Something got tangled (probably some neurons) when I pasted the code here. Thanks for the warning! Try the code now – Dr. belisarius – 2012-05-18T23:24:41.273

@belisarius Now it works +1. – Artes – 2012-05-18T23:27:29.050

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

Posted 2012-05-18T12:53:06.873

Reputation: 4 892

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 – 2012-05-18T13:29:58.853

1@s0rce For me it works. Did you copy the first Line of the code Options[flippeAchsen]=Union... ? – Peter Breitfeld – 2012-05-18T13:38:29.517

nope, I missed it. Thanks, it works now! – s0rce – 2012-05-18T13:50:38.690

9

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

Verbeia

Posted 2012-05-18T12:53:06.873

Reputation: 33 191

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

Posted 2012-05-18T12:53:06.873

Reputation: 112 848

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

user14592

Posted 2012-05-18T12:53:06.873

Reputation: 29

3I'm afraid that it doesn't show the same output as the other answers. – Öskå – 2014-05-25T10:48:35.500

The question is about flipping the y-axis values, not exchanging them with the x-axis. – Sjoerd C. de Vries – 2014-05-25T13:02:53.157