Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matplotlib legend: I see everything twice

I have a couple of data series, each of which is a noiseless theoretical curve, and an Nx2 array of noisy data that I need to display with a legend. The following code works, but because of the Nx2 data I get two entries in the legend... is there a way to avoid this?

import numpy as np
import matplotlib.pyplot as plt

t = np.arange(0,1,0.001)
td = np.arange(0,1,0.1)
td = np.atleast_2d(td).T
N = len(td)
x1 = t
x1r = td + 0.1*np.random.randn(N,2)
x2 = 2-t
x2r = 2-td + 0.1*np.random.randn(N,2)

plt.plot(t,x1,color='red')
plt.plot(td,x1r,'.',color='red',label='A')

plt.plot(t,x2,color='green')
plt.plot(td,x2r,'x',color='green',label='B')

plt.legend()

enter image description here

like image 838
Jason S Avatar asked Feb 10 '26 17:02

Jason S


2 Answers

I'm able to fix the issue by specifying the handles on the legend:

import numpy as np
import matplotlib.pyplot as plt

t = np.arange(0,1,0.001)
td = np.arange(0,1,0.1)
td = np.atleast_2d(td).T
N = len(td)
x1 = t
x1r = td + 0.1*np.random.randn(N,2)
x2 = 2-t
x2r = 2-td + 0.1*np.random.randn(N,2)

plt.plot(t,x1,color='red')
red_dots,_ = plt.plot(td,x1r,'.',color='red',label='A')

plt.plot(t,x2,color='green')
green_xs,_ =plt.plot(td,x2r,'x',color='green',label='B')

plt.legend(handles=[red_dots, green_xs])
plt.show()

enter image description here

However, I'm not quite sure why you're running into that issue...will update the answer when I have more insights to it.

like image 133
masotann Avatar answered Feb 13 '26 09:02

masotann


You get 2 legend entries, because you plot a vector with two columns, i.e. you get one legend entry per column. Usually one would plot 1D arrays, and hence get a single legend entry.

At least in the case of the question there is no reason to plot a 2D array, so a solution would be to use a single dimension.

import numpy as np
import matplotlib.pyplot as plt

t = np.arange(0,1,0.001)
td = np.arange(0,1,0.1)
td = np.repeat(td,2)
N = len(td)
x1 = t
x1r = td + 0.1*np.random.randn(N)
x2 = 2-t
x2r = 2-td + 0.1*np.random.randn(N)

plt.plot(t,x1,color='red')
plt.plot(td,x1r,'.',color='red',label='A')

plt.plot(t,x2,color='green')
plt.plot(td,x2r,'x',color='green',label='B')

plt.legend()
plt.show()

If for any reason you need to have 2D arrays (e.g. because they come from some other part of the code), you can simply plot their flattened version.

plt.plot(td.flatten(),x1r.flatten(),'.',color='red',label='A')

Lastly it seems that the newest matplotlib release (2.1.1) actually does not have 2 legend entries, even if 2 columns are plotted, so updating may be a solution as well.

like image 45
ImportanceOfBeingErnest Avatar answered Feb 13 '26 08:02

ImportanceOfBeingErnest



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!