Ok, here's a very brief toy example while I don't have access to my desktop computer at work.
It's easy enough to figure out, that a `LogPlot` of `f` is basically the plot of `Log[f[x]]`. And A `LogLinearPlot` is the plot of `f[Exp[x]]`. But we can extend this to arbitrary scalings of the axes.
I start with defining a piecewise function which maps x values between 0 and 1 to the interval from 1 to 10 logarithmically and x values between 1 and 2 to the interval 10 to 100 linearly, as well as the inverse of that.
g[x_] := Piecewise[{{10^x, 0 <= x < 1},
{Rescale[x, {1, 2}, {10, 100}], x >= 1}}]
inverseg[x_] :=
Piecewise[{{Log[10, x], 1 <= x < 10},
{Rescale[x, {10, 100}, {1, 2}], x >= 10}}]
Then if you have the `CustomTicks` package:
Needs["CustomTicks`"];
ticks = LinTicks[1, 10, TickPostTransformation -> inverseg]~Join~
LinTicks[10, 100, TickPostTransformation -> inverseg];
If you don't have it:
ticks = {N@inverseg@#,
ToString@#, {0.01, 0}, {}} & /@ (Range[2, 10, 2]~Join~
Range[20, 100, 20]);
Finally (I show `Sin[x]` in this toy example):
Plot[Sin[g[x]], {x, 0, 2}, Ticks -> {ticks, Automatic}]
![Scaled ticks][1]
Note, how according to the `x-y` coordinates taken from the axes labels this is just the regular Sin[x] function, but everything is distorted such, that we see the desired log scaling before 10 and linear scaling after.
This plot was generated without using the `CustomTicks` package, hence lazy and without minor ticks. I'll go into more details tomorrow.
**Update 05.05.15**
Writing out these piecewise functions by hand is tedious. I've automated this.
Firstly, a function I called `MapLog`, though `logRescale` may have been more appropriate. Although, unlike `Rescale[x, {x1, x2}, {y1 y2}]` where simply swapping the 2nd and 3rd argument gives you the inverse function, with a logarithmic/exponential mapping it's a bit less straightforward.
MapLog[{x1_, x2_, y1_, y2_}, type_String: "Direct"] :=
Which[
type == "Direct", (Log[(x2/x1)^(1/(y2 - y1)), #1/x1] + y1 &),
type == "Inverse", (x1 (x2/x1)^((#1 - y1)/(y2 - y1)) &)]
The default `"Direct"` form take the interval `{x1, x2}` and maps it to the interval `{y1, y2}` logarithmically.
Plot[MapLog[{1, 10, 0, 1}][x], {x, 1, 10}]
![MapLog Direct][2]
MapLog[{1,10,0,1}, "Inverse"]
will naturally give the inverse of such an operation.
Next comes the main function `AxisBreaks`, which handles the construction of the direct and inverse transformation functions for the ticks and coordinates.
Options[AxisBreaks] = {Output -> "Direct"};
AxisBreaks[specs :
PatternSequence[{{_?NumericQ, _?NumericQ, _?NumericQ, _String : "Lin"} ..}],
opts : OptionsPattern[]] :=
Module[{
fullspecs = (If[Length[#] == 3, Join[#, {"Lin"}], #, #] &) /@ specs,
ranges2 = Accumulate[specs[[All, 3]]],
ranges1 = Accumulate[specs[[All, 3]]] - specs[[All, 3]],
expspecs, dirfunc, invfunc, output
},
expspecs =
Transpose@{fullspecs[[All, 1]], fullspecs[[All, 2]], ranges1, ranges2, fullspecs[[All, 4]]};
If[OptionValue[Output] == "Direct",
dirfunc[x_] :=
Piecewise[Table[
{Which[j[[5]] == "Lin", Rescale[x, j[[1 ;; 2]], j[[3 ;; 4]]],
j[[5]] == "Log", MapLog[j[[1 ;; 4]], "Direct"][x]],
j[[1]] <= x <= j[[2]]}, {j, expspecs}]];];
If[OptionValue[Output] == "Inverse",
invfunc[x_] :=
Piecewise[Table[
{Which[j[[5]] == "Lin", Rescale[x, j[[3 ;; 4]], j[[1 ;; 2]]],
j[[5]] == "Log", MapLog[j[[1 ;; 4]], "Inverse"][x]],
j[[3]] <= x <= j[[4]]}, {j, expspecs}]];];
Which[OptionValue[Output] == "Direct", output = dirfunc;,
OptionValue[Output] == "Inverse", output = invfunc;];
output
]
Usage is as follows:
specs = {{1, 30, 1, "Log"}, {30, 500, 4}};
dg = AxisBreaks[specs];
ig = AxisBreaks[specs, Output -> "Inverse"];
Which means in plain English "give me a function, that maps the interval `{1, 30}` logarithmically to 1 part of the plot and the interval `{30, 500}` to 4 parts of the plot (specifically, to `{0, 1}` and `{1, 5}`, respectively. Also give me the inverse function of this."
Then a little helper to generate the ticks:
makeTicks[func_, major_List, minor_List: {}] :=
({func@#, ToString@#, {0.01, 0}, {}} & /@ major) ~Join~
({func@#, "", {0.005, 0}, {}} & /@ minor);
Usage:
major = {2, 10, 30}~Join~Range[100, 500, 100]; (* can't be bothered to make minor ticks *)
ticks = makeTicks[dg, major];
Basically give the transformation function as the first argument, the list of major ticks as the second, minor ticks are an optional third argument.
Now plot `f[x]`, replacing as `f[ig[x]]` (`ig` is the inverse transformation), and if you want to plot between `x1` and `x2`, you now need to substitute `dg[x1]` and `dg[x2]` (`dg` is the direct transformation).
Plot[Sin[15/Sqrt[ig@x]], {x, dg[1], dg[500]},
Ticks -> {ticks, Automatic}, PlotRange -> Full]
![Plot][3]
**Neat examples**
This goes beyond the scope of the OP, but `AxisBreaks` can do a lot more, that I'd like to showcase.
`LogLinearPlot` for negative values? Negative and positive values? No problem.
specs = {{-1000, -5, 2, "Log"}, {-5, 5, 1}, {5, 1000, 2, "Log"}};
dg = AxisBreaks[specs];
ig = AxisBreaks[specs, Output -> "Inverse"];
ticks =
makeTicks[dg,
{-1000, -300, -100, -30, -10, 10, 30, 100, 300, 1000}~Join~Range[-4, 4, 2]];
Plot[Log[1 + y^2] /. y -> ig[x], {x, dg[-1000], dg[1000]},
Ticks -> {ticks, Automatic}, AxesOrigin -> {dg[0], 0}]
![LogLinear][4]
More examples coming up...
[1]: https://i.sstatic.net/5Gld3.png
[2]: https://i.sstatic.net/APNba.png
[3]: https://i.sstatic.net/MJt1R.png
[4]: https://i.sstatic.net/IaE19.png