python Matplotlib基础--如何添加文本和标注


Posted in Python onJanuary 26, 2021

创建一个优秀的可视化图表的关键在于引导读者,让他们能理解图表所讲述的故事。在一些情况下,这个故事可以通过纯图像的方式表达,不需要额外添加文字,但是在另外一些情况中,图表需要文字的提示和标签才能将故事讲好。也许标注最基本的类型就是图表的标签和标题,但是其中的选项参数却有很多。让我们在本节中使用一些数据来创建可视化图表并标注这些图表来表达这些有趣的信息。首先还是需要将要用到的模块和包导入Pycharm:

import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('seaborn-whitegrid')
import numpy as np
import pandas as pd

例子:节假日对美国出生率的影响

本例中的数据可以在 https://raw.githubusercontent.com/jakevdp/data-CDCbirths/master/births.csv 下载。

我们先按照前面的方式进行同样的数据清洗程序,然后以图表展示这个结果:

births = pd.read_csv(r'D:\python\Github学习材料\Python数据科学手册\data\births.csv')

quartiles = np.percentile(births['births'], [25, 50, 75])
mu, sig = quartiles[1], 0.74 * (quartiles[2] - quartiles[0])
births = births.query('(births > @mu - 5 * @sig) & (births < @mu + 5 * @sig)')

births['day'] = births['day'].astype(int)

births.index = pd.to_datetime(10000 * births.year +
               100 * births.month +
               births.day, format='%Y%m%d')
births_by_date = births.pivot_table('births',
                  [births.index.month, births.index.day])
births_by_date.index = [pd.datetime(2012, month, day)
            for (month, day) in births_by_date.index]
fig, ax = plt.subplots(figsize=(12, 4))
births_by_date.plot(ax=ax);

python Matplotlib基础--如何添加文本和标注

当我们绘制了这样的图表来表达数据时,如果我们能对一些图表的特性作出标注来吸引读者的注意力通常是非常有帮助的。这可以通过调用plt.text或ax.text函数来实现,它们可以在某个特定的 x,y 轴位置输出一段文字:

fig, ax = plt.subplots(figsize=(12, 4))
births_by_date.plot(ax=ax)

# 在折线的特殊位置标注文字
style = dict(size=10, color='gray')

ax.text('2012-1-1', 3950, "New Year's Day", **style)
ax.text('2012-7-4', 4250, "Independence Day", ha='center', **style)
ax.text('2012-9-4', 4850, "Labor Day", ha='center', **style)
ax.text('2012-10-31', 4600, "Halloween", ha='right', **style)
ax.text('2012-11-25', 4450, "Thanksgiving", ha='center', **style)
ax.text('2012-12-25', 3850, "Christmas ", ha='right', **style)

# 设置标题和y轴标签
ax.set(title='USA births by day of year (1969-1988)',
    ylabel='average daily births')

# 设置x轴标签月份居中
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
ax.xaxis.set_minor_locator(mpl.dates.MonthLocator(bymonthday=15))
ax.xaxis.set_major_formatter(plt.NullFormatter())
ax.xaxis.set_minor_formatter(mpl.dates.DateFormatter('%h'));

python Matplotlib基础--如何添加文本和标注

ax.text方法接收 x 位置、y 位置、一个字符串和额外可选的关键字参数可以用来设置颜色、大小、样式、对齐等文本格式。上面我们使用了ha='right'和ha='center',这里的ha是*hirizonal alignment(水平对齐)*的缩写。要查阅更多的可用参数,请查看plt.text()和mpl.text.Text()的文档字符串内容。

转换和文本位置

在刚才的例子中,我们将文字标注根据数据位置进行了定位。有些时候我们需要将文字标注独立于数据位置而根据图表位置进行定位。Matplotlib 通过转换完成这项工作。

任何的图形显示框架都需要在坐标系统之间进行转换的机制。例如,一个数据点位于  被转换为图表中的某个位置,进而转换为屏幕上显示的像素。这样的坐标转换在数学上都相对来说比较直接,,而且 Matplotlib 提供了一系列的工具实现了转换(这些工具可以在matplotlib.transforms模块中找到)。

一般来说,用户很少需要关注这些转换的细节,但是当考虑将文本在图表上展示时,这些知识却比较有用。在这种情况中,下面三种定义好的转换是比较有用的:

  • ax.transData:与数据坐标相关的转换
  • ax.tranAxes:与 Axes 尺寸相关的转换(单位是 axes 的宽和高)
  • ax.tranFigure:与 figure 尺寸相关的转换(单位是 figure 的宽和高)

下面我们来看看使用这些转换将文字写在图表中不同位置的例子:

fig, ax = plt.subplots(facecolor='lightgray')
ax.axis([0, 10, 0, 10])

# transform=ax.transData是默认的,这里写出来是为了明确对比
ax.text(1, 5, ". Data: (1, 5)", transform=ax.transData)
ax.text(0.5, 0.1, ". Axes: (0.5, 0.1)", transform=ax.transAxes)
ax.text(0.2, 0.2, ". Figure: (0.2, 0.2)", transform=fig.transFigure);

python Matplotlib基础--如何添加文本和标注

注意默认情况下,文字是在指定坐标位置靠左对齐的:这里每个字符串开始的"."的位置就是每种转换的坐标位置。

transData坐标给定的是通常使用的 x 和 y 轴坐标位置。transAxes坐标给定的是从 axes 左下角开始算起(白色区域)的坐标位置,使用的是宽度和长度的占比。transFigure坐标类似,给定的是从 figure 左下角开始算起(灰色区域)的坐标位置,使用的也是宽度和长度的占比。

因此如果我们改变了轴的最大长度,只有transData坐标会收到影响,其他两个还是保持在相同位置:

ax.set_xlim(0, 2)
ax.set_ylim(-6, 6)
fig

python Matplotlib基础--如何添加文本和标注

这个变化可以通过动态改变轴的最大长度看的更加清楚:如果你在 notebook 执行这段代码,你可以将%matplotlib inline改为%matplotlib notebook,然后使用图表的菜单来交互式的改变图表。

箭头和标注

除了刻度标签和文字标签,另一种常用的标注是箭头。

在 Matplotlib 中绘制箭头通常比你想象的难得多。虽然有plt.arrow()函数,作者不建议使用它:这个函数绘制的箭头是一个 SVG 对象,因此在图表使用不同的比例的情况会产生问题,结果通常不能让用户满意。因此,作者建议使用plt.annotate()函数。这个函数会绘制一些文字以及一个箭头,并且箭头可以非常灵活的进行配置。

下面我们提供一些参数来使用annotate函数:

fig, ax = plt.subplots()

x = np.linspace(0, 20, 1000)
ax.plot(x, np.cos(x))
ax.axis('equal')

ax.annotate('local maximum', xy=(6.28, 1), xytext=(10, 4),
      arrowprops=dict(facecolor='black', shrink=0.05))

ax.annotate('local minimum', xy=(5 * np.pi, -1), xytext=(2, -6),
      arrowprops=dict(arrowstyle="->",
              connectionstyle="angle3,angleA=0,angleB=-90"));

python Matplotlib基础--如何添加文本和标注

箭头的样式是使用箭头属性字典值进行控制的,里面有很多可用的参数。这些参数在 Matplotlib 的在线文档中已经有了很详细的说明,因此在这里就不将这部分内容重复介绍一遍了。我们在前面出生率图上再使用一些参数进行更多的说明:

fig, ax = plt.subplots(figsize=(12, 4))
births_by_date.plot(ax=ax)
 
# 为图表添加标注
ax.annotate("New Year's Day", xy=('2012-1-1', 4100),  xycoords='data',
            xytext=(50, -30), textcoords='offset points',
            arrowprops=dict(arrowstyle="->",
                            connectionstyle="arc3,rad=-0.2"))
 
ax.annotate("Independence Day", xy=('2012-7-4', 4250),  xycoords='data',
            bbox=dict(boxstyle="round", fc="none", ec="gray"),
            xytext=(10, -40), textcoords='offset points', ha='center',
            arrowprops=dict(arrowstyle="->"))
 
ax.annotate('Labor Day', xy=('2012-9-4', 4850), xycoords='data', ha='center',
            xytext=(0, -20), textcoords='offset points')
ax.annotate('', xy=('2012-9-1', 4850), xytext=('2012-9-7', 4850),
            xycoords='data', textcoords='data',
            arrowprops={'arrowstyle': '|-|,widthA=0.2,widthB=0.2', })
 
ax.annotate('Halloween', xy=('2012-10-31', 4600),  xycoords='data',
            xytext=(-80, -40), textcoords='offset points',
            arrowprops=dict(arrowstyle="fancy",
                            fc="0.6", ec="none",
                            connectionstyle="angle3,angleA=0,angleB=-90"))
 
ax.annotate('Thanksgiving', xy=('2012-11-25', 4500),  xycoords='data',
            xytext=(-120, -60), textcoords='offset points',
            bbox=dict(boxstyle="round4,pad=.5", fc="0.9"),
            arrowprops=dict(arrowstyle="->",
                            connectionstyle="angle,angleA=0,angleB=80,rad=20"))
 
 
ax.annotate('Christmas', xy=('2012-12-25', 3850),  xycoords='data',
             xytext=(-30, 0), textcoords='offset points',
             size=13, ha='right', va="center",
             bbox=dict(boxstyle="round", alpha=0.1),
             arrowprops=dict(arrowstyle="wedge,tail_width=0.5", alpha=0.1));
 
# 设置图表标题和坐标轴标记
ax.set(title='USA births by day of year (1969-1988)',
       ylabel='average daily births')
 
# 设置月份坐标居中显示
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
ax.xaxis.set_minor_locator(mpl.dates.MonthLocator(bymonthday=15))
ax.xaxis.set_major_formatter(plt.NullFormatter())
ax.xaxis.set_minor_formatter(mpl.dates.DateFormatter('%h'));
 
ax.set_ylim(3600, 5400);

python Matplotlib基础--如何添加文本和标注

上图中箭头和文字框都非常详尽了:可以看出你几乎可以使用plt.annotate创建任何你想要的箭头样式。不幸的是,这意味着这种特性都需要手工进行调整,因此如果需要获得印刷质量的图像,这将是一个非常耗费时间的工作。最后,必须指出,上述这种多种样式混合的方式来展现数据肯定不是最佳实践,这里只是为了尽可能多的介绍可用的参数。

更多关于 Matplotlib 的箭头和标注样式的讨论和例子可以访问 Matplotlib gallery。

以上就是python Matplotlib基础--如何添加文本和标注的详细内容,更多关于python Matplotlib添加文本和标注的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
状态机的概念和在Python下使用状态机的教程
Apr 11 Python
介绍Python中内置的itertools模块
Apr 29 Python
详解Django中Request对象的相关用法
Jul 17 Python
Django使用httpresponse返回用户头像实例代码
Jan 26 Python
使用python装饰器计算函数运行时间的实例
Apr 21 Python
Python进阶之@property动态属性的实现
Apr 01 Python
用python拟合等角螺线的实现示例
Dec 27 Python
python 计算概率密度、累计分布、逆函数的例子
Feb 25 Python
pycharm远程连接vagrant虚拟机中mariadb数据库
Jun 05 Python
Python numpy矩阵处理运算工具用法汇总
Jul 13 Python
运行python提示no module named sklearn的解决方法
Nov 29 Python
Python使用pandas导入csv文件内容的示例代码
Dec 24 Python
python如何用matplotlib创建三维图表
Jan 26 #Python
python软件测试Jmeter性能测试JDBC Request(结合数据库)的使用详解
Jan 26 #Python
Python数据模型与Python对象模型的相关总结
Jan 26 #Python
使用豆瓣源来安装python中的第三方库方法
Jan 26 #Python
详解用selenium来下载小姐姐图片并保存
Jan 26 #Python
selenium与xpath之获取指定位置的元素的实现
Jan 26 #Python
详解Python中的Lock和Rlock
Jan 26 #Python
You might like
PHP+MySQL5.0中文乱码解决方法
2006/11/20 PHP
yii实现图片上传及缩略图生成的方法
2014/12/04 PHP
百度地图API使用方法详解
2015/08/25 PHP
php的lavarel框架中join和orWhere的用法
2020/12/28 PHP
奇妙的js
2007/09/24 Javascript
简明json介绍
2008/09/28 Javascript
jquery 使用点滴函数代码
2011/05/20 Javascript
基于jquery实现拆分姓名的方法(纯JS版)
2013/05/08 Javascript
JavaScript把数组作为堆栈使用的方法
2015/03/20 Javascript
Node.js中的流(Stream)介绍
2015/03/30 Javascript
Node.js编程中客户端Session的使用详解
2015/06/23 Javascript
利用jquery获取select下拉框的值
2016/11/23 Javascript
Vue.js实战之组件的进阶
2017/04/04 Javascript
微信小程序常用简易小函数总结
2019/02/01 Javascript
vue-cli3环境变量与分环境打包的方法示例
2019/02/18 Javascript
jquery 验证用户名是否重复代码实例
2019/05/14 jQuery
深入学习js函数的隐式参数 arguments 和 this
2019/06/24 Javascript
Python如何快速上手? 快速掌握一门新语言的方法
2017/11/14 Python
Python3实现带附件的定时发送邮件功能
2020/12/22 Python
用tensorflow搭建CNN的方法
2018/03/05 Python
Python切片操作深入详解
2018/07/27 Python
浅谈Python3 numpy.ptp()最大值与最小值的差
2019/08/24 Python
PyCharm无法引用自身项目解决方式
2020/02/12 Python
SpringBoot实现登录注册常见问题解决方案
2020/03/04 Python
python GUI模拟实现计算器
2020/06/22 Python
中国电子产品外贸网站:MiniIntheBox
2017/02/06 全球购物
JAVA高级程序员面试题
2013/09/06 面试题
初婚初育证明
2014/01/14 职场文书
《特殊的葬礼》教学反思
2014/04/27 职场文书
党的群众路线教育实践活动对照检查材料范文
2014/09/24 职场文书
2015年七一建党节演讲稿
2015/03/19 职场文书
MySQL 自定义变量的概念及特点
2021/05/13 MySQL
python爬虫之selenium库的安装及使用教程
2021/05/23 Python
TensorFlow的自动求导原理分析
2021/05/26 Python
Python机器学习之决策树和随机森林
2021/07/15 Javascript
CSS 一行代码实现头像与国旗的融合
2021/10/24 HTML / CSS