# Two Axes, One plot

Consider the following data indicating temperature in degree Celcius vs time in hours:

SeedRandom[95];
TEMPvsTIME = {Range[100],
Accumulate[RandomReal[{-1, 1}, 100]]}\[Transpose];

ListPlot[TEMPvsTIME, Joined -> True, Frame -> True,
FrameLabel -> {"Time (hr)", "Temp (C)"}]


How can I include another horizontal and vertical axis on the top and on the right, scaled for the same data/plot to show time in minutes and temperature in Fahrenheit respectively? Unlike this question, I am not plotting 2 datasets and the only way that comes to my mind is to create an empty dataset and use TwoAxisPlot. Is there a better way of doing this?

### ChartingFindTicks

You can also use ChartingFindTicks to get the linearly scaled ticks:

ListPlot[TEMPvsTIME, Joined -> True, Frame -> True,
FrameTicks -> {{Automatic,   ChartingFindTicks[{0, 100}, {32, 212}]},
{Automatic,  ChartingFindTicks[{0, 1}, {0, 60}]}},
FrameLabel -> {{"Temp (C)", "Temp (F)"}, {"Time (hr)", "Time (min)"}}]


Update: If you wish to have the same positions but different labels for axes pairs (as suggested by Jose in a comment) you can do

cft = ChartingFindTicks[{0, 1}, {0, 1}];
ListPlot[TEMPvsTIME, Joined -> True, Frame -> True,
FrameTicks -> {{cft,
Replace[cft[##], {x_?NumericQ, Except[""], z___} :> {x,  32 + 9/5 x, z}, 1] &},
{cft,  Replace[cft[##], {x_?NumericQ, Except[""], z___} :> {x, Floor[60  x], z}, 1] &}},
FrameLabel -> {{"Temp (C)", "Temp (F)"}, {"Time (hr)",  "Time (min)"}}]


Update 2: To add GridLines (thanks @JoseAntonioDiazNavas for the suggestion) and quantity units in temperature labels (as in egwene sedai's answer):

ListPlot[TEMPvsTIME, Joined -> True, Frame -> True,
FrameTicks -> {{Replace[cft[##], {x_?NumericQ, Except[""], z___} :>
{x, Quantity[x, "Celsius"], z}, 1] &,
Replace[cft[##], {x_?NumericQ, Except[""], z___} :>
{x,  UnitConvert[Quantity[x, "Celsius"], "Fahrenheit"], z},  1] &},
{cft, Replace[cft[##], {x_?NumericQ, Except[""], z___} :> {x, Floor[60 x], z}, 1] &}},
FrameLabel -> {{"Temp (C)", "Temp (F)"}, {"Time (hr)",  "Time (min)"}},
GridLines -> {Automatic, (DeleteCases[cft[##], {_, "", ___}][[All, 1]] &)}]


• Although a good solution, as well as that of @CarlWoll, I am more in favor in plotting axes in which corresponding ticks are aligned to better see how values are related. Feb 13, 2018 at 20:40
• @JoséAntonioDíazNavas, very good point. Updated with a version that changes the labels only.
– kglr
Feb 13, 2018 at 21:04
• Nice and useful, particularly when someone wants to add GridLines +1 Feb 13, 2018 at 22:17

You can use FrameTicks to specify the kind of ticks you want. I like using ChartingScaledTicks to specify ticks, so the following would be my approach:

ListPlot[
TEMPvsTIME,
Joined->True,
Frame->True,
FrameTicks->{
{Automatic,ChartingScaledTicks[{5/9(#-32)&,9/5#+32&}]},
{Automatic,ChartingScaledTicks["Linear",{#/60&,# 60&},"Nice"]}
},
FrameLabel->{{"Temp (C)", "Temp (F)"},{"Time (hr)", "Time (min)"}}
]


• Can we get ScaledTicks documented and added to the System functions? Feb 14, 2018 at 1:37

You may use the SciDraw Package:

Needs["SciDraw"];

SeedRandom[95];
TEMPvsTIME = {Range[100],
Accumulate[RandomReal[{-1, 1}, 100]]}\[Transpose];

ListPlot[TEMPvsTIME, Joined -> True, Frame -> True,
FrameLabel -> {{"Temp (C)", "Temp (F)"}, {"Time (hr)",
"Time (min)"}},
FrameTicks -> {{LinTicks[0, 6, 1, 2],
LinTicks[0, 6, 1, 2,
TickLabelFunction -> (UnitConvert[Quantity[#, "Celsius"],
"Fahrenheit"] &)]}, {LinTicks[0, 100, 20, 2],
LinTicks[0, 100, 20, 2, TickLabelFunction -> (#*60 &)]}}]


• note: Carl Woll's answer works wonderfully and does not require 3rd party packages; here you need to load the extra package, but it is better documented than Charting ScaledTicks Feb 13, 2018 at 20:30
• seai, I did not know about SciDraw. I'll start using it. Thanks! Feb 14, 2018 at 4:36