.. root2matplot documentation master file, created by sphinx-quickstart on Mon Mar 1 13:54:08 2010. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. .. module:: root2matplot :synopsis: Tools for plotting ROOT histograms in matplotlib .. moduleauthor:: Jeff Klukas .. |root2matplot| replace:: :mod:`root2matplot` .. |pyROOT| replace:: :mod:`pyROOT` .. |matplotlib| replace:: :mod:`matplotlib` .. |pip| replace:: :command:`pip` .. |overlayHists| replace:: :mod:`overlayHists` |root2matplot| --- Beautifying ROOT ========================================== ---!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |root2matplot| is deprecated! The same functionality has been moved to a new package called rootplot: http://packages.python.org/rootplot/ ---!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ROOT is a powerful data analysis tool within the particle physics community, and the primary lens through which we see our data. The framework includes quite a bit of graphical capabilities, but producing high-quality graphics output was not the first priority in designing its capabilities or its interface. It becomes useful, then, to consider using an outside library focused on graphics for producing final plots. The |pyROOT| interface to ROOT makes it easy to have ROOT objects interact with other python modules. The goal of |root2matplot| is to enable easy plotting of ROOT histograms using the full-featured and mature |matplotlib| library. Some possibilities in matplotlib that are unavailable in ROOT include transparent fills and text output using LaTeX. You may want to use |root2matplot| to achieve effects or complex diagrams that would be difficult or impossible in ROOT, or you may simply want to recreate a ROOT figure with the higher-quality text available through a LaTeX engine. For immediate figures with a minimum of effort (with output directly from ROOT or through |matplotlib|, take a look at the section on the |overlayHists| command-line tool, which is included in |root2matplot| Contact ------------------------------------------ |root2matplot| is developed and maintained by Jeff Klukas [(klukas) (at) (wisc) (dot) (edu)]. Feel free to contact the author for help or with suggestions. Installation ------------------------------------------ The |root2matplot| library requires that you have both |pyROOT| and |matplotlib| available within a single python installation. This may not be easy (so if you have a CERN lxplus account, check below). You can find some help on the `PyROOT site `_, although specific needs may vary by platform, and you may need to search for additional information (like `instructions for a Mac OSX 10.6 installation `_). The easiest installation of |root2matplot| is through |pip|:: $ pip install root2matplot If you don't have |pip| installed, you can obtain it through :command:`easy_install`, which is probably already installed on your system if you have python installed:: $ easy_install pip The |pip| installer will place the |root2matplot| library in an appropriate place in your python tree. It will also install the |overlayHists| script in an appropriate :mod:`bin` directory so that it is available on the command line. Installing from the Repository ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |root2matplot| is version controlled with Mercurial. To download the latest development version:: $ hg clone http://bitbucket.org/klukas/root2matplot $ ln -s root2matplot/lib/root2matplot/ /path/to/your/python/lib/area Easy Access on lxplus ^^^^^^^^^^^^^^^^^^^^^ As a temporary solution for lxplus users, you may logon to any of the SLC5 machines (lxplus5) and source the following script:: $ source /afs/cern.ch/user/k/klukas/public/Sharing/root2matplot_setup.sh This will point to a local installation of |root2matplot| and should also set up a compatible cocktail of python, matplotlib, and ROOT. After you run the script, you can check that it works by trying out one of the below examples. Examples ----------------------------------------- First plot ^^^^^^^^^^ A first example:: import root2matplot as r2m import ROOT from matplotlib import pyplot as plt from random import gauss th1f = ROOT.TH1F("hpx", "Distribution of p_{x};p_{x};Events", 40, -4, 4) for i in range(25000): th1f.Fill(gauss(0., 1.)) # Make a figure with width 6 inches and height 4 inches plt.figure(1, (8, 6)) # Create an axes instance ax1 = plt.axes() hist = r2m.Hist(th1f) # Plot a bar chart in red hist.bar(color='r') hist.show_titles() plt.savefig('first') plt.show() Running this will produce the following as a ``png`` file and also display the plot onscreen: .. image:: images/first.png So far, this is probably not the prettiest output you've seen, but we're relying on all of |matplotlib|'s defaults. The real power of the solution is the amount of customization that's possible, and how comparitively easy it is to achieve the results you desire. Notice that ROOT's simplified TeX-esque syntax doesn't isn't understood by |matplotlib|. By default, matplotlib uses an internal typesetting engine that allows simple expressions following the official TeX syntax, using ``$`` to denote math mode and ``\`` characters to start commands. To handle conversion from the names you gave the histograms in ROOT to names that are compatible with matplotlib, you can provide a list of ordered pairs in the Hist constructor with the ``replace`` keyword:: replacements = [('p_{x}', r'$p_x$'), ('#eta', r'$\eta$')] hist.bar(color='r', replace=replacements) This will replace all instances of ``p_{x}`` with ``$p_x$``, generating the correct LaTeX expressions, and you should give it a try. Notice the ``r`` prefix on the second string, which denotes a "raw" string. In this case, it doesn't matter, but if the LaTeX string were to contain any commands using ``\``, a normal string would interpret these as escaped characters. Now, let's add the replacements above and make a more ROOT-style filled histogram with a single line along the top of the bins:: import root2matplot as r2m import ROOT import matplotlib from matplotlib import pyplot as plt from random import gauss th1f = ROOT.TH1F("hpx", "Distribution of p_{x};p_{x};Events", 40, -4, 4) for i in range(25000): th1f.Fill(gauss(0., 1.)) plt.figure() replace = [('p_{x}', r'$p_x$'), ('#eta', r'$\eta$')] hist = r2m.Hist(th1f, replace=replace) hist.hist(color='r', histtype='stepfilled') hist.show_titles() plt.savefig('firstrep', dpi=50) plt.show() .. image:: images/firstrep.png A more complicated example ^^^^^^^^^^^^^^^^^^^^^^^^^^ Imagine that you are preparing a LaTeX document using the ``mathpazo`` package, which sets up Palatino as the default font. With |matplotlib|, you can generate an output PS or PDF that has all its text rendered with the full-blown LaTeX distribution on your system, so that your plots match exactly with the rest of your document. The following example loads the PDF backend, and enables the ``text.usetex`` option to tell |matplotlib| to use your real LaTeX engine. It also highlights some extra matplotlib functions, like transparent fills, legends, and colormaps.:: import matplotlib matplotlib.use("PDF") matplotlib.rc('text', usetex=True) matplotlib.rc('font', family="serif", serif="palatino") from matplotlib import pyplot as plt import ROOT import root2matplot as r2m from random import gauss th1f_1 = ROOT.TH1F("hpt1", "Distribution of pT;pT;Events", 40, 0, 8) th1f_2 = ROOT.TH1F("hpt2", "Distribution of pT;pT;Events", 40, 0, 8) for i in range(2500): th1f_1.Fill(gauss(4, 1.)) th1f_2.Fill(gauss(6, 1.)) cmap = plt.get_cmap('Set3') colors = [cmap(i/5.) for i in range(5)] plt.figure(1, (6, 4)) ax1 = plt.axes() replace = [('pT', r'$p_\mathrm{T}$'), ('ZMM', r'$Z\rightarrow \mu\mu$'), ('ttbar', r'$t\bar{t}$')] hist1 = r2m.Hist(th1f_1, replace) hist2 = r2m.Hist(th1f_2, replace) stack = r2m.HistStack() stack.add(hist1, color=colors[0], label="ZMM", replace=replace) stack.add(hist2, color=colors[1], label="ttbar", replace=replace) stack.bar(alpha=0.5) stack.show_titles() plt.legend(loc='upper left') plt.xlim(0,8) plt.savefig('second') The result should look like this: .. image:: images/second.png A Two-Dimensional Histogram ^^^^^^^^^^^^^^^^^^^^^^^^^^^ |root2matplot| also supports 2D histograms. A Hist2D object has functions such as ``box``, ``col``, or ``colz`` to replicate ROOT drawing options, but also the ability to make ``contour`` plots:: import root2matplot as r2m import ROOT from matplotlib import pyplot as plt from random import gauss th2f = ROOT.TH2F("data", "", 20, -3, 3, 20, -3, 3) for i in range(20000): th2f.Fill(gauss(0., 1.), gauss(0., 1.)) ax = plt.axes() hist = r2m.Hist2D(th2f) hist.colz() plt.savefig('colz') plt.clf() # clear figure ax = plt.axes(aspect='equal') hist.contour() plt.savefig('contour') The results should look like: .. image:: images/colz.png .. image:: images/contour.png Navigating Within a ROOT file ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In real life, you won't be making random Gaussian distributions from within python. Instead, you'll be pulling histograms from an existing ROOT file. The |root2matplot| module includes a ``RootFile`` class as a wrapper to provide easier, more pythonic access to your files. In the following example, we open a file, navigate to a directory, and get a histogram as a ``Hist`` object:: from matplotlib import pyplot as plt import ROOT import root2matplot as r2m f = r2m.RootFile("histograms.root") f.cd("muons") print r2m.pwd() print r2m.ls() hist = r2m.get("muon_pt") hist.bar() plt.show() The |root2matplot| Library ------------------------------------------ .. automodule:: root2matplot.core :members: The |overlayHists| Command-Line App ============================================ .. automodule:: root2matplot.overlayHists Customization of |overlayHists| ------------------------------------------ Most of the style options for your output can be specified in a `rootlogon.C `_ or `matplotlibrc `_ depending on which kind of output you'd like. Documentation on this kind of configuration can be found on the websites of ROOT and |matplotlib| respectively. There are, however, several style options which are specific to |overlayHists|. These include the line colors and markers used, as well as the dictionary used for text replacement with |matplotlib|. If you'd like to customize these for your own use, simply make a configuration file with a `.py` extension and add the file to your list of arguments to |overlayHists|. You can get a nice default with all the configurable parameters by calling:: $ overlayHists --config The command-line options available are described in the help message output:: $ overlayHists -h Usage: overlayHists [options] [style_config.py] [file1.root ...] Documentation: http://packages.python.org/root2matplot/ Function: overlays corresponding histograms from several files, dumping the images into a directory structure that mirrors that of the ROOT file and, if output format is pdf, also merging all images into a single file. Most style options can be controlled from your rootlogon.C macro. Power users: advanced operation using configuration files is described in the full online documentation. This allows you control over colors, styles, names for the legends, and more. Get the default config with --config. Matplotlib: if you have the matplotlib python plotting library installed on your system, you can produce output in matplotlib. This will be activated by enabling any of the options 'mpl', 'bar', 'errorbar', 'hist', or 'stack'. Options: --version show program's version number and exit -h, --help show this help message and exit --config do nothing but write a template configuration file called overlayHists_config.py -e EXT, --ext=EXT choose an output extension; default is png -m, --markers add markers to histograms -s, --sticky enable name-based special plotting options (see below) --merge creates a single pdf file containing all plots --noclean skips destroying the output directory before drawing --data=FILENUM the histogram from the FILENUMth (starting from 1) file will be drawn as black datapoints, while all others will be filled, as is the custom for showing data vs. Monte Carlo. --output=NAME name of output directory; default is 'overlaidHists' --numbering add a page number in the upper right of each plot --path=PATH only process plot(s) in the given location or its subdirectories; PATH may be a regular expression (use .* for wildcard) --normalize=VALUE if integer, normalize to the VALUEth file (starting with 1); if float, scale by VALUE --range=LOWxHIGH only use the specified data range in determining the normalization --colormap=COLORMAP Select colors from the given matplotlib colormap rather than the defaults --ncolors=NCOLORS The number of colors with which to divide the colormap --legend=LOC Place legend in LOC, according to matplotlib location codes; examples include 'upper right', 'center', or 'center left' --title=TITLE Replace the plot titles, or add to them by preceeding with a '+' --xlabel=XLABEL Replace the x-axis labels, or add to them by preceeding with a '+' --ylabel=YLABEL Replace the y-axis labels, or add to them by preceeding with a '+' --grid Toggle the grid on or off for both axes --gridx Toggle the grid on or off for the x axis --gridy Toggle the grid on or off for the y axis --efficiency-from=DENOM Divide all plots by the histogram in path DENOM --processors=NUM Divide plot making up into NUM different processes Options specific to ROOT (default) output: --draw="p H" argument to pass to ROOT's Draw command; try 'e' for error bars --draw2D="box" argument to pass to ROOT's Draw command for 2D hists (only drawn when a single file is present); set to "" to turn off 2D drawing -f, --fill Histograms will have a color fill Producing output with matplotlib: --mpl produce output in matplotlib; automatically turned on by --stack, --errorbar, --bar, or --hist --mpl2D="box" Type of plot to produce for 2D histograms in matplotlib. Choose from 'contour', 'col', 'colz', or 'box' --stack output a matplotlib stacked bar graph --errorbar output a matplotlib errorbar graph --bar output a matplotlib bar graph --hist output a matplotlib hist graph (with solid fill) --alpha=ALPHA set the transparency factor used for matplotlib bar and hist graphs (default is 0.5; 1.0 is fully opaque) --transparent use a transparent background --size=SIZE Define the plot size as 'width x height' in inches; default is '6x4.5' --dpi=DPI Set the resolution of matplotlib output (default is 100) Special plotting options: Use the command line options given below to apply changes to all plots. If you only wish to apply an option to a specific plot, you can use '-s' to turn on sticky keywords (such as 'Norm'). Any plot that includes the given keyword in its ROOT name will have the option applied regardless of its presence or absence on the command line. -n, --area-normalize 'Norm': area normalize the histograms --efficiency 'Eff' : force y axis scale to run from 0 to 1 --logx 'Logx': force log scale for x axis --logy 'Logy': force log scale for y axis --zero 'Zero': force zero for the y-axis minimum --overflow 'Overflow' : display overflow content in highest bin --underflow 'Underflow': display underflow content in lowest bin --ratio=FILENUM 'Ratio': cut the canvas in two, displaying on the bottom the ratio of each histogram to the histogram in the FILENUMth (starting from 1) file. Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search`