Set legend symbol opacity with matplotlib?
UPDATED: There is an easier way! First, assign your legend to a variable when you create it:
leg = plt.legend()
Then:
for lh in leg.legendHandles:
lh.set_alpha(1)
OR if the above doesn't work (you may be using an older version of matplotlib
):
for lh in leg.legendHandles:
lh._legmarker.set_alpha(1)
to make your markers opaque for a plt.plot
or a plt.scatter
, respectively.
Note that using simply lh.set_alpha(1)
on a plt.plot
will make the lines in your legend opaque rather than the markers. You should be able to adapt these two possibilities for the other plot types.
Sources: Synthesized from some good advice by DrV about marker sizes. Update was inspired by useful comment from Owen.
If you want to have something specific in your legend, it's easier to define objects that you place in the legend with appropriate text. For example:
import matplotlib.pyplot as plt
import pylab
plt.plot_date( x = xaxis, y = yaxis, marker = 'x', color=[1, 0, 0, .2], label='Data Series' )
line1 = pylab.Line2D(range(1),range(1),color='white',marker='x',markersize=10, markerfacecolor="red",alpha=1.0)
line2 = pylab.Line2D(range(10),range(10),marker="_",linewidth=3.0,color="dodgerblue",alpha=1.0)
plt.legend((line1,line2),('Text','Other Text'),numpoints=1,loc=1)
Here, line1 defines a short, white line (so essentially invisible) with the marker 'x' in red and full opacity. As an example, line2 gives you a longer blue line with no markers visible. By creating this "lines," you are able to more easily control their properties within the legend.
Other answers here give good practical solutions by either changing the alpha value in the legend after creation, or changing the alpha of the line after legend creation.
A solution to achieve a different opacity in the legend without manipulating anything afterwards would be the following. It uses a handler_map
and an updating function.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(43)
from matplotlib.collections import PathCollection
from matplotlib.legend_handler import HandlerPathCollection, HandlerLine2D
plt.plot(np.linspace(0,1,8), np.random.rand(8), marker="o", markersize=12, label="A line", alpha=0.2)
plt.scatter(np.random.rand(8),np.random.rand(8), s=144,
c="red", marker=r"$\clubsuit$", label="A scatter", alpha=0.2)
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.show()
Following up on cosmosis's answer, to make the "fake" lines for the legend invisible on the plot, you can use NaNs, and they will still work for generating legend entries:
import numpy as np
import matplotlib.pyplot as plt
# Plot data with alpha=0.2
plt.plot((0,1), (0,1), marker = 'x', color=[1, 0, 0, .2])
# Plot non-displayed NaN line for legend, leave alpha at default of 1.0
legend_line_1 = plt.plot( np.NaN, np.NaN, marker = 'x', color=[1, 0, 0], label='Data Series' )
plt.legend()