7
$\begingroup$
curveData = Import["D:\\Curve.txt", "Table",  "FieldSeparators" -> " "]
lineData = Import["D:\\Line.txt", "Table",  "FieldSeparators" -> " "]
curvePlot = ListPlot[curveData, PlotRange -> {{200, 600}, All},  AxesOrigin -> {200, 0},  Frame -> {True, True, True, False}]
linePlot = ListPlot[lineData, PlotRange -> {{200, 600}, All},  PlotStyle -> {PointSize[0]}, AxesOrigin -> {200, 0},  Frame -> {False, False, False, True}, Filling -> Axis,  FillingStyle -> {Thickness[Tiny]}]
Overlay[{curvePlot, linePlot}]

I am trying to overlay two plots. However, overlay does not produce aligned plots. The reason seems to be that the plots don't have the same absolute X range, despite the same PlotRange. Could you help to comment the reason ? Many thanks !

Curve.txt

Lines.txt

{curveData, lineData} = Import["https://pastebin.com/raw/SEg5tThi", "RawJSON"];

Cannot overlay

$\endgroup$
  • 1
    $\begingroup$ Try Show instead of Overlay $\endgroup$ – Ulrich Neumann Jun 30 at 11:33
  • $\begingroup$ @UlrichNeumann Could you help to suggest more specifically how to use show in this circumstance ? Many thanks ! $\endgroup$ – SOUser Jun 30 at 12:26
5
$\begingroup$

Here's a way to combine the plots and keep the frame scales that seem intended by the OP. It would have been easier if Charting`ScaledTicks[{curveScale, curveScaleInv}] didn't insist that log-spaced major ticks were the way to go. One can use Charting`ScaledTicks in place of myScaledTicks in many cases.

{curveData, lineData} = Import["https://pastebin.com/raw/SEg5tThi", "RawJSON"];

(* creates scaling functions
 *   to scale data to canonical {0,1} interval and back *)
ClearAll[scalingFunctions];
scalingFunctions[data_] :=
  Function /@ ({Rescale[#, #2, #3], Rescale[#, #3, #2]} &[#, MinMax@data, {0, 1}]);
{curveScale, curveScaleInv} = scalingFunctions[curveData[[All, 2]]];
{lineScale, lineScaleInv} = scalingFunctions[lineData[[All, 2]]];

(* creates ticks corresponding to scaling functions *)
ClearAll[myScaledTicks];
myScaledTicks[{sf_, isf_}][min_, max_, n_: {6, 6}] := 
  Module[{major, minor},
   {major, minor} = FindDivisions[isf@{min, max}, n] /. x_Rational :> N[x];
   minor = Complement[Join @@ minor, major];
   major = {
       sf[#], #,
       {0.01, 0.},
       {AbsoluteThickness[0.1]}
       } & /@ major;
   minor = {
       sf[#], Spacer[{0, 0}],
       {0.005, 0.},
       {AbsoluteThickness[0.1]}
       } & /@ minor;
   Join[major, minor]
   ];

Plot of OP's data:

Show[
 curvePlot = ListPlot[curveData, PlotRange -> {{200, 600}, All}, 
   AxesOrigin -> {200, 0}, Frame -> True, 
   ScalingFunctions -> {curveScale, curveScaleInv}],
 linePlot = ListPlot[lineData,
   PlotRange -> {{200, 600}, All}, PlotStyle -> {PointSize[0]}, 
   AxesOrigin -> {200, 0}, Filling -> Axis, 
   FillingStyle -> {Thickness[Tiny]}, 
   ScalingFunctions -> {lineScale, lineScaleInv}],
 FrameTicks -> {
   {myScaledTicks[{curveScale, curveScaleInv}],
    myScaledTicks[{lineScale, lineScaleInv}]},
   {Automatic, Automatic}},
 FrameLabel -> {{"curve (units?)", "line (units?)"}, {"x (units?)", None}}
 ]

enter image description here

$\endgroup$
  • $\begingroup$ Thank you for your knowledgeable help ! $\endgroup$ – SOUser Jul 1 at 1:41
  • $\begingroup$ @SOUser You're welcome! $\endgroup$ – Michael E2 Jul 1 at 3:26
5
$\begingroup$
{curveData, lineData} = Import["https://pastebin.com/raw/SEg5tThi", "RawJSON"];


curvePlot = ListPlot[
   curveData
   , PlotRange -> {{200, 600}, All}
   , AxesOrigin -> {200, 0}
   , Frame -> {True, True, True, False}
   ];
linePlot = ListPlot[
   lineData.DiagonalMatrix[{1, 40000}]
   , PlotRange -> {{200, 600}, All}
   , PlotStyle -> {PointSize[0]}
   , AxesOrigin -> {200, 0}
   , Frame -> {False, False, False, True}
   , Filling -> Axis
   , FillingStyle -> {Thickness[Tiny]}
   ];

Show[curvePlot, linePlot]

Mathematica graphics

$\endgroup$
4
$\begingroup$

Try

Show[{curvePlot, linePlot}]

enter image description here

As you can see the scaling of your data should be adapted!

$\endgroup$
3
$\begingroup$

If you want a more automated version of @MiachelE2's answer, you can use the CombinePlots function of the ForScience` paclet (see below for instructions on how to install it) with the setting "AxesSides" -> "TwoY" (see the documentation of the paclet for more details and examples):

<<ForScience`

{curveData, lineData} = Import["https://pastebin.com/raw/SEg5tThi", "RawJSON"];

curvePlot = ListPlot[
  curveData,
  PlotRange -> {{200, 600}, All},
  AxesOrigin -> {200, 0},
  Frame -> True,
  FrameLabel -> {"x axis", "curve (units?)"}
  ]
linePlot = ListPlot[
  lineData,
  PlotRange -> {{200, 600}, All},
  PlotStyle -> {PointSize[0], Red},
  AxesOrigin -> {200, 0},
  Filling -> Axis,
  FillingStyle -> {Thickness[Tiny]},
  Frame -> True,
  FrameLabel -> {"x axis", "line (units?)"},
  FrameStyle -> Red
  ]

enter image description here

CombinePlots[curvePlot, linePlot, "AxesSides" -> "TwoY"]

enter image description here

Note how the FrameLabel,FrameTicks and FrameStyle of the second plot were automatically moved to the right side

How to install the paclet

The current version (0.88.45) of the paclet can be installed by running

PacletInstall[
  "https://github.com/MMA-ForScience/ForScience/releases/download/v0.88.45/ForScience-0.88.45.paclet"
]
$\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.