|
9 | 9 | from config import XSectionConfig |
10 | 10 | from tools.file_utilities import read_data_from_JSON, make_folder_if_not_exists |
11 | 11 | from tools.hist_utilities import value_error_tuplelist_to_hist, \ |
12 | | -value_tuplelist_to_hist, value_errors_tuplelist_to_graph |
| 12 | +value_tuplelist_to_hist, value_errors_tuplelist_to_graph, graph_to_value_errors_tuplelist |
13 | 13 | from math import sqrt |
14 | 14 | # rootpy & matplotlib |
15 | 15 | from ROOT import kRed, kGreen, kMagenta, kBlue |
|
18 | 18 | mpl.use( 'agg' ) |
19 | 19 | import rootpy.plotting.root2matplotlib as rplt |
20 | 20 | import matplotlib.pyplot as plt |
| 21 | +import matplotlib.gridspec as gridspec |
| 22 | +from matplotlib.ticker import MultipleLocator |
21 | 23 | from config import CMS |
22 | 24 | from matplotlib import rc |
23 | 25 | rc( 'font', **CMS.font ) |
@@ -258,7 +260,7 @@ def get_cms_labels( channel ): |
258 | 260 | return label |
259 | 261 |
|
260 | 262 |
|
261 | | -def make_plots( histograms, category, output_folder, histname, show_before_unfolding = False ): |
| 263 | +def make_plots( histograms, category, output_folder, histname, show_ratio = True, show_before_unfolding = False ): |
262 | 264 | global variable, k_values |
263 | 265 |
|
264 | 266 | channel = 'electron' |
@@ -286,11 +288,16 @@ def make_plots( histograms, category, output_folder, histname, show_before_unfol |
286 | 288 | hist_measured.marker = 'o' |
287 | 289 | hist_measured.color = 'red' |
288 | 290 |
|
289 | | - plt.figure( figsize = ( 16, 16 ), dpi = 200, facecolor = 'white' ) |
290 | | - axes = plt.axes() |
| 291 | + plt.figure( figsize = CMS.figsize, dpi = CMS.dpi, facecolor = CMS.facecolor ) |
| 292 | + if show_ratio: |
| 293 | + gs = gridspec.GridSpec( 2, 1, height_ratios = [5, 1] ) |
| 294 | + axes = plt.subplot( gs[0] ) |
| 295 | + else: |
| 296 | + axes = plt.axes() |
| 297 | + plt.xlabel( '$%s$ [GeV]' % variables_latex[variable], CMS.x_axis_title ) |
| 298 | + |
291 | 299 | axes.minorticks_on() |
292 | 300 |
|
293 | | - plt.xlabel( '$%s$ [GeV]' % variables_latex[variable], CMS.x_axis_title ) |
294 | 301 | plt.ylabel( r'$\frac{1}{\sigma} \frac{d\sigma}{d' + variables_latex[variable] + '} \left[\mathrm{GeV}^{-1}\\right]$', CMS.y_axis_title ) |
295 | 302 | plt.tick_params( **CMS.axis_label_major ) |
296 | 303 | plt.tick_params( **CMS.axis_label_minor ) |
@@ -341,9 +348,64 @@ def make_plots( histograms, category, output_folder, histname, show_before_unfol |
341 | 348 | new_handles.append( handle ) |
342 | 349 | new_labels.append( label ) |
343 | 350 |
|
344 | | - plt.legend( new_handles, new_labels, numpoints = 1, loc = 'upper right', prop = CMS.legend_properties ) |
| 351 | + legend_location = 'upper right' |
| 352 | + if variable == 'MT': |
| 353 | + legend_location = 'upper left' |
| 354 | + plt.legend( new_handles, new_labels, numpoints = 1, loc = legend_location, prop = CMS.legend_properties ) |
345 | 355 | plt.title( get_cms_labels( channel ), CMS.title ) |
346 | | - plt.tight_layout() |
| 356 | + |
| 357 | + if show_ratio: |
| 358 | + plt.setp( axes.get_xticklabels(), visible = False ) |
| 359 | + ax1 = plt.subplot( gs[1] ) |
| 360 | + ax1.minorticks_on() |
| 361 | + #ax1.grid( True, 'major', linewidth = 1 ) |
| 362 | + # setting the x_limits identical to the main plot |
| 363 | + x_limits = axes.get_xlim() |
| 364 | + ax1.set_xlim(x_limits) |
| 365 | + ax1.yaxis.set_major_locator( MultipleLocator( 0.5 ) ) |
| 366 | + ax1.yaxis.set_minor_locator( MultipleLocator( 0.1 ) ) |
| 367 | + |
| 368 | + plt.xlabel( '$%s$ [GeV]' % variables_latex[variable], CMS.x_axis_title ) |
| 369 | + plt.tick_params( **CMS.axis_label_major ) |
| 370 | + plt.tick_params( **CMS.axis_label_minor ) |
| 371 | + plt.ylabel( '$\\frac{\\textrm{theory}}{\\textrm{data}}$', CMS.y_axis_title_small ) |
| 372 | + ax1.yaxis.set_label_coords(-0.115, 0.8) |
| 373 | + #draw a horizontal line at y=1 for data |
| 374 | + plt.axhline(y = 1, color = 'black', linewidth = 1) |
| 375 | + |
| 376 | + for key, hist in sorted( histograms.iteritems() ): |
| 377 | + if not 'unfolded' in key and not 'measured' in key: |
| 378 | + ratio = hist.Clone() |
| 379 | + ratio.Divide( hist_data ) #divide by data |
| 380 | + rplt.hist( ratio, axes = ax1, label = 'do_not_show' ) |
| 381 | + |
| 382 | + stat_lower = hist_data.Clone() |
| 383 | + stat_upper = hist_data.Clone() |
| 384 | + syst_lower = hist_data.Clone() |
| 385 | + syst_upper = hist_data.Clone() |
| 386 | + |
| 387 | + # plot error bands on data in the ratio plot |
| 388 | + for bin_i in range( 1, hist_data.GetNbinsX() + 1 ): |
| 389 | + stat_errors = graph_to_value_errors_tuplelist(hist_data) |
| 390 | + stat_lower.SetBinContent( bin_i, 1 - stat_errors[bin_i-1][1]/stat_errors[bin_i-1][0] ) |
| 391 | + stat_upper.SetBinContent( bin_i, 1 + stat_errors[bin_i-1][2]/stat_errors[bin_i-1][0] ) |
| 392 | + if category == 'central': |
| 393 | + syst_errors = graph_to_value_errors_tuplelist(hist_data_with_systematics) |
| 394 | + syst_lower.SetBinContent( bin_i, 1 - syst_errors[bin_i-1][1]/syst_errors[bin_i-1][0] ) |
| 395 | + syst_upper.SetBinContent( bin_i, 1 + syst_errors[bin_i-1][2]/syst_errors[bin_i-1][0] ) |
| 396 | + |
| 397 | + if category == 'central': |
| 398 | + rplt.fill_between( syst_lower, syst_upper, ax1, facecolor = 'yellow', alpha = 0.5 ) |
| 399 | + |
| 400 | + rplt.fill_between( stat_upper, stat_lower, ax1, facecolor = '0.75', alpha = 0.5 ) |
| 401 | + |
| 402 | + # p1 = plt.Rectangle((0, 0), 1, 1, fc="yellow") |
| 403 | + # p2 = plt.Rectangle((0, 0), 1, 1, fc="0.75") |
| 404 | + # plt.legend([p1, p2], ['Stat. $\\oplus$ Syst.', 'Stat.'], loc = 'upper left', prop = {'size':20}) |
| 405 | + ax1.set_ylim( ymin = 0.5, ymax = 1.5 ) |
| 406 | + |
| 407 | + if CMS.tight_layout: |
| 408 | + plt.tight_layout() |
347 | 409 |
|
348 | 410 | path = output_folder + str( measurement_config.centre_of_mass_energy ) + 'TeV/' + variable + '/' + category |
349 | 411 | make_folder_if_not_exists( path ) |
|
0 commit comments