3
$\begingroup$

I have two sets of points I need to ListLogLinearPlot plot:

{{1,10},{10,-20},{100,55},{1000,5000}}
{{1,0.8},{10,2},{100,-0.58},{1000,15}}

How can I plot them together with ListLogLinearPlot? The second will be an almost flat line around 0.

$\endgroup$
1
$\begingroup$

Here's a quick hack borrowed from the how-to on two-axis plotting:

list1 = {{1, 10}, {10, -20}, {100, 55}, {1000, 5000}};
list2 = {{1, 0.8}, {10, 2}, {100, -0.58}, {1000, 15}};

Module[{f = Interpolation[list1, InterpolationOrder -> 1], 
  g = Interpolation[list2, InterpolationOrder -> 1]},
 LogLinearPlot[f[x], {x, Min@list1, Max@list1}];
 LogLinearPlot[f[x], {x, Min@list2, Max@list2}];
 TwoAxisPlot[{f[x], g[x]}, {x, 0, Max@list2}]]

TwoAxisPlot[{f_, g_}, {x_, x1_, x2_}] := 
 Module[{fgraph, ggraph, frange, grange, fticks, 
   gticks}, {fgraph, ggraph} = 
   MapIndexed[
    Plot[#, {x, x1, x2}, Axes -> True, 
      PlotStyle -> ColorData[1][#2[[1]]]] &, {f, g}]; {frange, 
    grange} = (PlotRange /. 
        AbsoluteOptions[#, PlotRange])[[2]] & /@ {fgraph, ggraph}; 
  fticks = N@FindDivisions[frange, 5];
  gticks = 
   Quiet@Transpose@{fticks, 
      ToString[NumberForm[#, 2], StandardForm] & /@ 
       Rescale[fticks, frange, grange]};
  Show[fgraph, 
   ggraph /. 
    Graphics[graph_, s___] :> 
     Graphics[
      GeometricTransformation[graph, 
       RescalingTransform[{{0, 1}, grange}, {{0, 1}, frange}]], s], 
   Axes -> False, Frame -> True, 
   FrameStyle -> {ColorData[1] /@ {1, 2}, {Automatic, Automatic}}, 
   FrameTicks -> {{fticks, gticks}, {Automatic, Automatic}}]]

A more straightforward approach might be to normalize and scale the data to a common range and add custom FrameTicks to the left and right sides. Check out Standardize.

$\endgroup$
2
$\begingroup$

Update: Combining all steps in a function that works like ListLogLinearPlot:

ClearAll[listLogLinearPlot]

listLogLinearPlot = Module[{r1 = MinMax[#[[1, All, 2]]], r2 = MinMax[#[[2, All, 2]]]},
  ListLogLinearPlot[{#[[1]], Transpose[{#, Rescale[#2, r2, r1]} & @@ Transpose[#[[2]]]]},
   Frame -> True, FrameTicks -> {{Automatic, Charting`FindTicks[r1, r2]}, 
      {Automatic, Automatic}}, ##2]] &;

Example:

listLogLinearPlot[{l1, l2}, Joined -> True, PlotStyle -> {Thickness[.015], Thick}, 
   PlotLegends -> {"l1", "l2"}, ImageSize -> 500]

enter image description here

Original answer:

l1 = {{1, 10}, {10, -20}, {100, 55}, {1000, 5000}};
l2 = {{1, 0.8}, {10, 2}, {100, -0.58}, {1000, 15}};

Find the vertical ranges of l1 and l2:

{vrange1, vrange2} = MinMax[#[[All, 2]]] & /@ {l1, l2};

Rescale the second column of l2 to the vertical range of l1:

l2b = Transpose[{#, Rescale[#2, vrange2, vrange1]} & @@ Transpose[l2]];

Use ListLogLinearPlot with {l1, l2b} as input and the function Charting`FindTicks[vrange1, vrange2] to get the ticks for the right frame:

ListLogLinearPlot[{l1, l2b}, Joined -> True, Frame -> True, 
 PlotStyle -> {Directive[Thickness[.02], Red], Blue}, 
 FrameTicks -> {{Automatic, Charting`FindTicks[vrange1, vrange2]}, {Automatic, Automatic}}, 
 PlotLegends -> {"l1", "l2"}, ImageSize -> Medium]

enter image description here

$\endgroup$

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.