In the following histogram,
import numpy as np import matplotlib.pyplot as plt tinter = [0.8253909999999998, 0.8804020000000001, 0.14202099999999973, 0.7727520000000005, 1.1040220000000005, 0.10714699999999944, 0.5750040000000016, 0.7876929999999973, 0.8980040000000002, 1.1478490000000008, 0.44635099999999994, 1.052067000000001, 0.4327469999999991, 0.3272960000000005, 0.26918099999999967, 0.3854459999999982, 0.1827140000000007, 0.8867760000000011, 0.7774879999999982, 0.21082900000000038, 0.6758939999999996, 0.4335760000000022, 0.6791699999999992, 0.7758439999999993, 0.15755200000000258, 0.1414289999999987, 0.36975599999999886, 0.8993549999999999, 0.6577640000000002, 1.043728999999999, 0.19952800000000082, 0.12645200000000045, 0.3454990000000002, 0.9054520000000004, 0.7165229999999987, 0.9425269999999983, 0.7159280000000052, 0.7413279999999958, 0.12669900000000212, 0.2822880000000012, 0.3690029999999993, 0.7246340000000018, 0.4718329999999966, 0.7580859999999987, 0.744059, 0.19344999999999857, 0.12031900000000206, 0.47543600000000197, 0.437542999999998, 0.44232000000000227, 0.5250109999999992, 0.17673200000000122, 0.2440649999999991, 0.31524799999999686, 0.7674680000000009, 0.7837700000000041, 1.1910290000000003, 0.14404899999999543, 0.21560399999999902, 0.19931500000000568, 0.27113699999999596, 0.728234999999998, 0.5061920000000057, 0.6459329999999994, 0.7817450000000008, 0.8265129999999985, 0.17931199999999592, 0.30208600000000274, 0.32583699999999993, 0.41771599999999864] n, bins, patches = plt.hist(x=tinter, bins='auto', color='#0504aa', alpha=0.7, rwidth=0.9,) plt.grid(axis='y', alpha=0.35) plt.xlabel('time [s]') plt.ylabel('Frequency') plt.title('Hit interval')
I would like to set two different colors for the bars of the histogram. There is a precedent question (this link), but the solution sets the bars’ colors in a range, e.g., bars 0 to 3 of one color.
This is a different problem since I would like to differentiate two zones in the histogram in general. I do not exactly how the particular histogram is and how many bars are. In the example above, the separation of colors should be at 0.6: left of time=0.6s of one color and right of time=0.6 of another. If it is not possible to make a bar of two colors (in the example, a range of time values is covered in the bar including 0.6), the separation of colors should go from the lowest bar in the example (bar of time=0.2) to the bar of time=0.6 included. And, in the example, the last four bars (above time=0.6s) of another color.
For example, in this example the values of n
and bins
that gives ‘plt.hist()` are:
n = array([16., 11., 10., 3., 16., 8., 3., 3.]) bins=array([0.107147 , 0.24263225, 0.3781175 , 0.51360275, 0.649088 , 0.78457325, 0.9200585 , 1.05554375, 1.191029 ])
I would like bars with n
16, 11, 10 and 3 of one color different of the other group of bars with n
16, 8, 3,3, and make it for a general histogram plot.
Advertisement
Answer
You could loop through the bars and test whether it is completely to the right of the separation, completely to the left or crosses it. You change the bar’s color correspondingly.
When a bar crosses the separator, the bar gets the color for the left area and its size is narrowed to touch the separator. A copy of the bar can be added, with the right-area color and its x-position moved.
import matplotlib.pyplot as plt import numpy as np from copy import copy tinter = [0.82539, 0.8804, 0.14202, 0.77275, 1.10402, 0.10715, 0.575, 0.78769, 0.898, 1.14785, 0.44635, 1.05207, 0.43275, 0.3273, 0.26918, 0.38545, 0.18271, 0.88678, 0.77749, 0.21083, 0.67589, 0.43358, 0.67917, 0.77584, 0.15755, 0.14143, 0.36976, 0.89935, 0.65776, 1.04373, 0.19953, 0.12645, 0.3455, 0.90545, 0.71652, 0.94253, 0.71593, 0.74133, 0.1267, 0.28229, 0.369, 0.72463, 0.47183, 0.75809, 0.74406, 0.19345, 0.12032, 0.47544, 0.43754, 0.44232, 0.52501, 0.17673, 0.24406, 0.31525, 0.76747, 0.78377, 1.19103, 0.14405, 0.2156, 0.19932, 0.27114, 0.72823, 0.50619, 0.64593, 0.78175, 0.82651, 0.17931, 0.30209, 0.32584, 0.41772] n, bins, patches = plt.hist(x=tinter, bins='auto', color='#0504aa', alpha=0.7, rwidth=0.9) plt.grid(axis='y', alpha=0.35) plt.xlabel('time [s]') plt.ylabel('Frequency') plt.title('Hit interval') separator = 0.6 left_color = 'turquoise' right_color = 'tomato' for bar in patches: x, y = bar.get_xy() w = bar.get_width() if x > separator: bar.set_color(right_color) else: bar.set_color(left_color) if x + w > separator: bar.set_width(separator-x) new_bar = copy(bar) new_bar.set_x(separator) new_bar.set_width(x+w-separator) new_bar.set_color(right_color) plt.gca().add_patch(new_bar) plt.show()
If you want the complete bar that contains the separator value to be one color, you can leave out the block below if x + w > separator:
.
n, bins, patches = plt.hist(x=tinter, bins='auto', color='#0504aa', alpha=0.7, rwidth=0.9) plt.grid(axis='y', alpha=0.35) plt.xlabel('time [s]') plt.ylabel('Frequency') plt.title('Hit interval') separator = 0.6 left_color = 'turquoise' right_color = 'tomato' for bar in patches: x, y = bar.get_xy() w = bar.get_width() if x > separator: bar.set_color(right_color) else: bar.set_color(left_color) plt.show()