       Re: Plot axis length and size ratio (TwoPlot revive)

• To: mathgroup at smc.vnet.net
• Subject: [mg121635] Re: Plot axis length and size ratio (TwoPlot revive)
• From: matyigtm <matyigtm at gmail.com>
• Date: Fri, 23 Sep 2011 03:43:47 -0400 (EDT)
• Delivered-to: l-mathgroup@mail-archive0.wolfram.com
• References: <j5cb27\$crg\$1@smc.vnet.net>

```Thanks for the ideas.

I've already found the TwoAxisPlot version, but I didn't like that it
had to plot three times the diagrams in total, which is time consuming
in my occasion.
In Ray's version, which short enough to be usable, its hard to guess
the scale factor if I need to make several "two plots" in loops
(hundreds of plots), which motivates me to make a function that
retains most of the Plot function's parameters, options.

Options[TwoPlot] = {PlotOptions1 -> {}, PlotOptions2 -> {},
PlotOptionsAll -> {}, PlotOptionsFrame -> {}, PlotFcn -> Plot,
Scale -> Automatic};

TwoPlot[{f_, g_}, {x_, xmin_, xmax_},
opts : OptionsPattern[{TwoPlot, Graphics}]] :=
Module[{plt1, plt2, absOpt1, absOpt2, absOptTmp, fcnTmp, lenF, lenG,
a, b, range1, range2, rangeDst, scale, ticks2, base = 0},
(* number of elements in f and g *)
{lenF, lenG} = (If[ListQ[#], Length[#], 1] &) /@ {f, g};

plt1 = (OptionValue@PlotFcn)[f, {x, xmin, xmax},
Evaluate@OptionValue@PlotOptions1,
Evaluate@OptionValue@PlotOptionsAll];
absOpt1 = AbsoluteOptions[plt1];
plt2 = (OptionValue@PlotFcn)[g, {x, xmin, xmax},
Evaluate@OptionValue@PlotOptions2,
Evaluate@OptionValue@PlotOptionsAll,
PlotStyle ->
ColorData[1, "ColorList"][[lenF + 1 ;; lenF + lenG]]];
absOpt2 = AbsoluteOptions[plt2];

(* scale factor *)
range1 = PlotRange /. absOpt1;
range2 = PlotRange /. absOpt2;
If[TrueQ[OptionValue@Scale == Automatic],
(*then*)
scale = Min[
Table[If[range2[[2, i]] != 0., range1[[2, i]]/
range2[[2, i]], \[Infinity]], {i, 1, 2}]],
(* else *) scale = OptionValue@Scale];
rangeDst =
Table[({Min, Max}[[i]])@{range1[[2, i]],
range2[[2, i]] scale}, {i, 1, 2}];
(* creates internal plot to create new ticks for plot nr .2 *)
a = (rangeDst[] /scale - rangeDst[]/ scale)/(xmax - xmin);
fcnTmp = a x + (rangeDst[]/ scale - a xmin);
absOptTmp =
AbsoluteOptions[(OptionValue@PlotFcn)[fcnTmp, {x, xmin, xmax},
PlotRange -> {All, rangeDst/ scale}, PlotPoints -> 2,
MaxRecursion -> 0, Evaluate@OptionValue@PlotOptions2,
Evaluate@OptionValue@PlotOptionsAll]];
(* rescale the ticks *)
ticks2 = (Ticks /. absOptTmp)[[
2]] /. {v_, label_, len_, style_} -> {v scale , label, len,
style};

(* create the overlaid plots *)
Graphics[{Drop[plt1[[1, 1]], 2],
Scale[Drop[plt2[[1, 1]], 2], {1, scale}, {xmin, base}]},
FilterRules[{opts}, Options[Graphics]],
AspectRatio -> (AspectRatio /. absOpt1), Frame -> True,
FrameTicks -> {{Automatic, ticks2}, {All, Automatic}},
FrameStyle -> {{(AxesStyle /. absOpt1)[[
2]], (AxesStyle /. absOpt2)[]}, {(AxesStyle /. absOpt1)[[
1]], Automatic}},
PlotRange -> {Automatic, rangeDst}]
];

SetAttributes[TwoPlot, HoldAll];

which applies in different manners:
TwoPlot[{x (x - 10) Sin[x], 10 x (x - 10) Cos[x]}, {x, 0, 10}]
TwoPlot[{{x (x - 10) Sin[x], 20 Cos[x]}, 10 x (x - 10) Cos[x]}, {x, 0,
10}, FrameLabel -> {{"y1", "y2"}, {, }}]

I thought that an easy conversion to functions LogPlot,LogLinearPlot
etc.. would be easy, but I found that not.
I should convert the ticks accordingly to the Plot function used:

TwoPlot[{{x (x - 10) Sin[x], 20 Cos[x]}, 10 x (x - 10) Cos[x]}, {x, 1,
10}, FrameLabel -> {{"y1", "y2"}, {, }}, PlotFcn -> LogPlot]

Matyi

```

• Prev by Date: Re: Bug with Sequence and Assignment by Part...
• Next by Date: Re: Compilation: Avoiding inlining
• Previous by thread: Re: Error Message on Magnification
• Next by thread: Re: Plot axis length and size ratio (TwoPlot revive)