[d2n-analysis-talk] Plotting Two Data Sets With Different Scales on the Same Canvas
David Flay
flay at jlab.org
Fri Mar 26 21:38:08 EDT 2010
Hi all,
Brad has suggested I share my code and information regarding how to plot
two data sets on the same canvas, subject to two different scales, be they
linear or log, or a mixture of both.
Today I was interested in plotting two data sets on the same canvas -- one
on linear scale, and one on log scale.
I found a way to do this, which you may find in:
$ROOTSYS/tutorials/hist/transpad.C
However, this example deals only with <linear> scales -- for histograms.
My plots consist of using TGraphErrors objects, rather than TH1F objects,
in addition to my want to use one data set being plotted on linear scale,
and one on log scale.
Thankfully, the process is not terribly difficult (after a good amount of
fighting with the code!)
Attached you will find a snippet of the necessary code to generate such a
plot -- it starts from the creation of the canvas, pads and the
instantiation of the TGraphErrors class. The basic outline of how the
code works is:
1. Create the canvas, and two pads. Make sure to make the second pad
<transparent>.
2. Make an instance of your desired object that will essentially be your
plot (TH1F, TGraph, TGraphErrors, etc.), and plot the data as you normally
would, with your 'working directory' set to the first pad (the
non-transparent one). [NOTE: If you wish to use log and linear scales,
plot the LOG scale data in this pad! It will NOT work if you plot the log
data in the transparent pad.]
3. Here is the tricky part. One must determine the global coordinates of
the transparent pad, to be drawn directly on top of the first pad. One
may alter these boundary conditions, but I believe Rene Brun's example
(the code from which I took this segment from -- that first link I showed
you) has the coordinates mapped out perfectly, such that the transparent
pad lines up perfectly with the first pad. My code defines min and max x
and y values, and determines dx,dy values which are essentially used in
determining the pad placement.
4. Similar to step (2), draw your second (LINEAR-scale) plot. Be sure
your 'working directory' is the transparent pad.
5. We now make an instance of the TGaxis class. This will be used to
draw an axis on the right hand side of the plot. <be sure to follow my
code explicitly, or it will not work!> The entries look funny -- it takes
arguments of the form:
TGaxis *F = new TGaxis(xmax,ymin,xmax,ymax,wmin,wmax,ndiv,options);
the x and y values are clear. However, the order is strange. From the
PaintAxis() method:
xmin : X origin coordinate in WC space.
xmax : X end axis coordinate in WC space.
ymin : Y origin coordinate in WC space.
ymax : Y end axis coordinate in WC space.
wmin : Lowest value for the tick mark
labels written on the axis.
wmax : Highest value for the tick mark labels
written on the axis.
ndiv : Number of divisions.
Where WC = world coordinate (of pad).
I believe it's easiest to set wmin = ymin, wmax = ymax, since those are
also the lowest and highest points in the graph. You may note in my code
I've chosen ndiv to be 510. If you use 505, it gives a broader range --
shows less detail in the tick-marks. One may also substitute in for the
ymin and ymax values by a function -- like f(x) = log10(x) -- this will
give you a log scale -- however, after my long battle with trying to make
that work properly, I find it to somehow 'detach' itself from the actual
data. It seems fishy to me. It's best to use gPad->SetLogy(1) to set
your log scale (in that first pad!).
As for the requirement of plotting the log-scale data in the first pad,
well it's a mystery to me. I think the issue somehow arises in the
transparent pad, because after one sets the pad to log-scale (via
gPad->SetLogy(1)) it tries to calculate the coordinates using the log of
the values you've specified as your global coordinates (ymin, ymax). It's
a guess, I may be wrong. But my way works, so it does the job :)
This may be quite lengthy, but I found it useful to know what the code is
doing.
Attached, you will find the code I've described above, with my input data
code snipped out. Also, my output plot is attached, for reference.
On a side note -- I have found the TVector class to be quite useful when
utilizing the TGraph and its derived classes. I'm not sure if any of you
use TVector, but I find it to be better than arrays -- you don't need to
specify its size when making an instance, but just use its associated
push_back method to increase the size as you fill it.
Any questions, let me know.
Dave
-------------------------------------------------
David Flay
Physics Department
Temple University
Philadelphia, PA 19122
office: Barton Hall, BA319
phone: (215) 204-1331
e-mail: flay at jlab.org
flay at temple.edu
website: http://www.jlab.org/~flay
http://quarks.temple.edu
-------------------------------------------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: plot_data_final.C
Type: application/octet-stream
Size: 1922 bytes
Desc: not available
Url : https://mailman.jlab.org/pipermail/d2n-analysis-talk/attachments/20100326/e85559b2/attachment-0001.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cer_pid_4p60_3_26_10.png
Type: image/png
Size: 18635 bytes
Desc: not available
Url : https://mailman.jlab.org/pipermail/d2n-analysis-talk/attachments/20100326/e85559b2/attachment-0001.png
More information about the d2n-analysis-talk
mailing list