Matplotlib可视化入门,看这一篇就够了

Matplotlib是 Python 最著名的2D绘图库,提供了丰富的数据绘图工具,主要用于绘制一些统计图形。Matplotlib可用于Python脚本,Python和IPython shell,Jupyter笔记本,Web应用程序服务器和四个图形用户界面工具包。
matplotlib.pyplot API 官方教程
高效使用 Python 可视化工具 Matplotlib
相信初接触matplotlib肯定会有些困惑,同样一个目标有多个解决方案,有人用plt.xx,有人用ax.xx,对小白及其不友好,照葫芦画瓢搞出来了,但不明白为什么,写出来的代码很混乱。下次遇到问题依然一头雾水。我也是这样,所以,花时间读了很多文章,整理了一下知识点,入门够用了。另,涉及到的文章都贴出了链接,可以一并阅读,加深理解。
matplotlib架构 【Matplotlib可视化入门,看这一篇就够了】matplotlib的架构分为以下三层

  • Scripting (脚本)层
  • Artist (表现)层。拥有许多可视化元素,如figure、axes、axis等元素。
  • Backend (后端)层。包含 pyplot 和 pylab 模块(已弃用,不推荐)
它们之间的访问关系是:
Scripting 访问 Artist, Artist 访问 Backend
理论上各层都可以画出相同的图形,但越底层的操作越细节越困难,越高层越易于人机交互,越容易。也就是说上层是下层的封装,把一些不需要打交道的事情封装好,实际画图只关心效果即可。
matplotlib 架构
matplotlib两种绘图API 在Matplotlib库中提供了两种风格的API供开发者使用。这也就是为什么有人用plt.xx,有人用ax.xx的原因。好的代码应该坚持使用一种风格,否则会显得混乱,阅读起来困难,不利于维护。
  • Pyplot编程接口(state-based)不推荐
  • 面向对象的编程接口(object-based)推荐
之前有三种api,还有一种pylab api,模仿matlab的工作方式,但大量导入全局命名方式导致意外行为,被认为是糟糕的风格,matplotlib最新版中已弃用此方式。理解matplotlib、pylab与pyplot之间的关系
另外,pandas自带的df.plot()方法也可以绘制简单的图形,它是使用matplotlib库的plot()方法的简单包装实现的。最好不要用,pandas作为数据分析来用,绘图就交给matplotlib等专业的绘图库来做。下文也介绍一下,下次看到这种解决方案可以心中有数,不迷惑。
Matplotlib中的两种绘图API说明
matplotlib 实际上就是提供了 3 种API
Matplotlib中的plt和ax都是啥?
matplotlib:先搞明白plt. /ax./ fig再画

matplotlib图像的结构 Matplotlib可视化入门,看这一篇就够了
文章图片
matplotlib_PartsOfAFugure_2021_01_16 在matplotlib中,整个图像为一个Figure对象,相当于画板。在Figure对象中可以包含一个或者多个Axes对象(画纸)。每个Axes(ax)对象都是一个拥有自己坐标系统axis的绘图区域。
Python matplotlib结构详解
以两个例子来介绍两种方法的使用。下面两幅图分别用pyplot编程接口和面向对象编程接口实现。单子图、多子图都涉及到了,用法在代码里表达的很清楚了。
单子图柱状图
Matplotlib可视化入门,看这一篇就够了
文章图片
matplotlib_两种绘图api比较示例_单子图_2021_01_18 多子图柱状图
Matplotlib可视化入门,看这一篇就够了
文章图片
matplotlib_两种绘图api比较示例_多子图_2021_01_18 一些其他图形如折线图、散点图、饼图等跟示例的柱状图大同小异,各种参数自行学习。不容错过的Matplotlib常见用法小结 非常全面的Matplotlib画图方法、Matplotlib 1.4W+字教程的图形绘制部分
  • plot 折线图
  • bar 柱状图
  • barh 条形图
  • hist 直方图
  • pie 饼图
  • boxplot 箱形图
  • scatter 散点图
  • polar 极坐标图
Pyplot编程接口(state-based)不推荐 Pyplot封装了底层的绘图函数提供了一种绘图环境,当使用plt.xx绘制图形的时候,默认的Figure以及Axes等对象会自动创建以支持图形的绘制。此方式屏蔽了一些底层通用的绘图对象的创建细节,书写简洁。另外,pyplot是有状态的,亦即它会保存当前图片和作图区域的状态,新的作图函数会作用在当前图片的状态基础之上,代码的位置要注意。遇到一些比较复杂的图时不方便。官方推荐使用面向对象方式绘图。
import numpy as np import matplotlib.pyplot as plt # 准备数据 dog = (20, 28, 22, 30) cat = (25, 32, 20, 27)ind = np.arange(len(dog)) # 生成0-3的数组,用于x轴刻度值 quarter = ['一季度','二季度','三季度','四季度'] width = 0.35# 图形柱的宽度################################################# # 一个子图# 绘图 # x的位置调节好,不然两个柱会重叠 plt.bar(ind - width/2, dog, width, label='Dog') plt.bar(ind + width/2, cat, width, label='Cat')# 调节组件 plt.ylabel('销售额(万)') plt.title('各季度猫狗产业销售额') plt.xticks(ind,quarter) plt.legend(loc=2)# 保存图形 plt.savefig('matplotlib_pyplot方式单子图.png') ################################################################################################## # 多个子图。有状态,细节调整需在各个subplot内调节# 绘图 第一个子图 plt.subplot(121)#1行2列,占用第一个 plt.bar(ind, dog, width, color='dodgerblue', label='Dog')# 调节组件 plt.ylabel('销售额(万)') plt.title('各季度狗产业销售额') plt.xticks(ind,quarter)# 绘图 第二个子图 plt.subplot(122)#1行2列,占用第二个 plt.bar(ind, cat, width, color='darkorange', label='Cat')# 调节组件 plt.ylabel('销售额(万)') plt.title('各季度猫产业销售额') plt.xticks(ind,quarter)# 保存图形 plt.savefig('matplotlib_pyplot方式多子图.png') ################################################## 交互展示 plt.show()

面向对象的编程接口(object-based)推荐 面向对象的绘图方式主要使用matplotlib的两个子类:matplotlib.figure.Figure和matplotlib.axes.Axes。我们需要自己创建figure(画板),axes(画纸)。画板(figure)为matplotlib.figure.Figure的一个实例,每个子图(画纸,axes)为matplotlib.axes.Axes的一个实例,分别可以继承父类的所有方法,也就是说你绘图时,你想设置的元素(网格线啊,坐标刻度啊等)都可以在二者的属性中找出来使用。使用面向对象编程接口有利于我们对于图形绘制的完整控制,处理复杂图形更有优势。但是相对于Pyplot接口可能需要书写更多的代码。
import numpy as np import matplotlib.pyplot as plt# 准备数据 dog = (20, 28, 22, 30) cat = (25, 32, 20, 27)ind = np.arange(len(dog)) # 生成0-3的数组,用于x轴刻度值 quarter = ['一季度','二季度','三季度','四季度'] width = 0.35# 图形柱的宽度################################################# # 一个子图# 绘图 fig, ax = plt.subplots()# 实例画板fig画纸ax # x的位置调节好,不然两个柱会重叠 ax.bar(ind - width/2, dog, width, label='Dog') ax.bar(ind + width/2, cat, width, label='Cat')# 调节组件 ax.set_ylabel('销售额(万)') ax.set_title('各季度猫狗产业销售额') ax.set_xticks(ind) ax.set_xticklabels(quarter) ax.legend(loc=2)# 保存图形 fig.savefig('matplotlib_两种绘图api比较示例_单子图.png') ################################################################################################## # 多个子图。无状态,ax[0],ax[1]代表各子图# 绘图 fig, ax = plt.subplots(1,2) #(1,2)代表1行2列两个区域 # 设置图形对象 :窗口# ax[0]代表第一个子图,ax[1]代表第二个子图 ax[0].bar(ind, dog, width, color='dodgerblue', label='Dog') ax[1].bar(ind, cat, width, color='darkorange', label='Cat')# 调节组件 ax[0].set_ylabel('销售额(万)') ax[0].set_title('各季度狗产业销售额') ax[0].set_xticks(ind) ax[0].set_xticklabels(quarter)ax[1].set_ylabel('销售额(万)') ax[1].set_title('各季度猫产业销售额') ax[1].set_xticks(ind) ax[1].set_xticklabels(quarter)# 保存图形 fig.savefig('matplotlib_两种绘图api比较示例_多子图.png') ################################################## 交互展示 plt.show()# 面向对象接口不能使用交互式的show()方法对图像直接进行显示。如果想交互显示,需要用pyplot方式

pandas自带df.plot()方法 不要用 pandas自带的df.plot()方法也可以绘制简单的图形,它是使用matplotlib库的plot()方法的简单包装实现的。最好不要用,pandas作为数据分析来用,绘图就交给matplotlib等专业的绘图库来做。
import numpy as np import pandas as pd import matplotlib.pyplot as plt# 准备数据 dog = (20, 28, 22, 30) cat = (25, 32, 20, 27) data = https://www.it610.com/article/{'Dog': dog, 'Cat': cat}ind = np.arange(len(dog)) # 生成0-3的数组,用于x轴刻度值 quarter = ['一季度','二季度','三季度','四季度'] width = 0.35# 图形柱的宽度# 生成DataFrame df = pd.DataFrame(data,index=ind)# df.plot()方法绘图。kind代表绘图类型 ax = df.plot(kind='bar')# 调节组件 ax.set_ylabel('销售额(万)') ax.set_title('各季度猫狗产业销售额') ax.set_xticks(ind) ax.set_xticklabels(quarter) ax.legend(loc=2)# 交互展示 plt.show()

Matplotlib可视化入门,看这一篇就够了
文章图片
matplotlib_两种绘图api比较示例_单子图_2021_01_18 Pandas的可视化操作(利用pandas得到图表)
matplotlib组件详解 在matplotlib中,整个图像为一个Figure对象。在Figure对象中可以包含一个或者多个Axes对象。每个Axes(ax)对象都是一个拥有自己坐标系统的绘图区域。
matplotlib的图的构成元素
Matplotlib可视化入门,看这一篇就够了
文章图片
matplotlib_AnatomyOfAFigure_2021_01_16
  • 坐标轴(axis)
  • 坐标轴名称(axis label)
  • 坐标轴刻度(tick)
  • 坐标轴刻度标签(tick label)
  • 坐标轴边界(lim)
  • 网格线(grid)
  • 图例(legend)
  • 标题(title)
  • 边框(spine)
建议收藏!Matplotlib常见组件设置整理
中文乱码、负号显示 知乎问题-中文乱码、负号不能正常显示。看猴子的回答
设置标题 ax.set_title()
单子图用ax.,多子图用ax[].
ax.set_title('标题',fontdict={'size':16},loc = 'left')#设置16px的字体大小,将标题显示在左侧

设置边框(spine) ax.spines 默认图表中会显示上下左右四条spine,可根据需要设置为不显示
ax.spines['right'].set_visible(False)#去除右边的spines ax.spines['bottom'].set_color('r')#设置底部的spines为红色

设置坐标轴相关 设置坐标轴名称
ax.set_xlabel('季度',fontsize=16) ax.set_xlabel('销售额',fontsize=16)

设置坐标轴刻度标签
# 更改刻度标签。此例将0,1,2,3更改为一季度,二季度,三季度,四季度 ax.set_xticks(ind) ax.set_xticklabels(quarter)# 设置刻度标签属性 # axis : 可选{‘x’, ‘y’, ‘both’} ,选择对哪个轴操作,默认是’both’ # labelsize设置刻度标签的大小 # direction{‘in’, ‘out’, ‘inout’}刻度线的方向 # color : 刻度线的颜色 # labelcolor : 刻度值颜色 ax.tick_params(axis = 'y', labelsize=14,direction='in',labelcolor='r')

ax.tick_params()参数详解
设置刻度间隔
#从pyplot导入MultipleLocator类,这个类用于设置刻度间隔 from matplotlib.pyplot import MultipleLocator#把x轴的刻度间隔设置为1,并存在变量里 x_major_locator=MultipleLocator(1)#把y轴的刻度间隔设置为10,并存在变量里 y_major_locator=MultipleLocator(10)#把x轴的主刻度设置为1的倍数 ax.xaxis.set_major_locator(x_major_locator)#把y轴的主刻度设置为10的倍数 ax.yaxis.set_major_locator(y_major_locator)

设置坐标轴边界
ax.set_xlim([0,12])# x轴边界 ax.set_ylim([0,50])# y轴边界

设置图例 ax.legend() 图例是对图形所展示的内容的解释,比如在一张图中画了三条线,那么这三条线都代表了什么呢?这时就需要做点注释。
两种方式设置图例
# 第一种 # 绘图的时候加上label,之后调用ax.legend() ax.bar(ind - width/2, dog, width, label='Dog') ax.bar(ind + width/2, cat, width, label='Cat') ax.legend()# 第二种 # 使用ax.legend()按顺序设置好图例 ax.bar(ind - width/2, dog, width) ax.bar(ind + width/2, cat, width) ax.legend(['Dog','Cat'])

图例位置 loc参数用来规定图例的位置
如:将图例放在左上角:ax.legend(loc=2)
图例各位置如下
  • 0: ‘best'
  • 1: ‘upper right'
  • 2: ‘upper left'
  • 3: ‘lower left'
  • 4: ‘lower right'
  • 5: ‘right'
  • 6: ‘center left'
  • 7: ‘center right'
  • 8: ‘lower center'
  • 9: ‘upper center'
  • 10: ‘center'
设置网格线 ax.grid() 网格线多用于辅助查看具体的数值大小,横纵坐标都可以设置相应的网格线,视具体情况而论。
# b参数设置是否显示网格 # linestyle:线型 # color:颜色 # linewidth:宽度 # axis:x,y,both,显示x/y/两者的格网。默认both ax.grid(b = True, linestyle = "--",color = "gray", linewidth = "0.5",axis = 'y')

设置背景颜色 设置整个图像背景颜色
fig.set_facecolor('white')

设置某个子图背景颜色
ax.set_facecolor('white')

保存图像 fig.savefig 保存图像的时候可以设置分辨率
fig.savefig('xxx.png',dpi=300)

交互展示 ax.show() 显示最终绘制的图像
ax.show()

    推荐阅读