8
$\begingroup$

Consider the following simple LogPlot:

LogPlot[Exp[x],{x,0,5}]

LogPlot of Exp[x]

Is there a nice way to switch the axes of a LogPlot?

I'm aware that plotting the inverse function as follows

LogLinearPlot[Log[y],{y,Exp[0],Exp[5]}]

will do the job. The actual function I'm using is more complicated so I want to avoid using the inverse if possible.

I've tried the various methods here

How can I transpose x and y axis on a Plot?

but they would seem to require some modification in order to work.

$\endgroup$
3
  • $\begingroup$ Would you explain the reason you wish to avoid the solution included in your question? $\endgroup$
    – Mr.Wizard
    Jul 25, 2014 at 14:59
  • $\begingroup$ The main reason is that it would be cumbersome and more difficult to follow. I imagine someone not familiar with Mathematica would be confused about why I am going to pains to plot the inverse function. It does not help that my function inverse is multi-valued. $\endgroup$
    – Michael
    Jul 26, 2014 at 10:37
  • $\begingroup$ That makes sense. Incidentally I asked not because I thought this was a bad question, but because without understanding why that solution should be avoided I (or someone else) might recommend another one with the same detractions. $\endgroup$
    – Mr.Wizard
    Jul 26, 2014 at 10:48

3 Answers 3

7
$\begingroup$

Would a ListPlot style solution work for you as in the following:

ListLogPlot[Table[{x, Abs[Gamma[x]]}, {x, -5, 2, 0.01}], Joined -> True]

enter image description here

and it's "transpose"

ListLogLinearPlot[Table[{Abs[Gamma[x]], x}, {x, -5, 2, 0.01}], Joined -> True]

enter image description here

$\endgroup$
1
  • $\begingroup$ I did not know about ListLogPlots. For my purposes, this method is simple and works fine. Thanks! $\endgroup$
    – Michael
    Jul 26, 2014 at 9:52
10
$\begingroup$

You can use ParametricPlot to transpose the axes by plotting $\{y,x\}$, and ScalingFunctions to get the log scale:

ParametricPlot[{Abs[Gamma[x]], x}, {x, -5, 2},
 PlotTheme -> "Business",
 ScalingFunctions -> {"Log", Identity}]

enter image description here

Note that ScalingFunctions does not appear to be officially supported for *Plot functions so this should be regarded as undocumented behaviour and may change in future releases.

$\endgroup$
1
  • $\begingroup$ Alas I have Mathematica 8.0 and ScalingFunctions does not seem to be supported in this version. Looks good though! $\endgroup$
    – Michael
    Jul 26, 2014 at 10:20
6
$\begingroup$

I was working on my solution and then I saw bobthechemist's answer, which is much better than mine. However, if you insist on using LogPlot(and not ListLogPlot) for your original plot, here's what I would do to transpose it:

1) Note that if you evaluate gammaPlot = LogPlot[Abs[Gamma[x]], {x, -5, 2}]; gammaPlot // InputForm, the internal representation of your gammaPlot curve are the pairs of points within the Line function. In fact, there are 4 separate Line's in the curve as it breaks at x = -2, x = -1, and x= 0 (not sure why the curve doesn't break at the other negative integer values).

2) To extract these points, I use Cases with a transformation rule involving Reverse to switch the x and y plot points. You can just use Line[points_] to pick out the pattern since all the points are nested within a huge list anyway, but I decided to hash out the pattern structure in more detail to illustrate the use of Map.

Cases[gammaPlot, 
 Line[points : {{_, _} ..}] :> Reverse /@ points, Infinity]

3) Since Log (natural log) was applied to the y values to produce the y plot points of the LogPlot, I use Exp[y] in a transformation rule to restore the y-values (which are now the horizontal/x values). I then used ListLogLinearPlot (with the Joined -> True option to connect the points) to display the final curve. As you can see the 4 Line sections are reproduced.

ListLogLinearPlot[% /. {y_, x_} :> {Exp[y], x}, Joined -> True]

Mathematica graphics

Sidenote: to make the plot one color, just apply Join to combine the Line's together. Warning: doing so might artificially connect any discontinuities in your plot. Therefore, I'd recommend leaving Join out and instead specify the overall look of your plot using PlotStyle at the end.

ListLogLinearPlot[
 Join @@ Cases[gammaPlot, 
    Line[points : {{_, _} ..}] :> Reverse /@ points, Infinity] /. {y_,
     x_} :> {Exp[y], x}, Joined -> True]

Mathematica graphics


One-step solution to plot the inverse of a LogPlot curve on a ListLogLinearPlot

Clear[inverseLogPlot]
inverseLogPlot[f_, {xp_, xmin_?NumericQ, xmax_?NumericQ}, 
  options___] := 
 With[{originalPlot = LogPlot[f, {xp, xmin, xmax}]}, 
  ListLogLinearPlot[
   Cases[originalPlot, 
     Line[points : {{_, _} ..}] :> Reverse /@ points, 
     Infinity] /. {y_, x_} :> {Exp[y], x}, Joined -> True, options]]
inverseLogPlot[Abs[Gamma[x]], {x, -5, 2}, Frame -> True, 
 PlotStyle -> Red]

Mathematica graphics


Comparison with bobthechemist's method

Bob's method is much more comprehensible and intuitive than my method, so I would suggest you to use that method if you need to plot something quick. However, one advantage of my method--and please let me know if I'm mistaken--is that it uses the adaptive sampling of MMA when it plots a function (ref):

Mathematica graphics

This could be seen by comparing my transposed plot to that of Bob. The peaks of my plot go much higher than Bob's to reflect the fact that f[x] goes to infinity at negative integer values of x.

Clear[bobLogPlot]
bobLogPlot[f_, {xp_, xmin_?NumericQ, xmax_?NumericQ}, options___] :=
 ListLogLinearPlot[Table[{f, xp}, {xp, xmin, xmax, 0.01}], 
  Joined -> True, options]
TableForm[{LogPlot[#, {x, -5, 2}, Frame -> True],
    inverseLogPlot[#, {x, -5, 2}, Frame -> True],
    ListLogPlot[Table[{x, #}, {x, -5, 2, 0.01}], Joined -> True, 
     Frame -> True],
    bobLogPlot[#, {x, -5, 2}, Frame -> True]} &@Abs[Gamma[x]], 
 TableHeadings -> {{"LogPlot", "inverseLogPlot (transposed)", 
    "ListLogPlot", "bobLogPlot (transposed)"}}]

Mathematica graphics


Edit: this plot should show how LogPlot is sampled differently from ListLogPlot. Please delete if unnecessary.

Show[
 LogPlot[Abs[Gamma[x]], {x, -5, 2},
  PlotLegends -> 
   Style["LogPlot[Abs[Gamma[x]],{x,-5,2}]", Red]~Placed~Above,
  PlotStyle -> None, Mesh -> All, 
  MeshStyle -> Directive[Red, AbsolutePointSize[0.7]]],
 ListLogPlot[Table[{x, Abs[Gamma[x]]}, {x, -5, 2, 0.01}], 
  PlotLegends -> 
   Style["ListLogPlot[Table[{x,Abs[Gamma[x]]},{x,-5,2,0.01}]]", Blue]~
    Placed~Below, 
  PlotStyle -> Directive[Blue, AbsolutePointSize[0.7]]]]

Mathematica graphics

$\endgroup$
2
  • $\begingroup$ +1 - I like exploring the internals of graphics (complexes) in mma. I agree that adaptive sampling is the main advantage of your route, as creating a table with a fine step size could become cumbersome. $\endgroup$ Jul 26, 2014 at 0:55
  • $\begingroup$ This is a nicely written function and well-explained! I like that you have managed to keep the properties of LogPlot, especially adaptive sampling. For my purposes - I have no sharply changing gradients, so I have chosen bobthechemist's simpler method. Why Wolfram can't simply implement this as an option in their Plot functions.. $\endgroup$
    – Michael
    Jul 26, 2014 at 10:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.