141
$\begingroup$

enter image description here

I would like to plot those two datasets on top of each other. But they have very different range on the $y$ axis. How can I have two different axis?

I found the following on the help menu but quite esoteric for me and I can`t adapt it to data (vs. function):

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}}]]
$\endgroup$
  • 2
    $\begingroup$ You'll find a lot of info with this search: groups.google.com/forum/#!searchin/… $\endgroup$ – Szabolcs Jan 24 '12 at 17:20
  • $\begingroup$ @Szabolcs, Thank You I found the above bouncing from your link ! $\endgroup$ – 500 Jan 24 '12 at 17:33
  • $\begingroup$ You can start by replacing the appropriate line: {fgraph, ggraph} = MapIndexed[ListPlot[#, Axes -> True, Joined -> True, PlotStyle -> ColorData[1][#2[[1]]]] &, {f, g}];. $\endgroup$ – J. M. is away Jan 24 '12 at 17:35
  • $\begingroup$ Ooh, this is an ancient one, I remember implementing my own version some 5 years before. $\endgroup$ – István Zachar Jan 24 '12 at 18:16
  • 5
    $\begingroup$ Come on, am I the only one who finds "2 scales, 1 plot" hilarious? $\endgroup$ – Aron May 12 '14 at 11:57
138
$\begingroup$

This can be done with Overlay if the ImagePadding and the horizontal range for each plot is the same. For example,

plot1 = ListLinePlot[
    Accumulate[RandomReal[{0, 1}, {100}]],
    PlotStyle -> Blue,
    ImagePadding -> 25,
    Frame -> {True, True, True, False},
    FrameStyle -> {Automatic, Blue, Automatic, Automatic}
]

Plot 1

plot2 = ListLinePlot[
    Accumulate[RandomReal[{0, 100}, {100}]],
    PlotStyle -> Red,
    ImagePadding -> 25,
    Axes -> False,
    Frame -> {False, False, False, True},
    FrameTicks -> {None, None, None, All},
    FrameStyle -> {Automatic, Automatic, Automatic, Red}
]

Plot 2

Overlay[{plot1, plot2}]

Double-axis plot

Edit: Cleared up which axis is which using FrameStyle.

$\endgroup$
  • 2
    $\begingroup$ BTW +1 for using Overlay :-) I never managed to make good use of it. $\endgroup$ – Szabolcs Jan 24 '12 at 19:01
  • 2
    $\begingroup$ @P.Fonseca I guess you could do it if you specified the ticks in an interleaved fashion. But I wouldn't want to read a plot like that, would you? I prefer to stack up plots with a single pair of axes. $\endgroup$ – ArgentoSapiens Jan 24 '12 at 22:52
  • 1
    $\begingroup$ @ArgentoSapiens in my field, there are a lot of graphics organized like in the following schematics: i.imgur.com/h13bH.jpg. $\endgroup$ – P. Fonseca Jan 25 '12 at 7:09
  • 5
    $\begingroup$ Setting PlotRange -> All or PlotRange -> Full breaks the numbering on the right-hand axis. Any idea why, and how to fix it? $\endgroup$ – Benjamin Hodgson Apr 16 '13 at 3:33
  • 2
    $\begingroup$ @BenjaminHodgson using FrameTicks -> All instead of the proposed solution solved it for me. $\endgroup$ – Valacar Jan 23 '17 at 9:11
35
$\begingroup$

As I said, it's pretty easy to adapt the TwoAxisPlot[] function given in the OP. I'll give two flavors here, named TwoAxisListPlot[] and TwoAxisListLinePlot[]:

TwoAxisListPlot[{f_, g_}] := 
 Module[{fgraph, ggraph, frange, grange, fticks, 
   gticks}, {fgraph, ggraph} = 
   MapIndexed[
    ListPlot[#, Axes -> True, 
      PlotStyle -> ColorData[1][#2[[1]]]] &, {f, g}]; {frange, 
    grange} = 
   Last[PlotRange /. AbsoluteOptions[#, PlotRange]] & /@ {fgraph, 
     ggraph}; 
  fticks = Last[
     Ticks /. 
      AbsoluteOptions[fgraph, 
       Ticks]] /. _RGBColor | _GrayLevel | _Hue :> ColorData[1][1];
  gticks = (MapAt[Function[r, Rescale[r, grange, frange]], #, {1}] & /@
       Last[Ticks /. 
        AbsoluteOptions[ggraph, 
         Ticks]]) /. _RGBColor | _GrayLevel | _Hue -> 
     ColorData[1][2];
  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, Transparent}}, 
   FrameTicks -> {{fticks, gticks}, {Automatic, Automatic}}]]

TwoAxisListLinePlot[{f_, g_}] := 
 Module[{fgraph, ggraph, frange, grange, fticks, 
   gticks}, {fgraph, ggraph} = 
   MapIndexed[
    ListLinePlot[#, Axes -> True, 
      PlotStyle -> ColorData[1][#2[[1]]]] &, {f, g}]; {frange, 
    grange} = 
   Last[PlotRange /. AbsoluteOptions[#, PlotRange]] & /@ {fgraph, 
     ggraph}; 
  fticks = Last[
     Ticks /. 
      AbsoluteOptions[fgraph, 
       Ticks]] /. _RGBColor | _GrayLevel | _Hue :> ColorData[1][1];
  gticks = (MapAt[Function[r, Rescale[r, grange, frange]], #, {1}] & /@
       Last[Ticks /. 
        AbsoluteOptions[ggraph, 
         Ticks]]) /. _RGBColor | _GrayLevel | _Hue -> 
     ColorData[1][2];
  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, Transparent}}, 
   FrameTicks -> {{fticks, gticks}, {Automatic, Automatic}}]]

Test:

d1 = Accumulate[RandomReal[{0, 1}, {100}]];
d2 = Accumulate[RandomReal[{0, 50}, {100}]];
GraphicsGrid[{{ListLinePlot[d1], ListPlot[d2]},
             {TwoAxisListPlot[{d1, d2}], TwoAxisListLinePlot[{d1, d2}]}}]

two-axis plots

$\endgroup$
  • 7
    $\begingroup$ If anybody's interested, I could modify the functions a bit to take options (e.g. nondefault colors for the two plots)... $\endgroup$ – J. M. is away Jan 25 '12 at 3:45
  • $\begingroup$ I would definitely be interested to add options I like to customize my plot a lot. Would it be possible for the function to take all the ListPlot option. Many thanks for your answer and attention. $\endgroup$ – 500 Jan 25 '12 at 7:32
  • $\begingroup$ That would take a fair bit of effort. Would you mind a wait of a few days? $\endgroup$ – J. M. is away Jan 25 '12 at 7:50
  • $\begingroup$ TwoAxisListPlot does not work on version 7, but TwoAxisListLinePlot does. Can you tell why? $\endgroup$ – Mr.Wizard Jan 25 '12 at 16:30
  • 1
    $\begingroup$ @J.M. no worries. Many thanks again ! $\endgroup$ – 500 Jan 25 '12 at 20:12
27
$\begingroup$

Even though this question has been flagged as answered, I think the answers are more complicated than they need to be (with respect to the authors). I offer the following, which takes advantage of FrameTics:

(*create 2 lists*)
x1 = Accumulate[RandomVariate[NormalDistribution[0, 1], 100]];
x2 = 25 Accumulate[RandomVariate[NormalDistribution[0, 1], 100]];

(*set nice plot options*)
SetOptions[ListPlot, ImageSize -> 500, Frame -> True, Joined -> True, 
GridLines -> Automatic, PlotStyle -> {{Thick, Red}, {Thick, Blue}}, 
PlotRange -> {{0, 100}, {-50, 50}}, 
FrameLabel -> {"Progress", "Red Line","Descriptive Title", "Blue line"}, 
 LabelStyle -> {12, FontFamily -> "Arial"}];

(*display, using FrameTicks for the bottom axis to show what it does*)
ListPlot[{x1, x2},FrameTicks -> {{{0, "Beginning"}, {25, "Early"},
{50, "Middle"},{75,"Almost\nFinished"}, {100, "Finished"}}, Automatic, None,Automatic}]

Mathematica graphics

As expected, x2 goes off ListPlot's range and needs a different scale. This can be accomplished by rescaleing x2 and using FrameTics to create a rescaled axis on the right. First, rescale x2 using the function rescaled[]:

datamax = Max[x2]; datamin = Min[x2];
datarange = datamax - datamin;
plotrange = 100; plotmin = -50;
rescaled[x_] := (x - datamin) plotrange/datarange + plotmin

Next, create new axis lables for the right axis::

axeslabel[v_] := {rescaled[v], ToString[v]}
rightaxis = Table[axeslabel[v], {v, -500, 500, 100}]

Finally, create the new ListPlot:

lp = ListPlot[{x1, x3},FrameTicks -> {{{0, "Beginning"}, {25, "Early"}, {50, 
  "Middle"}, {75, "Almost\nFinished"}, {100, "Finished"}}, Automatic, None, rightaxis}]
x3 = rescaled[#] & /@ x2;

Mathematica graphics

See how easy that was!

Upon reflection my approach isn't too different from Peter Breitfeld's, except perhaps that I made a more general rescaling routine.

$\endgroup$
17
$\begingroup$

Most compatible solution:

The solutions provided are not compatible with plots that contain labels. Here's a solution with possibility to add options:

TwoAxisListPlot[{f_, g_}, opts___] := 
 Module[{fgraph, ggraph, frange, grange, fticks, 
   gticks}, {fgraph, ggraph} = 
   MapIndexed[
    ListPlot[#, Axes -> True, PlotStyle -> ColorData[1][#2[[1]]], 
      opts] &, {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}}]]

And here's how it's called:

TwoAxisListPlot[{Accumulate[RandomReal[{0, 1}, {100}]], 
  Accumulate[RandomReal[{0, 1}, {100}]]}, {Frame -> True, 
  PlotLabel -> "Hello there!", PlotRange -> All, Joined -> True, 
  PlotMarkers -> {Automatic, Small}, ImageSize -> Large, 
  FrameLabel -> {{"Mean magnetic field (T)", 
     "(Hz)"}, {"Some parameter", ""}}, BaseStyle -> {FontSize -> 16}}]

enter image description here

$\endgroup$
  • $\begingroup$ Nice solution, however the scaling appears to have gone wrong, I notice the y-axis plots I was conducting were not aligning perfectly with the y-axis, it was slightly out. Please can you check and fix. $\endgroup$ – SPIL Sep 30 '18 at 13:07
  • $\begingroup$ @SPIL sorry man. I haven't worked on Mathematica in a while. $\endgroup$ – The Quantum Physicist Sep 30 '18 at 14:21
  • $\begingroup$ Have you switched to using R instead then? $\endgroup$ – SPIL Sep 30 '18 at 15:07
  • $\begingroup$ @SPIL I used to be in science/academia. Now I'm a professional software developer. I don't need Mathematica anymore because I used to use it for data analysis. $\endgroup$ – The Quantum Physicist Sep 30 '18 at 16:15
13
$\begingroup$

If you want to use David Park's Presentations package, you can reset the ticks and it will look like this:

data1 = {{1, 1.1}, {2, 1.5}, {3, 0.9}, {4, 2.3}, {5, 1.1}};
data2 = {{1, 1001.1}, {2, 1001.5}, {3, 1000.9}, {4, 1002.3}, {5, 1001.1}};

<<Presentations`
crop[x_] := (x - 1000)
Draw2D[
 {
  {Red, Thickness[0.02], Opacity[0.3], 
   ListDraw[data1, Joined -> True]},
  Blue, ListDraw[{#1, crop[#2]} & @@@ data2, Joined -> True]
  },
 AspectRatio -> 1/GoldenRatio,
 Frame -> True,
 FrameTicks -> {{Automatic,
      CustomTicks[crop, {1001, 1002.2, 0.2, 5},
         CTNumberFunction -> (Style[#, FontColor -> Blue] &)]},
   {Automatic, Automatic}},
 PlotLabel -> Row[{Style["data1", Red], ", ", Style["data2", Blue]}],
 PlotRange -> All
 ]

Mathematica graphics

$\endgroup$
13
$\begingroup$

Here is just a quick update of J.M.'s code to use some newer (read undocumented) functions in the Charting`context.

TwoAxisListPlot[{list1_, list2_}, opts : OptionsPattern[]] := 
 Module[{plot1, plot2, ranges},
  {plot1, plot2} = ListLinePlot /@ {list1, list2};
  ranges = Last@Charting`get2DPlotRange@# & /@ {plot1, plot2};
  ListPlot[
   {list1, Rescale[list2, Last@ranges, First@ranges]},
   Frame -> True,
   FrameTicks -> {{Automatic, 
      Charting`FindTicks[First@ranges, Last@ranges]}, {Automatic, 
      Automatic}},
   FrameStyle -> {{Automatic, ColorData[97][2]}, {Automatic, 
      Automatic}},
   FilterRules[{opts}, Options[ListPlot]]
   ]
  ]

d1 = Accumulate[RandomReal[{0, 1}, {100}]];
d2 = Accumulate[RandomReal[{0, 50}, {100}]];
GraphicsGrid[{{ListLinePlot[d1], 
   ListPlot[d2]}, {TwoAxisListPlot[{d1, d2}], 
   TwoAxisListPlot[{d1, d2}, Joined -> True]}}]

enter image description here

$\endgroup$
  • 1
    $\begingroup$ Superb! This should be a Mathematica builtin function! $\endgroup$ – grbl Feb 14 '17 at 20:22
  • $\begingroup$ @grbl - Thanks! You should take a second and send them a message, wolfram.com/support/contact , even linking here if you like. The more users who request a feature, the more likely it will be hooked up. $\endgroup$ – Jason B. Feb 14 '17 at 20:47
  • 1
    $\begingroup$ It's been requested by many users since the 90s $\endgroup$ – Mike Honeychurch Apr 26 '17 at 0:22
11
$\begingroup$

I needed a easy to modify "TwoAxisDateListPlot".

Thanks ArgentoSapiens for the inspiration. Here is my version.

list1 = FinancialData["GE", "Feb. 5, 2014"];
list2 = FinancialData["Gold", "March. 5, 2014"];
TwoAxisDateListPlot3[list1, list2, AspectRatio -> 0.3, ImageSize -> Large]

enter image description here

ClearAll[TwoAxisDateListPlot3]
Needs["Calendar`"];
TwoAxisDateListPlot3[dat1__, dat2__, opts : OptionsPattern[]] := Block[
{data1 = dat1, data2 = dat2, plot1, plot2, userOptions,defaultOptions, minx, maxx, temp},
(* display two datelist-graphs on one diagram *)

(* span x *)
If[DateQ[data1[[1, 1]]] (* find out date format *),
temp = SortBy[data1[[;; , 1]]~Join~data2[[;; , 1]], AbsoluteTime];
minx = temp[[1]]; maxx = temp[[-1]],
minx = Min[{data1[[;; , 1]], data2[[;; , 1]]}]; 
maxx = Max[{data1[[;; , 1]], data2[[;; , 1]]}]
];

(* get options *)
userOptions = FilterRules[{opts}, Options[DateListPlot]];
defaultOptions = FilterRules[{PlotRange -> {{minx, maxx}, {All, All}}, 
ImagePadding -> {{40, 40}, {25, 5}}}, Options[DateListPlot]];

(* do the plots *)
plot1 = DateListPlot[data1, PlotStyle -> Blue, 
  Frame -> {{True, False}, {True, True}},
  FrameStyle -> {Directive[FontFamily -> "Helvetica", Bold], 
  Directive[FontFamily -> "Helvetica", Bold, Blue], Automatic, 
  Automatic}, userOptions, defaultOptions] // Quiet;
plot2 = DateListPlot[data2, PlotStyle -> Darker[Green], Axes -> False, 
  Frame -> {{False, True}, {False, False}},
  FrameTicks -> All,
  FrameStyle -> {Automatic, Automatic, Automatic, 
    Directive[FontFamily -> "Helvetica", Bold, Darker[Green]]}, 
  userOptions, defaultOptions] // Quiet;
Overlay[{plot1, plot2}]];
$\endgroup$
  • $\begingroup$ What is DateQ? It seems not to a buit-in. $\endgroup$ – iav Jul 30 '15 at 11:40
  • 3
    $\begingroup$ @iav It is loaded by Needs["Calendar`"] $\endgroup$ – Mr.Wizard Aug 4 '15 at 6:50
  • $\begingroup$ How can make a FrameLabel appear if the scale of one of the axes is such that ticks like 0.0001, 0.0002, etc. are displayed (the point is that it essentially requires 5 digits plus a dot to show the scale of the axis and hence the corresponding FrameLabel is not visible)? The FrameLabel is there, when I export the plot to PDF, I can see a small part of it. I tried to play with FrameMargin as an option to the Overlay function, but that only adds white space. $\endgroup$ – Skumin Mar 7 '16 at 15:03
3
$\begingroup$

ArgentoSapiens's answer works well, but if the two plots don't have quite the same horizontal range, or you want to add different-sized labels to the two vertical axes, then it can be a bit tricky to line the two plots up correctly in the Overlay. I figured out the following trick that helped a lot with the alignment:

  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.)

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.

$\endgroup$
1
$\begingroup$

By the upper Mr. Jason B.'s nice codes on TwoAxisListPlot, I made one on DateListPlot as TwoAxisDateListPlot as following, some notations listed for helping others to change it to other ***Plot cases.

TwoAxisDateListPlot[{datelistLeft_?ListQ, dateListRight_?ListQ},opts : OptionsPattern[]] :=
    Module[ {shapedListRight, plotLeft, plotRight, twoRanges, result},

        (*check lists' depth*)
        If[ Or[ArrayDepth@datelistLeft != 2, ArrayDepth@dateListRight != 2],
            Return[$Failed]
        ];

        (* to be reshaped*)
        shapedListRight = dateListRight;

        (*find plots'Ranges*)
        {plotLeft, plotRight} = 
         DateListPlot /@ {datelistLeft, shapedListRight};
        twoRanges = 
         Last@Charting`get2DPlotRange@# & /@ {plotLeft, plotRight};

        (*reshape dataRight*)
        shapedListRight[[;; , 2]] = 
         Rescale[shapedListRight[[;; , 2]], Last@twoRanges, First@twoRanges];

        (*draw together*)
        result = DateListPlot[{datelistLeft, shapedListRight},
          Frame -> True, 
          FrameTicks -> {{Automatic, 
             Charting`FindTicks[First@twoRanges, 
              Last@twoRanges]}, {Automatic, Automatic}}, 
          FrameStyle -> {{ColorData[97][1], ColorData[97][2]}, {Automatic, 
             Automatic}}, FilterRules[{opts}, Options[DateListPlot]]];

        (*return shaped plots*)
        Return[result];
    ]
TwoAxisDateListPlot[datelistLeft_?ListQ, dateListRight_?ListQ, opts : OptionsPattern[]] := TwoAxisDateListPlot[{datelistLeft, dateListRight}, opts]

simple demos as :

list1 = FinancialData["NYSE:IBM", "March. 8, 2015"];
list2 = FinancialData["NASDAQ:AAPL", "March. 8, 2015"];

TwoAxisDateListPlot[list1, list2]

enter image description here

If some options given, it shows as this.

TwoAxisDateListPlot[list1, list2,
 DateTicksFormat -> {"MonthNameShort", ".", "Year"},
 FrameLabel -> {{Style["IBM", Larger, Bold], 
    Style["AAPL", Larger, Bold]}, {None, None}},
 PlotLabel -> Style["Stocks Comparsion", 18, Bold]
 ]

enter image description here

If PlotTheme be used, a new version comes up

 TwoAxisDateListPlot[{datelistLeft_?ListQ, dateListRight_?ListQ}, opts : OptionsPattern[]] :=
        Module[ {shapedListRight, plotLeft, plotRight, twoRanges, theme, colors, result},

           (*check lists' depth*)
            If[ Or[ArrayDepth@datelistLeft != 2, ArrayDepth@dateListRight != 2],
                Return[$Failed]
            ];

            (*get colors*)
            theme = Lookup[Association[opts], PlotTheme, Automatic];
            colors = 
             Most /@ PadRight[{}, {2}, 
               "DefaultPlotStyle" /. (Method /. 
                  Charting`ResolvePlotTheme[theme, DateListPlot])];

            (* to be reshaped*)
            shapedListRight = dateListRight;

            (*find plots'Ranges*)
            {plotLeft, plotRight} = 
             DateListPlot /@ {datelistLeft, shapedListRight};
            twoRanges = 
             Last@Charting`get2DPlotRange@# & /@ {plotLeft, plotRight};

            (*reshape dataRight*)
            shapedListRight[[;; , 2]] = 
             Rescale[shapedListRight[[;; , 2]], Last@twoRanges, First@twoRanges];

            (*draw together*)
            result = DateListPlot[{datelistLeft, shapedListRight},
              Frame -> True, 
              FrameTicks -> {{Automatic, 
                 Charting`FindTicks[First@twoRanges, 
                  Last@twoRanges]}, {Automatic, Automatic}},
              FrameStyle -> {colors, {Automatic, Automatic}}, 
              FilterRules[{opts}, Options[DateListPlot]]];

            (*return shaped plots*)
            Return[result];
        ]
    TwoAxisDateListPlot[datelistLeft_?ListQ, dateListRight_?ListQ, opts : OptionsPattern[]] := TwoAxisDateListPlot[{datelistLeft, dateListRight}, opts]

demos as

TwoAxisDateListPlot[list1, list2,
 DateTicksFormat -> {"MonthNameShort", ".", "Year"},
 FrameLabel -> {{Style["IBM", Larger, Bold], 
    Style["AAPL", Larger, Bold]}, {None, None}},
 PlotLabel -> Style["Stocks Comparsion", 18, Bold],
 PlotTheme -> "Marketing"
 ]

enter image description here

or

TwoAxisDateListPlot[list1, list2,
 DateTicksFormat -> {"MonthNameShort", ".", "Year"},
 FrameLabel -> {{Style["IBM", Larger, Bold], 
    Style["AAPL", Larger, Bold]}, {None, None}},
 PlotLabel -> Style["Stocks Comparsion", 18, Bold],
 PlotTheme -> "Business"
 ]

enter image description here

or

TwoAxisDateListPlot[list1, list2,
 DateTicksFormat -> {"MonthNameShort", ".", "Year"},
 FrameLabel -> {{Style["IBM", Larger, Bold], 
    Style["AAPL", Larger, Bold]}, {None, None}},
 PlotLabel -> Style["Stocks Comparsion", 18, Bold],
 PlotTheme -> "Detailed"
 ]

enter image description here

There's always one for using.

$\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.