Thanks Pierre, I used your technique to build a graph that also represents saturation and value as a gradient in the direction of the radius.
Here is what it returns for the example given (with saturation and value ranges added)
Code:
def radius_barplot(lower_color, upper_color, ax, index=None, angle_precision=1, full_color=0.9, plot_index=(1, 1, 1)):
ax = plt.subplot(plot_index[0], plot_index[1], plot_index[2], projection="polar")
#print("Building graph")
if index is None:
if isinstance(lower_color[0], pd.Series):
index = lower_color[0].index
lower_color = [parameter.tolist() for parameter in lower_color]
upper_color = [parameter.tolist() for parameter in upper_color]
else:
index= range(len(lower_color[0]))
pi2 = 2*pi
hue_only = 1 - full_color
for i in range(len(index)):
#print("Frame n°", i+1, sep='')
min_hue, max_hue = lower_color[0][i] / 179 * 2 * pi, upper_color[0][i] / 179 * 2 * pi
min_sat, min_val = lower_color[1][i] / 255, lower_color[2][i] / 255
range_hue, range_sat, range_val = max_hue - min_hue, round(upper_color[1][i] - lower_color[1][i]), round(upper_color[2][i] - lower_color[2][i])
n_height = min(max(range_sat, range_val), 20)
pas_height = 1*full_color/n_height
large_pas_angle, large_pas_height = angle_precision*1.5/180*pi, pas_height*1.25
pas_sat, pas_val = range_sat / 255 / n_height, range_val / 255 / n_height
#print("Angle range: [", round(min_hue/pi*180), "; ", round((max_hue)/pi*180), "]", sep='')
# For each degree of the angle
for angle in np.arange(min_hue, max_hue, angle_precision/180*pi):
# To avoid an overflow on the end of the interval
if angle + large_pas_angle > max_hue: large_pas_angle = max_hue - angle
# Keep a positive angle for the hue value
if angle < 0: angle = 2*pi + angle
# For each line inside the current bar
if full_color > 0:
for height in range(n_height):
"""
print("Height: [", round(i + height*pas_height, 2), ", ", round(i + height*pas_height + pas_height, 2),
"], angle: ", round(angle/pi*180, 3),
"°: color [", round(angle*360), ", ", round((min_sat + height*pas_sat)*100), ", ", round((min_val + height*pas_val)*100), "]", sep='')
"""
ax.barh(y=i + height*pas_height,
width=large_pas_angle, left=angle, height=large_pas_height, align='edge',
color=colorsys.hsv_to_rgb(angle/pi2,
min_sat + height*pas_sat,
min_val + height*pas_val)
)
# To display the reference hue (with full saturation and value)
ax.barh(y=i + full_color,
width=large_pas_angle, left=angle, height=hue_only, align='edge',
color=(colorsys.hsv_to_rgb(angle/pi2, 1, 1)))
# """
ax.set_rgrids(range(len(index)), labels=index)
radius_barplot(
((0, (3*pi/4)/(2*pi)*179, (pi/6)/(2*pi)*179), (0, 200, 50), (0, 50, 200)), # Minimal values of colors ranges
(((pi/3)/(2*pi)*179, (21*pi/20)/(2*pi)*179, (2*pi/3)/(2*pi)*179), (255, 250, 100), (255, 100, 250)), # Maximal values of colors ranges
axes)
Graph:

The main problem of this technique is its complexity: returning this graph took 1 minute and 45 seconds on my computer and getting the graph I am interested in takes almost 5 minutes.
So if someone has a better, more optimal method to obtain a similar result I would still be interested.