I'd like to plot

Abs[s]/λ - 1 + Log[λ/s]

as a function of $s > 0$, for some fixed value for $\lambda$, say 0.1. This function behaves essentially linearly for $s > \lambda$, and the log-linear plot is linear for $s < \lambda$. It would therefore be nice to see the plot from $s=e^{-8}$ to $s=8$. There should be roughly the same number of ticks on both sides, if I'm not mistaken.

I'd like to depict this by having a plot that is log linear to the left of $\lambda$, and linear to the right of $\lambda$. Any advice?

  • 1
    $\begingroup$ Your function assumes complex values for $\lambda=0.1$ and $s<0$. Could you check your expressions? $\endgroup$ – MarcoB May 25 '18 at 14:37
  • $\begingroup$ s must be nonnegative. I've fixed the associated typo. $\endgroup$ – Wannabe Mathematician May 26 '18 at 1:04

Using the scaling functions {f[λ], if[λ]} from Brett's excellent answer and adding a few embellishments:

Quiet[With[{λ = 0.3}, 
 {lscale, rscale} = Thread[{0,  NMaxValue[{Abs[s]/λ - 1 + Log[λ/s] , #}, s] & /@ 
   {10^(-4) <= s <= λ , λ <= s <= 8}}];
 plot = Plot[If[s < λ, Abs[s]/λ - 1 + Log[λ/s], 
       Rescale[Abs[s]/λ - 1 + Log[λ/s], rscale, lscale ]], {s, 10^-4, 8}, 
    ScalingFunctions -> {{f[λ], if[λ]}, None}, 
    Frame -> True, 
    FrameTicks -> {{Automatic,  Charting`FindTicks[lscale, rscale]}, {All, All}}, 
    Mesh -> {{λ}}, MeshShading -> {Red, Blue}, 
    FrameStyle -> {{Red, Blue}, {Automatic, Automatic}}];
 ticks = FrameTicks /. Options[plot, FrameTicks];
 ticks[[2, 1]] = Join[ticks[[2, 1]], {λ, λ}, {#, #} & /@ Range[8]]; 
 ticks[[2, 2]] = ticks[[2, 1]];
 Show[plot, FrameTicks -> ticks, ImageSize -> 500]]]

enter image description here


Here's my attempt, using ScalingFunctions.

The first step is to define a function (and it's inverse) that is linear for inputs greater than $\lambda$, and is log-scaled for input below, with a shift so that we preserve continuity:

f[λ_][a_] := If[a < λ, Log[a] + λ - Log[λ], a]
if[λ_][a_] := If[a < λ, E^(-λ + a) λ, a]

Just for fun, I've included λ as a parameter to the scaling functions.

Now we just plot as usual:

With[{λ = 0.1}, 
     Plot[Abs[s]/λ - 1 + Log[λ/s], {s, 10^-4, 8}, 
          ScalingFunctions -> {{f[λ], if[λ]}, None}
] // VisualQuiet

enter image description here

The ticks aren't perhaps what you'd want, since in this case Plot decided to go for powers of 10 across the domain; that could be changed with a custom Ticks specification.

Also, at least in V11.3, the graphic pinks because of some apparently benign recursion error I haven't debugged yet, so I'm throwing in a utility I have for telling the frontend to not turn the graphic pink if there are errors:

VisualQuiet[expr_] := Style[expr, AutoStyleOptions -> {
    "FormattingErrorTooltips" -> False, 
    "HighlightFormattingErrors" -> False

It is hard to see how to improve on side-by-side plots:

With[{λ = 0.1}, GraphicsRow@{
   LogLinearPlot[Abs[s]/λ - 1 + Log[λ/s], {s, Exp[-8], λ}],
   Plot[Abs[s]/λ - 1 + Log[λ/s], {s, λ, 8}]
  • $\begingroup$ I'm now figuring out how to make the two graphs overlap so that I actually realize my goal. $\endgroup$ – Wannabe Mathematician May 26 '18 at 1:06
  • $\begingroup$ The solution of @kglr gives you that (and elegantly), but we usually plot for communication, and I suspect communication will be much more rapid with side-by-side separate plots. (E.g., ask why color is needed to make the combined plot comprehensible.) $\endgroup$ – Alan May 26 '18 at 13:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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