import numpy as np
import matplotlib.pyplot as plt

matplotlib.pyplot.legend

在开始教程之前,我们必须先了解matplotlib.pyplot.legend(),该函数可以用以添加图例。

方法1自动检测

通过这种方式,lendgend()会从artist中获取label属性,并自动生成图例,比如:

fig, ax = plt.subplots()
line, = ax.plot([1, 2, 3], label="Inline label")
ax.legend()
plt.show()

或者:

line.set_label("Inline label")
ax.legend()

方法2为现有的Artist添加

我们也可以通过下列操作,为已经存在的Artist添加图例,但是这种方式并不推荐,因为我们很容易混淆。

fig, ax = plt.subplots()
line, = ax.plot([1, 2, 3])
ax.legend(["A simple line"])

方3显示添加图例

我们也可以显示添加图例:

fig, ax = plt.subplots()
line1, = ax.plot([1, 2, 3])
line2, = ax.plot([3, 2, 1])
ax.legend((line1, line2), ("line1", "line2"))

参数:

handle: Artist

label: 标签

loc:位置,比如"best":0, "upper right" 1 ...

fontsize

...

控制图例的输入

直接使用legend()命令,matplotlib会自动检测并生成图例,这种方式等价于:

handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels)

需要注意的是,只有为Artist设置标签了,通过get_legend_handles_labels()才有效。

有些时候,我们只需要为部分Artist设置图例,这时只需手动传入handles:

line_up, = plt.plot([1,2,3], label='Line 2')
line_down, = plt.plot([3,2,1], label='Line 1')
plt.legend(handles=[line_up, line_down])

当然了,相应的可以传入标签:

line_up, = plt.plot([1,2,3], label='Line 2')
line_down, = plt.plot([3,2,1], label='Line 1')
plt.legend([line_up, line_down], ['Line Up', 'Line Down'])

为一类Artist设置图例

并不是所有的Artist都能被自动设置为图例,也不是所有Artist都需要被设置为图例。

假如我们想要为所有红颜色的玩意儿设置图例:

import matplotlib.patches as mpatches

x = np.arange(1, 4)
fig, ax = plt.subplots()
for i in range(1, 10):
ax.plot(x, i * x, color = "red" if i % 2 else "blue") red_patch = mpatches.Patch(color="red")
# red_patch: <matplotlib.patches.Patch object at 0x00000228D0D4BF60>
plt.legend(handles=[red_patch], labels=["red line"])
plt.show()

如果没理解错,通过patches.Patch构造了一个颜色为红色的Artist类,然后legend()就会对所有满足条件的Artist的类进行处理(其实也用不了处理啊,只是加了图例)。错啦错啦,实际上,就是简单地造了一个颜色为红色的片,价格red line标签而已,跟已有的Artist没啥关系。



实际上,图例并不十分依赖于现有的Artist,我们完全可以随心所欲地添加:

import matplotlib.lines as mlines
blue_line = mlines.Line2D([], [], color='blue', marker='*',
markersize=15, label='Blue stars')
plt.legend(handles=[blue_line]) plt.show()

Legend 的位置 loc, bbox_to_anchor

legend()提供了loc参数,可以处理一般的位置。而bbox_to_anchor参数可以更加有效强大地来定位:

x = np.arange(1, 4)
fig, ax = plt.subplots()
for i in range(1, 10):
ax.plot(x, i * x, color = "red" if i % 2 else "blue", label="line{0}".format(i)) plt.legend(bbox_to_anchor=(1, 1),
bbox_transform=plt.gcf().transFigure)
plt.show()



bbox_to_anchor=(1,1)表示legend的位置在右上角,因为bbox_transform,我们将坐标转换为了当前figure的坐标系,也就是图例会放在整个图片的右上角,如果我们去掉这个选项:

plt.legend(bbox_to_anchor=(1, 1))



这个时候和下面是等价的:

plt.legend(bbox_to_anchor=(1,1),
bbox_transform=ax.transAxes)

即,此时的(1,1)表示的是Axes的右上角。

当我们这么做的时候:

plt.legend(bbox_to_anchor=(1, 1),
bbox_transform=ax.transData)

这个时候以数据,也就是我们看到的坐标为依据:

一个具体的例子

下面会用到的一些参数分析:

bbox_to_anchor: (x, y, width, height) 说实话,我并没有搞懂width, height的含义,有的时候能调正宽度,有的时候又不能

ncol: 图例的列数,有些时候图例太多,让他分成俩列三列啊

boderraxespad: axes与图例边界的距离。


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='lower left',
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='upper left', borderaxespad=1.) plt.show()

同一个Axes多个legend

如果我们多次使用legend(),实际上并不会生成多个图例:

fig, ax = plt.subplots()
line1, = ax.plot([1, 2, 3])
line2, = ax.plot([3, 2, 1])
ax.legend([line1], ["line1"])
ax.legend([line2], ["line2"]) plt.show()



为此,我们需要手动添加图例:

fig, ax = plt.subplots()
line1, = ax.plot([1, 2, 3])
line2, = ax.plot([3, 2, 1])
legend1 = ax.legend([line1], ["line1"], loc="upper right")
ax.add_artist(legend1)
ax.legend([line2], ["line2"]) plt.show()

Legend Handlers

没看懂啥意思。

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


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"])



从这例子中感觉,就是legend_handler里面有一些现成,稀奇古怪的图例供我们使用?

from matplotlib.legend_handler import HandlerLine2D, HandlerTuple

p1, = plt.plot([1, 2.5, 3], 'r-d')
p2, = plt.plot([3, 2, 1], 'k-o') l = plt.legend([(p1, p2)], ['Two keys'], numpoints=1,
handler_map={tuple: HandlerTuple(ndivide=None)})

自定义图例处理程序

这一节呢,主要就是告诉我们,如何通过handler_map这个参数,传入一个映射,可以构造任意?奇形怪状的图例?不过参数也忒多了吧,不过感觉蛮有用的。

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

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

"""都是啥和啥啊。。。"""
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 = mlines.Line2D([1, 2, 3, 4, 6], [1, 2, 3, 4, 6], linewidth=width/2, color='red',
transform=handlebox.get_transform())
handlebox.add_artist(patch)
return patch plt.legend([AnyObject()], ['My first handler'],
handler_map={AnyObject: AnyObjectHandler()})

函数链接

plt.lengend()-添加图例

get_legend_handles_labels()-获取图例处理对象和对应的标签

matplotlib.patches-包括向量,圆,矩形,多边形等等

legend_artist

matplotlib 进阶之Legend guide的更多相关文章

  1. matplotlib中的legend()—显示图例

    源自  matplotlib中的legend()——用于显示图例 -- 博客园 http://www.cnblogs.com/yinheyi/p/6792120.html legend()的一个用法: ...

  2. matplotlib 进阶之Tight Layout guide

    目录 简单的例子 Use with GridSpec Legend and Annotations Use with AxesGrid1 Colorbar 函数链接 matplotlib教程学习笔记 ...

  3. matplotlib 进阶之Constrained Layout Guide

    目录 简单的例子 Colorbars Suptitle Legends Padding and Spacing spacing with colobars rcParams Use with Grid ...

  4. matplotlib 入门之Usage Guide

    文章目录 Usage Guide plotting函数的输入 matplotlib, pyplot, pylab, 三者的联系 Coding style Backends 后端 matplotlib教 ...

  5. 【Python学习笔记】调整matplotlib的图例legend的位置

    有时默认的图例位置不符合我们的需要,那么我们可以使用下面的代码对legend位置进行调整. plt.legend(loc='String or Number', bbox_to_anchor=(num ...

  6. 【转】matplotlib制图——图例legend

    转自:https://www.cnblogs.com/alimin1987/p/8047833.html import matplotlib.pyplot as pltimport numpy as ...

  7. matplotlib中的legend()——用于显示图例

    legend()的一个用法: 当我们有多个 axes时,我们如何把它们的图例放在一起呢?? 我们可以这么做: import matplotlib.pyplot as plt import numpy ...

  8. 【python】matplotlib进阶

    参考文章:https://liam0205.me/2014/09/11/matplotlib-tutorial-zh-cn/ 几个重要对象:图像.子图.坐标轴.记号 figure:图像, subplo ...

  9. matplotlib 进阶之origin and extent in imshow

    目录 显示的extent Explicit extent and axes limits matplotlib教程学习笔记 import numpy as np import matplotlib.p ...

随机推荐

  1. 【vector+pair】洛谷 P4715 【深基16.例1】淘汰赛

    题目:P4715 [深基16.例1]淘汰赛 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 这道题因为数据范围不大,所以做法可以非常简单,使用一个vector加上pair就可以了: ...

  2. 一文读懂RESTful架构

    转载自https://zhuanlan.zhihu.com/p/381554129 RESTful架构究竟是什么 别着急,想要了解RESTful,我们先来了解一位大佬Roy Thomas Fieldi ...

  3. Centos 常用指令

    1.*.tar 用 tar  xvf 解压 2.*.gz 用 gzip  d或者gunzip 解压 3.*.tar.gz和*.tgz 用 tar xzf 解压 4.*.bz2 用 bzip2 d或者用 ...

  4. Python enumerate():使用计数器简化循环

    摘要:当您需要计数和迭代中的值时,Pythonenumerate()允许您编写 Pythonicfor循环.最大的优点enumerate()是它返回一个带有计数器和值的元组,因此您不必自己增加计数器. ...

  5. java的bio和nio写入及读取txt文件

    一.bio的写入及读取 1.采用bio之BufferedWriter 写入文件 public static void main(String[] args) throws IOException { ...

  6. IM即时通讯设计 高并发聊天服务:服务器 + qt客户端(附源码)

    来源:微信公众号「编程学习基地」 目录 IM即时通信程序设计 IM即时通讯 设计一款高并发聊天服务需要注意什么 如何设计可靠的消息处理服务 什么是粘包 什么是半包 解决粘包和半包 IM通信协议 应用层 ...

  7. Xpath 使用技巧

    使用xpath 简介 常见语法 选取节点 谓语 通配符 选取多个路径 运算符 其他用法 使用contains选取包含属性 使用tostring()将对象转换为字符串 使用starts-with 使用n ...

  8. ciscn_2019_s_4***(栈迁移)

    这是十分经典的栈迁移题目 拿到题目例行检查 32位程序开启了nx保护 进入ida,发现了很明显的system 我们进入main函数查看vul 可以看到溢出的部分不够我们rop所以这道题通过栈迁移去做 ...

  9. [BUUCTF]PWN——picoctf_2018_buffer overflow 1/2

    picoctf_2018_buffer overflow 1 附件 步骤: 例行检查,32位程序,没开保护 本地运行一下程序,看看程序大概的执行情况 32位ida载入,习惯性的检查程序里的字符串,发现 ...

  10. [BUUCTF]PWN——bjdctf_2020_babyrop2

    bjdctf_2020_babyrop2 附件 步骤: 例行检查,64位程序,开启了NX和canary保护 2. 试运行一下程序,看看大概的情况 提示我们去泄露libc 3. 64位ida载入,从ma ...