Reputation: 1343
I have this plot in which some areas between curves are being filled by definition. Is there any way to include them in legend? Especially where those filled areas are overlapped and as well as that a new and different color is being appeared.
Or there is possibility to define an arbitrary legend regardless of the curves' data?
Upvotes: 4
Views: 1195
Reputation: 2697
Using fill_bettween
to plot your data will automatically include the filled area in the legend.
To include the areas where the two datasets overlap, you can combine the legend handles from both dataset into a single legend handle.
As pointed out in the comments, you can also define any arbitrary legend handle with a proxy.
Finally, you can define exactly what handles and labels you want to appear in the legend, regardless of the data plotted in your graph.
See the MWE below that illustrates the points stated above:
import matplotlib.pyplot as plt
import numpy as np
plt.close('all')
# Gererate some datas:
x = np.random.rand(50)
y = np.arange(len(x))
# Plot data:
fig, ax = plt.subplots(figsize=(11, 4))
fillA = ax.fill_between(y, x-0.25, 0.5, color='darkolivegreen', alpha=0.65, lw=0)
fillB = ax.fill_between(y, x, 0.5, color='indianred', alpha=0.75, lw=0)
linec, = ax.plot(y, np.zeros(len(y))+0.5, color='blue', lw=1.5)
linea, = ax.plot(y, x, color='orange', lw=1.5)
lineb, = ax.plot(y, x-0.25, color='black', lw=1.5)
# Define an arbitrary legend handle with a proxy:
rec1 = plt.Rectangle((0, 0), 1, 1, fc='blue', lw=0, alpha=0.25)
# Generate the legend:
handles = [linea, lineb, linec, fillA, fillB, (fillA, fillB),
rec1, (fillA, fillB, rec1)]
labels = ['a', 'b', 'c', 'A', 'B', 'A+B', 'C', 'A+B+C']
ax.legend(handles, labels, loc=2, ncol=4)
ax.axis(ymin=-1, ymax=2)
plt.show()
Upvotes: 2
Reputation: 1343
Yes, you are absolutely right ian_itor, tacaswell and Jean-Sébastien, user defined legend seems to be the unique solution, in addition I made different linewidth for those area to be distinguishable from the curves, and playing with alpha got the right color.
handles, labels = ax.get_legend_handles_labels()
display = (0,1,2,3,4)
overlap_1 = plt.Line2D((0,1),(0,0), color='firebrick', linestyle='-',linewidth=15, alpha = 0.85)
overlap_2= plt.Line2D((0,1),(0,0), color='darkolivegreen',linestyle='-',linewidth=15, alpha = 0.65)
over_lo_3= plt.Line2D((0,1),(0,0), color='indianred',linestyle='-',linewidth=15, alpha = 0.75)
ax.legend([handle for i,handle in enumerate(handles) if i in display]+[overlap_1 , overlap_2 , overlap_3 ],
[label for i,label in enumerate(labels) if i in display]+['D','F','G'])
Upvotes: 1