# Legend problem

My legend shows both plots as the same colour (blue) when in fact they
are different colours. Here's the relevant code:

font = FontProperties(size='small');
...
b1 = bar(i,lowermeans,width,color='b')
b2 = bar(i+width,uppermeans,width,color='y')
...
legend((b1,b2),(l,u),prop=font)

I use legend exactly like this elsewhere and it works. So I can't figure
out why in this case the legend shows both bars as blue.

Any help? Thanks

Screenshot http://www.10pix.com/show.php/172028_figure1.png.html and
full code (lowermeans and uppermeans are the lists of values to be
plotted):

i = arange(0,len(lowermeans))
width=0.4
b1 = bar(i,lowermeans,width,color='b')
b2 = bar(i+width,uppermeans,width,color='y')

mean,variance,deviation = stats(lowermeans)
m = "Mean: "+str(round(mean,2))
v = "Variance: "+str(round(variance,2))
d = "Standard deviation: "+str(round(deviation,2))
l = "Lower-bounds"+'\n'+m+'\n'+v+'\n'+d
mean,variance,deviation = stats(uppermeans)
m = "Mean: "+str(round(mean,2))
v = "Variance: "+str(round(variance,2))
d = "Standard deviation: "+str(round(deviation,2))
u = "Upper-bounds"+'\n'+m+'\n'+v+'\n'+d
legend((b1,b2),(l,u),prop=font)

ticks = arange(1,len(lowermeans)+1)
xticks(i+width,ticks,rotation='vertical')
xlim(0,len(i))

ylabel('Lower- and upper-bounds in %')
xlabel('Sessions')
title('Means of lower- and upper-bound measures per session')

chombee wrote:

My legend shows both plots as the same colour (blue) when in fact they
are different colours. Here's the relevant code:

font = FontProperties(size='small');
...
b1 = bar(i,lowermeans,width,color='b')
b2 = bar(i+width,uppermeans,width,color='y')
...
legend((b1,b2),(l,u),prop=font)

I use legend exactly like this elsewhere and it works. So I can't figure
out why in this case the legend shows both bars as blue.

I managed to replicate with this example:
import numpy as N
import matplotlib.pyplot as P
lowermeans = N.arange(10)
uppermeans = lowermeans + 2
i = N.arange(0,len(lowermeans))
width = 0.4
b1 = P.bar(i,lowermeans,width,color='b')
b2 = P.bar(i+width,uppermeans,width,color='y')
P.legend((b1,b2),('lower','upper'))

Changing the legend call to this fixed it:
P.legend((b1[0],b2[0]),('lower','upper'))

It seems to work since a list of patch objects is returned by the calls
to bar, and legend seems to only use the first two objects from the
*first* list. The question is, is it a bug, because it *is* very
unexpected behavior?

Ryan

···

--
Ryan May
School of Meteorology
University of Oklahoma

Ryan May wrote:

chombee wrote:

My legend shows both plots as the same colour (blue) when in fact they
are different colours. Here's the relevant code:

font = FontProperties(size='small');
...
b1 = bar(i,lowermeans,width,color='b')
b2 = bar(i+width,uppermeans,width,color='y')
...
legend((b1,b2),(l,u),prop=font)

I use legend exactly like this elsewhere and it works. So I can't figure
out why in this case the legend shows both bars as blue.

I managed to replicate with this example:
import numpy as N
import matplotlib.pyplot as P
lowermeans = N.arange(10)
uppermeans = lowermeans + 2
i = N.arange(0,len(lowermeans))
width = 0.4
b1 = P.bar(i,lowermeans,width,color='b')
b2 = P.bar(i+width,uppermeans,width,color='y')
P.legend((b1,b2),('lower','upper'))

Changing the legend call to this fixed it:
P.legend((b1[0],b2[0]),('lower','upper'))

It seems to work since a list of patch objects is returned by the calls
to bar, and legend seems to only use the first two objects from the
*first* list. The question is, is it a bug, because it *is* very
unexpected behavior?

Further investigation shows that the Axes.legend method calls
cbook.flatten on what is passed in as handles, which for this case where
two lists are passed in, essentially concatenates them together. Maybe
they should be zipped first before flattening so that this use case
should work? Or would this break some other use case for legend?

Ryan

···

--
Ryan May
School of Meteorology
University of Oklahoma

That fixed it for me too. Thanks. The thread just started by Reckoner
about the same problem also has the answer: "In a nutshell, bar returns
a list of rectangle objects, and you need to pass a proxy element of
this list (eg the first element) to the legend command."

···

On Thu, 2008-02-07 at 10:21 -0600, Ryan May wrote:

Changing the legend call to this fixed it:
P.legend((b1[0],b2[0]),('lower','upper'))