pythonmatplotlibseabornlegendopacity

Problem with symbol opacity of errorbar within legend


I'm trying to indicate perfectly symbols within legend once I want to plot complicated combinations of line and errorbar in grid plots. I noticed that it's not easy to apply desired opacity for any symbol kinds when they are error bar.

I have tried following checking this post unsuccessfully.

import matplotlib.pyplot as plt
from matplotlib.collections import PathCollection
from matplotlib.legend_handler import HandlerPathCollection, HandlerLine2D, HandlerErrorbar


x1 = np.linspace(0,1,8)
y1 = np.random.rand(8)

# Compute prediction intervals
sum_of_squares_mid = np.sum((x1 - y1) ** 2)
std_mid            = np.sqrt(1 / (len(x1) - 2) * sum_of_squares_mid)

# Plot the prediction intervals
y_err_mid = np.vstack([std_mid, std_mid]) * 1.96

plt.plot(x1, y1, 'bo', label='label', marker=r"$\clubsuit$",  alpha=0.2)                                                 # Default alpha is 1.0.
plt.errorbar(x1, y1, yerr=y_err_mid, fmt="o", ecolor="#FF0009", capsize=3, color="#FF0009", label="Errorbar", alpha=.1)  # Default alpha is 1.0.


def update(handle, orig):
    handle.update_from(orig)
    handle.set_alpha(1)

plt.legend(handler_map={PathCollection : HandlerPathCollection(update_func = update),
                            plt.Line2D : HandlerLine2D(        update_func = update),
                          plt.errorbar : HandlerErrorbar(      update_func = update) # I added this but it deos not apply alpha=1 only for errobar symbol in legend
                        })

plt.show()

My current output:

resulting plot without updated alpha


Solution

  • It appears that you were not specifying the right handler for the second Artist which is an ErrorbarContainer, thus the set_alpha(1) instruction was not executed for that object.

    Indeed, importing

    import matplotlib.pyplot as plt
    from matplotlib.container import ErrorbarContainer
    from matplotlib.legend_handler import HandlerLine2D, HandlerErrorbar
    

    and then modifying the handler_map to

    def update(handle, orig):
        handle.update_from(orig)
        handle.set_alpha(1)
    
    leg = plt.legend(handler_map={
        plt.Line2D : HandlerLine2D(update_func = update),
        ErrorbarContainer: HandlerErrorbar(update_func = update)
                            })
    

    results in

    Figure with solid symbols in legend

    Hope this helps!