# Plotting curves of different orders of magnitudes on the same graph

I want to plot

Plot[{Exp[x],Sin[x]},{x,0,10}]


The issue is that Sin[x] and Exp[x] are not of the same order of magnitude, so we do not see Sin[x]. Therefore, I would like to set different y-axis but on the same graph. For Exp[x], the y axis would go from 0 to 25000 and for Sin[x] from -1 to 1. How can I do that ?

• Why do you need to plot curves with widely-varying ranges together? Oct 8 '18 at 9:02
• I have a case when I want to visualize the data and the log of the data. The curve is supposed to be an exponential at the beginning and vary linearly at the end. I want to see a linear evolution at the beginning with the log of the data, a linear evolution at the end with the data, and a transition area. I asked my question in a simple way, since the data is pretty big and that it's a general question
– J.A
Oct 8 '18 at 9:13
• How about LogPlot? Oct 8 '18 at 11:42
• @ΑλέξανδροςΖεγγ: That won't work so well for a function that becomes negative, like Sin[x] does. (There are ways around this, of course.) Oct 8 '18 at 12:39
• @MichaelSeifert Actually, it is about data rescaling. Admittedly, log function is not "good at" dealing with non-positive values, but it is not difficult to find a proper rescaling function to use. Oct 9 '18 at 4:44

Rescaling the y-coordinates:

rescaleShow[p1_, p2_] := Module[{g1, g2, pr1, pr2, rs1, rs2},
{g1, g2} = Cases[{p1, p2}, _Graphics, Infinity];
{pr1, pr2} = Last /@ PlotRange /@ {g1, g2};
rs1 = With[{pr = Last@PlotRange[g1]}, Rescale[#, pr] &];
rs2 = With[{pr = Last@PlotRange[g2]}, Rescale[#, pr] &];
Show[
p1 /. Line[p_] :> Line[Transpose@MapAt[rs1, Transpose@p, 2]],
p2 /. Line[p_] :> Line[Transpose@MapAt[rs2, Transpose@p, 2]],
PlotRange -> {0, 1}, Frame -> True,
FrameTicks -> {{ChartingFindTicks[{0, 1}, pr1],
ChartingFindTicks[{0, 1}, pr2]}, {Automatic, Automatic}}
]
];


OP's example:

rescaleShow[
Plot[Exp[x], {x, 0, 10},
PlotStyle -> ColorData[97][1], PlotLegends -> {HoldForm@Exp[x]},
Frame -> True, PlotRange -> All],
Plot[Sin[x], {x, 0, 10},
PlotStyle -> ColorData[97][2], PlotLegends -> {Sin[x]}]
]


This method uses Plot so you get the Plot bells and whistles, like discontinuity processing, except for automatic coloring of the graphs:

rescaleShow[
Plot[Tan[x], {x, 0, 10},
PlotStyle -> ColorData[97][1], PlotLegends -> {Tan[x]},
Frame -> True],
Plot[Sin[x], {x, 0, 10},
PlotStyle -> ColorData[97][2], PlotLegends -> {Sin[x]}]
]


A slightly modified version using Overlay.

combine[data1_, data2_] := Overlay[{ListLinePlot[data1,
Frame -> {True, True, False, False},
FrameLabel -> {"x1", "y1"}, LabelStyle -> Directive[12, Blue],
PlotStyle -> Blue, PlotRange -> All,
ImagePadding -> {{50, 50}, {40, 40}}],
ListLinePlot[data2, Frame -> {False, False, True, True},
FrameTicks -> All, FrameLabel -> {{None, "y2"}, {None, "x2"}},
LabelStyle -> Directive[12, Red], PlotStyle -> {Red, Dashed},
PlotRange -> All, ImagePadding -> {{50, 50}, {40, 40}}]},
Alignment -> Center]

data1 = Table[{x, Sin[x]}, {x, 0, 10, 0.01}];
data2 = Table[{x, Exp[x]}, {x, -5, 5, 0.01}];
combine[data1, data2]


One advantage here is that you can use any range for x and y.

You can use Plot as well in the combine and modify the appearance.

• +1 for the coding ingenuity, but honestly, for me this just reinforces the idea that a small multiple chart is often the way to go. Oct 8 '18 at 12:45

Multiply, Sin[x] by, say, 1000 and rescale the right axis:

Plot[{Exp[x], 1000 Sin[x]}, {x, 0, 10}, Frame -> True,
FrameTicks -> {{Automatic, ChartingFindTicks[{-1000, 1000}, {-1, 1}]},
{Automatic, Automatic}},
PlotLegends -> {HoldForm @ Exp[x], Sin[x]}]
`

• Not to nitpick, but both curves use the left axis (according to the legend). Oct 8 '18 at 18:26
• thank you @AndreasRejbrand; good catch. Fixed now.
– kglr
Oct 8 '18 at 18:27