Re: Q> on COMBINING PLOTS w/ diff. axes. (LONG)

*To*: mathgroup at smc.vnet.net*Subject*: [mg2659] Re: [mg2607] Q> on COMBINING PLOTS w/ diff. axes. (LONG)*From*: Preston Nichols <nichols at godel.math.cmu.edu>*Date*: Sun, 3 Dec 1995 02:53:42 -0500

Zorro <berriz at husc.harvard.edu> asked: "So my question are 1) in general, how does one get Mathematica to superimpose plots with different units on the vertical or horizontal axis, and 2) in particular, how does one get it to display histograms and functions together?" -------------------------------------------------------------------- Both issues are addressed by the functionality of the FullGraphics command. In[1]:= ?FullGraphics FullGraphics[g] takes a graphics object, and generates a new one in which objects specified by graphics options are given as explicit lists of graphics primitives. The "objects specified by graphics options" are principally axes and ticks, and FullGraphics "protects" them from Mathematica's default procedures for graphics options. Here are some examples which illustrate the use of FullGraphics when combining 2D graphics. (The later ones use the results of the earlier ones, so if you try them out, be sure to execute them in order. I made this message as a Notebook, available at http://www.contrib.andrew.cmu.edu/usr/pdn/CombinePlot.ma.) Plot1 will serve as a "fixed" reference plot,and will not be transformed; Plot2 will be altered and overlayed on Plot1 in various ways. First, without FullGraphics: In[2]:= Plot1 = Plot[Sin[x], {x,0,2 Pi}]; Plot2 = Plot[Sin[x], {x,0,Pi},AxesOrigin->{Pi,1}]; Show[{Plot1,Plot2}]; The same plots, using FullGraphics: In[5]:= FullPlot1 = Plot1//FullGraphics; FullPlot2 = Plot2//FullGraphics; Show[{FullPlot1,FullPlot2}]; Be sure to note the effect of the AxesOrigin option in Plot2. -------------------------------------------------------------------- If we want the two plots, when displayed simutaneously, to occupy the same horizontal space on the screen (or page) even though their abscissas have different ranges, we can use: In[8]:= Needs["Graphics`Graphics`"]; ?SkewGraphics SkewGraphics[graphics, m] applies the matrix m to all coordinates in graphics. So (just to have an example) let's stretch Plot2 horizontally by a factor of 2, by using SkewGraphics on the FullGraphics version of Plot2: In[10]:= SkewFullPlot2 = SkewGraphics[FullPlot2, {{2,0},{0,1}}]; Show[SkewFullPlot2]; Show[{FullPlot1,SkewFullPlot2}]; Note how the two distinct abscissa scales appear. And again take note of the effect of the AxesOrigin option. -------------------------------------------------------------------- For this to work properly, the use of FullGraphics is essential, and it is important that FullGraphics is applied before SkewGraphics. If the opposite order is used, the "data" in the plot will be Skew'ed, but not the coordinate scale(s): In[13]:= FullSkewPlot2 = SkewGraphics[Plot2, {{2,0},{0,1}}]//FullGraphics; Show[FullSkewPlot2]; Show[{FullPlot1,FullSkewPlot2}]; -------------------------------------------------------------------- The ordinate scales can be manipulated in the same way as the abscissa scales have been, just by using a suitable matrix in SkewGraphics. If the scales to be superimposed are related by nonlinear functions, TranformGraphics can be used in place of SkewGraphics. In[16]:= ?TransformGraphics TransformGraphics[graphics, f] applies the function f to all lists of coordinates in graphics. Here's a toy example. In[17]:= f[{x_,y_}] := {2 x Exp[x]/Exp[Pi],y^2} In[18]:= TransformFullPlot2 = TransformGraphics[FullPlot2, f]; Show[TransformFullPlot2]; Show[{FullPlot1,TransformFullPlot2}]; As this example suggests, in many cases it may work better to generate the original Plots with one of the versions of ScaledPlot or LogPlot, and then Skew the results linearly. -------------------------------------------------------------------- Here's an example with a BarChart version of Plot2. In[21]:= BarPlot2 = BarChart[Table[Sin[x], {x,0,Pi,Pi/6}], AxesOrigin->{7,1}]; In[22]:= FullBarPlot2 = BarPlot2//FullGraphics; SkewFullBarPlot2 = SkewGraphics[FullBarPlot2, {{Pi/3,0},{0,1}}]; Show[{FullPlot1,SkewFullBarPlot2}]; Since that's not quite "right", try this affine transformation: In[24]:= TransformFullBarPlot3 =TransformGraphics[ FullBarPlot2, ({{Pi/3,0},{0,1}}.(# -{1,0}))&]; Show[{FullPlot1,TransformFullBarPlot3}]; -------------------------------------------------------------------- Preston Nichols Visiting Assistant Professor Department of Mathematics Carnegie Mellon University