Change size/alpha of markers in the legend box

Question:

What is the most convenient way to enlarge and set the alpha value of the markers (back to 1.0) in the legend box? I’m also happy with big coloured boxes.

import matplotlib.pyplot as plt
import numpy as np

n = 100000
s1 = np.random.normal(0, 0.05, n)
s2 = np.random.normal(0, 0.08, n)
ys = np.linspace(0, 1, n)

plt.plot(s1, ys, ',', label='data1', alpha=0.1)
plt.plot(s2, ys, ',', label='data2', alpha=0.1)
plt.legend(bbox_to_anchor=(1.005, 1), loc=2, borderaxespad=0.)

enter image description here

Asked By: tamasgal

||

Answers:

We can use the handler_map option to .legend() to define a custom function to update the alpha or marker for all Line2D instances in the legend. This method has the advantage that it gets the legend markers correct first time, they do not need to be modified afterwards, and fixes issues where the original legend markers can sometimes still be seen.

This method makes use of HandlerLine2D from the matplotlib.legend_handler module. I’m not aware of a way to do this without adding the extra import.

A complete script would look like this:

import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerLine2D
import numpy as np

# Generate data
n = 100000
s1 = np.random.normal(0, 0.05, n)
s2 = np.random.normal(0, 0.08, n)
ys = np.linspace(0, 1, n)

# Create figure and plot the data
fig, ax = plt.subplots()
ax.plot(s1, ys, ',', label='data1', alpha=0.1)
ax.plot(s2, ys, ',', label='data2', alpha=0.1)

def change_alpha(handle, original):
    ''' Change the alpha and marker style of the legend handles '''
    handle.update_from(original)
    handle.set_alpha(1)
    handle.set_marker('.')

# Add the legend, and set the handler map to use the change_alpha function
ax.legend(bbox_to_anchor=(1.005, 1), loc=2, borderaxespad=0.,
          handler_map={plt.Line2D: HandlerLine2D(update_func=change_alpha)})

plt.show()

enter image description here


Note, below is my original answer. I have left it here for posterity as is may work for some use cases, but has the problem that when you change the alpha and markers, it actually creates new instances on the legend, and does not remove the old ones, so both can still be visible. I would recommend the method above in most cases.

If you name your legend, you can then iterate over the lines contained within it. For example:

leg=plt.legend(bbox_to_anchor=(1.005, 1), loc=2, borderaxespad=0.)

for l in leg.get_lines():
    l.set_alpha(1)
    l.set_marker('.')

note, you also have to set the marker again. I suggest setting it to . rather than , here, to make it a little more visible
enter image description here

Answered By: tmdavison

For the size you can include the keyword markerscale=## in the call to legend and that will make the markers bigger (or smaller).

import matplotlib.pyplot as plt 
import numpy as np
fig = plt.figure(1)
fig.clf()

x1,y1 = 4.*randn(10000), randn(10000)
x2,y2 = randn(10000), 4.*randn(10000)
ax = [fig.add_subplot(121+c) for c in range(2)]


ax[0].plot(x1, y1, 'bx',ms=.1,label='blue x')
ax[0].plot(x2, y2, 'r^',ms=.1,label='red ^')
ax[0].legend(loc='best')

ax[1].plot(x1, y1, 'bx',ms=.1,label='blue x')
ax[1].plot(x2, y2, 'r^',ms=.1,label='red ^')
ax[1].legend(loc='best', markerscale=40)

The output from the code

Answered By: CCHaggerty

for me the trick was to use the right property:

leg = axs.legend()

for l in leg.get_lines():
    l._legmarker.set_markersize(6)
Answered By: IljaBek
leg = plt.legend()    
for lh in leg.legendHandles: 
    lh.set_alpha(1)

credit to https://izziswift.com/set-legend-symbol-opacity-with-matplotlib/

Answered By: Max Podkorytov

Another option: instead of altering your legend’s markers, you can make a custom legend (ref the matplotlib legend tutorial)

import matplotlib.pyplot as plt
from matplotlib.patches import Patch
import numpy as np

n = 100000
s1 = np.random.normal(0, 0.05, n)
s2 = np.random.normal(0, 0.08, n)
ys = np.linspace(0, 1, n)

plt.plot(s1, ys, ',', label='data1', alpha=0.1)
plt.plot(s2, ys, ',', label='data2', alpha=0.1)

# manually generate legend
handles, labels = plt.axes().get_legend_handles_labels()
patches = [Patch(color=handle.get_color(), label=label) for handle, label in zip(handles, labels)]
plt.legend(handles=patches, bbox_to_anchor=(1.005, 1), loc=2, borderaxespad=0., frameon=False)

example

Answered By: Avi Vajpeyi
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.