I have a two time differential equations system: A[t] and B[t]. (I am omitting their specific form.) I would like to display the evolution of the two variables over time in a one plot with two y-axes with a label on each axis and a legend below the x-axis After days of research I found that Overlay could be one solution. So my code is the following:

p1 = Plot[A[t] /. sol, {t, 1, 10}, PlotStyle -> {Black}, BaseStyle -> {FontSize -> 14},
Ticks -> {{}, {94, 96, 98, 100}}, ImagePadding -> 25, FrameTicks -> {None, All, None, None},
Frame -> {True, True, False, False}]

p2 = Plot[B[t] /. sol, {t, 1, 10}, PlotStyle -> {Black, Dashed}, BaseStyle -> {FontSize -> 14}, 
Ticks -> {{}, {2, 4, 6, 8, 10}}, FrameTicks -> {None, None, None, All}, ImagePadding -> 25, 
Frame -> {False, False, False, True}]

p = Overlay[{p1, p2}]

Export["p.pdf", %]

This produces enter image description here

However, after another days of research I failed to figure out how to include label for each axis, A for left y-axis, B for right y-axis, and t for x-axis, and a legend (for the two curves) below x-axis. I tried various combinations and various versions of PlotLabel, FrameLabel, PlotLegend, etc. without success. Can anyone help?


2 Answers 2


Edit: In 10.x the syntax for FrameTicks was changed. More in:

Is there a good reason for the removal of this FrameTicks syntax?

You just need more ImagePadding at the side for the FrameLabel to show. (Note I've changed the functions being plotted since I don't have your differential equation handy.) You can add a legend at the bottom without worrying about adding extra ImagePadding because it's outside the plot. Notice that I had to create both lines in the legend. Because there is only one line in this plot, an automatic setting for LineLegend like LineLegend["Expressions"] would only have had one element.

Notice also that I've turned Axes off, since you are using Frame instead.

p1 = Plot[5 Sin[t] + 95, {t, 1, 10}, PlotStyle -> {Black}, 
  Axes -> None, BaseStyle -> {FontSize -> 14}, 
  Ticks -> {{}, {94, 96, 98, 100}}, 
  ImagePadding -> {{50, 50}, {20, 2}}, 
  FrameTicks -> {None, All, None, None}, 
  Frame -> {True, True, False, False}, 
  PlotLegends -> 
      Directive[Dashed, Black]}, {"First thing", "Other thing"}], 
    Bottom], FrameLabel -> {{"First thing", None}, {"Stuff", None}}]

enter image description here

 p2 = Plot[5 Cos[t] + 5, {t, 1, 10}, Axes -> None,
  PlotStyle -> {Directive[Black, Dashed]}, 
  BaseStyle -> {FontSize -> 14}, Ticks -> {{}, {2, 4, 6, 8, 10}}, 
  FrameTicks -> {None, None, None, All}, 
  ImagePadding -> {{50, 50}, {20, 2}}, 
  Frame -> {False, False, False, True}, 
  FrameLabel -> {{None, "Thing"}, {None, None}}] 

enter image description here

p = Overlay[{p1, p2}]

enter image description here

There are some more complex examples at: 1 Plot, 2 Scale/Axis

  • $\begingroup$ Thanks a lot! I forgot to mention that I also want a legend below the x-axis for the two curves. Can I add this? And why do we have that extra vertical line? $\endgroup$
    – ppp
    Commented Nov 14, 2014 at 6:25
  • $\begingroup$ @Verbeia Is it right that the option Ticks -> {{}, {94, 96, 98, 100}} does not function here, or I missed something? $\endgroup$ Commented Nov 14, 2014 at 8:40
  • $\begingroup$ @ Verbeia, wonderful. I really appreciate! $\endgroup$
    – ppp
    Commented Nov 14, 2014 at 15:58

I just had to do the same thing, but with an even more complicated data set where the horizontal ranges weren't quite the same and the two axis labels were different sizes. I found the following trick made it much easier to line things up between the two plots:

  1. Include both plots' frames and labels in each plot. E.g. set Frame -> {{True, True},{True,False}} in both plots, and add the exact same labels to both plots. This way all the spacing will be consistent between the two plots.

  2. Set each duplicated feature to be Transparent in one of the two plots (e.g. using FrameStyle). This way the elements will still take up the right amount of space, but when you overlay them, they won't be twice as dark as they should be.

Now when you combine the two plots using Overlay, they should be almost perfectly lined up, and you don't need to worry about setting the ImagePadding. (Although you still may need to tweak the individual plots with ImageSize, and/or the Overlay with the Alignment option, in order to line them up perfectly. For example, note that in the example in your OP, the right-hand vertical axis is a tiny bit longer than the left-hand one, and the axes don't quite meet up at the bottom-right corner.)

Also, if you do it this way then the image will be cropped correctly, whereas there will be extra white space around the sides if you set ImagePadding too big.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.