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实现Tab自动补全和历史命令管理的方法
Mar 12 Python
Python3安装Pymongo详细步骤
May 26 Python
详解python中executemany和序列的使用方法
Aug 12 Python
python交互式图形编程实例(一)
Nov 17 Python
Python中生成器和迭代器的区别详解
Feb 10 Python
Python子类继承父类构造函数详解
Feb 19 Python
python matplotlib库直方图绘制详解
Aug 10 Python
python numpy数组中的复制知识解析
Feb 03 Python
Python3标准库之functools管理函数的工具详解
Feb 27 Python
详解pycharm配置python解释器的问题
Oct 15 Python
浅谈Selenium 控制浏览器的常用方法
Dec 04 Python
Python 恐龙跑跑小游戏实现流程
Feb 15 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实现ping
2006/10/09 PHP
十天学会php(3)
2006/10/09 PHP
MayFish PHP的MVC架构的开发框架
2009/08/13 PHP
PHP中exec与system用法区别分析
2014/09/22 PHP
yii2 开发api接口时优雅的处理全局异常的方法
2019/05/14 PHP
textarea的value是html文件源代码,存成html文件的代码
2007/04/20 Javascript
JavaScript 拾漏补遗
2009/12/27 Javascript
使用jQuery.fn自定义jQuery翻页插件
2013/01/20 Javascript
jquery实现select选中行、列合计示例
2014/04/25 Javascript
关于img的href和src取变量及赋值的方法
2014/04/28 Javascript
jQuery 1.9移除了$.browser可以使用$.support来替代
2014/09/03 Javascript
javascript实现俄罗斯方块游戏的思路和方法
2015/04/27 Javascript
BootStrap Validator对于隐藏域验证和程序赋值即时验证的问题浅析
2016/12/01 Javascript
WebView启动支付宝客户端支付失败的问题小结
2017/01/11 Javascript
js实现鼠标拖拽多选功能示例
2017/08/01 Javascript
详解VScode编辑器vue环境搭建所遇问题解决方案
2019/04/26 Javascript
微信小程序如何修改本地缓存key中单个数据的详解
2019/04/26 Javascript
D3.js的基础部分之数组的处理数组的排序和求值(v3版本)
2019/05/09 Javascript
原生js实现html手机端城市列表索引选择城市
2020/06/24 Javascript
nuxt引入组件和公共样式的操作
2020/11/05 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
2020/11/06 Javascript
[01:34]2016国际邀请赛中国区预选赛IG战队教练采访
2016/06/27 DOTA
开始着手第一个Django项目
2015/07/15 Python
13个最常用的Python深度学习库介绍
2017/10/28 Python
对python3标准库httpclient的使用详解
2018/12/18 Python
基于Python的PIL库学习详解
2019/05/10 Python
如何通过Python实现RabbitMQ延迟队列
2020/11/28 Python
哥伦比亚最大的网上商店:Linio哥伦比亚
2016/09/25 全球购物
ajax是什么及其工作原理
2012/02/08 面试题
工商管理专业实习生自我鉴定
2013/09/29 职场文书
大专自我鉴定范文
2013/10/01 职场文书
大一学生假期实习的自我评价
2013/10/12 职场文书
植树节活动总结
2014/04/30 职场文书
办公室主任个人总结
2015/02/28 职场文书
幼儿园元旦主持词
2015/07/06 职场文书
详解Java实践之适配器模式
2021/06/18 Java/Android