Search code examples
pythonmatplotliblegendlegend-properties

Combine two patches for legend


I am trying to plot some data with confidence bands. I am doing this with two plots for each data stream: plot, and fill_between. I would like the legend to look similar to the plots, where each entry has a box (the color of the confidence region) with a darker, solid line passing through the center.

So far I have been able to use patches to create the rectangle legend key, but I don't know how to achieve the centerline. I tried using hatch, but there is no control over the placement, thickness, or color.

My original idea was to try and combine two patches (Patch and 2DLine); however, it hasn't worked yet. Is there a better approach? My MWE and current figure are shown below.

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0,1,11)
y = np.linspace(0,1,11)

plt.plot(x, y, c='r')
plt.fill_between(x, y-0.2, y+0.2, color='r', alpha=0.5)
p = mpatches.Patch(color='r', alpha=0.5, linewidth=0)

plt.legend((p,), ('Entry',))

Figure


Solution

  • The solution is borrowed from the comment by CrazyArm, found here: Matplotlib, legend with multiple different markers with one label. Apparently you can make a list of handles and assign only one label and it magically combines the two handles/artists.

    import matplotlib.patches as mpatches
    import matplotlib.pyplot as plt
    import numpy as np
    
    x = np.linspace(0,1,11)
    y = np.linspace(0,1,11)
    
    p1, = plt.plot(x, y, c='r')  # notice the comma!
    plt.fill_between(x, y-0.2, y+0.2, color='r', alpha=0.5)
    p2 = mpatches.Patch(color='r', alpha=0.5, linewidth=0)
    
    plt.legend(((p1,p2),), ('Entry',))
    

    Figure