How to delete legend in pandas

Viewed 1373

I try to plot with both pandas (pd) and matplotlib.pyplot (plt). But I don't want pandas to show legend yet I still need the plt legend. Is there a way I could delete the legend of pandas plot? (legend=False doesn't work)

import pandas as pd
import matplotlib.pyplot as plt

xs = [i for i in range(1, 11)]
ys = [i for i in range(1, 11)]

df = pd.DataFrame(list(zip(xs, ys)), columns=['xs', 'ys'])

fig, ax = plt.subplots()

# plot pd data-frame, I don't want this to show legend
df.plot(x='xs', y='ys', ax=ax, kind='line', legend=False)

# these doesn't work
ax.legend([])
ax.get_legend().remove()
ax.legend().set_visible(False)

# plot by plt, I only want this to show legend
ax.plot(xs, ys, label='I only need this label to be shown')

ax.legend()

plt.show()  # still showing both legends

Note: I prefer not to change the order of plotting (even though plot plt first and then pd could allow showing only plt legend, but the plt plot will get block by pd plot), and not using plt to plot the dataframe's data

3 Answers

You can use matplotlib to plot DataFrame data (and other data from other sources) on the same plot without using df.plot(). Do you need to use df.plot(), or would this be okay?

import pandas as pd
import matplotlib.pyplot as plt

xs = [i for i in range(1, 11)]
ys = [i for i in range(1, 11)]

df = pd.DataFrame(list(zip(xs, ys)), columns=['xs', 'ys'])

fig, ax = plt.subplots()

#just keep using mpl but reference the data in the dataframe, basically what df.plot() does
ax.plot(df['xs'], df['ys'])

ax.plot(xs, ys, label='I only need this label to be shown')

ax.legend()

plt.show() 

enter image description here

If you do insist on using df.plot(), you can still take advantage of the underscore trick, as described in the documentation:

Specific lines can be excluded from the automatic legend element selection by defining a label starting with an underscore.

import pandas as pd
import matplotlib.pyplot as plt

xs = [i for i in range(1, 11)]
ys = [i for i in range(1, 11)]

df = pd.DataFrame(list(zip(xs, ys)), columns=['xs', 'ys'])

fig, ax = plt.subplots()

# plot pd data-frame, I don't want this to show legend
df.plot(x='xs', y='ys', ax=ax, kind='line', label='_hidden')

# plot by plt, I only want this to show legend
ax.plot(xs, ys, label='I only need this label to be shown')

ax.legend()

plt.show()  # still showing both legends

This will yield the same result as above, but I get a warning (UserWarning: The handle <matplotlib.lines.Line2D object at 0x00000283F0FFDB38> has a label of '_hidden' which cannot be automatically added to the legend.). This feels messier and more hacky, so I prefer the first option.

You can remove the 1st set of lines and labels from the legend:

fig, ax = plt.subplots()

df.plot(x='xs', y='ys', ax=ax, kind='line', label='Something')
ax.plot(xs, ys, label='I only need this label to be shown')

# Legend except 1st lines/labels
lines, labels = ax.get_legend_handles_labels()
ax.legend(lines[1:], labels[1:])

plt.show()

enter image description here

Use label='_nolegend_' as recommended here. This worked for me:

import pandas as pd
import matplotlib.pyplot as plt

xs = [i for i in range(1, 11)]
ys = [i for i in range(1, 11)]

df = pd.DataFrame(list(zip(xs, ys)), columns=['xs', 'ys'])

fig, ax = plt.subplots()

# plot pd data-frame, I don't want this to show legend
df.plot(x='xs', y='ys', ax=ax, kind='line', label='_nolegend_')

# plot by plt, I only want this to show legend
ax.plot(xs, ys, label='I only need this label to be shown')

ax.legend()

plt.show()  # now showing one legend

enter image description here

Related