17 """Constructor for a two dimensional ROOT histogram TH2Poly setup with hexagonal bins.
19 In contrast to TH2Poly.Honeycomb this does not leave any space in the histogram range uncovered
20 and allows for different scales in the x and y direction.
25 The name of the histogram to identify the object in ROOT.
27 Title of the histogram
28 n_x_bins : float or int
29 Number of hexagons in the x direction to cover the whole range
31 The lower bound of the histogram in the x direction.
33 The upper bound of the histogram in the x direction.
34 n_y_bins : float or int
35 Number of hexagons in the y direction to cover the whole range
37 The lower bound of the histogram in the y direction.
39 The upper bound of the histogram in the x direction.
40 y_orientation : bool, optional
41 Switch whether the hexagones should be primarily aligned along the y coordinate
42 instead of the x coordinate, which is the default
47 Two dimensional histogram populated with
51 hex_histogram = ROOT.TH2Poly(name,
64 unit_radius_hex_xs = np.array([math.sin(2.0 * pi * i / 6.0)
for i
in range(-2, 4)])
65 unit_radius_hex_ys = np.array([math.cos(2.0 * pi * i / 6.0)
for i
in range(-2, 4)])
68 unit_radius_hex_xs -= unit_radius_hex_xs[0]
69 unit_radius_hex_ys -= unit_radius_hex_ys[0]
72 hex_x_width = unit_radius_hex_xs[3] - unit_radius_hex_ys[0]
73 hex_y_width = unit_radius_hex_ys[2] - unit_radius_hex_ys[0]
74 hex_y_protrusion = unit_radius_hex_ys[2] - unit_radius_hex_ys[1]
76 unit_width_hex_xs = unit_radius_hex_xs / hex_x_width
77 unit_width_hex_ys = unit_radius_hex_ys / hex_y_width
81 n_x_bins, n_y_bins = n_y_bins, n_x_bins
82 x_lower_bound, y_lower_bound = y_lower_bound, x_lower_bound
83 x_upper_bound, y_upper_bound = y_upper_bound, x_upper_bound
86 n_y_bins_protrusion_correction = hex_y_protrusion / hex_y_width
88 base_x_bin_width = float(x_upper_bound - x_lower_bound) / n_x_bins
89 base_y_bin_width = float(y_upper_bound - y_lower_bound) / (n_y_bins - n_y_bins_protrusion_correction)
91 base_hex_xs = unit_width_hex_xs * base_x_bin_width
92 base_hex_ys = unit_width_hex_ys * base_y_bin_width
93 base_y_protrusion = base_hex_ys[2] - base_hex_ys[1]
96 x_bin_edges = np.linspace(x_lower_bound, x_upper_bound, n_x_bins + 1)
97 even_x_lower_bin_edges = x_bin_edges[:-1]
99 odd_x_lower_bin_edges = x_bin_edges - base_x_bin_width / 2.0
101 y_bin_edges = np.linspace(y_lower_bound, y_upper_bound + base_y_protrusion, n_y_bins + 1)
102 y_lower_bin_edges = y_bin_edges[:-1]
105 for i_y_bin, y_lower_bin_edge
in enumerate(y_lower_bin_edges):
107 x_lower_bin_edges = odd_x_lower_bin_edges
109 x_lower_bin_edges = even_x_lower_bin_edges
111 for x_lower_bin_edge
in x_lower_bin_edges:
112 hex_xs = base_hex_xs + x_lower_bin_edge
113 hex_ys = base_hex_ys + y_lower_bin_edge
117 hex_histogram.AddBin(6, hex_ys, hex_xs)
119 hex_histogram.AddBin(6, hex_xs, hex_ys)
127 normal_distributed_x_values = np.random.randn(n_data)
128 normal_distributed_y_values = 2.0 * np.random.randn(n_data)
129 weights = np.ones_like(normal_distributed_y_values)
139 hex_histogram = TH2Hex(
"hex_normal",
140 "Two dimensional normal distribution in a hexagonal binning",
149 hex_histogram.FillN(n_data, normal_distributed_x_values, normal_distributed_y_values, weights)
160 ROOT.gStyle.SetPalette(root_palette[
"rainbow"])
162 hex_histogram.Draw(
"colz")
165 if __name__ ==
"__main__":