user3601704
user3601704

Reputation: 763

error of adding a legend for a plot in Python 3.2 Matplotlib

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

Upvotes: 0

Views: 3230

Answers (1)

ljetibo
ljetibo

Reputation: 3094

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()

Upvotes: 2

Related Questions