How do you just show the text label in plot legend? (e.g. remove a label's line in the legend)

30,153

Solution 1

At that point, it's arguably easier to just use annotate.

For example:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000).cumsum()

fig, ax = plt.subplots()
ax.plot(data)
ax.annotate('Label', xy=(-12, -12), xycoords='axes points',
            size=14, ha='right', va='top',
            bbox=dict(boxstyle='round', fc='w'))
plt.show()

enter image description here

However, if you did want to use legend, here's how you'd do it. You'll need to explicitly hide the legend handles in addition to setting their size to 0 and removing their padding.

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000).cumsum()

fig, ax = plt.subplots()
ax.plot(data, label='Label')

leg = ax.legend(handlelength=0, handletextpad=0, fancybox=True)
for item in leg.legendHandles:
    item.set_visible(False)
plt.show()

enter image description here

Solution 2

You can just set the handletextpad and handlelength in the legend via the legend_handler as shown below:

import matplotlib.pyplot as plt
import numpy as np
# Plot up a generic set of lines
x = np.arange( 3 )
for i in x:
    plt.plot( i*x, x, label='label'+str(i), lw=5 )
# Add a legend 
# (with a negative gap between line and text, and set "handle" (line) length to 0)
legend = plt.legend(handletextpad=-2.0, handlelength=0)

Detail on handletextpad and handlelength is in documentation (linked here, & copied below):

handletextpad : float or None

The pad between the legend handle and text. Measured in font-size units. Default is None, which will take the value from rcParams["legend.handletextpad"].

handlelength : float or None

The length of the legend handles. Measured in font-size units. Default is None, which will take the value from rcParams["legend.handlelength"].

With the above code:

enter image description here

With a few extra lines the labels can have the same color as their line. just use .set_color() via legend.get_texts().

# Now color the legend labels the same as the lines
color_l = ['blue', 'orange', 'green']
for n, text in enumerate( legend.texts ):
    print( n, text)
    text.set_color( color_l[n] )

enter image description here

Just calling plt.legend() gives:

enter image description here

Solution 3

I found another much simpler solution - simply set the scale of the marker to zero in the legend properties:

plt.legend(markerscale=0)

This is particularly useful in scatter plots, when you don't want the marker to be visually mistaken for a true data point (or even outlier!).

Solution 4

Suggesting the best answer: handlelength=0, for example: ax.legend(handlelength=0).

Share:
30,153
Java.beginner
Author by

Java.beginner

I am a data scientist working with Seismic mixtures and analysis and other fields which related signal analysis especially control system signals from Oil and Gas Systems, Interested in Digital Signal Processing, love to work with MATLAB, Python, Java (Just learning). Presently started learning and working in Java...

Updated on July 28, 2022

Comments

  • Java.beginner
    Java.beginner almost 2 years

    I want to show the text for a line's label in the legend, but not a line too (As shown in the figure below):

    enter image description here

    I have tried to minimise the legend's line and label, and overwrite only the new-label too (as in the code below). However, the legend brings both back.

        legend = ax.legend(loc=0, shadow=False) 
        for label in legend.get_lines(): 
            label.set_linewidth(0.0) 
        for label in legend.get_texts(): 
            label.set_fontsize(0) 
    
        ax.legend(loc=0, title='New Title')