0

I need to add a legend for a plot in Python 3.2 Matplotlib.

But, the legend cannot be displayed after I added "black_dash"

My code:

   blue_line, = plt.plot([0, 1], [-3, -3], color='b', linestyle='-',    linewidth=1)

   black_dash, = plt.plot([0, 1], [-7, -7], color='k', linestyle='--', linewidth=1)

   plt.legend([blue_line, black_dash] , ["boundary of reg_zip", "lat/lon line"] , loc='upper center', bbox_to_anchor=(0.5, -0.5), \
           fancybox=True, shadow=True, ncol=5, fontsize=11)

The legend should have two lines and their explanations.

UPDATE:

I need to polt a filled black circle in legend, But I got error:

 File "C:\Python32\lib\site-packages\matplotlib\backends\backend_agg.py", line 146, in draw_path

self._renderer.draw_path(gc, path, transform, rgbFace)

**TypeError: float() argument must be a string or a number**

My code:

plt.plot([0, 1], [-3, -3], "ro", ms=10, mfc="k", mew=2, mec="k", label="boundary of reg_zip")

Thanks

1
  • Code in the edit is not erroneous. Provide a minimal example demonstrating the error. Also a upvote or an accepted answer would be nice after all this trouble.... Commented Feb 15, 2015 at 15:55

1 Answer 1

2

Here's what should work

plt.plot([0, 1], [-3, -3], color='b', linestyle='-', linewidth=1, label="blue line")
plt.plot([0, 1], [-7, -7], color='k', linestyle='--', linewidth=1, label="black dash")
plt.legend(loc='upper center', fancybox=True, shadow=True, ncol=5, fontsize=11)
plt.show()

So basically, add labels to lines, not legend, legend needs to recognize objects by name, and if you don't label them it can't (it will also automagically change the lines in the legend to fit the current look).

Also always check your y axis range. It often tries to auto resize them, and with horizontal lines it often fails and places them at the very edge of the graph. They're there you jsut can't see them!

EDIT 1:

Since I can see you're confused by this. I made couple of plots. First one is of text (and generally any other box). Second is of legends which position was determined by loc keyword. Third is of legends whose positions were determined by bbox_to_anchor. Notice how the boxes for text don't correspond to boxes for legends. Main reason is that bbox_to_anchor anchors upper right corner of the legend, while the text anchors lower left corner of the box.

Also notice how the loc keyword doesn't depend on the graph scaling like bbox_to_anchor does. To get rid of that nasty habit you have to declare a transformation for the bbox_to_anchorby doing

plt.legend(bbox_to_anchor=(1, 1),
       bbox_transform=plt.gcf().transFigure)

as described in the legend manual.

Additionally, if your legend doesn't even fit within the gray plot area in the interactive plotting screen, you have to select the "Configure subplots" icon, and change the values until you can find your legend again.

Locations for text boxes

Legend locations by <code>loc</code> keyword

enter image description here

It's also important to realize that by adding loc keyword to a legend with bbox_to_anchor makes no difference at all. bbox_to_anchorwill trample all other locations you provide the legend with.

Now far from the fact that I'm saying you shouldn't really meddle a lot into bbox_to_anchor option if you're not willing to read the manual and dabble deeper into matplotlib implementations, but I do suggest avoiding bbox_to_anchor in all cases except those when your graph is so overcrowded you have to place it outside. (in which case it's good time to consider graph design?)

In the end, here's the code for plotting graphs from above.

import matplotlib.pyplot as plt

plt.plot((0,0), (1,1), label="legend")

legends = []
for i in range(0, 11):
    legends.append(plt.legend([str(i)], loc=i))

for legend in legends:
    plt.gca().add_artist(legend)
#legends with loc=5 and 7 overlap
plt.show()


plt.plot((0,1), (0,1), label="legend")

legend1 = plt.legend(["0,0"], bbox_to_anchor=(0, 0))
legend3 = plt.legend(["1,1"], bbox_to_anchor=(1, 1))
legend2 = plt.legend(["0.5,0.5"], bbox_to_anchor=(0.5, 0.5))
legend4 = plt.legend(["0.5,0"], bbox_to_anchor=(0.5, 0))
legend6 = plt.legend(["0,0.5"], bbox_to_anchor=(0, 0.5))
legend5 = plt.legend(["1,0.5"], bbox_to_anchor=(1, 0.5))
legend7 = plt.legend(["0.5,1"], bbox_to_anchor=(0.5, 1))
legend8 = plt.legend(["1,0"], bbox_to_anchor=(1, 0))
legend9 = plt.legend(["0,1"], bbox_to_anchor=(0, 1))

plt.gca().add_artist(legend1)
plt.gca().add_artist(legend2)
plt.gca().add_artist(legend3)
plt.gca().add_artist(legend4)
plt.gca().add_artist(legend5)
plt.gca().add_artist(legend6)
plt.gca().add_artist(legend7)
plt.gca().add_artist(legend8)
plt.gca().add_artist(legend9)

plt.show()
Sign up to request clarification or add additional context in comments.

7 Comments

thanks, but it does not work. Still no legend show up.
My bad, your bbox_to_anchor is also set off the grid. Why don't you just remove it? Like I said, with the lines, "they're there you just can't see them!"
@user3601704 Does this edit make it any clearer? Apart from this the only thing left is for me to write you the code. Which I won't :P
thanks, I prefer the legend located at the bottom of the plot not inside the plot because my plost is a map with zip code polygons. I do not want legend text box cover the polygons.
I used "legend4 = plt.legend(["0.5,0"], bbox_to_anchor=(0.5, 0))", , it show up but cover my axis label and ticks, So, how to move it down, I tried bbox_to_anchor=(0.5, -0.5), the legend box disappear. thanks
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.