Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fill the right column of a matplotlib legend first

Hey I am trying to fit a legend onto a plot so that it doesn't obscure the graph.

import numpy as np
import matplotlib.pyplot as plt

X = np.linspace(0,100,11)

plt.plot(X,-X, label='plot 1')
plt.plot(X,-2*X, label='plot 2')
plt.plot(X,-3*X, label='plot 3')

leg=plt.legend(ncol=2)
leg.get_frame().set_visible(False)

plt.show()

So in the minimum working example, above, what I want to be able to do is move the 'plot 2' label in the legend into the right column, i.e. directly under 'plot 3'.

Any help would be appreciated, thanks.

like image 511
user1562862 Avatar asked Feb 06 '13 20:02

user1562862


People also ask

How to add a legend to a plot in Matplotlib?

For example, you can use the following syntax to place the legend in the upper left corner of the plot: The default location is “best” – which is where Matplotlib automatically finds a location for the legend based on where it avoids covering any data points.

How to place the legend outside of the plot in R?

You can also use the bbox_to_anchor () argument to place the legend outside of the plot. For example, you can use the following syntax to place the legend in the top right corner outside of the plot:

How do I place a legend on a figure?

For example, if you want your axes legend located at the figure’s top right-hand corner instead of the axes’ corner, simply specify the corner’s location, and the coordinate system of that location: More examples of custom legend placement: Sometimes it is more clear to split legend entries across multiple legends.

How to import Pyplot with Matplotlib in Python?

In the matplotlib, there is a function called legend () which is used to place a legend on the mentioned axis. Note: Before declaring matplotlib and pyplot, it is better to declare numpy library also. Basically, we can import pyplot with matplotlib as we generally import other libraries in python, such like import matplotlib.pyplot as plt


3 Answers

The legend is filling in the columns from left to right. In other words, if you trick it into believing that there is another line (without any text or line color in the legend), then you can populate the space under 'plot 3'.

import numpy as np
import matplotlib.pyplot as plt
from pylab import *

X = np.linspace(0,100,11)

plt.plot(X,-X, label='plot 1', color='red')
plt.plot(X,-2*X, label='plot 2', color='green')
plt.plot(X,-3*X, label='plot 3', color='blue')


line1 = Line2D(range(10), range(10), marker='', color="red")
line2 = Line2D(range(10), range(10), marker='',color="green")
line3 = Line2D(range(10), range(10), marker='', color="blue")
line4 = Line2D(range(10), range(10), marker='', color="white")
plt.legend((line1,line4, line3,line2),('plot1','','plot3','plot2'),numpoints=1, loc=4,ncol=2)

plt.show()
like image 85
cosmosis Avatar answered Oct 17 '22 05:10

cosmosis


A diffrerent implementation of @cosmosis answer. It's probably more flexible.

import numpy as np
import matplotlib.pyplot as plt

X = np.linspace(0,100,11)

plt.plot(X,-X, label='plot 1', color='red')
plt.plot(X,-2*X, label='plot 2', color='green')
plt.plot(X,-3*X, label='plot 3', color='blue')

(lines, labels) = plt.gca().get_legend_handles_labels()
#it's safer to use linestyle='none' and marker='none' that setting the color to white
#should be invisible whatever is the background
lines.insert(1, plt.Line2D(X,X, linestyle='none', marker='none'))
labels.insert(1,'')

plt.legend(lines,labels,numpoints=1, loc=4,ncol=1)

plt.show()

An other option is to create two legends as here and then displace them using bbox_to_anchor keyword here

(lines, labels) = plt.gca().get_legend_handles_labels()
leg1 = plt.legend(lines[:1], labels[:1], bbox_to_anchor=(0,0,0.8,1), loc=1)
leg2 = plt.legend(lines[1:], labels[1:], bbox_to_anchor=(0,0,1,1), loc=1)
gca().add_artist(leg1)

doing it I get this without the need of add any on other object.

like image 7
Francesco Montesano Avatar answered Oct 17 '22 07:10

Francesco Montesano


A third approach, based on the answer of Franesco. Draw a placeholder line with alpha=0 (transparent).

#draw your actual lines here
#plt....

lines, labels = plt.gca().get_legend_handles_labels()

lines.insert(1, plt.Line2D([],[], alpha=0))
labels.insert(1,'')

plt.legend(lines,labels,ncol=2)
plt.show()

This has the same advantages as described in his answer. However that solution did not work in matplotlib 1.5.1 (under python3) saying ValueError: Unrecognized marker style none

like image 2
Sebastian Avatar answered Oct 17 '22 05:10

Sebastian