Wolfram Research

Function Repository Resource:

CombinePlots

Source Notebook

Combine plots, enabling the creation of plots with two sets of axes and merging of prologs and epilogs

Contributed by: Lukas Lang

ResourceFunction["CombinePlots"][g1,g2,]

works like Show, but can reorder labels/callouts and reposition frame axes.

Details and Options

ResourceFunction["CombinePlots"] combines graphics expressions while trying to move labels and callouts to the front.
ResourceFunction["CombinePlots"] by default merges the primitives inside the Prolog and Epilog options.
ResourceFunction["CombinePlots"] can reposition frame axes, allowing the creation of plots with two x/y axes.
ResourceFunction["CombinePlots"] accepts the following options:
"CombineProlog" True whether to merge prologs
"CombineEpilog" True whether to merge epilogs
"AnnotationPattern" (GraphicsGroup|Text)[___] the pattern used to match annotations
"AxesSides" Automatic on which side to put the frame axes
ResourceFunction["CombinePlots"] effectively removes all expressions matching the pattern specified by "AnnotationPattern" and inserts them on top of the remaining primitives.
The default setting of "AnnotationPattern", (GraphicsGroup|Text)[___] matches the primitives generated from Label and Callout directives.
The option "AxesSides" accepts the following settings:
Automatic do not move frame axes
"TwoY" move the vertical frame axis of the second plot to the right
"TwoX" move the horizontal frame axis of the second plot to the top
"TwoXY" move the bottom/left frame axes of the second plot to the top/right
spec use explicit settings for different plots
"AxesSides" supports the same sequence specification as documented for Spacings.
For each plot, the setting can be one of the following:
Bottom put horizontal frame axis to the bottom
Top put horizontal frame axis to the top
Left put vertical frame axis to the left
Right put vertical frame axis to the right
{ side x , side y } position both horizontal and vertical frame axes
Directive [ side x , side y ] same as {sidex,sidey}
The option "AxesSides" settings "TwoY"/"TwoX"/"TwoXY" are effectively equivalent to settings of the form {2spec}.
The sides for the frame axes of plots can also be specified by wrapping plots with Axes[plot,sideSpec], similar to how Item works for Grid.
The arguments of ResourceFunction["CombinePlots"] can be (nested) lists of plots, where each level can be wrapped in Axes[plots,sideSpec]. Deeper specifications override outer ones as necessary.
The setting of "AxesSides" applies to each argument of ResourceFunction["CombinePlots"] as one. Use Axes[] type specifications for more granular control.
ResourceFunction["CombinePlots"] will use the frame axis of the first appropriate plot for each side. The values of the FrameLabel, FrameTicks, FrameStyle and FrameTicksStyle options are used to create the frame axis in the resulting plot.
ResourceFunction["CombinePlots"] effectively uses GeometricTransformation to rescale plot contents shown on secondary axes.
ResourceFunction["CombinePlots"] sets CoordinatesToolOptions to enable extraction of coordinates form any of the axes. The format is {{sidex,sidey}{x,y},}, with one entry for each unique horizontal/vertical axis combination.
ResourceFunction["CombinePlots"] will always return a (possibly Legended) Graphics expression.
If there are no labels/callouts and no prolog/epilog to combine, ResourceFunction["CombinePlots"][args] is equivalent to Show[args].

Examples

Basic Examples (3) 

Combine two plots containing annotations:

In[1]:=
ResourceFunction["CombinePlots"][
 Plot[
  Callout[Sin[x], "Sin[x]", 0.8, Appearance -> "Balloon", Background -> White],
  {x, 0, 2 \[Pi]}
  ],
 Plot[
  Callout[Cos[x], "Cos[x]", 5, Appearance -> "Balloon", Background -> White
   ],
  {x, 0, 2 \[Pi]}, PlotStyle -> Directive[Thick, Red]
  ]
 ]
Out[1]=

If Show is used instead, the annotations of the first plot are covered by the contents of the second one:

In[2]:=
Show[
 Plot[
  Callout[Sin[x], "Sin[x]", 0.8, Appearance -> "Balloon", Background -> White],
  {x, 0, 2 \[Pi]}
  ],
 Plot[
  Callout[Cos[x], "Cos[x]", 5, Appearance -> "Balloon", Background -> White],
  {x, 0, 2 \[Pi]}, PlotStyle -> Directive[Thick, Red]
  ]
 ]
Out[2]=

Use CombinePlots to combine Prolog and Epilog contents:

In[3]:=
ResourceFunction["CombinePlots"][
 Graphics[
  {Green, Disk[{0, 0}]},
  Prolog -> {Red, Disk[{0, 1}]},
  Epilog -> {Blue, Disk[{1, 0}]},
  PlotRange -> 2
  ],
 Graphics[
  {},
  Prolog -> {Red, Disk[{0, -1}]},
  Epilog -> {Blue, Disk[{-1, 0}]}
  ]
 ]
Out[3]=

Show only keeps the Prolog/Epilog of the first Graphics:

In[4]:=
Show[
 Graphics[
  {Green, Disk[{0, 0}]},
  Prolog -> {Red, Disk[{0, 1}]},
  Epilog -> {Blue, Disk[{1, 0}]},
  PlotRange -> 2
  ],
 Graphics[
  {},
  Prolog -> {Red, Disk[{0, -1}]},
  Epilog -> {Blue, Disk[{-1, 0}]}
  ]
 ]
Out[4]=

Use CombinePlots to create a plot with two vertical axes:

In[5]:=
ResourceFunction["CombinePlots"][
 Plot[x^2, {x, 0, 10}, Frame -> True],
 Plot[
  100 x^4, {x, 0, 10},
  ScalingFunctions -> "Log",
  Frame -> True, FrameStyle -> Red, PlotStyle -> Red
  ],
 "AxesSides" -> "TwoY"
 ]
Out[5]=

Scope (1) 

Merge arbitrary plots into plots with two y axes:

In[6]:=
ResourceFunction["CombinePlots"][
 BarChart[RandomReal[{0, 1}, 5]],
 DiscretePlot[
  n!, {n, 1, 5},
  PlotStyle -> Red, FrameStyle -> Red, PlotMarkers -> Style["\[Bullet]", FontSize -> 20]
  ],
 "AxesSides" -> "TwoY", Frame -> True
 ]
Out[6]=

Options (16) 

CombineProlog (2) 

With the default setting "CombineProlog"True, the graphics primitives of each Prolog are combined:

In[7]:=
ResourceFunction["CombinePlots"][
 Graphics[
  {Green, Disk[{0, 0}]},
  Prolog -> {Red, Disk[{0, 1}]},
  Epilog -> {Blue, Disk[{1, 0}]},
  PlotRange -> 2
  ],
 Graphics[
  {},
  Prolog -> {Red, Disk[{0, -1}]},
  Epilog -> {Blue, Disk[{-1, 0}]}
  ]
 ]
Out[7]=

Only take the Prolog of the first Graphics, mimicking the behavior of Show:

In[8]:=
ResourceFunction["CombinePlots"][
 Graphics[
  {Green, Disk[{0, 0}]},
  Prolog -> {Red, Disk[{0, 1}]},
  Epilog -> {Blue, Disk[{1, 0}]},
  PlotRange -> 2
  ],
 Graphics[
  {},
  Prolog -> {Red, Disk[{0, -1}]},
  Epilog -> {Blue, Disk[{-1, 0}]}
  ],
 "CombineProlog" -> False
 ]
Out[8]=

CombineEpilog (2) 

With the default setting "CombineEpilog"True, the graphics primitives of each Epilog are combined:

In[9]:=
ResourceFunction["CombinePlots"][
 Graphics[
  {Green, Disk[{0, 0}]},
  Prolog -> {Red, Disk[{0, 1}]},
  Epilog -> {Blue, Disk[{1, 0}]},
  PlotRange -> 2
  ],
 Graphics[
  {},
  Prolog -> {Red, Disk[{0, -1}]},
  Epilog -> {Blue, Disk[{-1, 0}]}
  ]
 ]
Out[9]=

Only take the Epilog of the first Graphics, mimicking the behavior of Show:

In[10]:=
ResourceFunction["CombinePlots"][
 Graphics[
  {Green, Disk[{0, 0}]},
  Prolog -> {Red, Disk[{0, 1}]},
  Epilog -> {Blue, Disk[{1, 0}]},
  PlotRange -> 2
  ],
 Graphics[
  {},
  Prolog -> {Red, Disk[{0, -1}]},
  Epilog -> {Blue, Disk[{-1, 0}]}
  ],
 "CombineEpilog" -> False
 ]
Out[10]=

AnnotationPattern (3) 

The default setting of "AnnotationPattern" matches primitives generated for Callout and Label wrappers:

In[11]:=
ResourceFunction["CombinePlots"][
 Plot[
  Labeled[
   Callout[Sin[x], "Sin[x]", 0.8, Appearance -> "Balloon", Background -> White],
   Style["A label", Background -> White], 3.8
   ],
  {x, 0, 2 \[Pi]}
  ],
 Plot[
  Callout[Cos[x], "Cos[x]", 5, Appearance -> "Balloon", Background -> White],
  {x, 0, 2 \[Pi]}
  ]
 ]
Out[11]=

Bring only Text primitives to the front:

In[12]:=
ResourceFunction["CombinePlots"][
 Plot[
  Labeled[
   Callout[Sin[x], "Sin[x]", 0.8, Appearance -> "Balloon", Background -> White],
   Style["A label", Background -> White], 3.8
   ],
  {x, 0, 2 \[Pi]}
  ],
 Plot[
  Callout[Cos[x], "Cos[x]", 5, Appearance -> "Balloon", Background -> White],
  {x, 0, 2 \[Pi]}
  ],
 "AnnotationPattern" -> _Text
 ]
Out[12]=

Bring only GraphicsGroup primitives to the front:

In[13]:=
ResourceFunction["CombinePlots"][
 Plot[
  Labeled[
   Callout[Sin[x], "Sin[x]", 0.8, Appearance -> "Balloon", Background -> White],
   Style["A label", Background -> White], 3.8
   ],
  {x, 0, 2 \[Pi]}
  ],
 Plot[
  Callout[Cos[x], "Cos[x]", 5, Appearance -> "Balloon", Background -> White],
  {x, 0, 2 \[Pi]}
  ],
 "AnnotationPattern" -> _GraphicsGroup
 ]
Out[13]=

AxesSides (9) 

With the default setting "AxesSides"Automatic, all plots share the same axes:

In[14]:=
ResourceFunction["CombinePlots"][
 Plot[x^2, {x, 0, 10}, Frame -> True],
 Plot[
  100 x^4, {x, 0, 10},
  Frame -> True, FrameStyle -> Red, PlotStyle -> Red
  ]
 ]
Out[14]=

Use a secondary vertical axis for the second plot:

In[15]:=
ResourceFunction["CombinePlots"][
 Plot[x^2, {x, 0, 10}, Frame -> True],
 Plot[
  100 x^4, {x, 0, 10},
  Frame -> True, FrameStyle -> Red, PlotStyle -> Red
  ],
 "AxesSides" -> "TwoY"
 ]
Out[15]=

The different axes can have different ScalingFunctions:

In[16]:=
ResourceFunction["CombinePlots"][
 Plot[x^2, {x, 0, 10}, Frame -> True],
 Plot[
  100 x^4, {x, 0, 10},
  ScalingFunctions -> "Log",
  Frame -> True, FrameStyle -> Red, PlotStyle -> Red
  ],
 "AxesSides" -> "TwoY"
 ]
Out[16]=

Create a plot with a secondary horizontal axis:

In[17]:=
ResourceFunction["CombinePlots"][
 Plot[Cos[x], {x, 0, 10}, Frame -> True],
 Plot[
  Sin[x], {x, 0, 30},
  Frame -> True, FrameStyle -> Red, PlotStyle -> Red
  ],
 "AxesSides" -> "TwoX"
 ]
Out[17]=

Use both secondary x and y axes:

In[18]:=
ResourceFunction["CombinePlots"][
 Plot[Cos[x], {x, 0, 10}, Frame -> True],
 Plot[
  1 + 10 Sin[x]^2, {x, 0, 30},
  ScalingFunctions -> "Log",
  Frame -> True, FrameStyle -> Red, PlotStyle -> Red
  ],
 "AxesSides" -> "TwoXY"
 ]
Out[18]=

Put the contents of multiple plots on the secondary axis:

In[19]:=
ResourceFunction["CombinePlots"][
 Plot[Cos[x], {x, 0, 10}, Frame -> True],
 {
  Plot[
   1 + 10 Sin[x]^2, {x, 0, 10},
   ScalingFunctions -> "Log",
   Frame -> True, FrameStyle -> Red, PlotStyle -> Red
   ],
  Plot[
   2 + 10 Cos[x]^2, {x, 0, 10},
   ScalingFunctions -> "Log",
   PlotStyle -> Orange
   ]
  },
 "AxesSides" -> "TwoY"
 ]
Out[19]=

Move the vertical axis of all plots to the right:

In[20]:=
ResourceFunction["CombinePlots"][
 Plot[Cos[x], {x, 0, 10}, Frame -> True],
 Plot[
  2 Sin[x], {x, 0, 10},
  Frame -> True, FrameStyle -> Red, PlotStyle -> Red
  ],
 "AxesSides" -> Right
 ]
Out[20]=

Use Axes[plot,sideSpec] to specify the sides on which to put axes:

In[21]:=
ResourceFunction["CombinePlots"][
 Axes[Plot[Cos[x], {x, 0, 10}, Frame -> True], Right],
 Plot[
  1 + 10 Sin[x]^2, {x, 0, 10},
  ScalingFunctions -> "Log",
  Frame -> True, FrameStyle -> Red, PlotStyle -> Red
  ]
 ]
Out[21]=

Put one plot on the secondary vertical axis, and another one on both the secondary horizontal and vertical axes:

In[22]:=
ResourceFunction["CombinePlots"][
 Plot[Cos[x], {x, 0, 10}, Frame -> True],
 Plot[
  1 + 10 Sin[x]^2, {x, 0, 10},
  ScalingFunctions -> "Log",
  Frame -> True, FrameStyle -> Red, PlotStyle -> Red
  ],
 Plot[
  {2 + 10 Sin[x]^2, 2 + 10 Sin[x]^2}, {x, 0, 30},
  ScalingFunctions -> "Log",
  Frame -> True, FrameStyle -> Blue, PlotStyle -> {Blue, Directive[Red, Dashed]}
  ],
 "AxesSides" -> {Automatic, Right, Directive[Right, Top]}
 ]
Out[22]=

Possible issues (2) 

CombinePlots only moves the Frame type axis. Normal Axes are not supported:

In[23]:=
ResourceFunction["CombinePlots"][
 Plot[x^2, {x, 0, 10}],
 Plot[100 x^4, {x, 0, 10}, PlotStyle -> Red, AxesStyle -> Red],
 "AxesSides" -> "TwoY"
 ]
Out[23]=

Specify FrameTrue to fix the issue:

In[24]:=
ResourceFunction["CombinePlots"][
 Plot[x^2, {x, 0, 10}],
 Plot[100 x^4, {x, 0, 10}, PlotStyle -> Red, FrameStyle -> Red],
 "AxesSides" -> "TwoY", Frame -> True
 ]
Out[24]=

Resource History

Source Metadata

Related Resources

Author Notes

Changes from version 2.0.0 to 2.0.1:

Fixed issues when a non-default kernel is used
Fixed issues with certain WindowSize settings

License Information