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读写excel的方法
Nov 18 Python
使用Python操作MySQL的一些基本方法
Aug 16 Python
Python与Java间Socket通信实例代码
Mar 06 Python
python实现分页效果
Oct 25 Python
利用python将json数据转换为csv格式的方法
Mar 22 Python
python将txt等文件中的数据读为numpy数组的方法
Dec 22 Python
Django框架组成结构、基本概念与文件功能分析
Jul 30 Python
Python中的self用法详解
Aug 06 Python
Python 自动登录淘宝并保存登录信息的方法
Sep 04 Python
python 爬虫百度地图的信息界面的实现方法
Oct 27 Python
jupyter 实现notebook中显示完整的行和列
Apr 09 Python
Scrapy模拟登录赶集网的实现代码
Jul 07 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
PL-880隐藏功能
2021/03/01 无线电
WindowsXP中快速配置Apache+PHP5+Mysql
2008/06/05 PHP
用Php编写注册后Email激活验证的实例代码
2013/03/11 PHP
注意:php5.4删除了session_unregister函数
2013/08/05 PHP
PHP简单实现上一页下一页功能示例
2016/09/14 PHP
PHP+JQUERY操作JSON实例
2017/03/23 PHP
JS的反射问题
2010/04/07 Javascript
js 去除字符串第一位逗号的方法
2014/06/07 Javascript
jQuery满屏焦点图左右滚动特效代码分享
2015/09/07 Javascript
js如何实现淡入淡出效果
2020/11/18 Javascript
JQuery中Ajax()的data参数类型实例分析
2015/12/15 Javascript
js表单处理中单选、多选、选择框值的获取及表单的序列化
2016/03/08 Javascript
JavaScript数据绑定实现一个简单的 MVVM 库
2016/04/08 Javascript
温习Javascript基础语法之词法结构
2016/05/31 Javascript
jQuery实现的小图列表,大图展示效果幻灯片示例
2016/10/25 Javascript
[50:38]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第二场 3月7日
2021/03/11 DOTA
Python lxml模块安装教程
2015/06/02 Python
Python实现翻转数组功能示例
2018/01/12 Python
matplotlib实现热成像图colorbar和极坐标图的方法
2018/12/13 Python
python Popen 获取输出,等待运行完成示例
2019/12/30 Python
tensorflow实现打印ckpt模型保存下的变量名称及变量值
2020/01/04 Python
Python如何获取文件路径/目录
2020/09/22 Python
美国第二大团购网站:LivingSocial
2016/07/24 全球购物
英国领先的珍珠首饰品牌:Orchira
2016/09/11 全球购物
塑料制成的可水洗的编织平底鞋和鞋子:Rothy’s
2018/09/16 全球购物
Urban Decay官方网站:美国化妆品品牌
2020/06/04 全球购物
如何判断一段程序是由C 编译程序还是由C++编译程序编译的
2013/08/04 面试题
什么是Connection-oriented Protocol/Connectionless Protocol面向连接的协议/无连接协议
2012/09/06 面试题
Java语言程序设计测试题改错题部分
2014/07/22 面试题
环境工程与管理大学毕业生求职信
2013/10/02 职场文书
2014年高三毕业生自我评价
2014/01/11 职场文书
英语教研活动总结
2014/07/02 职场文书
国庆节演讲稿范文2014
2014/09/19 职场文书
简易离婚协议书范本
2014/10/24 职场文书
2015年化验员工作总结
2015/04/10 职场文书