0

I'm trying to add a color legend for the overlap in a overlapping histogram. Currently the legend only includes the colors for the non-overlapping portion. I want to have a third line in the legend for the color that results in the overlap between the other two colors.

X = [3,2,1,30,20,16]
Y = [4,1,6,4,34,21]
bins=[0,10,20,30,40]
plt.figure
plt.hist(X,bins=bins,edgecolor='black',color='red',alpha=0.5,label='X')
plt.hist(Y,bins=bins,edgecolor='black',color='blue',alpha=0.5,label='Y')
plt.legend()
plt.show

Here is my output:

Plot with overlapping colors but without a legend that includes the mixed color.

Joshua Shew
  • 618
  • 2
  • 19

2 Answers2

1

This functionality is pretty elegantly supported by using the handles directly. This approach doesn't require manually instantiating artists or mixing colors.

X = [3,2,1,30,20,16]
Y = [4,1,6,4,34,21]
#TMM_norm(X,Y,1)
bins=[0,10,20,30,40]
plt.figure
_,_,x_handle = plt.hist(X,bins=bins,edgecolor='black',color='red',alpha=0.5)
_,_,y_handle = plt.hist(Y,bins=bins,edgecolor='black',color='blue',alpha=0.5)
plt.legend((x_handle, y_handle, (x_handle, y_handle)), ('X','Y','X & Y'))
plt.show()

Output Graph

Darren Midkiff
  • 23
  • 1
  • 1
  • 3
0

You will need to mix the colours and add it to the legend. Below code will do this for you. Remember to add the second color first (b2 and then b1 in code below), so that the colors come out correctly. You can edit the text as you want for the legend(X, Y, X & Y) in the last line. Code borrowed from here. Hope this helps.

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

X = [3,2,1,30,20,16]
Y = [4,1,6,4,34,21]
bins=[0,10,20,30,40]

def mix_colors(cf, cb): # cf = foreground color, cb = background color 
    a = cb[-1] + cf[-1] - cb[-1] * cf[-1] # fixed alpha calculation
    r = (cf[0] * cf[-1] + cb[0] * cb[-1] * (1 - cf[-1])) / a
    g = (cf[1] * cf[-1] + cb[1] * cb[-1] * (1 - cf[-1])) / a
    b = (cf[2] * cf[-1] + cb[2] * cb[-1] * (1 - cf[-1])) / a
    return [r,g,b,a]

b1 = [1.0, 0.0, 0.0, 0.5]
b2 = [0.0, 0.0, 1.0, 0.5]
b12  = mix_colors(b2, b1) # mix b2 over b1

plt.figure()
plt.hist(X,bins=bins,edgecolor='black',color='red',alpha=0.5)
plt.hist(Y,bins=bins,edgecolor='black',color='blue',alpha=0.5)
plt.legend()
plt.show

b1 = Line2D([0], [0], linestyle='none', marker='s', markersize=10, markerfacecolor=b1)
b2 = Line2D([0], [0], linestyle='none', marker='s', markersize=10, markerfacecolor=b2)
b12 = Line2D([0], [0], linestyle='none', marker='s', markersize=10, markerfacecolor=b12)

plt.legend((b1, b2, b12), ('X', 'Y', 'X & Y'), numpoints=1, loc='best')

Output Graph

Graph

Redox
  • 9,321
  • 5
  • 9
  • 26