28

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')
tsherwen
  • 1,076
  • 16
  • 21
Java.beginner
  • 871
  • 2
  • 19
  • 37
  • 2
    You could set the `legend.handlelength` to `0` - see e.g. [here](http://stackoverflow.com/a/21286741/3001761). – jonrsharpe Aug 04 '14 at 16:32
  • Thanks @jonrsharpe I had tried code by minimising line and label and overwrite only the label but 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') – Java.beginner Aug 04 '14 at 16:40
  • 2
    @Java.beginner You should edit your question to include that code. It is un-readable in a comment. – tacaswell Aug 04 '14 at 22:26
  • Hi @tcaswell thanks, I have accepted the answer (second part from 'Joe Kington'). Still you want me edit the question. Thanks – Java.beginner Aug 05 '14 at 08:33
  • 2
    Yes, so that future uses can understand what you were asking so they can tell if it is the problem they are having – tacaswell Aug 05 '14 at 12:03

5 Answers5

27

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

trblnc
  • 222
  • 5
  • 14
Joe Kington
  • 275,208
  • 71
  • 604
  • 463
  • Thanks @Joe Kington, Have used your second part of the solution. Since I was using dataframe, couldn't force the label name to desired one by default it takes the column name, so have changed the column name according to desired one and font size is too big when I tried to reduce the size -> legend = ax.legend(loc=0, shadow=False)for label in legend.get_texts(): label.set_fontsize(10) -> the it brings back the old legend, is there anyway to fix this, thanks for your time. – Java.beginner Aug 04 '14 at 17:07
  • @Java.beginner - That's because you're creating a new legend when you call `legend = ax.legend(...)` the second time. If you want to access the first legend, use `ax.get_legend()`. – Joe Kington Aug 04 '14 at 20:30
  • I actually like this method. Thanks! –  Mar 11 '21 at 19:43
23

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!).

tsando
  • 4,557
  • 2
  • 33
  • 35
  • 1
    @tsherwen I'm sorry but I don't think this question was specific to a line plot. The title is "How to hide/remove legend line and retain the label" and does not specify that this is intended for a line plot. Also, in theory a line plot can be also created via a scatter plot. Please consider removing the negative marking thanks. – tsando Apr 06 '18 at 13:10
  • 1
    Still shows the legend for the least square line on scatter plot, but it does hide the legend for the points. – Anonymous May 22 '21 at 12:46
23

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

tsherwen
  • 1,076
  • 16
  • 21
6

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

Ji Ma
  • 71
  • 2
  • 5
0

For custom legends add lw=0 too

p5 = mpatches.Patch(color="green",  label="r={}".format(cor_rh), lw=0)
p6 = mpatches.Patch(color=p1.get_color(), label="t={}".format(rh_trend), lw=0)
p7 = mpatches.Patch(color=p3.get_color(), label="t={}".format(hx_trend), lw=0)


ln1 = [p5,p6,p7]
host.legend(handles=ln1, loc=1,  labelcolor='linecolor, handlelength=0)
KT12
  • 549
  • 11
  • 24