0. 前言

最近因为项目进度,需要使用matplotlib画图。等真正动手画图的时候,突然发现虽然使用matplotlib时间也不短了,但是认知好像还不是很清晰很全面。每次需要调一下格式,改变一下坐标轴形式什么的,都需要重新google搜索。离开了google感觉完全画不来图,效率也低,俗称的面向google编程。痛定思痛,等项目需求满足完,图画完以后,决心抽出时间来,好好整理一下matplotlib的相关知识点。

1.figure, axes, axis

很多同学,包括我自己,最初画图,都是从plt.figure(), plt.plot()这种方式开始的。但是这种方式,只是matplotlib提供了的一个api,如果想要画出更漂亮,更细致的图,这种方式可能就没法达到目的。

同时,在google的过程中,我们经常会发现matplotlib里面包含各种元素,像什么figure,axes,axis等等出现频率很高,而且实现的方式多种多样。综合自己的使用体验,感觉大家为什么开始阶段会对matplotlib迷茫,主要是对figure,axes,axis等这些概念理解不清楚。要对matplotlib理解清楚,首先需要从根本上理解清楚这些概念。

matplotlib官方文档

上面为官网地址,从官网上面先截一张图,通过这张图首先可以看得比较清晰。

上面这张图比较清晰的描述了matplotlib中的几个关键元素。

Figure
The whole figure (marked as the outer red box).
The figure keeps track of all the child Axes,
a smattering of ‘special’ artists (titles, figure legends, etc),
and the canvas.
(Don’t worry too much about the canvas,it is crucial as it is the object that actually does the drawing to get you your plot,
but as the user it is more-or-less invisible to you).
A figure can have any number of Axes, but to be useful should have at least one.

通过上面的描述,我们可以对figure元素下个简单定义:
figure是图中的红色区域,可以简单认为就是整个画布。画图的第一件事就是创建一个figure,然后基于该figure做各种操作。

Axes
This is what you think of as ‘a plot’,
it is the region of the image with the data space (marked as the inner blue box).
A given figure can contain many Axes,
but a given Axes object can only be in one Figure.
The Axes contains two (or three in the case of 3D) Axis objects
(be aware of the difference between Axes and Axis)
which take care of the data limits (the data limits can also be controlled via set via the set_xlim() and set_ylim() Axes methods).
Each Axes has a title (set via set_title()), an x-label (set via set_xlabel()), and a y-label set via set_ylabel()).

Axes这个名称很误导人,尤其容易与Axis混淆,文档里也提到了这点,但是这段文档的解释很精彩,把上面这段话看明白基本就明白了matplotlib中的大部分逻辑。

1.axes是你认为的’a plot’,图中的蓝色部分。换句话说,axes才是真正的图片内容。
2.一个figure里面可以包含多个axes,但是一个axes只能在一个figure中。
3.特别提示,Axes与Axis的不同。
4.数据范围的限制可以通过Axes中set_xlim与set_ylim方法。
5.每个Axes可以通过set_title设置一个title,通过set_xlabel与set_ylabel设置xlabel与ylabel。

Axis
These are the number-line-like objects (circled in green).
They take care of setting the graph limits and generating the ticks
(the marks on the axis)
and ticklabels (strings labeling the ticks).
The location of the ticks is determined by a Locator object and
the ticklabel strings are formatted by a Formatter.
The combination of the correct Locator and Formatter
gives very fine control over the tick locations and labels.

1.Axis是图中的绿色区域,是坐标轴的部分。
2.Axis可以控制图片的范围并生成ticks, ticks是axis上的标识。
3.ticks的位置是由Locator对象决定,格式由Formatter对象决定。
4.通过合适的Locator对象与Formatter对象,可以对tick的位置与样式进行很好的控制。

2.比较合理的画图方式

通过第一部分的分析,比较合理的画图可以为下面这种:

 fig, axes = plt.subplot()
def subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True,subplot_kw=None, gridspec_kw=None, **fig_kw):"""Create a figure and a set of subplots.This utility wrapper makes it convenient to create common layouts ofsubplots, including the enclosing figure object, in a single call.Parameters----------nrows, ncols : int, optional, default: 1Number of rows/columns of the subplot grid.......

通过subplots的源码注释不难看出,该方法Create a figure and a set of subplots.。产生的fig,axes就是我们上面提到的figure与axes,我们可以通过调整没一个axes来达到精细化画图的目的。

3.每个Axes中的元素

前面提到,我们得到Axes以后,就可以针对Axes对象开始调整各种元素画图。下面再通过官方文档里的一张图,可以了解Axes里面到底包含那些内容。

Matplotlib Basic Usage


图中的元素,包含有常用的line, grid, legend, markers, tick, title等等,画图的过程,实际上就是对这些元素调整优化的过程,下面我们可以来进行实验。

4.逐步优化画图

首先我们用subplots画个最基本的图

def plot_data():import matplotlib.pyplot as pltimport numpy as npfig, axes = plt.subplots(2, 1)y1 = np.random.randint(100, 110, 10)y2 = np.random.uniform(0.3, 0.6, 10)dates = np.arange(20211201, 20211211)axes[0].plot(dates, y1)axes[1].plot(dates, y2)plt.show()

上面的图,包含两幅子图,横坐标为dates,纵坐标分别为y1, y2。
图片效果如下

上面的图很明显各种问题
1.坐标轴被遮挡。
2.横坐标自动使用了科学计数法。

首先我们解决这两个问题,并加上标题。

def plot_data():import matplotlib.pyplot as pltimport numpy as npfig, axes = plt.subplots(2, 1)y1 = np.random.randint(100, 110, 10)y2 = np.random.uniform(0.3, 0.6, 10)dates = np.arange(20211201, 20211211)axes[0].plot(dates, y1)axes[1].plot(dates, y2)# 设置tick的格式为plainaxes[0].ticklabel_format(useOffset=False, style='plain')axes[1].ticklabel_format(useOffset=False, style='plain')# 设置标题axes[0].set_title("uv num")axes[1].set_title("ctr num")# 自动排版,让标题,坐标轴不遮挡fig.tight_layout()plt.show()


上面的图,x坐标的数字显示不全,我们先把所有的数字都显示出来

def plot_data():import matplotlib.pyplot as pltimport numpy as npfig, axes = plt.subplots(2, 1)y1 = np.random.randint(100, 110, 10)y2 = np.random.uniform(0.3, 0.6, 10)dates = np.arange(20211201, 20211211)axes[0].plot(dates, y1)axes[1].plot(dates, y2)# 设置tick的格式为plainaxes[0].ticklabel_format(useOffset=False, style='plain')axes[1].ticklabel_format(useOffset=False, style='plain')# 把所有ticks都显示axes[0].set_xticks(dates)axes[1].set_xticks(dates)# 设置标题axes[0].set_title("uv num")axes[1].set_title("ctr num")# 自动排版,让标题,坐标轴不遮挡fig.tight_layout()plt.show()


这个时候坐标重叠了,需要修改一下ticks样式

def plot_data():import matplotlib.pyplot as pltimport numpy as npfig, axes = plt.subplots(2, 1)y1 = np.random.randint(100, 110, 10)y2 = np.random.uniform(0.3, 0.6, 10)dates = np.arange(20211201, 20211211)axes[0].plot(dates, y1)axes[1].plot(dates, y2)# 设置tick的格式为plainaxes[0].ticklabel_format(useOffset=False, style='plain')axes[1].ticklabel_format(useOffset=False, style='plain')# 把所有ticks都显示axes[0].set_xticks(dates)axes[1].set_xticks(dates)# ticks旋转60度axes[0].tick_params(axis='x', labelsize='small', rotation=60)axes[1].tick_params(axis='x', labelsize='small', rotation=60)# 设置标题axes[0].set_title("uv num")axes[1].set_title("ctr num")# 自动排版,让标题,坐标轴不遮挡fig.tight_layout()plt.show()

我们希望对每个点做上标记,并对点,线的格式进行设置

def plot_data():import matplotlib.pyplot as pltimport numpy as npfig, axes = plt.subplots(2, 1)y1 = np.random.randint(100, 110, 10)y2 = np.random.uniform(0.3, 0.6, 10)dates = np.arange(20211201, 20211211)#显示每个数据点axes[0].plot(dates, y1, color="b", linewidth=1.0, marker="o", markerfacecolor='r', markersize = 4)axes[1].plot(dates, y2, color="b", linewidth=1.0, marker="o", markerfacecolor='r', markersize = 4)# 设置tick的格式为plainaxes[0].ticklabel_format(useOffset=False, style='plain')axes[1].ticklabel_format(useOffset=False, style='plain')# 把所有ticks都显示axes[0].set_xticks(dates)axes[1].set_xticks(dates)# ticks旋转60度axes[0].tick_params(axis='x', labelsize='small', rotation=60)axes[1].tick_params(axis='x', labelsize='small', rotation=60)# 设置标题axes[0].set_title("uv num")axes[1].set_title("ctr num")# 自动排版,让标题,坐标轴不遮挡fig.tight_layout()plt.show()


再给图片加上网格线

def plot_data():import matplotlib.pyplot as pltimport numpy as npfig, axes = plt.subplots(2, 1)y1 = np.random.randint(100, 110, 10)y2 = np.random.uniform(0.3, 0.6, 10)dates = np.arange(20211201, 20211211)#显示每个数据点axes[0].plot(dates, y1, color="b", linewidth=1.0, marker="o", markerfacecolor='r', markersize = 4)axes[1].plot(dates, y2, color="b", linewidth=1.0, marker="o", markerfacecolor='r', markersize = 4)# 设置tick的格式为plainaxes[0].ticklabel_format(useOffset=False, style='plain')axes[1].ticklabel_format(useOffset=False, style='plain')# 把所有ticks都显示axes[0].set_xticks(dates)axes[1].set_xticks(dates)# ticks旋转60度axes[0].tick_params(axis='x', labelsize='small', rotation=60)axes[1].tick_params(axis='x', labelsize='small', rotation=60)# 网格线axes[0].grid(which='major', axis='x', linewidth=0.75, linestyle='-', color='0.75')axes[0].grid(which='minor', axis='x', linewidth=0.25, linestyle='-', color='0.75')axes[0].grid(which='major', axis='y', linewidth=0.75, linestyle='-', color='0.75')axes[0].grid(which='minor', axis='y', linewidth=0.25, linestyle='-', color='0.75')axes[1].grid(which='major', axis='x', linewidth=0.75, linestyle='-', color='0.75')axes[1].grid(which='minor', axis='x', linewidth=0.25, linestyle='-', color='0.75')axes[1].grid(which='major', axis='y', linewidth=0.75, linestyle='-', color='0.75')axes[1].grid(which='minor', axis='y', linewidth=0.25, linestyle='-', color='0.75')# 设置标题axes[0].set_title("uv num")axes[1].set_title("ctr num")# 自动排版,让标题,坐标轴不遮挡fig.tight_layout()plt.show()


基本上,想要针对那个元素优化,参考Basic Usage图中对应的位置,设置相应的参数即可。

5.坐标轴显示指定时间格式

def plot_data():import matplotlib.pyplot as pltimport matplotlib.dates as mdatesimport numpy as npfrom datetime import datetimefig, axes = plt.subplots(2, 1)y1 = np.random.randint(100, 110, 10)y2 = np.random.uniform(0.3, 0.6, 10)dates = np.arange(20211201, 20211211)dates = [str(i) for i in dates]xs = [datetime.strptime(d, "%Y%m%d").date() for d in dates]# 把所有ticks都显示axes[0].set_xticks(xs)axes[1].set_xticks(xs)# ticks旋转60度axes[0].tick_params(axis='x', labelsize='small', rotation=60)axes[1].tick_params(axis='x', labelsize='small', rotation=60)axes[0].grid(which='major', axis='x', linewidth=0.75, linestyle='-', color='0.75')axes[0].grid(which='minor', axis='x', linewidth=0.25, linestyle='-', color='0.75')axes[0].grid(which='major', axis='y', linewidth=0.75, linestyle='-', color='0.75')axes[0].grid(which='minor', axis='y', linewidth=0.25, linestyle='-', color='0.75')axes[1].grid(which='major', axis='x', linewidth=0.75, linestyle='-', color='0.75')axes[1].grid(which='minor', axis='x', linewidth=0.25, linestyle='-', color='0.75')axes[1].grid(which='major', axis='y', linewidth=0.75, linestyle='-', color='0.75')axes[1].grid(which='minor', axis='y', linewidth=0.25, linestyle='-', color='0.75')# 将横坐标按指定日期格式显示axes[0].xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))axes[1].xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))# 设置标题axes[0].set_title("uv num")axes[1].set_title("ctr num")axes[0].plot(xs, y1, color="b", linewidth=1.0, marker="o", markerfacecolor='r', markersize = 4)axes[1].plot(xs, y2, color="b", linewidth=1.0, marker="o", markerfacecolor='r', markersize = 4)# 自动排版,让标题,坐标轴不遮挡fig.tight_layout()plt.show()

matplotlib易混概念理解与画图详解相关推荐

  1. python色卡_python matplotlib:plt.scatter() 大小和颜色参数详解

    语法 plt.scatter(x, y, s=20, c='b') 大小s默认为20,s=0时点不显示:颜色c默认为蓝色. 为每一个点指定大小和颜色 有时我们需要为每一个点指定大小和方向,以区分不同的 ...

  2. 【matplotlib】可视化之路——Rectangle类详解

    概述 Rectangle 类官方文档,以下是 maplotlib 库中的继承图: 由图可知 Rectangle 类继承自 Patch 类,关于 Patch 类,详情见 [matplotlib]可视化之 ...

  3. python不同颜色数值大小_python matplotlib:plt.scatter() 大小和颜色参数详解

    语法 plt.scatter(x, y, s=20, c='b') 大小s默认为20,s=0时点不显示:颜色c默认为蓝色. 为每一个点指定大小和颜色 有时我们需要为每一个点指定大小和方向,以区分不同的 ...

  4. 集合 (一) ----- 集合的基本概念与Collection集合详解

    相关文章: <集合 (一) ----- 集合的基本概念与Collection集合详解> <集合 (二) ----- Map集合详解> 文章目录 集合的基本概念 一.集合的分类 ...

  5. shell181网格划分_【2017年整理】ANSYS中SHELL181单元理解和参数详解.docx

    [2017年整理]ANSYS中SHELL181单元理解和参数详解 ANSYS中SHELL181单元参数详解 SHELL181单元说明: SHELL181单元适合对薄的到具有一定厚度的壳体结构进行分析. ...

  6. 矩概念与图像矩详解及其hu矩的运用

    一.矩概念详解 矩这个东西,能组成的名词太多了,矩形,就是长方形,矩阵,就是m行n列的二维数组,所以想了解矩,就要从其具体的场景中去理解. 今天我们要讲的图像矩,就是一个新的概念,图像矩就是图像的矩, ...

  7. Android vector Path Data画图详解

    下面来解释一下"M 100,240 C510,300 80,100 300,160 H40 v80"这样字符串的意义.  分为四种情况来解释:  1. 移动指令:Move Comm ...

  8. Qt-事件循环概念及循环函数详解

    Qt事件循环详解 事件循环简介 QT事件循环过程 启动事件循环 QEventLoop事件循环 QEventDispatcherUNIX事件处理 QCoreApplicationPrivate事件处理 ...

  9. android surface windows,Android易混概念辨析之Surface,Window,View,SurfaceView,Bitmap

    本文来自stackoverflow上的一个回答,很适合那些对这些概念感觉明白又说不明白它们之间的区别与联系的Android开发者. Surface 一个Surface就是一个对象,该对象持有一群像素( ...

  10. 阿里云的一些易混概念整理

    DBS,DTS,RDS,PTS区别: DBS:Database Backup Service,数据库备份服务,是为数据库提供连续数据保护.低成本的备份服务 DTS:Data Transmission ...

最新文章

  1. 书籍推荐——按内容划分
  2. linux perl 报错 Can‘t locate CPAN.pm in @INC (@INC contains: inc /usr/local/lib64/perl5 /usr.... 解决方法
  3. 【鸿蒙 HarmonyOS】Ability 简介 ( 简介 | 创建应用 | Page Ability 生命周期 )
  4. Linux -- gpasswd
  5. carsim学习笔记4——路面的一些设置1
  6. SQL中group by的用法
  7. python 生成 和 加载 requirements.txt
  8. 栈的输出_算法:栈和队列题目集合(一)
  9. 在浏览器设置里能看到cookie, 页面调试Application里看不到
  10. matlab 程序 收缩,基于MATLAB的小波收缩去噪方法研究(程序)
  11. 光伏机器人最前线_送水、送药、送餐!哈市这些地方率先用上AI配送机器人(视频)...
  12. 虚拟仿真实验室 服务器,网络及教学信息化平台-虚拟仿真实验室
  13. 微型计算机启天m425显卡驱动,Lenovo联想启天M425台式机NVIDIA VGA驱动26.21.14.4223版For Win10-64(2020年4月7日发布)...
  14. smartPrinter安装报错
  15. 局域网中使用来宾账户访问计算机
  16. CMOS与TTL电路的区别
  17. 点云配准之NDT算法
  18. 【Codeforces】1665E MinimizOR 题解
  19. SIMULIA 官方技术论坛全年时间表新鲜出炉!
  20. Scrapy 爬取百度贴吧指定帖子的发帖人和回帖人

热门文章

  1. Js中apply和Math.max()函数的问题及区别
  2. 总结之:CentOS 6.5 rsync+inotify实现数据实时同步备份
  3. 一.Spring boot食用指南:HELLO WORLD
  4. R6300V2 从 DD-WRT 回刷恢复 官方原厂固件   DD-WRT to R6300V2
  5. arduino 部分有用的函数
  6. 结合XML的数据检索技术
  7. python学习一:基本数据类型
  8. 这是阿里人手机里,这一年最舍不得删的照片
  9. 滴滴自研分布式NoSQL数据库Fusion的演进之路
  10. Solr系列三:solr索引详解(Schema介绍、字段定义详解、Schema API 介绍)