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使用xlrd模块读写Excel文件的方法
May 06 Python
Python numpy生成矩阵、串联矩阵代码分享
Dec 04 Python
利用Python批量提取Win10锁屏壁纸实战教程
Mar 27 Python
python 获取字符串MD5值方法
May 29 Python
详解基于django实现的webssh简单例子
Jul 17 Python
python 3.6.4 安装配置方法图文教程
Sep 18 Python
python实现给scatter设置颜色渐变条colorbar的方法
Dec 13 Python
深度辨析Python的eval()与exec()的方法
Mar 26 Python
教你如何编写、保存与运行Python程序的方法
Jul 12 Python
Python必须了解的35个关键词
Jul 16 Python
Python自定义sorted排序实现方法详解
Sep 18 Python
Python中Yield的基本用法
Oct 18 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使之能同时支持GIF和JPEG
2006/10/09 PHP
解析php file_exists无效的解决办法
2013/06/26 PHP
windows下配置apache+php+mysql时出现问题的处理方法
2014/06/20 PHP
JavaScript实际应用:innerHTMl和确认提示的使用
2006/06/22 Javascript
JavaScript Undefined,Null类型和NaN值区别
2008/10/22 Javascript
js 禁用浏览器的后退功能的简单方法
2008/12/10 Javascript
jquery序列化方法实例分析
2015/06/10 Javascript
学习JavaScript鼠标响应事件
2015/12/25 Javascript
深入浅析Extjs中store分组功能的使用方法
2016/04/20 Javascript
基于jQuery实现表格内容的筛选功能
2016/08/21 Javascript
ionic在开发ios系统微信时键盘挡住输入框的解决方法(键盘弹出问题)
2016/09/06 Javascript
完美解决node.js中使用https请求报CERT_UNTRUSTED的问题
2017/01/08 Javascript
easyui关于validatebox实现多重规则验证的方法(必看)
2017/04/12 Javascript
js中变量的连续赋值(实例讲解)
2017/07/08 Javascript
vue2利用Bus.js如何实现非父子组件通信详解
2017/08/25 Javascript
基于js中document.cookie全面解析
2017/09/14 Javascript
详解NODEJS基于FFMPEG视频推流测试
2017/11/17 NodeJs
vue项目base64字符串转图片的实现代码
2018/07/13 Javascript
基于Webpack4和React hooks搭建项目的方法
2019/02/05 Javascript
javascript 设计模式之组合模式原理与应用详解
2020/04/08 Javascript
写一个Vue loading 插件
2020/11/09 Javascript
python中的实例方法、静态方法、类方法、类变量和实例变量浅析
2014/04/26 Python
Python中操作MySQL入门实例
2015/02/08 Python
使用Python生成url短链接的方法
2015/05/04 Python
Python 40行代码实现人脸识别功能
2017/04/02 Python
利用python脚本如何简化jar操作命令
2019/02/24 Python
详解css3中的伪类before和after常见用法
2020/11/17 HTML / CSS
JAVA的事件委托机制和垃圾回收机制
2014/09/07 面试题
医院辞职信范文
2014/01/17 职场文书
国际贸易毕业生求职信范文
2014/02/21 职场文书
中专生毕业个人鉴定
2014/02/26 职场文书
安全生产计划书
2014/05/04 职场文书
劳动竞赛口号
2014/06/16 职场文书
国家奖学金获奖感言
2014/08/16 职场文书
2015年学校总务工作总结
2015/07/20 职场文书
python 实现的截屏工具
2021/05/08 Python