(xyplots)= # x-y plots :::::{admonition} Python programmers: Not so fast! :class: warning You probably saw the title of this page, thought "I don't need this; I know [matplotlib](https://matplotlib.org/stable/users/index)" and were tempted to skip it. Give this page a skim. There are features of ROOT's `TGraphErrors` that are not in matplotlib, such as interactive plots. It's OK to decide to stick with matplotlib if you feel more comfortable with it, but at least make the choice as an informed decision. ::::: The main ROOT tools for creating x-y plots are: * [TGraph](https://root.cern.ch/doc/master/classTGraph.html) for x-y plots without error bars; e.g., plots that consist mostly of lines and curves. * [TGraphErrors](https://root.cern.ch/doc/master/classTGraphErrors.html) for x-y plots with error bars (in y, x, or both). When I want to create a ROOT plot that is *not* a histogram, I usually look at the [graphs examples](https://root.cern/doc/master/group__tutorial__graphs.html) in the [ROOT tutorials](https://root.cern/doc/master/group__Tutorials.html). If you use the method I discussed in the {ref}`references` section, you can see these files on your system with: cd `root-config --tutdir`/graphs ls The two examples I look at most often are: * [graph.C](https://root.cern/doc/master/gr001__simple_8C.html) for `TGraph`; * [gerrors.C](https://root.cern/doc/master/gr002__errors_8C.html) for `TGraphErrors`. Let's focus on {file}`graph.C`. First the program sets up some example data points: :::{code-block} python :name: setup-graph-python-code :caption: Setting up the {file}`graph.C` data points in Python import numpy as np import math # Set up example points to plot. n = 20 x = np.empty(n,float) y = np.empty(n,float) for i in range(n): x[i] = i*0.1 y[i] = 10*math.sin(x[i]+0.2) ::: :::{code-block} c++ :name: setup-graph-c-code :caption: Setting up the {file}`graph.C` data points in C++ // Set up example points to plot. const Int_t n = 20; Double_t x[n], y[n]; for (Int_t i=0;i The x-y plot from {file}`graph.C`. ::: Here's the C++ code in {file}`graph.C`. I copied it and added lots of {ref}`comments `: :::{code-block} c++ :name: graph-c-code :caption: The code from {file}`graph.C` with my comments added %jsroot // Define a default canvas TCanvas *canvas = new TCanvas(); // In ROOT, a grid is a property of the canvas, // not the graph. canvas->SetGrid(); // Define our graph, using the points we defined above. TGraph *graph = new TGraph(n,x,y); // Set the properties of the plot. // Line attributes are defined in TAttLine graph->SetLineColor(kRed); graph->SetLineWidth(4); // Marker attributes are defined in TAttMarker // Colors are defined in TColor. graph->SetMarkerColor(kBlue); graph->SetMarkerStyle(21); graph->SetTitle("a simple graph"); // Axis properties are defined in TGAxis graph->GetXaxis()->SetTitle("X title"); graph->GetYaxis()->SetTitle("Y title"); // From TGraphPainter: A = plot axes, C = plot a curve, P = plot points graph->Draw("ACP"); // In a notebook, after we draw a graph, we have to draw its canvas canvas->Draw(); ::: Here's the same code in Python. They don't look all that different, do they? :::{code-block} python :name: graph-python-code :caption: The equivalent of {file}`graph.C` in Python import ROOT %jsroot # Define a default canvas canvas = ROOT.TCanvas() # In ROOT, a grid is a property of the canvas, # not the graph. canvas.SetGrid() # Define our graph, using the points we defined above. graph = ROOT.TGraph(n,x,y) # Set the properties of the plot. # Line attributes are defined in TAttLine. # Colors are defined in TColor. graph.SetLineColor(ROOT.kRed) graph.SetLineWidth(4) # Marker attributes are defined in TAttMarker graph.SetMarkerColor(ROOT.kBlue) graph.SetMarkerStyle(21) graph.SetTitle("a simple graph") # Axis properties are defined in TGAxis graph.GetXaxis().SetTitle("X title") graph.GetYaxis().SetTitle("Y title") # From TGraphPainter: A = plot axes, C = plot a curve, P = plot points graph.Draw("ACP") # In a notebook, after we draw a graph, we have to draw its canvas canvas.Draw() ::: For your convenience, here are links to the classes I mention in the comments: * [TGraphPainter](https://root.cern.ch/doc/master/classTGraphPainter.html) for general options when plotting graphs (e.g., the type of graph; axis placement; lines vs. curves). * [TAttMarker](https://root.cern.ch/doc/master/classTAttMarker.html) for the color, shape, and size of markers (the points in an x-y plot). * [TAttLine](https://root.cern.ch/doc/master/classTAttLine.html) for the color, width, and style (solid, dotted, dashed) of lines on the graph. * [TGAxis](https://root.cern.ch/doc/master/classTGaxis.html) to control parameters of the axes (e.g., linear vs. log; tick position; labels). * [TColor](https://root.cern.ch/doc/master/classTColor.html) for the full range of colors available for a graph's elements. :::::{admonition} matplotlib comparison :class: note If you're a Python programmer: * Thanks for being willing to read this far! * How is this different from using matplotlib? Let's start with the matplotlib equivalent of {numref}`Listing %s `: :::{code-block} python :name: graph-matplot-code :caption: The equivalent of {file}`graph.C` in Python import matplotlib.pyplot as plt plt.plot(x,y, linestyle='solid', linewidth=4, color='red', marker='s', markeredgecolor="blue", markerfacecolor="blue", ) plt.grid() plt.title('a simple graph') plt.xlabel("X title") plt.ylabel("Y title") None ::: If your first reaction is "The matplotlib version is much shorter!" then you're being misled by all the comments in {numref}`Listing %s `. I count 14 executable lines (include the `%jsroot`) in the ROOT code, 13 lines in the matplotlib code (*not* including the closing parenthesis on its own line). In other words, in terms of lines of code, they're both of equal complexity. The reason why I prefer ROOT over matplotlib is the interactivity after I've created the graph. I went into detail about this in {ref}`magic-command`. To recap: - In command-line ROOT, you can use the same tools you learned about in {ref}`plotting-function` and {ref}`saving-c1` to interactively edit your plot's appearance, save it as a .C macro, then examine the macro to learn the ROOT commands to get a plot to look the way you want.

- In a ROOT {ref}`notebook `, you can use the {ref}`%jsroot magic command ` to make an x-y plot interactive, so you're able to modify the plot in much the same way as in command-line ROOT. The difference is that you can't save the plot as a .C macro... at least, not yet! Of course, complexity and interactivity are subjective. In a typical Python notebook matplotlib graph, you make your plot, adjust code parameters, and hit SHIFT-Enter to update the plot. This may be sufficient for your needs. At least now you know you have a choice! :::::