参考:http://blog.sina.com.cn/s/blog_b09d460201019c10.html
官网:http://matplotlib.org/users/legend_guide.html
legend(x, y = NULL, legend, fill = NULL, col = par("col"),
border ="black", lty, lwd, pch,
angle = 45,density = NULL, bty = "o", bg = par("bg"),
box.lwd = par("lwd"),box.lty = par("lty"), box.col = par("fg"),
pt.bg = NA, cex =1, pt.cex = cex, pt.lwd = lwd,
xjust = 0, yjust= 1, x.intersp = 1, y.intersp = 1,
adj = c(0, 0.5),text.width = NULL, text.col = par("col"),
text.font = NULL,merge = do.lines && has.pch, trace = FALSE,
plot = TRUE, ncol= 1, horiz = FALSE, title = NULL,
inset = 0, xpd,title.col = text.col, title.adj = 0.5,
seg.len = 2)
x, y |
X,y用于定位图例,也可用单键词"bottomright", "bottom", "bottomleft", "left", "topleft", "top", "topright", "right" and "center" |
legend |
字符或表达式向量 |
fill |
用特定的颜色进行填充 |
col |
图例中出现的点或线的颜色 |
border |
当fill = 参数存在的情况下,填充色的边框 |
lty, lwd |
图例中线的类型与宽度 |
pch |
点的类型 |
angle |
阴影的角度 |
density |
阴影线的密度 |
bty |
图例框是否画出,o为画出,默认为n不画出 |
bg |
bty != "n"时,图例的背景色 |
box.lty, box.lwd, box.col |
bty = "o"时,图例框的类型,box.lty决定是否为虚线,box.lwd决定粗线,box.col决定颜色 |
pt.bg |
点的背景色 |
cex |
字符大小 |
pt.cex |
点的大小 |
pt.lwd |
点的边缘的线宽 |
x.intersp |
图例中文字离图片的水平距离 |
y.intersp |
图例中文字离图片的垂直距离 |
adj |
图例中字体的相对位置 |
text.width |
图例字体所占的宽度 |
text.col |
图例字体的颜色 |
text.font |
图例字体 |
merge |
logical, if TRUE,合并点与线,但不填充图例框,默认为TRUE |
trace |
logical; if TRUE显示图例信息. |
plot |
logical. If FALSE不画出图例 |
ncol |
图例中分类的列数 |
horiz |
logical; if TRUE,水平放置图例 |
title |
给图例加标题 |
inset |
当图例用关键词设置位置后,inset = 分数,可以设置其相对位置 |
xpd |
xpd=FALSE,即不允许在作图区域外作图,改为TRUE即可,与par()参数配合使用。 |
title.col |
标题颜色 |
title.adj |
图例标题的相对位置,0.5为默认,在中间。0最左,1为最右。 |
seg.len |
lty 与lwd的线长,长度单位为字符宽度 |
legend 显示图例
1 legend基础
函数原型 legend(*args, **kwargs)
当len(args) == 2
args 是[artist]和[label]的集合
当len(args) == 0
args会自动调用get_legend_handles_labels()生成
等价于
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels)
ax.get_legend_handles_labels()的作用在于返回ax.lines, ax.patch所有对象以及ax.collection中的LineCollection or RegularPolyCollection对象
注意:这里只提供有限支持, 并不是所有的artist都可以被用作图例,比如errorbar支持不完善
1.1 调整顺序
ax = subplot(1,1,1)
p1, = ax.plot([1,2,3], label="line 1")
p2, = ax.plot([3,2,1], label="line 2")
p3, = ax.plot([2,3,1], label="line 3")
handles, labels = ax.get_legend_handles_labels()
# reverse the order
ax.legend(handles[::-1], labels[::-1])
# or sort them by labels
import operator hl = sorted(zip(handles, labels), key=operator.itemgetter(1))
handles2, labels2 = zip(*hl)
ax.legend(handles2, labels2)
1.2 使用代理artist
当需要使用legend不支持的artist时,可以使用另一个被legend支持的artist作为代理
比如以下示例中使用不在axe上的一个artist
p = Rectangle((0, 0), 1, 1, fc="r")
legend([p], ["Red Rectangle"])
2 多列图例
ax1 = plt.subplot(3,1,1)
ax1.plot([1], label="multi\nline")
ax1.plot([1], label="$2^{2^2}$")
ax1.plot([1], label=r"$\frac{1}{2}\pi$")
ax1.legend(loc=1, ncol=3, shadow=True)
ax2 = plt.subplot(3,1,2)
myplot(ax2)
ax2.legend(loc="center left", bbox_to_anchor=[0.5, 0.5],
ncol=2, shadow=True, title="Legend")
ax2.get_legend().get_title().set_color("red")
3 图例位置
ax.legend(…., loc=3) 具体对应位置如下图
绘制在图上是这样的,(具体没有分清 5和7的区别)
4 多个图例
如果不采取措施,连续调用两个legend会使得后面的legend覆盖前面的
from matplotlib.pyplot import * p1, = plot([1,2,3], label="test1")
p2, = plot([3,2,1], label="test2")
l1 = legend([p1], ["Label 1"], loc=1) l2 = legend([p2], ["Label 2"], loc=4) # this removes l1 from the axes.
gca().add_artist(l1) # add l1 as a separate artist to the axes
5. API
class matplotlib.legend.Legend(parent, handles, labels,**args)
三个最重要的必要参数
parent --- legend的父artist, 包含legend的对象
比如用ax.legend()调用之后
>>> print ax.get_legend().parent
Axes(0.125,0.1;0.775x0.8)
handles --- 图例上面画出的各个artist(lines, patches)
labels --- artist 对应的标签
其他参数
Keyword |
Description |
loc |
a location code |
prop |
the font property (matplotlib.font_manager.FontProperties 对象) eg song_font = matplotlib.font_manager.FontProperties(fname='simsun.ttc', size=8) |
fontsize |
the font size (和prop互斥,不可同时使用) |
markerscale |
the relative size of legend markers vs. original |
numpoints |
the number of points in the legend for line |
scatterpoints |
the number of points in the legend for scatter plot |
scatteryoffsets |
a list of yoffsets for scatter symbols in legend |
frameon |
if True, draw a frame around the legend. If None, use rc |
fancybox |
if True, draw a frame with a round fancybox. If None, use rc |
shadow |
if True, draw a shadow behind legend |
ncol |
number of columns |
borderpad |
the fractional whitespace inside the legend border |
labelspacing |
the vertical space between the legend entries |
handlelength |
the length of the legend handles |
handleheight |
the length of the legend handles |
handletextpad |
the pad between the legend handle and text |
borderaxespad |
the pad between the axes and legend border |
columnspacing |
the spacing between columns |
title |
the legend title |
bbox_to_anchor |
the bbox that the legend will be anchored. |
bbox_transform |
the transform for the bbox. transAxes if None. |
主要函数
get_frame() --- 返回legend所在的方形对象
get_lines()
get_patches()
get_texts()
get_title() --- 上面几个比较简单,不解释了
set_bbox_to_anchor(bbox, transform=None)
(…本函数待续…之后写axes的时候会加入,目前我没有看懂他的这个长宽和figure以及axes的关系)
6. 样例
leg = ax.legend(('Model length', 'Data length', 'Total message length'),
'upper center', shadow=True)
# the matplotlib.patches.Rectangle instance surrounding the legend 即外框
frame = leg.get_frame()
frame.set_facecolor('0.80') # set the frame face color to light gray
# matplotlib.text.Text instances 即legend中文本
for t in leg.get_texts():
t.set_fontsize('small') # the legend text fontsize
# matplotlib.lines.Line2D instances 即legend中所表示的artist
for l in leg.get_lines():
l.set_linewidth(1.5) # the legend line width
fig = plt.figure()
ax1 = fig.add_axes([0.1, 0.1, 0.4, 0.7])
ax2 = fig.add_axes([0.55, 0.1, 0.4, 0.7])
x = np.arange(0.0, 2.0, 0.02)
y1 = np.sin(2*np.pi*x)
y2 = np.exp(-x)
l1, l2 = ax1.plot(x, y1, 'rs-', x, y2, 'go')
y3 = np.sin(4*np.pi*x)
y4 = np.exp(-2*x)
l3, l4 = ax2.plot(x, y3, 'yd-', x, y3, 'k^')
fig.legend((l1, l2), ('Line 1', 'Line 2'), 'upper left')
fig.legend((l3, l4), ('Line 3', 'Line 4'), 'upper right')
import matplotlib.patches as mpatches import matplotlib.pyplot as plt red_patch = mpatches.Patch(color='red', label='The red data') plt.legend(handles=[red_patch]) plt.show()
import matplotlib.lines as mlines import matplotlib.pyplot as plt blue_line = mlines.Line2D([], [], color='blue', marker='*', markersize=15, label='Blue stars') plt.legend(handles=[blue_line]) plt.show()
import matplotlib.pyplot as plt plt.subplot(211) plt.plot([1,2,3], label="test1") plt.plot([3,2,1], label="test2") # Place a legend above this subplot, expanding itself to # fully use the given bounding box. plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=2, mode="expand", borderaxespad=0.) plt.subplot(223) plt.plot([1,2,3], label="test1") plt.plot([3,2,1], label="test2") # Place a legend to the right of this smaller subplot. plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.) plt.show()
import matplotlib.pyplot as plt line1, = plt.plot([1,2,3], label="Line 1", linestyle='--') line2, = plt.plot([3,2,1], label="Line 2", linewidth=4) # Create a legend for the first line. first_legend = plt.legend(handles=[line1], loc=1) # Add the legend manually to the current Axes. ax = plt.gca().add_artist(first_legend) # Create another legend for the second line. plt.legend(handles=[line2], loc=4) plt.show()
import matplotlib.pyplot as plt from matplotlib.legend_handler import HandlerLine2D line1, = plt.plot([3,2,1], marker='o', label='Line 1') line2, = plt.plot([1,2,3], marker='o', label='Line 2') plt.legend(handler_map={line1: HandlerLine2D(numpoints=4)})
import matplotlib.pyplot as plt from numpy.random import randn z = randn(10) red_dot, = plt.plot(z, "ro", markersize=15) # Put a white cross over some of the data. white_cross, = plt.plot(z[:5], "w+", markeredgewidth=3, markersize=15) plt.legend([red_dot, (red_dot, white_cross)], ["Attr A", "Attr A+B"])
import matplotlib.pyplot as plt import matplotlib.patches as mpatches class AnyObject(object): pass class AnyObjectHandler(object): def legend_artist(self, legend, orig_handle, fontsize, handlebox): x0, y0 = handlebox.xdescent, handlebox.ydescent width, height = handlebox.width, handlebox.height patch = mpatches.Rectangle([x0, y0], width, height, facecolor='red', edgecolor='black', hatch='xx', lw=3, transform=handlebox.get_transform()) handlebox.add_artist(patch) return patch plt.legend([AnyObject()], ['My first handler'], handler_map={AnyObject: AnyObjectHandler()})
from matplotlib.legend_handler import HandlerPatch import matplotlib.pyplot as plt import matplotlib.patches as mpatches class HandlerEllipse(HandlerPatch): def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): center = 0.5 * width - 0.5 * xdescent, 0.5 * height - 0.5 * ydescent p = mpatches.Ellipse(xy=center, width=width + xdescent, height=height + ydescent) self.update_prop(p, orig_handle, legend) p.set_transform(trans) return [p] c = mpatches.Circle((0.5, 0.5), 0.25, facecolor="green", edgecolor="red", linewidth=3) plt.gca().add_patch(c) plt.legend([c], ["An ellipse, not a rectangle"], handler_map={mpatches.Circle: HandlerEllipse()})