Reputation: 97
I'm plotting groups of circles using collections and I am not able to generate the legend of the three categories. I want:
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
from matplotlib.patches import Circle
import numpy as np
# (modified from one of the matplotlib gallery examples)
resolution = 50 # the number of vertices
N = 50
Na = 25
Nb = 10
x = np.random.random(N)
y = np.random.random(N)
radii = 0.1*np.random.random(30)
xa = np.random.random(Na)
ya = np.random.random(Na)
radiia = 0.1*np.random.random(50)
xb = np.random.random(Nb)
yb = np.random.random(Nb)
radiib = 0.1*np.random.random(60)
patches = []
patchesa = []
patchesb = []
for x1,y1,r in zip(x, y, radii):
circle = Circle((x1,y1), r)
patches.append(circle)
for x1,y1,r in zip(xa, ya, radiia):
circle = Circle((x1,y1), r)
patchesa.append(circle)
for x1,y1,r in zip(xb, yb, radiib):
circle = Circle((x1,y1), r)
patchesb.append(circle)
fig = plt.figure()
ax = fig.add_subplot(111)
colors = 100*np.random.random(N)
p = PatchCollection(patches, cmap=matplotlib.cm.jet, alpha=0.4, label= "Cat 1", facecolor="red")
pa = PatchCollection(patchesa, cmap=matplotlib.cm.jet, alpha=0.3, label= "Cat 2", facecolor="blue")
pb = PatchCollection(patchesb, cmap=matplotlib.cm.jet, alpha=0.4, label= "Cat 3", facecolor="yellow")
#p.set_array(colors)
ax.add_collection(p)
ax.add_collection(pa)
ax.add_collection(pb)
ax.legend(loc = 2)
plt.colorbar(p)
print p.get_label()
plt.show()
PathCollection
s are not iterable objects, so trying to generate the legend the following way;
legend([p, pa, pb], ["cat 1", "2 cat", "cat 3"])
does not work.
How can the caption to appear?
My system run on Python 2.7 and Matplotlib 1.2.0_1
Note that the command print p.get_label()
shows that the object has an associated label, but matplotlib is unable to mount the legend.
Upvotes: 9
Views: 9809
Reputation: 12923
One possible solution is to add Line2D
objects to use in the legend, also known as using proxy artists. To achieve this you have to add from matplotlib.lines import Line2D
to your script, and then you can replace this code:
ax.legend(loc = 2)
plt.colorbar(p)
print p.get_label()
with this:
circ1 = Line2D([0], [0], linestyle="none", marker="o", alpha=0.4, markersize=10, markerfacecolor="red")
circ2 = Line2D([0], [0], linestyle="none", marker="o", alpha=0.3, markersize=10, markerfacecolor="blue")
circ3 = Line2D([0], [0], linestyle="none", marker="o", alpha=0.4, markersize=10, markerfacecolor="yellow")
plt.legend((circ1, circ2, circ3), ("Cat 1", "Cat 2", "Cat 3"), numpoints=1, loc="best")
Upvotes: 15