时间线是按时间顺序显示的事件列表。它通常是一个图形设计,显示一个长条,标有与之平行的日期,通常是同时期的事件。


A_New_Chart_of_History_color 来源:维基百科

时间线可以使用任何合适的比例来表示时间,适合主题和数据;许多人使用线性刻度,其中一个距离单位等于设定的时间量。此时间刻度取决于时间轴中的事件。

Matplotlib最初是由John D. Hunter编写的,第一个公开版本于2003年发布。在2012年8月John Hunter去世前不久,Michael Droettboom被提名为matplotlib的首席开发者,2014年Thomas Caswell加入,他现在(2021年)是首席开发者。最新的版本是3.4(撰写本文时),并且只支持Python 3,而2.2版本是一个长期支持的版本,兼容Python 2和Python 3。

Timeline绘图

时间线

绘图步骤

  1. 创建画布、设置字体大小、设置x、y坐标轴及标签

  2. 绘制直线图、空心的散点图

  3. 隐藏x、y坐标轴

代码

# step1
fig = plt.figure(figsize=(15, 6))
ax = fig.add_subplot(111, xlim=(2002.5, 2021.5), ylim=(0, 6.5), yticks=([]))
ax.tick_params("x", labelsize="x-small", which="major")
ax.set_xticks(np.arange(2003, 2022, 2))
# step2
plt.plot([2002.5, 2021.5], [0, 0], color="black", linewidth=1.0, clip_on=False)
X = np.arange(2003, 2022)
Y = np.zeros(len(X))
plt.scatter(X,Y,s=100,         # 散点大小linewidth=1.0, # 散点线宽zorder=10,     # 见注解clip_on=False, # 是否设置两个线相交时的剪辑edgecolor="black", # 散点的边缘颜色facecolor="white", # 散点的填充颜色
)
# step3
ax.spines["right"].set_visible(False)
ax.spines["left"].set_visible(False)
ax.spines["top"].set_visible(False)
ax.spines["bottom"].set_visible(False)

注解:

Matplotlibzorder 属性决定了物体与前景的距离。zorder 值较小的对象出现在更靠近背景的位置,而具有较大值的对象出现在更靠近前面的位置。例如,如果我正在制作一个带有线图的散点图,我可以通过增加它的 zorder 来将线向前移动。

标注

要掌握时间轴图绘制,需要先了解 Matplotlib 中的标注。标注分为基本标注和高级标注。

  • 基本标注:
    使用annotate()函数,其中由参数xy表示的标注位置和xytext的文本位置,这两个参数都是(x, y)元组。

  • 高级标注:
    使用框和文本来标注,在pyplot模块(或Axes类的text方法)中的text()函数接受bbox关键字参数,在文本周围绘制一个框。

关键点:箭头及文本,首先学习下箭头➡️如何绘制。

箭头风格

Matplotlib 里面画箭头通常比较困难,推荐使用 plt.annotate() 函数。这个函数既可以创建文字,也可以创建箭头,而且它创建的箭头能够进行非常灵活的配置。

箭头的风格是通过 arrowprops 字典控制的,里面有许多可用的选项。由于这些选项在 Matplotlib 的官方文档中都有非常详细的介绍,为了方便阅读,这里给大家列出一些常用的参数及其设置值。

Axes.annotate(self, s, xy, *args, **kwargs)
主要参数:
  • s:是注释的文本。

  • xy:是要注释的点(x, y)。

  • xytext:是可选参数。它是放置文本的位置(x, y)。

  • xycoords:被注释点的坐标系属性,允许输入的值如下

参数 坐标系
'figure points' 距离图形左下角的点数量
'figure pixels' 距离图形左下角的像素数量
'figure fraction' 0,0 是图形左下角,1,1 是右上角
'axes points' 距离轴域左下角的点数量
'axes pixels' 距离轴域左下角的像素数量
'axes fraction' 0,0 是轴域左下角,1,1 是右上角
'data' 使用轴域数据坐标系
  • textcoords:注释文本的坐标系属性,默认与xycoords属性值相同,也可设为不同的值。除了允许输入xycoords的属性值,还允许输入以下两种:

价值 描述
''offset points'' xy值的偏移量(以磅为单位)
''offset points'' xy值偏移(以像素为单位)
  • arrowprops:箭头的样式,dict(字典)型数据,如果该属性非空,则会在注释文本和被注释点之间画一个箭头。如果不设置'arrowstyle' 关键字,则允许包含以下关键字:

关键字 描述
width 箭头的宽度(单位是点)
headwidth 箭头头部的宽度(点)
headlength 箭头头部的长度(点)
shrink 箭头两端收缩的百分比(占总长)
? 任何 matplotlib.patches.FancyArrowPatch中的关键字

FancyArrowPatch的关键字包括:

关键字 描述
arrowstyle 箭头的样式
connectionstyle 连接线的样式
relpos 箭头起始点相对注释文本的位置,默认为 (0.5, 0.5),即文本的中心,(0,0)表示左下角,(1,1)表示右上角
patchA 箭头起点处的图形(matplotlib.patches对象),默认是注释文字框
patchB 箭头终点处的图形(matplotlib.patches对象),默认为空
shrinkA 箭头起点的缩进点数,默认为2
shrinkB 箭头终点的缩进点数,默认为2
mutation_scale default is text size (in points)
mutation_aspect default is 1.
? any key for `matplotlib.patches.PathPatch`[1]
  • annotation_clip :
    布尔值,可选参数,默认为空。设为True时,只有被注释点在子图区内时才绘制注释;设为False时,无论被注释点在哪里都绘制注释。仅当xycoords为 'data' 时,默认值空相当于True。

箭头

箭头的绘制需要几个步骤:

① 创建两个点之间的连接路径。这由connectionstyle键值控制。

② 如果提供了patch对象(patchApatchB),则会剪切路径以避开该patch。

③ 路径进一步由提供的像素总量来缩小(shirnkA&shrinkB

④ 路径转换为箭头patch,由arrowstyle键值控制。

连接路径

两个点之间的连接路径的创建由connectionstyle键控制,并且可用以下样式。

名称 属性
angle angleA=90,angleB=0,rad=0.0
angle3 angleA=90,angleB=0
arc angleA=0,angleB=0,armA=None,armB=None,rad=0.0
arc3 rad=0.0
bar armA=0.0,armB=0.0,fraction=0.3,angle=None

注意,angle3arc3中的3意味着所得到的路径是二次样条段(三个控制点)。如下面将讨论的,当连接路径是二次样条时,可以使用一些箭头样式选项。

ax.annotate(arrowprops=dict(connectionstyle=connectionstyle)

在函数ax.annotate()中的连接路径的参数arrowprops,而实际控制箭头样式的参数是connectionstyle,通过设置不同的connectionstyle以改变不同的箭头路径样式。

例如我们设置如下参数connectionstyle具体值,并绘制出如下样式。

"angle3,angleA=90,angleB=0"
"angle3,angleA=0,angleB=90"
"arc3,rad=0."
"arc3,rad=0.3"
"arc3,rad=-0.3"
"angle,angleA=-90,angleB=180,rad=0"
"angle,angleA=-90,angleB=180,rad=5"
"angle,angleA=-90,angleB=10,rad=5"
"arc,angleA=-90,angleB=0,armA=30,armB=30,rad=0"
"arc,angleA=-90,angleB=0,armA=30,armB=30,rad=5"
"arc,angleA=-90,angleB=0,armA=0,armB=40,rad=0"
"bar,fraction=0.3"
"bar,fraction=-0.3"
"bar,angle=180,fraction=-0.2"

箭头样式

后根据给定的箭头样式将连接路径(在剪切和收缩之后)变换为箭头补丁。

在函数ax.annotate()中的箭头样式的参数arrowprops,而实际控制箭头样式的参数是arrowstyle,通过设置不同的arrowstyle以改变不同的箭头样式。

ax.annotate(arrowprops=dict(arrowstyle=stylenames)

我们可以设置哪些arrowstyle参数呢?可以通过mpatches.ArrowStyle.get_styles()方法查看所有可以设置的样式。

styles = mpatches.ArrowStyle.get_styles()
print(styles.keys())
dict_keys(['-', '<-', '->', '<->', '<|-','-|>', '<|-|>', ']-[', ']-', '-[','|-|', 'simple', 'fancy', 'wedge'])

箭头位置

xy(箭头尖端)和 xytext 位置(文本位置)都以数据坐标为单位。这两个参数可以通过分别设置xycoords和textcoords来指定xyxytext的坐标系。

设置xyxytext的坐标系如下:

(3.2, 6.8) (2.0, 6.8)
(4.2, 5.8) (2.0, 5.8)
(4.2, 4.8) (3.4, 4.8)
(3.2, 3.8) (3.2, 2.8)

通过上述设置完成操作后,设置标注函数:

def annotate(ax, x, y, text, fc="#ff7777", y0=0):y = y - 0.5ax.annotate(" " + text + " ",xy=(x, y),xycoords="data",xytext=(0, 25),textcoords="offset points",color="white",size="x-small",va="center",ha="center",weight="bold",bbox=dict(boxstyle="round", fc=fc, ec="none"),arrowprops=dict(arrowstyle="wedge, tail_width=1.", fc=fc, ec="none", patchA=None), )plt.plot([x, x], [y, y0], color="black", linestyle=":", linewidth=0.75)

并且通过上述函数绘制各个事件:

annotate(ax, 2021, 4, "3.4")
annotate(ax, 2020, 3, "3.3")
annotate(ax, 2019, 4, "3.2")
annotate(ax, 2019, 2, "3.1")
annotate(ax, 2018, 3, "3.0", y0=1.5)
annotate(ax, 2018, 1, "2.2", fc="#777777")
annotate(ax, 2017, 4, "2.1", y0=2.5)
annotate(ax, 2017, 2, "2.0")
annotate(ax, 2015, 2, "1.5")
annotate(ax, 2014, 1, "1.4")
annotate(ax, 2013, 2, "1.3")
annotate(ax, 2012, 1, "1.2")
annotate(ax, 2011, 3, "1.1", y0=2.5)
annotate(ax, 2011, 2, "1.0")
annotate(ax, 2009, 1, "0.99")
annotate(ax, 2003, 1, "0.10")

文本注释

Axes.text(self, x, y, s, fontdict=None, withdash=, **kwargs)
主要参数:
  • x,y:表示坐标值上的值

  • string:表示说明文字

  • fontsize:表示字体大小

  • verticalalignment or va:垂直对齐方式 ,参数:[ 'center' |'top' | 'bottom' | 'baseline' ]

  • horizontalalignment or ha:水平对齐方式 ,参数:[ 'center' |'right' |'left' ]

matplotlib.text.Text实例有各种属性,可以通过关键字参数配置文本命令(例如,title()xlabel()text())。

你可以使用对齐参数horizontalalignmentverticalalignmentmultialignment来布置文本。

  • horizontalalignment控制文本的x位置参数表示文本边界框的左边,中间或右边。

  • verticalalignment控制文本的y位置参数表示文本边界框的底部,中心或顶部。

  • multialignment,仅对于换行符分隔的字符串,控制不同的行是左,中还是右对齐。

这里是一个使用text()命令显示各种对齐方式的例子。在整个代码中使用transform = ax.transAxes,表示坐标相对于轴边界框给出,其中0,0是轴的左下角,1,1是右上角。

通过绘制两个端点及横线组合,绘制区间线段。

x0, x1 = 2002.5, 2011.9
ax.plot([x0, x1], [5, 5], color="black", linewidth=1, marker="|", clip_on=False)
ax.text((x0 + x1) / 2, 5.1, "J.D. Hunter", ha="center", va="bottom", size="x-small")x0, x1 = 2012.1, 2017.9
ax.plot([x0, x1], [5, 5], color="black", linewidth=1, marker="|", clip_on=False)
ax.text((x0 + x1) / 2, 5.1, "M. Droettboom", ha="center", va="bottom", size="x-small")x0, x1 = 2014.1, 2021.5
ax.plot([x0, x1 + 1], [6, 6], color="black", linewidth=1, marker="|")
ax.text((x0 + x1) / 2, 6.1, "T. Caswell", ha="center", va="bottom", size="x-small"

参考资料

[1]

matplotlib.patches.PathPatch: https://matplotlib.org/api/_as_gen/matplotlib.patches.PathPatch.html#matplotlib.patches.PathPatch

[2]

connectionstyle源码: https://matplotlib.org/stable/gallery/userdemo/connectionstyle_demo.html

[3]

fancyarrow_demo源码: http://matplotlib.org/mpl_examples/pylab_examples/fancyarrow_demo.py

[4]

annotation_demo源码: https://matplotlib.org/stable/gallery/text_labels_and_annotations/annotation_demo.html

[5]

Scientific Visualisation-Python & Matplotlib

END

各位伙伴们好,詹帅本帅搭建了一个个人博客和小程序,汇集各种干货和资源,也方便大家阅读,感兴趣的小伙伴请移步小程序体验一下哦!(欢迎提建议)

推荐阅读

牛逼!Python常用数据类型的基本操作(长文系列第①篇)

牛逼!Python的判断、循环和各种表达式(长文系列第②篇)

牛逼!Python函数和文件操作(长文系列第③篇)

牛逼!Python错误、异常和模块(长文系列第④篇)

Matplotlib 可视化之箭头与标注的高级应用相关推荐

  1. Python使用matplotlib可视化面积图(Area Chart)、通过给坐标轴和曲线之间的区域着色可视化面积图、在面积图的指定区域添加箭头和数值标签

    Python使用matplotlib可视化面积图(Area Chart).通过给坐标轴和曲线之间的区域着色可视化面积图.在面积图的指定区域添加箭头和数值标签 目录

  2. python使用matplotlib可视化、使用annotate函数以及arrowprops参数在可视化图像中添加箭头和文本注释(arrow and text annotation)

    python使用matplotlib可视化.使用annotate函数以及arrowprops参数在可视化图像中添加箭头和文本注释(arrow and text annotation) 目录

  3. python使用matplotlib可视化线图(line plot)、使用arrow函数在matplotlib可视化图像中添加箭头(drawing arrows in matplotlib)

    python使用matplotlib可视化线图(line plot).使用arrow函数在matplotlib可视化图像中添加箭头(drawing arrows in matplotlib) 目录

  4. 太干了,全网最全的Matplotlib可视化教程

    导读 Matplotlib 是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形.通过 Matplotlib,开发者可以仅需要几行代码,便可以生成绘图,直 ...

  5. 可能是全网最全的Matplotlib可视化教程

    导读 Matplotlib 是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形.通过 Matplotlib,开发者可以仅需要几行代码,便可以生成绘图,直 ...

  6. matplotlib 柱状图 分组_Python数据分析与可视化之matplotlib可视化(三)

    散点图显示字段相关性 文章目录 加载远程的数据集 散点图与乱码问题 Matplotlib 是 Python 的绘图库. 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案. 默 ...

  7. Python 大数据分析疫情:如何实现实时数据爬取及 Matplotlib 可视化?

    作者 | 杨秀璋 来源 | CSDN博客专家Eastmount 责编 | 夕颜 思来想去,虽然很忙,但还是挤时间针对这次肺炎疫情写个Python大数据分析系列博客,包括网络爬虫.可视化分析.GIS地图 ...

  8. Python+matplotlib可视化自定义轴域大小和位置

    推荐图书: <Python可以这样学>,ISBN:9787302456469,董付国,清华大学出版社,第9次印刷 图书详情(京东): 董付国老师17本Python系列图书均提供配套教学资源 ...

  9. python 可视化 二维坐标标注等等

    python 可视化 二维坐标标注等等 - 蔡军帅 - 博客园https://www.cnblogs.com/caiyishuai/p/9607250.html 大佬的分享,在这里方便自己总结学习,因 ...

最新文章

  1. Linux下l2tp客户端xl2tpd的安装配置
  2. android 之开关控件的使用
  3. Fabric--启动网络手动
  4. linux hadoop测试,快速搭建Hadoop环境并测试mapreduce
  5. 2014\Province_C_C++_B\3 李白打酒
  6. C++ 基类,子对象,派生类构造函数调用顺序
  7. 【BZOJ - 4318】OSU!(概率dp,数学期望,期望的线性性)
  8. GitHub开源项目 - Jeecg-Boot开始开发平台介绍
  9. 在浏览器中输入url地址 - 显示主页的过程
  10. LeetCode所有题目答案汇总
  11. python机器人编程教材_python人工智能机器人工具书籍: Learn Robotics Programming(python and Raspberry Pi 3) - 2018...
  12. 【项目实战——emos在线办公系统】:会议申请、请假申请等部分代码理解
  13. 标准modbus测试软件怎么用,Modbus测试软件使用说明
  14. Machine Learning读书会·北京今日启动(第3期周爱民、张帆)
  15. 半/全加器中的异或门和与门的应用
  16. iOS 【奇巧淫技】获取webView内容高度
  17. calendar java起始于结束时间,java获取一天的开始时间和一天的结束时间
  18. 简单常用JS函数集合大全107个
  19. css关键词:inherit、initial、overlay、revert、unset解释
  20. 电气工程及其自动化-课程体系介绍

热门文章

  1. 背景-需要-需求规格
  2. 利用JavaScript选择GridView行
  3. 响应式布局html像素值计算,CSS Calc():制作响应式网格布局的锋利武器
  4. Mysql 常用函数(19)- mod 函数
  5. Tomcat安装及配置教程(超详细的图文教程)(亲测)
  6. uWSGI + Nginx + Django 部署
  7. 关于在centos下安装python3.7.0以上版本时报错ModuleNotFoundError No module named _ctypes 的解决办法
  8. MySQL主从复制延时方法
  9. RabbitMQ报错NOT_ALLOWED - access to vhost ‘/‘ refused for user ‘zq‘(10, 40)
  10. redis日志_为什么我的Redis这么“慢”?