Reputation: 375
This is similar to Matlab: Combine the legends of shaded error and solid line mean, except for Matplotlib. Example code:
import numpy as np
import matplotlib.pyplot as plt
x = np.array([0,1])
y = x + 1
f,a = plt.subplots()
a.fill_between(x,y+0.5,y-0.5,alpha=0.5,color='b')
a.plot(x,y,color='b',label='Stuff',linewidth=3)
a.legend()
plt.show()
The above code produces a legend that looks like this:
How can I create a legend entry that combines the shading from fill_between
and the line from plot
, so that it looks something like this (mockup made in Gimp):
Upvotes: 19
Views: 19597
Reputation: 121
Here is an example using patches
. I use get_facecolor()
to get the color of fill_between()
plot and use it to draw a patch
. It is easier to customize.
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
x = np.array([0, 1])
y = x + 1
fig, ax = plt.subplots()
p0 = ax.fill_between(x, y + 0.5, y - 0.5, alpha=0.5, color='b')
p1 = ax.plot(x, y, color='b', linewidth=3, label ='abc')
patch = mpatches.Patch(color= p0.get_facecolor(),linewidth=0)
red_patch = mpatches.Patch(color= 'r',linewidth=0)
fig.legend(handles = [( patch,p1[0]), red_patch], labels = [p1[0].get_label(),'b'], handleheight = 2)
plt.show()
Upvotes: 0
Reputation: 10781
MPL supports tuple inputs to legend so that you can create composite legend entries (see the last figure on this page). However, as of now PolyCollections--which fill_between creates/returns--are not supported by legend, so simply supplying a PolyCollection as an entry in a tuple to legend won't work (a fix is anticipated for mpl 1.5.x).
Until the fix arrives I would recommend using a proxy artist in conjunction with the 'tuple' legend entry functionality. You could use the mpl.patches.Patch
interface (as demonstrated on the proxy artist page) or you could just use fill. e.g.:
import numpy as np
import matplotlib.pyplot as plt
x = np.array([0, 1])
y = x + 1
f, a = plt.subplots()
a.fill_between(x, y + 0.5, y - 0.5, alpha=0.5, color='b')
p1 = a.plot(x, y, color='b', linewidth=3)
p2 = a.fill(np.NaN, np.NaN, 'b', alpha=0.5)
a.legend([(p2[0], p1[0]), ], ['Stuff'])
plt.show()
Upvotes: 25